@heybox/hb-sdk 0.8.1-alpha.8 → 0.8.1
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 +97 -1
- package/README.md +64 -18
- package/dist/cli-chunks/{build-BYWPo2MY.cjs → build-DPe1Ycjd.cjs} +21 -7
- package/dist/cli-chunks/{context-B4tBsR6l.cjs → context-BSUhAv3Z.cjs} +2 -2
- package/dist/cli-chunks/{create-Dct-INxs.cjs → create-CaiKrGnb.cjs} +2 -1
- package/dist/cli-chunks/{dev-6N5ruKiC.cjs → dev-BG1o8Q-0.cjs} +45 -12
- package/dist/cli-chunks/doctor-DutO2P5H.cjs +195 -0
- package/dist/cli-chunks/{index-Cl5cfUqJ.cjs → index-Bur0U2z1.cjs} +2 -2
- package/dist/cli-chunks/{index-Bc4AXYHM.cjs → index-CKIyipP9.cjs} +77 -21
- package/dist/cli-chunks/{index.esm-DhXN7XjE.cjs → index.esm-BPlpP-O0.cjs} +8 -8
- package/dist/cli-chunks/{login-CTZgu8Q-.cjs → login-C1JlLEza.cjs} +2 -2
- package/dist/cli-chunks/{project-vite--h2M6eBb.cjs → project-vite-Bd0WzAqQ.cjs} +1 -1
- package/dist/cli-chunks/{remote-0hw42fDG.cjs → remote-DTFEf3Dj.cjs} +74 -10
- package/dist/cli-chunks/{runtime-permission-env-Bvggu6mn.cjs → runtime-permission-env-C2S34ldj.cjs} +145 -4
- package/dist/cli-chunks/{session-5fnHlEGO.cjs → session-zXVkHuhY.cjs} +1 -1
- package/dist/cli-chunks/{skill-DrFEqmdD.cjs → skill-CCB3DyXk.cjs} +3 -2
- package/dist/cli-chunks/{version-CccOA4so.cjs → version-0qwlEyZC.cjs} +1 -1
- package/dist/cli.cjs +2 -1
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-pUcws1MK.js +101 -0
- package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-DnPRjCa3.js → desktop-app-launch-DOfl5YvO.js} +3 -3
- package/dist/devtools/browser-dev-host/assets/{index-8LTH05np.js → index-CFr28-0O.js} +4 -4
- package/dist/devtools/browser-dev-host/assets/{index-D-aNERAr.css → index-DXd5IZBz.css} +1 -1
- package/dist/devtools/browser-dev-host/index.html +3 -3
- package/dist/index.cjs.js +24 -24
- package/dist/index.esm.js +24 -24
- package/dist/miniapp-publish.cjs.js +121 -3
- package/dist/miniapp-publish.esm.js +118 -4
- package/dist/protocol.cjs.js +27 -27
- package/dist/protocol.esm.js +27 -27
- package/dist/vite.cjs.js +179 -17
- package/dist/vite.esm.js +179 -18
- package/docs/device-logs.md +36 -0
- package/docs/runtime-host-migration.md +120 -0
- package/package.json +9 -7
- package/skill/SKILL.md +25 -20
- package/skill/references/api-protocol.md +3 -3
- package/skill/references/api-root.md +104 -11
- package/skill/references/cli.md +110 -9
- package/skill/references/examples.md +2 -2
- package/skill/references/recipes.md +25 -10
- package/skill/references/safety-boundaries.md +10 -7
- package/skill/skill.json +5 -5
- package/types/miniapp-manifest/bindings.d.ts +5 -0
- package/types/miniapp-manifest/index.d.ts +1 -0
- package/types/miniapp-manifest/node.d.ts +9 -1
- package/types/miniapp-manifest/schema.d.ts +94 -0
- package/types/miniapp-publish/index.d.ts +4 -2
- package/types/modules/companion/index.d.ts +68 -0
- package/types/modules/files/types.d.ts +10 -11
- package/types/modules/network/index.d.ts +3 -3
- package/types/skill-metadata.d.ts +16 -0
- package/types/vite/index.d.ts +1 -0
- package/dist/cli-chunks/doctor-9HtdddBL.cjs +0 -65
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-BQ9v4rI1.js +0 -101
package/dist/vite.cjs.js
CHANGED
|
@@ -11,7 +11,7 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
|
|
|
11
11
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
12
12
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
13
13
|
? undefined
|
|
14
|
-
: '0.8.1
|
|
14
|
+
: '0.8.1';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* iframe 与调试台页面的开发期 console 捕获转发。
|
|
@@ -3116,6 +3116,35 @@ function requireSemver () {
|
|
|
3116
3116
|
|
|
3117
3117
|
var semverExports = requireSemver();
|
|
3118
3118
|
|
|
3119
|
+
const MINIAPP_BIND_APP_IDS_MAX_COUNT = 20;
|
|
3120
|
+
function parseMiniappBindAppIds(value, options = {}) {
|
|
3121
|
+
const sourceLabel = options.sourceLabel ?? 'package.json#heybox.bindAppIds';
|
|
3122
|
+
if (value === undefined)
|
|
3123
|
+
return Object.freeze([]);
|
|
3124
|
+
if (!Array.isArray(value))
|
|
3125
|
+
throw new Error(`${sourceLabel} 必须是字符串数组`);
|
|
3126
|
+
if (value.length > MINIAPP_BIND_APP_IDS_MAX_COUNT) {
|
|
3127
|
+
throw new Error(`${sourceLabel} 最多包含 ${MINIAPP_BIND_APP_IDS_MAX_COUNT} 个游戏 appid`);
|
|
3128
|
+
}
|
|
3129
|
+
const seen = new Set();
|
|
3130
|
+
const appIds = [];
|
|
3131
|
+
for (const item of value) {
|
|
3132
|
+
if (typeof item !== 'string' || !/^[1-9]\d*$/.test(item)) {
|
|
3133
|
+
throw new Error(`${sourceLabel} 包含非法游戏 appid:${String(item)}`);
|
|
3134
|
+
}
|
|
3135
|
+
const numeric = Number(item);
|
|
3136
|
+
if (!Number.isSafeInteger(numeric) || numeric > 2_147_483_647) {
|
|
3137
|
+
throw new Error(`${sourceLabel} 包含超出正 int32 范围的游戏 appid:${item}`);
|
|
3138
|
+
}
|
|
3139
|
+
if (seen.has(item))
|
|
3140
|
+
throw new Error(`${sourceLabel} 包含重复游戏 appid:${item}`);
|
|
3141
|
+
seen.add(item);
|
|
3142
|
+
appIds.push(item);
|
|
3143
|
+
}
|
|
3144
|
+
appIds.sort((left, right) => Number(left) - Number(right));
|
|
3145
|
+
return Object.freeze(appIds);
|
|
3146
|
+
}
|
|
3147
|
+
|
|
3119
3148
|
const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
|
|
3120
3149
|
const MINI_PROGRAM_MESSAGE_VERSION = 2;
|
|
3121
3150
|
const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
|
|
@@ -3281,7 +3310,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
3281
3310
|
}
|
|
3282
3311
|
return { declared: false };
|
|
3283
3312
|
}
|
|
3284
|
-
if (!isRecord$
|
|
3313
|
+
if (!isRecord$3(value)) {
|
|
3285
3314
|
throw new Error(`${sourceLabel} 必须是 JSON 对象`);
|
|
3286
3315
|
}
|
|
3287
3316
|
const knownKeys = new Set(MINIAPP_PERMISSION_KEYS);
|
|
@@ -3295,7 +3324,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
3295
3324
|
continue;
|
|
3296
3325
|
const declaration = value[key];
|
|
3297
3326
|
const itemLabel = `${sourceLabel}.${key}`;
|
|
3298
|
-
if (!isRecord$
|
|
3327
|
+
if (!isRecord$3(declaration))
|
|
3299
3328
|
throw new Error(`${itemLabel} 必须是 JSON 对象`);
|
|
3300
3329
|
const definition = MINI_PROGRAM_PERMISSION_CATALOG.find((item) => item.key === key);
|
|
3301
3330
|
if (!definition)
|
|
@@ -3329,11 +3358,15 @@ function requiresExplicitPermissions(sdkVersion) {
|
|
|
3329
3358
|
function getMissingPermissionsWarning(sourceLabel = 'package.json#heybox.permissions') {
|
|
3330
3359
|
return `${sourceLabel} 尚未声明。当前按 0.8 兼容行为构建;0.9.0 起将拒绝构建,请尽快补充权限声明(无权限需求时配置 {})。`;
|
|
3331
3360
|
}
|
|
3332
|
-
function isRecord$
|
|
3361
|
+
function isRecord$3(value) {
|
|
3333
3362
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3334
3363
|
}
|
|
3335
3364
|
|
|
3336
3365
|
const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
|
|
3366
|
+
/** 窗口尺寸字段的脏值兜底上限;真正的上限是宿主侧显示器 workArea。 */
|
|
3367
|
+
const MINIAPP_WINDOW_SIZE_MAX = 16_384;
|
|
3368
|
+
const MINIAPP_WINDOW_NUMBER_FIELDS = ['defaultWidth', 'defaultHeight', 'minWidth', 'minHeight'];
|
|
3369
|
+
const MINIAPP_WINDOW_ALLOWED_FIELDS = [...MINIAPP_WINDOW_NUMBER_FIELDS, 'resizable'];
|
|
3337
3370
|
function validateMiniappPackageVersionForBuild(version) {
|
|
3338
3371
|
return validateMiniappManifestVersion(version, 'package.json.version');
|
|
3339
3372
|
}
|
|
@@ -3346,12 +3379,16 @@ function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version
|
|
|
3346
3379
|
}
|
|
3347
3380
|
function renderMiniappManifest(manifest) {
|
|
3348
3381
|
const platforms = validateMiniappPlatforms(manifest.platforms, 'manifest.platforms');
|
|
3382
|
+
const window = validateMiniappWindow(manifest.window, 'manifest.window');
|
|
3383
|
+
const bindAppIds = parseMiniappBindAppIds(manifest.bindAppIds, { sourceLabel: 'manifest.bindAppIds' });
|
|
3349
3384
|
const output = {
|
|
3350
3385
|
version: manifest.version,
|
|
3351
3386
|
sdkVersion: manifest.sdkVersion,
|
|
3352
3387
|
platforms,
|
|
3353
3388
|
...(manifest.permissions === undefined ? {} : { permissions: manifest.permissions }),
|
|
3354
3389
|
...(manifest.companions === undefined ? {} : { companions: manifest.companions }),
|
|
3390
|
+
...(window === undefined ? {} : { window }),
|
|
3391
|
+
...(bindAppIds.length === 0 ? {} : { bindAppIds }),
|
|
3355
3392
|
};
|
|
3356
3393
|
return `${JSON.stringify(output, null, 2)}\n`;
|
|
3357
3394
|
}
|
|
@@ -3372,6 +3409,70 @@ function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
|
|
|
3372
3409
|
}
|
|
3373
3410
|
return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
|
|
3374
3411
|
}
|
|
3412
|
+
/**
|
|
3413
|
+
* 校验并归一化 `package.json#heybox.window` / `manifest.window` 声明。
|
|
3414
|
+
*
|
|
3415
|
+
* @remarks
|
|
3416
|
+
* 与 `heybox.permissions` 同样的严格风格:未知字段报错,不做静默忽略。
|
|
3417
|
+
* `width` / `height` 显式给出改名提示;`x` / `y` 按未知字段显式报错(`INV-NO-DEV-POSITION`)。
|
|
3418
|
+
* 未声明时返回 `undefined`,由调用方决定不写入产物。
|
|
3419
|
+
* @param value - 待校验的原始声明(不可信输入)。
|
|
3420
|
+
* @param sourceLabel - 报错前缀,默认指向开发者声明路径。
|
|
3421
|
+
* @throws 当声明不是非空对象、含未知字段、数值/布尔类型不合法或 min/default 不配对时抛出。
|
|
3422
|
+
*/
|
|
3423
|
+
function validateMiniappWindow(value, sourceLabel = 'package.json#heybox.window') {
|
|
3424
|
+
if (value === undefined)
|
|
3425
|
+
return undefined;
|
|
3426
|
+
if (!isRecord$2(value) || Object.keys(value).length === 0) {
|
|
3427
|
+
throw new Error(`${sourceLabel} 至少需要声明 defaultWidth/defaultHeight/minWidth/minHeight/resizable 之一`);
|
|
3428
|
+
}
|
|
3429
|
+
if (Object.prototype.hasOwnProperty.call(value, 'width') || Object.prototype.hasOwnProperty.call(value, 'height')) {
|
|
3430
|
+
throw new Error(`${sourceLabel} 请使用 defaultWidth/defaultHeight,而不是 width/height`);
|
|
3431
|
+
}
|
|
3432
|
+
for (const key of Object.keys(value)) {
|
|
3433
|
+
if (!MINIAPP_WINDOW_ALLOWED_FIELDS.includes(key)) {
|
|
3434
|
+
throw new Error(`${sourceLabel} 包含未知字段:${key}`);
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
const window = {};
|
|
3438
|
+
for (const field of MINIAPP_WINDOW_NUMBER_FIELDS) {
|
|
3439
|
+
if (!Object.prototype.hasOwnProperty.call(value, field))
|
|
3440
|
+
continue;
|
|
3441
|
+
const size = value[field];
|
|
3442
|
+
if (typeof size !== 'number' || !Number.isSafeInteger(size) || size <= 0) {
|
|
3443
|
+
throw new Error(`${sourceLabel}.${field} 必须是正整数`);
|
|
3444
|
+
}
|
|
3445
|
+
if (size > MINIAPP_WINDOW_SIZE_MAX) {
|
|
3446
|
+
throw new Error(`${sourceLabel}.${field} 不能大于 ${MINIAPP_WINDOW_SIZE_MAX}`);
|
|
3447
|
+
}
|
|
3448
|
+
window[field] = size;
|
|
3449
|
+
}
|
|
3450
|
+
if (Object.prototype.hasOwnProperty.call(value, 'resizable')) {
|
|
3451
|
+
if (typeof value.resizable !== 'boolean') {
|
|
3452
|
+
throw new Error(`${sourceLabel}.resizable 必须是 boolean`);
|
|
3453
|
+
}
|
|
3454
|
+
window.resizable = value.resizable;
|
|
3455
|
+
}
|
|
3456
|
+
for (const [minimum, fallback] of [
|
|
3457
|
+
['minWidth', 'defaultWidth'],
|
|
3458
|
+
['minHeight', 'defaultHeight'],
|
|
3459
|
+
]) {
|
|
3460
|
+
const minimumValue = window[minimum];
|
|
3461
|
+
if (minimumValue === undefined)
|
|
3462
|
+
continue;
|
|
3463
|
+
const fallbackValue = window[fallback];
|
|
3464
|
+
if (fallbackValue === undefined) {
|
|
3465
|
+
throw new Error(`${sourceLabel}.${minimum} 必须与 ${fallback} 同时声明`);
|
|
3466
|
+
}
|
|
3467
|
+
if (minimumValue > fallbackValue) {
|
|
3468
|
+
throw new Error(`${sourceLabel}.${minimum} 必须小于等于 ${fallback}`);
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
return window;
|
|
3472
|
+
}
|
|
3473
|
+
function isRecord$2(value) {
|
|
3474
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3475
|
+
}
|
|
3375
3476
|
function getMiniappManifestVersionError(version) {
|
|
3376
3477
|
if (typeof version !== 'string' || version.trim() === '') {
|
|
3377
3478
|
return `必须是合法 SemVer:${String(version)}`;
|
|
@@ -3429,6 +3530,17 @@ function readMiniappPlatformsFromPackageJson(root) {
|
|
|
3429
3530
|
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3430
3531
|
return validateMiniappPlatforms(heybox?.platforms, 'package.json#heybox.platforms');
|
|
3431
3532
|
}
|
|
3533
|
+
/**
|
|
3534
|
+
* 读取并校验 `package.json#heybox.window`。
|
|
3535
|
+
*
|
|
3536
|
+
* @returns 合法声明;未声明时返回 `undefined`,调用方不得向 manifest 写入空对象或 `null`。
|
|
3537
|
+
* @throws 当声明违反 {@link validateMiniappWindow} 的规则时抛出,报错前缀为 `package.json#heybox.window`。
|
|
3538
|
+
*/
|
|
3539
|
+
function readMiniappWindowFromPackageJson(root) {
|
|
3540
|
+
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3541
|
+
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3542
|
+
return validateMiniappWindow(heybox?.window, 'package.json#heybox.window');
|
|
3543
|
+
}
|
|
3432
3544
|
function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
|
|
3433
3545
|
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3434
3546
|
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
@@ -3438,6 +3550,11 @@ function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
|
|
|
3438
3550
|
sdkVersion,
|
|
3439
3551
|
});
|
|
3440
3552
|
}
|
|
3553
|
+
function readMiniappBindAppIdsFromPackageJson(root) {
|
|
3554
|
+
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3555
|
+
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3556
|
+
return parseMiniappBindAppIds(heybox?.bindAppIds);
|
|
3557
|
+
}
|
|
3441
3558
|
function readMiniappPackageJson(root, requireVersion) {
|
|
3442
3559
|
const packageJsonPath = findNearestPackageJsonPath(root);
|
|
3443
3560
|
let content;
|
|
@@ -12893,11 +13010,23 @@ const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
|
|
|
12893
13010
|
const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
|
|
12894
13011
|
const miniDevLoggingConstant = ['__HB_SDK_DEV', 'LOGGING__'].join('_');
|
|
12895
13012
|
const DEV_MANIFEST_PATH = '/__hb_sdk__/companion/manifest.json';
|
|
13013
|
+
/**
|
|
13014
|
+
* 本地 PC 调试开窗时的 manifest 入口。
|
|
13015
|
+
*
|
|
13016
|
+
* 开窗发生在扩展拿到 `LocalDevelopmentBinding` 之前,所以不能用 Companion 会话令牌守护;
|
|
13017
|
+
* 该入口改由 CLI 随本地调试启动上下文(`mini_url` query)下发的专用令牌守护,
|
|
13018
|
+
* 只回最新快照,不参与 Companion 会话的 digest 钉扎。
|
|
13019
|
+
*/
|
|
13020
|
+
const DEV_MINI_PROGRAM_MANIFEST_PATH = '/__hb_sdk__/mini-program/manifest.json';
|
|
12896
13021
|
const DEV_TOKEN_HEADER = 'x-hb-sdk-companion-dev-token';
|
|
13022
|
+
const DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER = 'x-hb-sdk-mini-program-manifest-token';
|
|
12897
13023
|
const DEV_DIGEST_HEADER = 'x-hb-sdk-companion-manifest-sha256';
|
|
12898
13024
|
const DEV_ERROR_MESSAGE = 'Companion 开发资源暂时不可用';
|
|
13025
|
+
/** 与 Companion manifest 一致的单响应上限,避免本地调试入口被大体积声明撑爆。 */
|
|
13026
|
+
const DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
12899
13027
|
const DEV_COMPANION_PATH_PATTERN = /^\/__hb_sdk__\/companions\/([a-z][a-z0-9-]{0,31})\/(windows-x64|macos-arm64)\.zip$/;
|
|
12900
13028
|
const HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV = 'HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN';
|
|
13029
|
+
const HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV = 'HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN';
|
|
12901
13030
|
const devSnapshotStoreKey = Symbol.for('@heybox/hb-sdk/dev-companion-snapshots');
|
|
12902
13031
|
const devSnapshotRegistry = globalThis;
|
|
12903
13032
|
if (!devSnapshotRegistry[devSnapshotStoreKey]) {
|
|
@@ -12914,7 +13043,8 @@ function miniappManifest() {
|
|
|
12914
13043
|
const includeCompanions = process.env.HB_SDK_SKIP_COMPANIONS !== '1';
|
|
12915
13044
|
const deviceLogs = new DeviceLogStore();
|
|
12916
13045
|
const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
|
|
12917
|
-
let companionArtifactAccessToken =
|
|
13046
|
+
let companionArtifactAccessToken = parseDevAccessToken(process.env[HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV]);
|
|
13047
|
+
let miniProgramManifestAccessToken = parseDevAccessToken(process.env[HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV]);
|
|
12918
13048
|
let root = process.cwd();
|
|
12919
13049
|
let outDir = 'dist';
|
|
12920
13050
|
let command = 'build';
|
|
@@ -12962,8 +13092,16 @@ function miniappManifest() {
|
|
|
12962
13092
|
registerLogs();
|
|
12963
13093
|
let store = devSnapshotStores.get(root);
|
|
12964
13094
|
companionArtifactAccessToken ??= store?.token;
|
|
12965
|
-
|
|
12966
|
-
|
|
13095
|
+
// 与 Companion 令牌同因:配置重载时 env 已不在,只能从同一服务的注册表恢复。
|
|
13096
|
+
miniProgramManifestAccessToken ??= store?.manifestToken;
|
|
13097
|
+
if (!store ||
|
|
13098
|
+
store.token !== companionArtifactAccessToken ||
|
|
13099
|
+
store.manifestToken !== miniProgramManifestAccessToken) {
|
|
13100
|
+
store = {
|
|
13101
|
+
token: companionArtifactAccessToken ?? '',
|
|
13102
|
+
...(miniProgramManifestAccessToken ? { manifestToken: miniProgramManifestAccessToken } : {}),
|
|
13103
|
+
snapshots: new Map(),
|
|
13104
|
+
};
|
|
12967
13105
|
devSnapshotStores.set(root, store);
|
|
12968
13106
|
}
|
|
12969
13107
|
const snapshots = store.snapshots;
|
|
@@ -13068,7 +13206,8 @@ function miniappManifest() {
|
|
|
13068
13206
|
return;
|
|
13069
13207
|
}
|
|
13070
13208
|
const companionMatch = pathname?.match(DEV_COMPANION_PATH_PATTERN);
|
|
13071
|
-
|
|
13209
|
+
const miniProgramManifest = pathname === DEV_MINI_PROGRAM_MANIFEST_PATH;
|
|
13210
|
+
if (pathname !== DEV_MANIFEST_PATH && !companionMatch && !miniProgramManifest) {
|
|
13072
13211
|
next();
|
|
13073
13212
|
return;
|
|
13074
13213
|
}
|
|
@@ -13078,16 +13217,25 @@ function miniappManifest() {
|
|
|
13078
13217
|
response.end();
|
|
13079
13218
|
return;
|
|
13080
13219
|
}
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13220
|
+
// 两条链路共用「仅数值 loopback」边界,凭据各自独立。
|
|
13221
|
+
if (!isNumericLoopbackRequest(request) || !isNumericLoopbackHost(request.headers.host)) {
|
|
13222
|
+
response.statusCode = 403;
|
|
13223
|
+
response.end();
|
|
13224
|
+
return;
|
|
13225
|
+
}
|
|
13226
|
+
const authorized = miniProgramManifest
|
|
13227
|
+
? miniProgramManifestAccessToken !== undefined &&
|
|
13228
|
+
hasValidDevToken(request, DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER, miniProgramManifestAccessToken)
|
|
13229
|
+
: companionArtifactAccessToken !== undefined &&
|
|
13230
|
+
hasValidDevToken(request, DEV_TOKEN_HEADER, companionArtifactAccessToken);
|
|
13231
|
+
if (!authorized) {
|
|
13085
13232
|
response.statusCode = 403;
|
|
13086
13233
|
response.end();
|
|
13087
13234
|
return;
|
|
13088
13235
|
}
|
|
13089
13236
|
try {
|
|
13090
|
-
|
|
13237
|
+
// 本地调试入口只回最新快照;digest 钉扎仍然只服务 Companion 会话。
|
|
13238
|
+
const requestedDigest = miniProgramManifest ? undefined : request.headers[DEV_DIGEST_HEADER];
|
|
13091
13239
|
if (requestedDigest !== undefined && (typeof requestedDigest !== 'string' || !/^[a-f0-9]{64}$/.test(requestedDigest))) {
|
|
13092
13240
|
response.statusCode = 400;
|
|
13093
13241
|
response.end();
|
|
@@ -13099,9 +13247,15 @@ function miniappManifest() {
|
|
|
13099
13247
|
response.end();
|
|
13100
13248
|
return;
|
|
13101
13249
|
}
|
|
13250
|
+
if (miniProgramManifest && snapshot.manifestBytes.length > DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES) {
|
|
13251
|
+
response.statusCode = 500;
|
|
13252
|
+
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
13253
|
+
response.end(DEV_ERROR_MESSAGE);
|
|
13254
|
+
return;
|
|
13255
|
+
}
|
|
13102
13256
|
response.setHeader('Cache-Control', 'no-store');
|
|
13103
13257
|
response.setHeader('X-Content-Type-Options', 'nosniff');
|
|
13104
|
-
if (pathname === DEV_MANIFEST_PATH) {
|
|
13258
|
+
if (pathname === DEV_MANIFEST_PATH || miniProgramManifest) {
|
|
13105
13259
|
response.statusCode = 200;
|
|
13106
13260
|
response.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
13107
13261
|
response.setHeader('Content-Length', snapshot.manifestBytes.length);
|
|
@@ -13181,8 +13335,10 @@ function miniappManifest() {
|
|
|
13181
13335
|
const sdkVersion = resolveSdkVersion();
|
|
13182
13336
|
const platforms = readMiniappPlatformsFromPackageJson(root);
|
|
13183
13337
|
const parsedPermissions = readMiniappPermissionsFromPackageJson(root, sdkVersion);
|
|
13338
|
+
const windowDeclaration = readMiniappWindowFromPackageJson(root);
|
|
13184
13339
|
const companionConfig = readMiniappCompanionsFromPackageJson(root);
|
|
13185
13340
|
const companionDeclarations = includeCompanions ? companionConfig.declarations : undefined;
|
|
13341
|
+
const bindAppIds = readMiniappBindAppIdsFromPackageJson(root);
|
|
13186
13342
|
if (!parsedPermissions.declared)
|
|
13187
13343
|
this.warn(getMissingPermissionsWarning());
|
|
13188
13344
|
if (companionDeclarations && !parsedPermissions.permissions?.companion) {
|
|
@@ -13210,6 +13366,8 @@ function miniappManifest() {
|
|
|
13210
13366
|
platforms,
|
|
13211
13367
|
...(parsedPermissions.permissions === undefined ? {} : { permissions: parsedPermissions.permissions }),
|
|
13212
13368
|
...(companions === undefined ? {} : { companions }),
|
|
13369
|
+
...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
|
|
13370
|
+
...(bindAppIds.length === 0 ? {} : { bindAppIds }),
|
|
13213
13371
|
}));
|
|
13214
13372
|
},
|
|
13215
13373
|
};
|
|
@@ -13218,6 +13376,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
|
|
|
13218
13376
|
const version = validateMiniappPackageVersionForBuild(readMiniappVersionFromPackageJson(root));
|
|
13219
13377
|
const sdkVersion = resolveSdkVersion();
|
|
13220
13378
|
const permissions = readMiniappPermissionsFromPackageJson(root, sdkVersion).permissions;
|
|
13379
|
+
const windowDeclaration = readMiniappWindowFromPackageJson(root);
|
|
13221
13380
|
if (declarations && !permissions?.companion) {
|
|
13222
13381
|
throw new Error('配置 companions 时必须声明 package.json#heybox.permissions.companion.enabled=true');
|
|
13223
13382
|
}
|
|
@@ -13241,6 +13400,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
|
|
|
13241
13400
|
platforms,
|
|
13242
13401
|
...(permissions === undefined ? {} : { permissions }),
|
|
13243
13402
|
...(companions === undefined ? {} : { companions }),
|
|
13403
|
+
...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
|
|
13244
13404
|
};
|
|
13245
13405
|
return { artifacts, manifestBytes: Buffer.from(renderMiniappManifest(manifest)) };
|
|
13246
13406
|
}
|
|
@@ -13289,11 +13449,12 @@ function isNumericLoopbackHost(host) {
|
|
|
13289
13449
|
const port = Number(match[1]);
|
|
13290
13450
|
return port >= 1 && port <= 65_535;
|
|
13291
13451
|
}
|
|
13292
|
-
|
|
13452
|
+
/** 两条本地调试链路共用的凭据形状:32 字节 base64url,恰好 43 个字符。 */
|
|
13453
|
+
function parseDevAccessToken(value) {
|
|
13293
13454
|
return value && /^[A-Za-z0-9_-]{43}$/.test(value) ? value : undefined;
|
|
13294
13455
|
}
|
|
13295
|
-
function
|
|
13296
|
-
const value = request.headers[
|
|
13456
|
+
function hasValidDevToken(request, header, expected) {
|
|
13457
|
+
const value = request.headers[header];
|
|
13297
13458
|
const candidate = Buffer.alloc(43);
|
|
13298
13459
|
if (typeof value === 'string')
|
|
13299
13460
|
Buffer.from(value).copy(candidate, 0, 0, candidate.length);
|
|
@@ -13343,5 +13504,6 @@ function resolveHmrWebSocketUrl(resolved) {
|
|
|
13343
13504
|
}
|
|
13344
13505
|
|
|
13345
13506
|
exports.HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV = HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV;
|
|
13507
|
+
exports.HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV = HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV;
|
|
13346
13508
|
exports.MINIAPP_PLATFORM_VALUES = MINIAPP_PLATFORM_VALUES;
|
|
13347
13509
|
exports.miniappManifest = miniappManifest;
|