@heybox/hb-sdk-protocol 0.8.3-alpha.3 → 0.8.3-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -445,7 +445,7 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
445
445
  * @see [parseMiniProgramRuntimePermissions](/reference/symbols/protocol/functions/parseMiniProgramRuntimePermissions) Runtime 权限快照解析器。
446
446
  */
447
447
  function isMiniProgramBridgeMessage(value) {
448
- if (!isRecord$2(value))
448
+ if (!isRecord$3(value))
449
449
  return false;
450
450
  if (value.namespace !== MINI_PROGRAM_MESSAGE_NAMESPACE || (value.version !== 1 && value.version !== 2) || !isNonEmptyString$1(value.nonce)) {
451
451
  return false;
@@ -595,7 +595,7 @@ function isMiniProgramRelativePath(value) {
595
595
  * @see [DirectoryHandle](/reference/symbols/root/interfaces/DirectoryHandle) 可作为 derived path root 的目录代理。
596
596
  */
597
597
  function isMiniProgramPathRootRef(value) {
598
- if (!isRecord$2(value))
598
+ if (!isRecord$3(value))
599
599
  return false;
600
600
  if (value.kind === 'sandbox')
601
601
  return hasOnlyKeys(value, ['kind']);
@@ -661,7 +661,7 @@ function isMiniProgramPathRootRef(value) {
661
661
  * @see [FileHandle](/reference/symbols/root/interfaces/FileHandle) 使用文件引用的公开 I/O 代理。
662
662
  */
663
663
  function isMiniProgramFileRef(value) {
664
- if (!isRecord$2(value) || value.kind !== 'file')
664
+ if (!isRecord$3(value) || value.kind !== 'file')
665
665
  return false;
666
666
  if (isNonEmptyString$1(value.handleId)) {
667
667
  return hasOnlyKeys(value, ['kind', 'handleId']);
@@ -728,7 +728,7 @@ function isMiniProgramFileRef(value) {
728
728
  * @see [DirectoryHandle](/reference/symbols/root/interfaces/DirectoryHandle) 使用目录引用的公开路径操作代理。
729
729
  */
730
730
  function isMiniProgramDirectoryRef(value) {
731
- if (!isRecord$2(value) || value.kind !== 'directory')
731
+ if (!isRecord$3(value) || value.kind !== 'directory')
732
732
  return false;
733
733
  if (isNonEmptyString$1(value.handleId)) {
734
734
  return hasOnlyKeys(value, ['kind', 'handleId']);
@@ -802,7 +802,7 @@ function isMiniProgramDirectoryRef(value) {
802
802
  * @see [SaveFileResult](/reference/symbols/protocol/types/SaveFileResult) save picker 的 direct-ref 文件结果。
803
803
  */
804
804
  function isMiniProgramFileDescriptor(value) {
805
- return (isRecord$2(value) &&
805
+ return (isRecord$3(value) &&
806
806
  value.kind === 'file' &&
807
807
  isNonEmptyString$1(value.name) &&
808
808
  isFileMode(value.mode) &&
@@ -872,7 +872,7 @@ function isMiniProgramFileDescriptor(value) {
872
872
  * @see [PickDirectoryResult](/reference/symbols/protocol/types/PickDirectoryResult) picker 的 direct-ref 返回契约。
873
873
  */
874
874
  function isMiniProgramDirectoryDescriptor(value) {
875
- return (isRecord$2(value) &&
875
+ return (isRecord$3(value) &&
876
876
  value.kind === 'directory' &&
877
877
  isNonEmptyString$1(value.name) &&
878
878
  isFileMode(value.mode) &&
@@ -1051,7 +1051,7 @@ function isMiniProgramByteArray(value) {
1051
1051
  * @see [FileHandle](/reference/symbols/root/interfaces/FileHandle) 提供 `stat()` 的当前 session 文件代理。
1052
1052
  */
1053
1053
  function isMiniProgramFileStat(value) {
1054
- return (isRecord$2(value) &&
1054
+ return (isRecord$3(value) &&
1055
1055
  value.kind === 'file' &&
1056
1056
  isNonNegativeSafeInteger(value.size) &&
1057
1057
  (value.modifiedAt === undefined || isNonNegativeFiniteNumber(value.modifiedAt)) &&
@@ -1111,7 +1111,7 @@ function isMiniProgramFileStat(value) {
1111
1111
  * @see [isMiniProgramBridgeMessage](/reference/symbols/protocol/functions/isMiniProgramBridgeMessage) operation progress envelope 的最低校验。
1112
1112
  */
1113
1113
  function isMiniProgramDownloadProgressPayload(value) {
1114
- if (!isRecord$2(value) ||
1114
+ if (!isRecord$3(value) ||
1115
1115
  !isNonNegativeSafeInteger(value.loaded) ||
1116
1116
  typeof value.lengthComputable !== 'boolean' ||
1117
1117
  !hasOnlyKeys(value, ['loaded', 'total', 'lengthComputable'])) {
@@ -1122,7 +1122,7 @@ function isMiniProgramDownloadProgressPayload(value) {
1122
1122
  return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
1123
1123
  }
1124
1124
  function isMiniProgramCompanionPrepareProgress(value) {
1125
- if (!isRecord$2(value))
1125
+ if (!isRecord$3(value))
1126
1126
  return false;
1127
1127
  if (value.phase === 'downloading') {
1128
1128
  return (isNonNegativeSafeInteger(value.loaded) &&
@@ -1140,10 +1140,10 @@ function isMiniProgramOperationProgressPayload(value) {
1140
1140
  return isMiniProgramDownloadProgressPayload(value) || isMiniProgramCompanionPrepareProgress(value);
1141
1141
  }
1142
1142
  function isSDKHandshakePayload(value) {
1143
- return isRecord$2(value) && isNonEmptyString$1(value.href) && typeof value.userAgent === 'string' && isNonEmptyString$1(value.sdkVersion);
1143
+ return isRecord$3(value) && isNonEmptyString$1(value.href) && typeof value.userAgent === 'string' && isNonEmptyString$1(value.sdkVersion);
1144
1144
  }
1145
1145
  function isBridgeError(value) {
1146
- return isRecord$2(value) && isNonEmptyString$1(value.code) && typeof value.message === 'string';
1146
+ return isRecord$3(value) && isNonEmptyString$1(value.code) && typeof value.message === 'string';
1147
1147
  }
1148
1148
  function isFileMode(value) {
1149
1149
  return value === 'read' || value === 'readwrite';
@@ -1161,156 +1161,10 @@ function hasOnlyKeys(value, allowedKeys) {
1161
1161
  const allowed = new Set(allowedKeys);
1162
1162
  return Object.keys(value).every((key) => allowed.has(key));
1163
1163
  }
1164
- function isRecord$2(value) {
1164
+ function isRecord$3(value) {
1165
1165
  return typeof value === 'object' && value !== null && !Array.isArray(value);
1166
1166
  }
1167
1167
 
1168
- /** 由 scripts/generate-native-host-contract.mjs 生成,请勿手改。 */
1169
- const MINI_PROGRAM_NATIVE_HOST_PROTOCOL_VERSION = 1;
1170
- const MINI_PROGRAM_NATIVE_HOST_CONTRACT_REVISION = 1;
1171
- const MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES = 65536;
1172
- const MINI_PROGRAM_NATIVE_OPERATIONS = {
1173
- "system": [
1174
- "describe"
1175
- ],
1176
- "network": [
1177
- "open",
1178
- "read",
1179
- "release",
1180
- "transfer"
1181
- ],
1182
- "files": [
1183
- "create",
1184
- "remove",
1185
- "exists",
1186
- "openRead",
1187
- "openWrite",
1188
- "read",
1189
- "release",
1190
- "write",
1191
- "stat",
1192
- "list",
1193
- "pickFiles",
1194
- "pickDirectory",
1195
- "saveFile"
1196
- ]
1197
- };
1198
- const MINI_PROGRAM_NATIVE_HOST_DESCRIPTION = {
1199
- "protocolVersion": 1,
1200
- "contractRevision": 1,
1201
- "operations": {
1202
- "system": [
1203
- "describe"
1204
- ],
1205
- "network": [
1206
- "open",
1207
- "read",
1208
- "release",
1209
- "transfer"
1210
- ],
1211
- "files": [
1212
- "create",
1213
- "remove",
1214
- "exists",
1215
- "openRead",
1216
- "openWrite",
1217
- "read",
1218
- "release",
1219
- "write",
1220
- "stat",
1221
- "list",
1222
- "pickFiles",
1223
- "pickDirectory",
1224
- "saveFile"
1225
- ]
1226
- }
1227
- };
1228
-
1229
- /** Android WebMessageListener object 与 iOS WKScriptMessageHandler 共用名称。 */
1230
- const MINI_PROGRAM_NATIVE_HOST_OBJECT = 'hbMiniProgramHost';
1231
- /** Native 通过主文档 CustomEvent 回送 progress/result/error。 */
1232
- const MINI_PROGRAM_NATIVE_HOST_MESSAGE_EVENT = 'heybox:miniprogram-native-host-message';
1233
- function isMiniProgramNativeHostMessage(value) {
1234
- if (!isRecord$1(value) || !isNonEmptyString(value.requestId))
1235
- return false;
1236
- if (value.type === 'progress')
1237
- return Object.prototype.hasOwnProperty.call(value, 'payload');
1238
- if (value.type === 'result')
1239
- return !Object.prototype.hasOwnProperty.call(value, 'error');
1240
- if (value.type !== 'error' || !isRecord$1(value.error))
1241
- return false;
1242
- return isNonEmptyString(value.error.code) && isNonEmptyString(value.error.message);
1243
- }
1244
- function isMiniProgramNativeHostDescription(value) {
1245
- if (!isRecord$1(value) ||
1246
- !isPositiveSafeInteger(value.protocolVersion) ||
1247
- !isPositiveSafeInteger(value.contractRevision) ||
1248
- !isRecord$1(value.operations))
1249
- return false;
1250
- const operations = value.operations;
1251
- if (!isOperationList(operations.system) ||
1252
- !isOperationList(operations.network) ||
1253
- !isOperationList(operations.files))
1254
- return false;
1255
- return operations.system.includes('describe');
1256
- }
1257
- function isMiniProgramNativeBinaryChunk(value) {
1258
- return (isRecord$1(value) &&
1259
- isNonEmptyString(value.resourceId) &&
1260
- typeof value.data === 'string' &&
1261
- Number.isSafeInteger(value.byteLength) &&
1262
- Number(value.byteLength) >= 0 &&
1263
- Number(value.byteLength) <= MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES &&
1264
- typeof value.eof === 'boolean' &&
1265
- (Number(value.byteLength) > 0 || value.eof));
1266
- }
1267
- function isRecord$1(value) {
1268
- return value !== null && typeof value === 'object' && !Array.isArray(value);
1269
- }
1270
- function isNonEmptyString(value) {
1271
- return typeof value === 'string' && value.length > 0;
1272
- }
1273
- function isPositiveSafeInteger(value) {
1274
- return Number.isSafeInteger(value) && Number(value) > 0;
1275
- }
1276
- function isOperationList(value) {
1277
- return (Array.isArray(value) &&
1278
- value.every(operation => isNonEmptyString(operation) && operation === operation.trim()) &&
1279
- new Set(value).size === value.length);
1280
- }
1281
-
1282
- /** 当前用户信息与登录能力支持的完整 scope 目录(canonical 顺序)。 */
1283
- const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile', 'steam_account'];
1284
- /** Companion alias 的跨构建、Runtime 与 Host 规范。 */
1285
- const COMPANION_ALIAS_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;
1286
- /** Companion Host 可跨 bridge 保留的稳定领域错误码。 */
1287
- const COMPANION_ERROR_CODES = [
1288
- 'COMPANION_UNSUPPORTED',
1289
- 'COMPANION_PREVIEW_UNSUPPORTED',
1290
- 'COMPANION_NOT_DECLARED',
1291
- 'COMPANION_TARGET_UNSUPPORTED',
1292
- 'COMPANION_NOT_PREPARED',
1293
- 'COMPANION_PREPARATION_CANCELLED',
1294
- 'COMPANION_DOWNLOAD_FAILED',
1295
- 'COMPANION_DESCRIPTOR_UNAVAILABLE',
1296
- 'COMPANION_ARCHIVE_INVALID',
1297
- 'COMPANION_INTEGRITY_FAILED',
1298
- 'COMPANION_ENTRYPOINT_INVALID',
1299
- 'COMPANION_USER_CANCELLED',
1300
- 'COMPANION_ELEVATION_DENIED',
1301
- 'COMPANION_OS_BLOCKED',
1302
- 'COMPANION_LAUNCH_FAILED',
1303
- 'COMPANION_SESSION_VERSION_MISMATCH',
1304
- 'COMPANION_SESSION_OWNERSHIP_LOST',
1305
- 'COMPANION_SESSION_EXITED',
1306
- 'COMPANION_PIPE_CLOSED',
1307
- 'COMPANION_OUTPUT_LIMIT',
1308
- 'COMPANION_PROCESS_CRASHED',
1309
- 'COMPANION_ATTACHMENT_NOT_FOUND',
1310
- 'COMPANION_NOTIFICATION_UNAVAILABLE',
1311
- 'COMPANION_TERMINATE_FAILED',
1312
- ];
1313
-
1314
1168
  const MINI_PROGRAM_PERMISSION_KEYS = [
1315
1169
  'userInfo',
1316
1170
  'steamLibrary',
@@ -1605,7 +1459,7 @@ function isManagedMiniProgramRuntimePermissionKey(key) {
1605
1459
  * @see {@link https://docs.xiaoheihe.cn/hb_sdk/guide/permissions | 权限声明}
1606
1460
  */
1607
1461
  function parseMiniProgramRuntimePermissions(snapshot) {
1608
- if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
1462
+ if (!isRecord$2(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
1609
1463
  return { valid: false, permissions: {} };
1610
1464
  }
1611
1465
  if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
@@ -1614,7 +1468,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
1614
1468
  const seenKeys = new Set();
1615
1469
  const permissions = {};
1616
1470
  for (const rawEntry of snapshot.entries) {
1617
- if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
1471
+ if (!isRecord$2(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
1618
1472
  return { valid: false, permissions: {} };
1619
1473
  }
1620
1474
  const inputKey = rawEntry.key.trim();
@@ -1630,7 +1484,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
1630
1484
  }
1631
1485
  if (key === 'network') {
1632
1486
  const config = rawEntry.config;
1633
- if (!isRecord(config) || typeof config.useOfficialDomain !== 'boolean') {
1487
+ if (!isRecord$2(config) || typeof config.useOfficialDomain !== 'boolean') {
1634
1488
  return { valid: false, permissions: {} };
1635
1489
  }
1636
1490
  permissions[key] = {
@@ -1640,7 +1494,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
1640
1494
  };
1641
1495
  continue;
1642
1496
  }
1643
- if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
1497
+ if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord$2(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
1644
1498
  return { valid: false, permissions: {} };
1645
1499
  }
1646
1500
  permissions[key] = {
@@ -1651,8 +1505,264 @@ function parseMiniProgramRuntimePermissions(snapshot) {
1651
1505
  }
1652
1506
  return { valid: true, permissions };
1653
1507
  }
1654
- function isRecord(value) {
1508
+ function isRecord$2(value) {
1509
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
1510
+ }
1511
+
1512
+ /** 仅供开发工具和 Host 使用;新增权限必须单独评估,不能从平台审批目录自动推导。 */
1513
+ const LOCAL_DEV_GRANT_PERMISSION_KEYS = ['network', 'companion'];
1514
+ /**
1515
+ * 严格解析本地 grant。任何未知字段、重复权限或非法配置都拒绝整份输入。
1516
+ * 只校验数据合同;票据、身份、摘要、过期时间和 CLI lease 必须由 Host 另行验证。
1517
+ */
1518
+ function parseMiniProgramLocalDevGrant(value) {
1519
+ if (!hasExactFields(value, ['schema_version', 'revision', 'entries']) ||
1520
+ value.schema_version !== 1 ||
1521
+ typeof value.revision !== 'number' ||
1522
+ !Number.isSafeInteger(value.revision) ||
1523
+ value.revision < 0 ||
1524
+ !Array.isArray(value.entries) ||
1525
+ value.entries.length > LOCAL_DEV_GRANT_PERMISSION_KEYS.length)
1526
+ return { valid: false };
1527
+ const entries = [];
1528
+ const seen = new Set();
1529
+ for (const entry of value.entries) {
1530
+ if (!hasExactFields(entry, ['key', 'status', 'config']) || entry.status !== 'enabled')
1531
+ return { valid: false };
1532
+ if (typeof entry.key !== 'string' || seen.has(entry.key))
1533
+ return { valid: false };
1534
+ seen.add(entry.key);
1535
+ if (entry.key === 'network') {
1536
+ if (!hasExactFields(entry.config, ['useOfficialDomain']) || entry.config.useOfficialDomain !== false)
1537
+ return { valid: false };
1538
+ entries.push({ key: 'network', status: 'enabled', config: { useOfficialDomain: false } });
1539
+ }
1540
+ else if (entry.key === 'companion') {
1541
+ if (!hasExactFields(entry.config, []))
1542
+ return { valid: false };
1543
+ entries.push({ key: 'companion', status: 'enabled', config: {} });
1544
+ }
1545
+ else {
1546
+ return { valid: false };
1547
+ }
1548
+ }
1549
+ entries.sort((a, b) => LOCAL_DEV_GRANT_PERMISSION_KEYS.indexOf(a.key) - LOCAL_DEV_GRANT_PERMISSION_KEYS.indexOf(b.key));
1550
+ return { valid: true, grant: { schema_version: 1, revision: value.revision, entries } };
1551
+ }
1552
+ /**
1553
+ * 从已校验声明生成批准缺口。Companion 默认不符合资格,由 CLI 确认平台、产物与摘要后显式加入。
1554
+ * 空 entries 可保留 revision,不能作为存在临时权限的判断依据。
1555
+ */
1556
+ function createMiniProgramLocalDevGrant(options) {
1557
+ if (!Number.isSafeInteger(options.revision) || options.revision < 0)
1558
+ throw new Error('本地调试权限 revision 必须是非负安全整数');
1559
+ const approvals = parseMiniProgramRuntimePermissions(options.runtimePermissions);
1560
+ const eligible = new Set(options.eligiblePermissionKeys ?? ['network']);
1561
+ const entries = [];
1562
+ for (const key of LOCAL_DEV_GRANT_PERMISSION_KEYS) {
1563
+ if (!eligible.has(key) || options.declaredPermissions[key]?.enabled !== true)
1564
+ continue;
1565
+ if (approvals.valid && approvals.permissions[key]?.status === 'enabled')
1566
+ continue;
1567
+ entries.push(key === 'network'
1568
+ ? { key, status: 'enabled', config: { useOfficialDomain: false } }
1569
+ : { key, status: 'enabled', config: {} });
1570
+ }
1571
+ return { schema_version: 1, revision: options.revision, entries };
1572
+ }
1573
+ /**
1574
+ * 线上基线先与本地声明求交,再补齐临时权限,返回与输入脱离的普通 Runtime 快照。
1575
+ * 调用方只可在当前 Dev Session 已验证且用户接受后传入 grant;本函数不证明其可信来源。
1576
+ * 非法 grant 整体降权到基线,已批准配置不会被临时配置覆盖。
1577
+ */
1578
+ function composeLocalDevRuntimePermissions(options) {
1579
+ const baseline = parseMiniProgramRuntimePermissions(options.runtimePermissions);
1580
+ const parsed = parseMiniProgramLocalDevGrant(options.localDevGrant);
1581
+ const permissions = baseline.valid ? baseline.permissions : {};
1582
+ for (const key of MINI_PROGRAM_PERMISSION_KEYS) {
1583
+ if (options.declaredPermissions[key]?.enabled !== true) {
1584
+ delete permissions[key];
1585
+ }
1586
+ else if (key === 'network' && permissions.network) {
1587
+ permissions.network.config.useOfficialDomain = permissions.network.status === 'enabled'
1588
+ && permissions.network.config.useOfficialDomain === true
1589
+ && options.declaredPermissions.network?.useOfficialDomain === true;
1590
+ }
1591
+ }
1592
+ const temporaryPermissionKeys = [];
1593
+ if (parsed.valid) {
1594
+ for (const entry of parsed.grant.entries) {
1595
+ if (options.declaredPermissions[entry.key]?.enabled !== true || permissions[entry.key]?.status === 'enabled')
1596
+ continue;
1597
+ permissions[entry.key] = entry;
1598
+ temporaryPermissionKeys.push(entry.key);
1599
+ }
1600
+ }
1601
+ const revision = isRecord$1(options.runtimePermissions) && typeof options.runtimePermissions.revision === 'number'
1602
+ && Number.isSafeInteger(options.runtimePermissions.revision) && options.runtimePermissions.revision >= 0
1603
+ ? options.runtimePermissions.revision : undefined;
1604
+ return {
1605
+ runtimePermissions: {
1606
+ schema_version: 1,
1607
+ ...(revision === undefined ? {} : { revision }),
1608
+ entries: MINI_PROGRAM_PERMISSION_KEYS.flatMap((key) => permissions[key] ? [permissions[key]] : []),
1609
+ },
1610
+ temporaryPermissionKeys,
1611
+ grantValid: parsed.valid,
1612
+ };
1613
+ }
1614
+ function isRecord$1(value) {
1655
1615
  return typeof value === 'object' && value !== null && !Array.isArray(value);
1656
1616
  }
1617
+ function hasExactFields(value, fields) {
1618
+ return isRecord$1(value) && Object.keys(value).length === fields.length
1619
+ && fields.every((field) => Object.prototype.hasOwnProperty.call(value, field));
1620
+ }
1621
+
1622
+ /** 由 scripts/generate-native-host-contract.mjs 生成,请勿手改。 */
1623
+ const MINI_PROGRAM_NATIVE_HOST_PROTOCOL_VERSION = 1;
1624
+ const MINI_PROGRAM_NATIVE_HOST_CONTRACT_REVISION = 1;
1625
+ const MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES = 65536;
1626
+ const MINI_PROGRAM_NATIVE_OPERATIONS = {
1627
+ "system": [
1628
+ "describe"
1629
+ ],
1630
+ "network": [
1631
+ "open",
1632
+ "read",
1633
+ "release",
1634
+ "transfer"
1635
+ ],
1636
+ "files": [
1637
+ "create",
1638
+ "remove",
1639
+ "exists",
1640
+ "openRead",
1641
+ "openWrite",
1642
+ "read",
1643
+ "release",
1644
+ "write",
1645
+ "stat",
1646
+ "list",
1647
+ "pickFiles",
1648
+ "pickDirectory",
1649
+ "saveFile"
1650
+ ]
1651
+ };
1652
+ const MINI_PROGRAM_NATIVE_HOST_DESCRIPTION = {
1653
+ "protocolVersion": 1,
1654
+ "contractRevision": 1,
1655
+ "operations": {
1656
+ "system": [
1657
+ "describe"
1658
+ ],
1659
+ "network": [
1660
+ "open",
1661
+ "read",
1662
+ "release",
1663
+ "transfer"
1664
+ ],
1665
+ "files": [
1666
+ "create",
1667
+ "remove",
1668
+ "exists",
1669
+ "openRead",
1670
+ "openWrite",
1671
+ "read",
1672
+ "release",
1673
+ "write",
1674
+ "stat",
1675
+ "list",
1676
+ "pickFiles",
1677
+ "pickDirectory",
1678
+ "saveFile"
1679
+ ]
1680
+ }
1681
+ };
1682
+
1683
+ /** Android WebMessageListener object 与 iOS WKScriptMessageHandler 共用名称。 */
1684
+ const MINI_PROGRAM_NATIVE_HOST_OBJECT = 'hbMiniProgramHost';
1685
+ /** Native 通过主文档 CustomEvent 回送 progress/result/error。 */
1686
+ const MINI_PROGRAM_NATIVE_HOST_MESSAGE_EVENT = 'heybox:miniprogram-native-host-message';
1687
+ function isMiniProgramNativeHostMessage(value) {
1688
+ if (!isRecord(value) || !isNonEmptyString(value.requestId))
1689
+ return false;
1690
+ if (value.type === 'progress')
1691
+ return Object.prototype.hasOwnProperty.call(value, 'payload');
1692
+ if (value.type === 'result')
1693
+ return !Object.prototype.hasOwnProperty.call(value, 'error');
1694
+ if (value.type !== 'error' || !isRecord(value.error))
1695
+ return false;
1696
+ return isNonEmptyString(value.error.code) && isNonEmptyString(value.error.message);
1697
+ }
1698
+ function isMiniProgramNativeHostDescription(value) {
1699
+ if (!isRecord(value) ||
1700
+ !isPositiveSafeInteger(value.protocolVersion) ||
1701
+ !isPositiveSafeInteger(value.contractRevision) ||
1702
+ !isRecord(value.operations))
1703
+ return false;
1704
+ const operations = value.operations;
1705
+ if (!isOperationList(operations.system) ||
1706
+ !isOperationList(operations.network) ||
1707
+ !isOperationList(operations.files))
1708
+ return false;
1709
+ return operations.system.includes('describe');
1710
+ }
1711
+ function isMiniProgramNativeBinaryChunk(value) {
1712
+ return (isRecord(value) &&
1713
+ isNonEmptyString(value.resourceId) &&
1714
+ typeof value.data === 'string' &&
1715
+ Number.isSafeInteger(value.byteLength) &&
1716
+ Number(value.byteLength) >= 0 &&
1717
+ Number(value.byteLength) <= MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES &&
1718
+ typeof value.eof === 'boolean' &&
1719
+ (Number(value.byteLength) > 0 || value.eof));
1720
+ }
1721
+ function isRecord(value) {
1722
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
1723
+ }
1724
+ function isNonEmptyString(value) {
1725
+ return typeof value === 'string' && value.length > 0;
1726
+ }
1727
+ function isPositiveSafeInteger(value) {
1728
+ return Number.isSafeInteger(value) && Number(value) > 0;
1729
+ }
1730
+ function isOperationList(value) {
1731
+ return (Array.isArray(value) &&
1732
+ value.every(operation => isNonEmptyString(operation) && operation === operation.trim()) &&
1733
+ new Set(value).size === value.length);
1734
+ }
1735
+
1736
+ /** 当前用户信息与登录能力支持的完整 scope 目录(canonical 顺序)。 */
1737
+ const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile', 'steam_account'];
1738
+ /** Companion alias 的跨构建、Runtime 与 Host 规范。 */
1739
+ const COMPANION_ALIAS_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;
1740
+ /** Companion Host 可跨 bridge 保留的稳定领域错误码。 */
1741
+ const COMPANION_ERROR_CODES = [
1742
+ 'COMPANION_UNSUPPORTED',
1743
+ 'COMPANION_PREVIEW_UNSUPPORTED',
1744
+ 'COMPANION_NOT_DECLARED',
1745
+ 'COMPANION_TARGET_UNSUPPORTED',
1746
+ 'COMPANION_NOT_PREPARED',
1747
+ 'COMPANION_PREPARATION_CANCELLED',
1748
+ 'COMPANION_DOWNLOAD_FAILED',
1749
+ 'COMPANION_DESCRIPTOR_UNAVAILABLE',
1750
+ 'COMPANION_ARCHIVE_INVALID',
1751
+ 'COMPANION_INTEGRITY_FAILED',
1752
+ 'COMPANION_ENTRYPOINT_INVALID',
1753
+ 'COMPANION_USER_CANCELLED',
1754
+ 'COMPANION_ELEVATION_DENIED',
1755
+ 'COMPANION_OS_BLOCKED',
1756
+ 'COMPANION_LAUNCH_FAILED',
1757
+ 'COMPANION_SESSION_VERSION_MISMATCH',
1758
+ 'COMPANION_SESSION_OWNERSHIP_LOST',
1759
+ 'COMPANION_SESSION_EXITED',
1760
+ 'COMPANION_PIPE_CLOSED',
1761
+ 'COMPANION_OUTPUT_LIMIT',
1762
+ 'COMPANION_PROCESS_CRASHED',
1763
+ 'COMPANION_ATTACHMENT_NOT_FOUND',
1764
+ 'COMPANION_NOTIFICATION_UNAVAILABLE',
1765
+ 'COMPANION_TERMINATE_FAILED',
1766
+ ];
1657
1767
 
1658
- export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, COMPANION_ALIAS_PATTERN, COMPANION_CANCEL_PREPARATION_METHOD, COMPANION_ERROR_CODES, COMPANION_GET_ACTIVE_SESSION_METHOD, COMPANION_GET_INFO_METHOD, COMPANION_GET_PREPARATION_STATUS_METHOD, COMPANION_LAUNCH_METHOD, COMPANION_OPEN_ATTACHMENT_METHOD, COMPANION_PREPARE_METHOD, COMPANION_SESSION_ACK_OUTPUT_METHOD, COMPANION_SESSION_CLOSE_STDIN_METHOD, COMPANION_SESSION_EXIT_EVENT, COMPANION_SESSION_OUTPUT_EVENT, COMPANION_SESSION_OWNERSHIP_LOST_EVENT, COMPANION_SESSION_TERMINATE_METHOD, COMPANION_SESSION_WRITE_METHOD, COMPANION_SHOW_NOTIFICATION_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_NATIVE_CHUNK_MAX_BYTES, MINI_PROGRAM_NATIVE_HOST_CONTRACT_REVISION, MINI_PROGRAM_NATIVE_HOST_DESCRIPTION, MINI_PROGRAM_NATIVE_HOST_MESSAGE_EVENT, MINI_PROGRAM_NATIVE_HOST_OBJECT, MINI_PROGRAM_NATIVE_HOST_PROTOCOL_VERSION, MINI_PROGRAM_NATIVE_OPERATIONS, MINI_PROGRAM_NO_DECLARATION_METHODS, MINI_PROGRAM_OPERATION_PROGRESS_METHOD, MINI_PROGRAM_PERMISSION_CATALOG, MINI_PROGRAM_PERMISSION_KEYS, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_DOWNLOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_COPY_LINK_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_INFO_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, USER_INFO_AUTHORIZATION_SCOPES, USER_REVOKE_AUTHORIZATION_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_DISPLAY_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, isMiniProgramByteArray, isMiniProgramCompanionPrepareProgress, isMiniProgramDirectoryDescriptor, isMiniProgramDirectoryRef, isMiniProgramDownloadProgressPayload, isMiniProgramFileDescriptor, isMiniProgramFileRef, isMiniProgramFileStat, isMiniProgramFileSystemEntityDescriptor, isMiniProgramNativeBinaryChunk, isMiniProgramNativeHostDescription, isMiniProgramNativeHostMessage, isMiniProgramOperationProgressPayload, isMiniProgramPathRootRef, isMiniProgramPermissionKey, isMiniProgramRelativePath, parseMiniProgramRuntimePermissions };
1768
+ export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, COMPANION_ALIAS_PATTERN, COMPANION_CANCEL_PREPARATION_METHOD, COMPANION_ERROR_CODES, COMPANION_GET_ACTIVE_SESSION_METHOD, COMPANION_GET_INFO_METHOD, COMPANION_GET_PREPARATION_STATUS_METHOD, COMPANION_LAUNCH_METHOD, COMPANION_OPEN_ATTACHMENT_METHOD, COMPANION_PREPARE_METHOD, COMPANION_SESSION_ACK_OUTPUT_METHOD, COMPANION_SESSION_CLOSE_STDIN_METHOD, COMPANION_SESSION_EXIT_EVENT, COMPANION_SESSION_OUTPUT_EVENT, COMPANION_SESSION_OWNERSHIP_LOST_EVENT, COMPANION_SESSION_TERMINATE_METHOD, COMPANION_SESSION_WRITE_METHOD, COMPANION_SHOW_NOTIFICATION_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, LOCAL_DEV_GRANT_PERMISSION_KEYS, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES, MINI_PROGRAM_NATIVE_HOST_CONTRACT_REVISION, MINI_PROGRAM_NATIVE_HOST_DESCRIPTION, MINI_PROGRAM_NATIVE_HOST_MESSAGE_EVENT, MINI_PROGRAM_NATIVE_HOST_OBJECT, MINI_PROGRAM_NATIVE_HOST_PROTOCOL_VERSION, MINI_PROGRAM_NATIVE_OPERATIONS, MINI_PROGRAM_NO_DECLARATION_METHODS, MINI_PROGRAM_OPERATION_PROGRESS_METHOD, MINI_PROGRAM_PERMISSION_CATALOG, MINI_PROGRAM_PERMISSION_KEYS, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_DOWNLOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_COPY_LINK_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_INFO_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, USER_INFO_AUTHORIZATION_SCOPES, USER_REVOKE_AUTHORIZATION_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_DISPLAY_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, composeLocalDevRuntimePermissions, createMiniProgramLocalDevGrant, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, isMiniProgramByteArray, isMiniProgramCompanionPrepareProgress, isMiniProgramDirectoryDescriptor, isMiniProgramDirectoryRef, isMiniProgramDownloadProgressPayload, isMiniProgramFileDescriptor, isMiniProgramFileRef, isMiniProgramFileStat, isMiniProgramFileSystemEntityDescriptor, isMiniProgramNativeBinaryChunk, isMiniProgramNativeHostDescription, isMiniProgramNativeHostMessage, isMiniProgramOperationProgressPayload, isMiniProgramPathRootRef, isMiniProgramPermissionKey, isMiniProgramRelativePath, parseMiniProgramLocalDevGrant, parseMiniProgramRuntimePermissions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk-protocol",
3
- "version": "0.8.3-alpha.3",
3
+ "version": "0.8.3-alpha.5",
4
4
  "description": "Heybox mini-program iframe bridge wire contracts.",
5
5
  "sideEffects": false,
6
6
  "exports": {
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from './bridge';
2
2
  export * from './capabilities';
3
3
  export * from './constants';
4
4
  export * from './guards';
5
+ export * from './local-dev-grant';
5
6
  export * from './native-host';
6
7
  export * from './payloads';
7
8
  export * from './permission-catalog';