@heybox/hb-sdk 0.8.1-alpha.13 → 0.8.1-alpha.14
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 +8 -0
- package/README.md +25 -0
- package/dist/cli-chunks/{build-CBPmqCVZ.cjs → build-D-VaxzAE.cjs} +11 -7
- package/dist/cli-chunks/{context-CvuPJq1G.cjs → context-BH7BZPoY.cjs} +2 -2
- package/dist/cli-chunks/{create-CyMWFYrc.cjs → create-Bmp9E1n8.cjs} +1 -1
- package/dist/cli-chunks/{dev-BcAPHk9L.cjs → dev-BntAFyWR.cjs} +28 -10
- package/dist/cli-chunks/{doctor-CIwaVrM1.cjs → doctor-t3YMD3qv.cjs} +1 -1
- package/dist/cli-chunks/{index-B0KCGR9H.cjs → index-CjP8Qye_.cjs} +2 -2
- package/dist/cli-chunks/{index-E0qh3FUb.cjs → index-VP8boR-7.cjs} +15 -15
- package/dist/cli-chunks/{index.esm-DTEOIvDp.cjs → index.esm-B_5UnniK.cjs} +7 -7
- package/dist/cli-chunks/{login-DGvHzH9j.cjs → login-p38-WSHx.cjs} +2 -2
- package/dist/cli-chunks/{project-vite-CRnpRhSb.cjs → project-vite-BfJ5TGoA.cjs} +1 -1
- package/dist/cli-chunks/{remote-C1_Hs11w.cjs → remote-CBH04z6v.cjs} +11 -6
- package/dist/cli-chunks/{runtime-permission-env-Bn1ONUDU.cjs → runtime-permission-env-CVYOOxPB.cjs} +91 -1
- package/dist/cli-chunks/{session-BvZgS7VI.cjs → session-BEpV8CZQ.cjs} +1 -1
- package/dist/cli-chunks/{skill-BVT6fBpQ.cjs → skill-DuVDTrA2.cjs} +2 -2
- package/dist/cli-chunks/{version-CJTEIaOQ.cjs → version-Df-F-uhW.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/browser-dev-host/assets/{browser-dev-host-DOzYp6JS.js → browser-dev-host-D_nC-Zex.js} +21 -21
- package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-DZ_umnQp.js → desktop-app-launch-C1GHFN_L.js} +3 -3
- package/dist/devtools/browser-dev-host/assets/{index-DoPg_zh_.js → index-mfGqyKpq.js} +4 -4
- package/dist/devtools/browser-dev-host/index.html +2 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/vite.cjs.js +141 -17
- package/dist/vite.esm.js +141 -18
- package/package.json +4 -4
- package/skill/SKILL.md +2 -0
- package/skill/references/api-protocol.md +2 -2
- package/skill/references/api-root.md +1 -1
- package/skill/references/safety-boundaries.md +2 -0
- package/skill/skill.json +5 -5
- package/types/miniapp-manifest/node.d.ts +8 -1
- package/types/miniapp-manifest/schema.d.ts +37 -0
- package/types/vite/index.d.ts +1 -0
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="theme-color" content="#f4f5f7" />
|
|
7
7
|
<title>小程序工坊调试台</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/desktop-app-launch-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-mfGqyKpq.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/desktop-app-launch-C1GHFN_L.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-DXd5IZBz.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
package/dist/index.cjs.js
CHANGED
|
@@ -835,7 +835,7 @@ function createMessageId() {
|
|
|
835
835
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
836
836
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
837
837
|
? undefined
|
|
838
|
-
: '0.8.1-alpha.
|
|
838
|
+
: '0.8.1-alpha.14';
|
|
839
839
|
|
|
840
840
|
const RUNTIME_MODES = new Set(['production', 'preview', 'development', 'unknown']);
|
|
841
841
|
const OPERATING_SYSTEM_NAMES = new Set(['android', 'ios', 'ohos', 'windows', 'macos', 'linux', 'unknown']);
|
package/dist/index.esm.js
CHANGED
|
@@ -831,7 +831,7 @@ function createMessageId() {
|
|
|
831
831
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
832
832
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
833
833
|
? undefined
|
|
834
|
-
: '0.8.1-alpha.
|
|
834
|
+
: '0.8.1-alpha.14';
|
|
835
835
|
|
|
836
836
|
const RUNTIME_MODES = new Set(['production', 'preview', 'development', 'unknown']);
|
|
837
837
|
const OPERATING_SYSTEM_NAMES = new Set(['android', 'ios', 'ohos', 'windows', 'macos', 'linux', 'unknown']);
|
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-alpha.
|
|
14
|
+
: '0.8.1-alpha.14';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* iframe 与调试台页面的开发期 console 捕获转发。
|
|
@@ -3281,7 +3281,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
3281
3281
|
}
|
|
3282
3282
|
return { declared: false };
|
|
3283
3283
|
}
|
|
3284
|
-
if (!isRecord$
|
|
3284
|
+
if (!isRecord$3(value)) {
|
|
3285
3285
|
throw new Error(`${sourceLabel} 必须是 JSON 对象`);
|
|
3286
3286
|
}
|
|
3287
3287
|
const knownKeys = new Set(MINIAPP_PERMISSION_KEYS);
|
|
@@ -3295,7 +3295,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
3295
3295
|
continue;
|
|
3296
3296
|
const declaration = value[key];
|
|
3297
3297
|
const itemLabel = `${sourceLabel}.${key}`;
|
|
3298
|
-
if (!isRecord$
|
|
3298
|
+
if (!isRecord$3(declaration))
|
|
3299
3299
|
throw new Error(`${itemLabel} 必须是 JSON 对象`);
|
|
3300
3300
|
const definition = MINI_PROGRAM_PERMISSION_CATALOG.find((item) => item.key === key);
|
|
3301
3301
|
if (!definition)
|
|
@@ -3329,11 +3329,15 @@ function requiresExplicitPermissions(sdkVersion) {
|
|
|
3329
3329
|
function getMissingPermissionsWarning(sourceLabel = 'package.json#heybox.permissions') {
|
|
3330
3330
|
return `${sourceLabel} 尚未声明。当前按 0.8 兼容行为构建;0.9.0 起将拒绝构建,请尽快补充权限声明(无权限需求时配置 {})。`;
|
|
3331
3331
|
}
|
|
3332
|
-
function isRecord$
|
|
3332
|
+
function isRecord$3(value) {
|
|
3333
3333
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3334
3334
|
}
|
|
3335
3335
|
|
|
3336
3336
|
const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
|
|
3337
|
+
/** 窗口尺寸字段的脏值兜底上限;真正的上限是宿主侧显示器 workArea。 */
|
|
3338
|
+
const MINIAPP_WINDOW_SIZE_MAX = 16_384;
|
|
3339
|
+
const MINIAPP_WINDOW_NUMBER_FIELDS = ['defaultWidth', 'defaultHeight', 'minWidth', 'minHeight'];
|
|
3340
|
+
const MINIAPP_WINDOW_ALLOWED_FIELDS = [...MINIAPP_WINDOW_NUMBER_FIELDS, 'resizable'];
|
|
3337
3341
|
function validateMiniappPackageVersionForBuild(version) {
|
|
3338
3342
|
return validateMiniappManifestVersion(version, 'package.json.version');
|
|
3339
3343
|
}
|
|
@@ -3346,12 +3350,14 @@ function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version
|
|
|
3346
3350
|
}
|
|
3347
3351
|
function renderMiniappManifest(manifest) {
|
|
3348
3352
|
const platforms = validateMiniappPlatforms(manifest.platforms, 'manifest.platforms');
|
|
3353
|
+
const window = validateMiniappWindow(manifest.window, 'manifest.window');
|
|
3349
3354
|
const output = {
|
|
3350
3355
|
version: manifest.version,
|
|
3351
3356
|
sdkVersion: manifest.sdkVersion,
|
|
3352
3357
|
platforms,
|
|
3353
3358
|
...(manifest.permissions === undefined ? {} : { permissions: manifest.permissions }),
|
|
3354
3359
|
...(manifest.companions === undefined ? {} : { companions: manifest.companions }),
|
|
3360
|
+
...(window === undefined ? {} : { window }),
|
|
3355
3361
|
};
|
|
3356
3362
|
return `${JSON.stringify(output, null, 2)}\n`;
|
|
3357
3363
|
}
|
|
@@ -3372,6 +3378,70 @@ function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
|
|
|
3372
3378
|
}
|
|
3373
3379
|
return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
|
|
3374
3380
|
}
|
|
3381
|
+
/**
|
|
3382
|
+
* 校验并归一化 `package.json#heybox.window` / `manifest.window` 声明。
|
|
3383
|
+
*
|
|
3384
|
+
* @remarks
|
|
3385
|
+
* 与 `heybox.permissions` 同样的严格风格:未知字段报错,不做静默忽略。
|
|
3386
|
+
* `width` / `height` 显式给出改名提示;`x` / `y` 按未知字段显式报错(`INV-NO-DEV-POSITION`)。
|
|
3387
|
+
* 未声明时返回 `undefined`,由调用方决定不写入产物。
|
|
3388
|
+
* @param value - 待校验的原始声明(不可信输入)。
|
|
3389
|
+
* @param sourceLabel - 报错前缀,默认指向开发者声明路径。
|
|
3390
|
+
* @throws 当声明不是非空对象、含未知字段、数值/布尔类型不合法或 min/default 不配对时抛出。
|
|
3391
|
+
*/
|
|
3392
|
+
function validateMiniappWindow(value, sourceLabel = 'package.json#heybox.window') {
|
|
3393
|
+
if (value === undefined)
|
|
3394
|
+
return undefined;
|
|
3395
|
+
if (!isRecord$2(value) || Object.keys(value).length === 0) {
|
|
3396
|
+
throw new Error(`${sourceLabel} 至少需要声明 defaultWidth/defaultHeight/minWidth/minHeight/resizable 之一`);
|
|
3397
|
+
}
|
|
3398
|
+
if (Object.prototype.hasOwnProperty.call(value, 'width') || Object.prototype.hasOwnProperty.call(value, 'height')) {
|
|
3399
|
+
throw new Error(`${sourceLabel} 请使用 defaultWidth/defaultHeight,而不是 width/height`);
|
|
3400
|
+
}
|
|
3401
|
+
for (const key of Object.keys(value)) {
|
|
3402
|
+
if (!MINIAPP_WINDOW_ALLOWED_FIELDS.includes(key)) {
|
|
3403
|
+
throw new Error(`${sourceLabel} 包含未知字段:${key}`);
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
const window = {};
|
|
3407
|
+
for (const field of MINIAPP_WINDOW_NUMBER_FIELDS) {
|
|
3408
|
+
if (!Object.prototype.hasOwnProperty.call(value, field))
|
|
3409
|
+
continue;
|
|
3410
|
+
const size = value[field];
|
|
3411
|
+
if (typeof size !== 'number' || !Number.isSafeInteger(size) || size <= 0) {
|
|
3412
|
+
throw new Error(`${sourceLabel}.${field} 必须是正整数`);
|
|
3413
|
+
}
|
|
3414
|
+
if (size > MINIAPP_WINDOW_SIZE_MAX) {
|
|
3415
|
+
throw new Error(`${sourceLabel}.${field} 不能大于 ${MINIAPP_WINDOW_SIZE_MAX}`);
|
|
3416
|
+
}
|
|
3417
|
+
window[field] = size;
|
|
3418
|
+
}
|
|
3419
|
+
if (Object.prototype.hasOwnProperty.call(value, 'resizable')) {
|
|
3420
|
+
if (typeof value.resizable !== 'boolean') {
|
|
3421
|
+
throw new Error(`${sourceLabel}.resizable 必须是 boolean`);
|
|
3422
|
+
}
|
|
3423
|
+
window.resizable = value.resizable;
|
|
3424
|
+
}
|
|
3425
|
+
for (const [minimum, fallback] of [
|
|
3426
|
+
['minWidth', 'defaultWidth'],
|
|
3427
|
+
['minHeight', 'defaultHeight'],
|
|
3428
|
+
]) {
|
|
3429
|
+
const minimumValue = window[minimum];
|
|
3430
|
+
if (minimumValue === undefined)
|
|
3431
|
+
continue;
|
|
3432
|
+
const fallbackValue = window[fallback];
|
|
3433
|
+
if (fallbackValue === undefined) {
|
|
3434
|
+
throw new Error(`${sourceLabel}.${minimum} 必须与 ${fallback} 同时声明`);
|
|
3435
|
+
}
|
|
3436
|
+
if (minimumValue > fallbackValue) {
|
|
3437
|
+
throw new Error(`${sourceLabel}.${minimum} 必须小于等于 ${fallback}`);
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
return window;
|
|
3441
|
+
}
|
|
3442
|
+
function isRecord$2(value) {
|
|
3443
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3444
|
+
}
|
|
3375
3445
|
function getMiniappManifestVersionError(version) {
|
|
3376
3446
|
if (typeof version !== 'string' || version.trim() === '') {
|
|
3377
3447
|
return `必须是合法 SemVer:${String(version)}`;
|
|
@@ -3429,6 +3499,17 @@ function readMiniappPlatformsFromPackageJson(root) {
|
|
|
3429
3499
|
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3430
3500
|
return validateMiniappPlatforms(heybox?.platforms, 'package.json#heybox.platforms');
|
|
3431
3501
|
}
|
|
3502
|
+
/**
|
|
3503
|
+
* 读取并校验 `package.json#heybox.window`。
|
|
3504
|
+
*
|
|
3505
|
+
* @returns 合法声明;未声明时返回 `undefined`,调用方不得向 manifest 写入空对象或 `null`。
|
|
3506
|
+
* @throws 当声明违反 {@link validateMiniappWindow} 的规则时抛出,报错前缀为 `package.json#heybox.window`。
|
|
3507
|
+
*/
|
|
3508
|
+
function readMiniappWindowFromPackageJson(root) {
|
|
3509
|
+
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3510
|
+
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3511
|
+
return validateMiniappWindow(heybox?.window, 'package.json#heybox.window');
|
|
3512
|
+
}
|
|
3432
3513
|
function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
|
|
3433
3514
|
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3434
3515
|
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
@@ -12893,11 +12974,23 @@ const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
|
|
|
12893
12974
|
const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
|
|
12894
12975
|
const miniDevLoggingConstant = ['__HB_SDK_DEV', 'LOGGING__'].join('_');
|
|
12895
12976
|
const DEV_MANIFEST_PATH = '/__hb_sdk__/companion/manifest.json';
|
|
12977
|
+
/**
|
|
12978
|
+
* 本地 PC 调试开窗时的 manifest 入口。
|
|
12979
|
+
*
|
|
12980
|
+
* 开窗发生在扩展拿到 `LocalDevelopmentBinding` 之前,所以不能用 Companion 会话令牌守护;
|
|
12981
|
+
* 该入口改由 CLI 随本地调试启动上下文(`mini_url` query)下发的专用令牌守护,
|
|
12982
|
+
* 只回最新快照,不参与 Companion 会话的 digest 钉扎。
|
|
12983
|
+
*/
|
|
12984
|
+
const DEV_MINI_PROGRAM_MANIFEST_PATH = '/__hb_sdk__/mini-program/manifest.json';
|
|
12896
12985
|
const DEV_TOKEN_HEADER = 'x-hb-sdk-companion-dev-token';
|
|
12986
|
+
const DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER = 'x-hb-sdk-mini-program-manifest-token';
|
|
12897
12987
|
const DEV_DIGEST_HEADER = 'x-hb-sdk-companion-manifest-sha256';
|
|
12898
12988
|
const DEV_ERROR_MESSAGE = 'Companion 开发资源暂时不可用';
|
|
12989
|
+
/** 与 Companion manifest 一致的单响应上限,避免本地调试入口被大体积声明撑爆。 */
|
|
12990
|
+
const DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
12899
12991
|
const DEV_COMPANION_PATH_PATTERN = /^\/__hb_sdk__\/companions\/([a-z][a-z0-9-]{0,31})\/(windows-x64|macos-arm64)\.zip$/;
|
|
12900
12992
|
const HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV = 'HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN';
|
|
12993
|
+
const HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV = 'HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN';
|
|
12901
12994
|
const devSnapshotStoreKey = Symbol.for('@heybox/hb-sdk/dev-companion-snapshots');
|
|
12902
12995
|
const devSnapshotRegistry = globalThis;
|
|
12903
12996
|
if (!devSnapshotRegistry[devSnapshotStoreKey]) {
|
|
@@ -12914,7 +13007,8 @@ function miniappManifest() {
|
|
|
12914
13007
|
const includeCompanions = process.env.HB_SDK_SKIP_COMPANIONS !== '1';
|
|
12915
13008
|
const deviceLogs = new DeviceLogStore();
|
|
12916
13009
|
const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
|
|
12917
|
-
let companionArtifactAccessToken =
|
|
13010
|
+
let companionArtifactAccessToken = parseDevAccessToken(process.env[HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV]);
|
|
13011
|
+
let miniProgramManifestAccessToken = parseDevAccessToken(process.env[HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV]);
|
|
12918
13012
|
let root = process.cwd();
|
|
12919
13013
|
let outDir = 'dist';
|
|
12920
13014
|
let command = 'build';
|
|
@@ -12962,8 +13056,16 @@ function miniappManifest() {
|
|
|
12962
13056
|
registerLogs();
|
|
12963
13057
|
let store = devSnapshotStores.get(root);
|
|
12964
13058
|
companionArtifactAccessToken ??= store?.token;
|
|
12965
|
-
|
|
12966
|
-
|
|
13059
|
+
// 与 Companion 令牌同因:配置重载时 env 已不在,只能从同一服务的注册表恢复。
|
|
13060
|
+
miniProgramManifestAccessToken ??= store?.manifestToken;
|
|
13061
|
+
if (!store ||
|
|
13062
|
+
store.token !== companionArtifactAccessToken ||
|
|
13063
|
+
store.manifestToken !== miniProgramManifestAccessToken) {
|
|
13064
|
+
store = {
|
|
13065
|
+
token: companionArtifactAccessToken ?? '',
|
|
13066
|
+
...(miniProgramManifestAccessToken ? { manifestToken: miniProgramManifestAccessToken } : {}),
|
|
13067
|
+
snapshots: new Map(),
|
|
13068
|
+
};
|
|
12967
13069
|
devSnapshotStores.set(root, store);
|
|
12968
13070
|
}
|
|
12969
13071
|
const snapshots = store.snapshots;
|
|
@@ -13068,7 +13170,8 @@ function miniappManifest() {
|
|
|
13068
13170
|
return;
|
|
13069
13171
|
}
|
|
13070
13172
|
const companionMatch = pathname?.match(DEV_COMPANION_PATH_PATTERN);
|
|
13071
|
-
|
|
13173
|
+
const miniProgramManifest = pathname === DEV_MINI_PROGRAM_MANIFEST_PATH;
|
|
13174
|
+
if (pathname !== DEV_MANIFEST_PATH && !companionMatch && !miniProgramManifest) {
|
|
13072
13175
|
next();
|
|
13073
13176
|
return;
|
|
13074
13177
|
}
|
|
@@ -13078,16 +13181,25 @@ function miniappManifest() {
|
|
|
13078
13181
|
response.end();
|
|
13079
13182
|
return;
|
|
13080
13183
|
}
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13184
|
+
// 两条链路共用「仅数值 loopback」边界,凭据各自独立。
|
|
13185
|
+
if (!isNumericLoopbackRequest(request) || !isNumericLoopbackHost(request.headers.host)) {
|
|
13186
|
+
response.statusCode = 403;
|
|
13187
|
+
response.end();
|
|
13188
|
+
return;
|
|
13189
|
+
}
|
|
13190
|
+
const authorized = miniProgramManifest
|
|
13191
|
+
? miniProgramManifestAccessToken !== undefined &&
|
|
13192
|
+
hasValidDevToken(request, DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER, miniProgramManifestAccessToken)
|
|
13193
|
+
: companionArtifactAccessToken !== undefined &&
|
|
13194
|
+
hasValidDevToken(request, DEV_TOKEN_HEADER, companionArtifactAccessToken);
|
|
13195
|
+
if (!authorized) {
|
|
13085
13196
|
response.statusCode = 403;
|
|
13086
13197
|
response.end();
|
|
13087
13198
|
return;
|
|
13088
13199
|
}
|
|
13089
13200
|
try {
|
|
13090
|
-
|
|
13201
|
+
// 本地调试入口只回最新快照;digest 钉扎仍然只服务 Companion 会话。
|
|
13202
|
+
const requestedDigest = miniProgramManifest ? undefined : request.headers[DEV_DIGEST_HEADER];
|
|
13091
13203
|
if (requestedDigest !== undefined && (typeof requestedDigest !== 'string' || !/^[a-f0-9]{64}$/.test(requestedDigest))) {
|
|
13092
13204
|
response.statusCode = 400;
|
|
13093
13205
|
response.end();
|
|
@@ -13099,9 +13211,15 @@ function miniappManifest() {
|
|
|
13099
13211
|
response.end();
|
|
13100
13212
|
return;
|
|
13101
13213
|
}
|
|
13214
|
+
if (miniProgramManifest && snapshot.manifestBytes.length > DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES) {
|
|
13215
|
+
response.statusCode = 500;
|
|
13216
|
+
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
13217
|
+
response.end(DEV_ERROR_MESSAGE);
|
|
13218
|
+
return;
|
|
13219
|
+
}
|
|
13102
13220
|
response.setHeader('Cache-Control', 'no-store');
|
|
13103
13221
|
response.setHeader('X-Content-Type-Options', 'nosniff');
|
|
13104
|
-
if (pathname === DEV_MANIFEST_PATH) {
|
|
13222
|
+
if (pathname === DEV_MANIFEST_PATH || miniProgramManifest) {
|
|
13105
13223
|
response.statusCode = 200;
|
|
13106
13224
|
response.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
13107
13225
|
response.setHeader('Content-Length', snapshot.manifestBytes.length);
|
|
@@ -13181,6 +13299,7 @@ function miniappManifest() {
|
|
|
13181
13299
|
const sdkVersion = resolveSdkVersion();
|
|
13182
13300
|
const platforms = readMiniappPlatformsFromPackageJson(root);
|
|
13183
13301
|
const parsedPermissions = readMiniappPermissionsFromPackageJson(root, sdkVersion);
|
|
13302
|
+
const windowDeclaration = readMiniappWindowFromPackageJson(root);
|
|
13184
13303
|
const companionConfig = readMiniappCompanionsFromPackageJson(root);
|
|
13185
13304
|
const companionDeclarations = includeCompanions ? companionConfig.declarations : undefined;
|
|
13186
13305
|
if (!parsedPermissions.declared)
|
|
@@ -13210,6 +13329,7 @@ function miniappManifest() {
|
|
|
13210
13329
|
platforms,
|
|
13211
13330
|
...(parsedPermissions.permissions === undefined ? {} : { permissions: parsedPermissions.permissions }),
|
|
13212
13331
|
...(companions === undefined ? {} : { companions }),
|
|
13332
|
+
...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
|
|
13213
13333
|
}));
|
|
13214
13334
|
},
|
|
13215
13335
|
};
|
|
@@ -13218,6 +13338,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
|
|
|
13218
13338
|
const version = validateMiniappPackageVersionForBuild(readMiniappVersionFromPackageJson(root));
|
|
13219
13339
|
const sdkVersion = resolveSdkVersion();
|
|
13220
13340
|
const permissions = readMiniappPermissionsFromPackageJson(root, sdkVersion).permissions;
|
|
13341
|
+
const windowDeclaration = readMiniappWindowFromPackageJson(root);
|
|
13221
13342
|
if (declarations && !permissions?.companion) {
|
|
13222
13343
|
throw new Error('配置 companions 时必须声明 package.json#heybox.permissions.companion.enabled=true');
|
|
13223
13344
|
}
|
|
@@ -13241,6 +13362,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
|
|
|
13241
13362
|
platforms,
|
|
13242
13363
|
...(permissions === undefined ? {} : { permissions }),
|
|
13243
13364
|
...(companions === undefined ? {} : { companions }),
|
|
13365
|
+
...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
|
|
13244
13366
|
};
|
|
13245
13367
|
return { artifacts, manifestBytes: Buffer.from(renderMiniappManifest(manifest)) };
|
|
13246
13368
|
}
|
|
@@ -13289,11 +13411,12 @@ function isNumericLoopbackHost(host) {
|
|
|
13289
13411
|
const port = Number(match[1]);
|
|
13290
13412
|
return port >= 1 && port <= 65_535;
|
|
13291
13413
|
}
|
|
13292
|
-
|
|
13414
|
+
/** 两条本地调试链路共用的凭据形状:32 字节 base64url,恰好 43 个字符。 */
|
|
13415
|
+
function parseDevAccessToken(value) {
|
|
13293
13416
|
return value && /^[A-Za-z0-9_-]{43}$/.test(value) ? value : undefined;
|
|
13294
13417
|
}
|
|
13295
|
-
function
|
|
13296
|
-
const value = request.headers[
|
|
13418
|
+
function hasValidDevToken(request, header, expected) {
|
|
13419
|
+
const value = request.headers[header];
|
|
13297
13420
|
const candidate = Buffer.alloc(43);
|
|
13298
13421
|
if (typeof value === 'string')
|
|
13299
13422
|
Buffer.from(value).copy(candidate, 0, 0, candidate.length);
|
|
@@ -13343,5 +13466,6 @@ function resolveHmrWebSocketUrl(resolved) {
|
|
|
13343
13466
|
}
|
|
13344
13467
|
|
|
13345
13468
|
exports.HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV = HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV;
|
|
13469
|
+
exports.HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV = HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV;
|
|
13346
13470
|
exports.MINIAPP_PLATFORM_VALUES = MINIAPP_PLATFORM_VALUES;
|
|
13347
13471
|
exports.miniappManifest = miniappManifest;
|
package/dist/vite.esm.js
CHANGED
|
@@ -8,7 +8,7 @@ import { AsyncLocalStorage } from 'node:async_hooks';
|
|
|
8
8
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
9
9
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
10
10
|
? undefined
|
|
11
|
-
: '0.8.1-alpha.
|
|
11
|
+
: '0.8.1-alpha.14';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* iframe 与调试台页面的开发期 console 捕获转发。
|
|
@@ -3278,7 +3278,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
3278
3278
|
}
|
|
3279
3279
|
return { declared: false };
|
|
3280
3280
|
}
|
|
3281
|
-
if (!isRecord$
|
|
3281
|
+
if (!isRecord$3(value)) {
|
|
3282
3282
|
throw new Error(`${sourceLabel} 必须是 JSON 对象`);
|
|
3283
3283
|
}
|
|
3284
3284
|
const knownKeys = new Set(MINIAPP_PERMISSION_KEYS);
|
|
@@ -3292,7 +3292,7 @@ function parseMiniappPermissions(value, options) {
|
|
|
3292
3292
|
continue;
|
|
3293
3293
|
const declaration = value[key];
|
|
3294
3294
|
const itemLabel = `${sourceLabel}.${key}`;
|
|
3295
|
-
if (!isRecord$
|
|
3295
|
+
if (!isRecord$3(declaration))
|
|
3296
3296
|
throw new Error(`${itemLabel} 必须是 JSON 对象`);
|
|
3297
3297
|
const definition = MINI_PROGRAM_PERMISSION_CATALOG.find((item) => item.key === key);
|
|
3298
3298
|
if (!definition)
|
|
@@ -3326,11 +3326,15 @@ function requiresExplicitPermissions(sdkVersion) {
|
|
|
3326
3326
|
function getMissingPermissionsWarning(sourceLabel = 'package.json#heybox.permissions') {
|
|
3327
3327
|
return `${sourceLabel} 尚未声明。当前按 0.8 兼容行为构建;0.9.0 起将拒绝构建,请尽快补充权限声明(无权限需求时配置 {})。`;
|
|
3328
3328
|
}
|
|
3329
|
-
function isRecord$
|
|
3329
|
+
function isRecord$3(value) {
|
|
3330
3330
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3331
3331
|
}
|
|
3332
3332
|
|
|
3333
3333
|
const MINIAPP_PLATFORM_VALUES = ['android', 'ios', 'ohos', 'windows', 'macos', 'linux'];
|
|
3334
|
+
/** 窗口尺寸字段的脏值兜底上限;真正的上限是宿主侧显示器 workArea。 */
|
|
3335
|
+
const MINIAPP_WINDOW_SIZE_MAX = 16_384;
|
|
3336
|
+
const MINIAPP_WINDOW_NUMBER_FIELDS = ['defaultWidth', 'defaultHeight', 'minWidth', 'minHeight'];
|
|
3337
|
+
const MINIAPP_WINDOW_ALLOWED_FIELDS = [...MINIAPP_WINDOW_NUMBER_FIELDS, 'resizable'];
|
|
3334
3338
|
function validateMiniappPackageVersionForBuild(version) {
|
|
3335
3339
|
return validateMiniappManifestVersion(version, 'package.json.version');
|
|
3336
3340
|
}
|
|
@@ -3343,12 +3347,14 @@ function validateMiniappManifestVersion(version, sourceLabel = 'manifest.version
|
|
|
3343
3347
|
}
|
|
3344
3348
|
function renderMiniappManifest(manifest) {
|
|
3345
3349
|
const platforms = validateMiniappPlatforms(manifest.platforms, 'manifest.platforms');
|
|
3350
|
+
const window = validateMiniappWindow(manifest.window, 'manifest.window');
|
|
3346
3351
|
const output = {
|
|
3347
3352
|
version: manifest.version,
|
|
3348
3353
|
sdkVersion: manifest.sdkVersion,
|
|
3349
3354
|
platforms,
|
|
3350
3355
|
...(manifest.permissions === undefined ? {} : { permissions: manifest.permissions }),
|
|
3351
3356
|
...(manifest.companions === undefined ? {} : { companions: manifest.companions }),
|
|
3357
|
+
...(window === undefined ? {} : { window }),
|
|
3352
3358
|
};
|
|
3353
3359
|
return `${JSON.stringify(output, null, 2)}\n`;
|
|
3354
3360
|
}
|
|
@@ -3369,6 +3375,70 @@ function validateMiniappPlatforms(platforms, sourceLabel = 'platforms') {
|
|
|
3369
3375
|
}
|
|
3370
3376
|
return Object.freeze(MINIAPP_PLATFORM_VALUES.filter((platform) => seen.has(platform)));
|
|
3371
3377
|
}
|
|
3378
|
+
/**
|
|
3379
|
+
* 校验并归一化 `package.json#heybox.window` / `manifest.window` 声明。
|
|
3380
|
+
*
|
|
3381
|
+
* @remarks
|
|
3382
|
+
* 与 `heybox.permissions` 同样的严格风格:未知字段报错,不做静默忽略。
|
|
3383
|
+
* `width` / `height` 显式给出改名提示;`x` / `y` 按未知字段显式报错(`INV-NO-DEV-POSITION`)。
|
|
3384
|
+
* 未声明时返回 `undefined`,由调用方决定不写入产物。
|
|
3385
|
+
* @param value - 待校验的原始声明(不可信输入)。
|
|
3386
|
+
* @param sourceLabel - 报错前缀,默认指向开发者声明路径。
|
|
3387
|
+
* @throws 当声明不是非空对象、含未知字段、数值/布尔类型不合法或 min/default 不配对时抛出。
|
|
3388
|
+
*/
|
|
3389
|
+
function validateMiniappWindow(value, sourceLabel = 'package.json#heybox.window') {
|
|
3390
|
+
if (value === undefined)
|
|
3391
|
+
return undefined;
|
|
3392
|
+
if (!isRecord$2(value) || Object.keys(value).length === 0) {
|
|
3393
|
+
throw new Error(`${sourceLabel} 至少需要声明 defaultWidth/defaultHeight/minWidth/minHeight/resizable 之一`);
|
|
3394
|
+
}
|
|
3395
|
+
if (Object.prototype.hasOwnProperty.call(value, 'width') || Object.prototype.hasOwnProperty.call(value, 'height')) {
|
|
3396
|
+
throw new Error(`${sourceLabel} 请使用 defaultWidth/defaultHeight,而不是 width/height`);
|
|
3397
|
+
}
|
|
3398
|
+
for (const key of Object.keys(value)) {
|
|
3399
|
+
if (!MINIAPP_WINDOW_ALLOWED_FIELDS.includes(key)) {
|
|
3400
|
+
throw new Error(`${sourceLabel} 包含未知字段:${key}`);
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
const window = {};
|
|
3404
|
+
for (const field of MINIAPP_WINDOW_NUMBER_FIELDS) {
|
|
3405
|
+
if (!Object.prototype.hasOwnProperty.call(value, field))
|
|
3406
|
+
continue;
|
|
3407
|
+
const size = value[field];
|
|
3408
|
+
if (typeof size !== 'number' || !Number.isSafeInteger(size) || size <= 0) {
|
|
3409
|
+
throw new Error(`${sourceLabel}.${field} 必须是正整数`);
|
|
3410
|
+
}
|
|
3411
|
+
if (size > MINIAPP_WINDOW_SIZE_MAX) {
|
|
3412
|
+
throw new Error(`${sourceLabel}.${field} 不能大于 ${MINIAPP_WINDOW_SIZE_MAX}`);
|
|
3413
|
+
}
|
|
3414
|
+
window[field] = size;
|
|
3415
|
+
}
|
|
3416
|
+
if (Object.prototype.hasOwnProperty.call(value, 'resizable')) {
|
|
3417
|
+
if (typeof value.resizable !== 'boolean') {
|
|
3418
|
+
throw new Error(`${sourceLabel}.resizable 必须是 boolean`);
|
|
3419
|
+
}
|
|
3420
|
+
window.resizable = value.resizable;
|
|
3421
|
+
}
|
|
3422
|
+
for (const [minimum, fallback] of [
|
|
3423
|
+
['minWidth', 'defaultWidth'],
|
|
3424
|
+
['minHeight', 'defaultHeight'],
|
|
3425
|
+
]) {
|
|
3426
|
+
const minimumValue = window[minimum];
|
|
3427
|
+
if (minimumValue === undefined)
|
|
3428
|
+
continue;
|
|
3429
|
+
const fallbackValue = window[fallback];
|
|
3430
|
+
if (fallbackValue === undefined) {
|
|
3431
|
+
throw new Error(`${sourceLabel}.${minimum} 必须与 ${fallback} 同时声明`);
|
|
3432
|
+
}
|
|
3433
|
+
if (minimumValue > fallbackValue) {
|
|
3434
|
+
throw new Error(`${sourceLabel}.${minimum} 必须小于等于 ${fallback}`);
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
return window;
|
|
3438
|
+
}
|
|
3439
|
+
function isRecord$2(value) {
|
|
3440
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3441
|
+
}
|
|
3372
3442
|
function getMiniappManifestVersionError(version) {
|
|
3373
3443
|
if (typeof version !== 'string' || version.trim() === '') {
|
|
3374
3444
|
return `必须是合法 SemVer:${String(version)}`;
|
|
@@ -3426,6 +3496,17 @@ function readMiniappPlatformsFromPackageJson(root) {
|
|
|
3426
3496
|
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3427
3497
|
return validateMiniappPlatforms(heybox?.platforms, 'package.json#heybox.platforms');
|
|
3428
3498
|
}
|
|
3499
|
+
/**
|
|
3500
|
+
* 读取并校验 `package.json#heybox.window`。
|
|
3501
|
+
*
|
|
3502
|
+
* @returns 合法声明;未声明时返回 `undefined`,调用方不得向 manifest 写入空对象或 `null`。
|
|
3503
|
+
* @throws 当声明违反 {@link validateMiniappWindow} 的规则时抛出,报错前缀为 `package.json#heybox.window`。
|
|
3504
|
+
*/
|
|
3505
|
+
function readMiniappWindowFromPackageJson(root) {
|
|
3506
|
+
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3507
|
+
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
3508
|
+
return validateMiniappWindow(heybox?.window, 'package.json#heybox.window');
|
|
3509
|
+
}
|
|
3429
3510
|
function readMiniappPermissionsFromPackageJson(root, sdkVersion) {
|
|
3430
3511
|
const { packageJson } = readMiniappPackageJson(root, false);
|
|
3431
3512
|
const heybox = readMiniappHeyboxConfig(packageJson);
|
|
@@ -12890,11 +12971,23 @@ const sdkVersionPlaceholder = ['__HB_SDK', 'VERSION__'].join('_');
|
|
|
12890
12971
|
const sdkVersionBuildConstant = ['__HB_SDK_BUILD', 'VERSION__'].join('_');
|
|
12891
12972
|
const miniDevLoggingConstant = ['__HB_SDK_DEV', 'LOGGING__'].join('_');
|
|
12892
12973
|
const DEV_MANIFEST_PATH = '/__hb_sdk__/companion/manifest.json';
|
|
12974
|
+
/**
|
|
12975
|
+
* 本地 PC 调试开窗时的 manifest 入口。
|
|
12976
|
+
*
|
|
12977
|
+
* 开窗发生在扩展拿到 `LocalDevelopmentBinding` 之前,所以不能用 Companion 会话令牌守护;
|
|
12978
|
+
* 该入口改由 CLI 随本地调试启动上下文(`mini_url` query)下发的专用令牌守护,
|
|
12979
|
+
* 只回最新快照,不参与 Companion 会话的 digest 钉扎。
|
|
12980
|
+
*/
|
|
12981
|
+
const DEV_MINI_PROGRAM_MANIFEST_PATH = '/__hb_sdk__/mini-program/manifest.json';
|
|
12893
12982
|
const DEV_TOKEN_HEADER = 'x-hb-sdk-companion-dev-token';
|
|
12983
|
+
const DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER = 'x-hb-sdk-mini-program-manifest-token';
|
|
12894
12984
|
const DEV_DIGEST_HEADER = 'x-hb-sdk-companion-manifest-sha256';
|
|
12895
12985
|
const DEV_ERROR_MESSAGE = 'Companion 开发资源暂时不可用';
|
|
12986
|
+
/** 与 Companion manifest 一致的单响应上限,避免本地调试入口被大体积声明撑爆。 */
|
|
12987
|
+
const DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES = 1024 * 1024;
|
|
12896
12988
|
const DEV_COMPANION_PATH_PATTERN = /^\/__hb_sdk__\/companions\/([a-z][a-z0-9-]{0,31})\/(windows-x64|macos-arm64)\.zip$/;
|
|
12897
12989
|
const HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV = 'HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN';
|
|
12990
|
+
const HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV = 'HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN';
|
|
12898
12991
|
const devSnapshotStoreKey = Symbol.for('@heybox/hb-sdk/dev-companion-snapshots');
|
|
12899
12992
|
const devSnapshotRegistry = globalThis;
|
|
12900
12993
|
if (!devSnapshotRegistry[devSnapshotStoreKey]) {
|
|
@@ -12911,7 +13004,8 @@ function miniappManifest() {
|
|
|
12911
13004
|
const includeCompanions = process.env.HB_SDK_SKIP_COMPANIONS !== '1';
|
|
12912
13005
|
const deviceLogs = new DeviceLogStore();
|
|
12913
13006
|
const skipPlatformCsp = shouldSkipMiniappPlatformCspFromEnv();
|
|
12914
|
-
let companionArtifactAccessToken =
|
|
13007
|
+
let companionArtifactAccessToken = parseDevAccessToken(process.env[HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV]);
|
|
13008
|
+
let miniProgramManifestAccessToken = parseDevAccessToken(process.env[HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV]);
|
|
12915
13009
|
let root = process.cwd();
|
|
12916
13010
|
let outDir = 'dist';
|
|
12917
13011
|
let command = 'build';
|
|
@@ -12959,8 +13053,16 @@ function miniappManifest() {
|
|
|
12959
13053
|
registerLogs();
|
|
12960
13054
|
let store = devSnapshotStores.get(root);
|
|
12961
13055
|
companionArtifactAccessToken ??= store?.token;
|
|
12962
|
-
|
|
12963
|
-
|
|
13056
|
+
// 与 Companion 令牌同因:配置重载时 env 已不在,只能从同一服务的注册表恢复。
|
|
13057
|
+
miniProgramManifestAccessToken ??= store?.manifestToken;
|
|
13058
|
+
if (!store ||
|
|
13059
|
+
store.token !== companionArtifactAccessToken ||
|
|
13060
|
+
store.manifestToken !== miniProgramManifestAccessToken) {
|
|
13061
|
+
store = {
|
|
13062
|
+
token: companionArtifactAccessToken ?? '',
|
|
13063
|
+
...(miniProgramManifestAccessToken ? { manifestToken: miniProgramManifestAccessToken } : {}),
|
|
13064
|
+
snapshots: new Map(),
|
|
13065
|
+
};
|
|
12964
13066
|
devSnapshotStores.set(root, store);
|
|
12965
13067
|
}
|
|
12966
13068
|
const snapshots = store.snapshots;
|
|
@@ -13065,7 +13167,8 @@ function miniappManifest() {
|
|
|
13065
13167
|
return;
|
|
13066
13168
|
}
|
|
13067
13169
|
const companionMatch = pathname?.match(DEV_COMPANION_PATH_PATTERN);
|
|
13068
|
-
|
|
13170
|
+
const miniProgramManifest = pathname === DEV_MINI_PROGRAM_MANIFEST_PATH;
|
|
13171
|
+
if (pathname !== DEV_MANIFEST_PATH && !companionMatch && !miniProgramManifest) {
|
|
13069
13172
|
next();
|
|
13070
13173
|
return;
|
|
13071
13174
|
}
|
|
@@ -13075,16 +13178,25 @@ function miniappManifest() {
|
|
|
13075
13178
|
response.end();
|
|
13076
13179
|
return;
|
|
13077
13180
|
}
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
|
|
13181
|
+
// 两条链路共用「仅数值 loopback」边界,凭据各自独立。
|
|
13182
|
+
if (!isNumericLoopbackRequest(request) || !isNumericLoopbackHost(request.headers.host)) {
|
|
13183
|
+
response.statusCode = 403;
|
|
13184
|
+
response.end();
|
|
13185
|
+
return;
|
|
13186
|
+
}
|
|
13187
|
+
const authorized = miniProgramManifest
|
|
13188
|
+
? miniProgramManifestAccessToken !== undefined &&
|
|
13189
|
+
hasValidDevToken(request, DEV_MINI_PROGRAM_MANIFEST_TOKEN_HEADER, miniProgramManifestAccessToken)
|
|
13190
|
+
: companionArtifactAccessToken !== undefined &&
|
|
13191
|
+
hasValidDevToken(request, DEV_TOKEN_HEADER, companionArtifactAccessToken);
|
|
13192
|
+
if (!authorized) {
|
|
13082
13193
|
response.statusCode = 403;
|
|
13083
13194
|
response.end();
|
|
13084
13195
|
return;
|
|
13085
13196
|
}
|
|
13086
13197
|
try {
|
|
13087
|
-
|
|
13198
|
+
// 本地调试入口只回最新快照;digest 钉扎仍然只服务 Companion 会话。
|
|
13199
|
+
const requestedDigest = miniProgramManifest ? undefined : request.headers[DEV_DIGEST_HEADER];
|
|
13088
13200
|
if (requestedDigest !== undefined && (typeof requestedDigest !== 'string' || !/^[a-f0-9]{64}$/.test(requestedDigest))) {
|
|
13089
13201
|
response.statusCode = 400;
|
|
13090
13202
|
response.end();
|
|
@@ -13096,9 +13208,15 @@ function miniappManifest() {
|
|
|
13096
13208
|
response.end();
|
|
13097
13209
|
return;
|
|
13098
13210
|
}
|
|
13211
|
+
if (miniProgramManifest && snapshot.manifestBytes.length > DEV_MINI_PROGRAM_MANIFEST_MAX_BYTES) {
|
|
13212
|
+
response.statusCode = 500;
|
|
13213
|
+
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
13214
|
+
response.end(DEV_ERROR_MESSAGE);
|
|
13215
|
+
return;
|
|
13216
|
+
}
|
|
13099
13217
|
response.setHeader('Cache-Control', 'no-store');
|
|
13100
13218
|
response.setHeader('X-Content-Type-Options', 'nosniff');
|
|
13101
|
-
if (pathname === DEV_MANIFEST_PATH) {
|
|
13219
|
+
if (pathname === DEV_MANIFEST_PATH || miniProgramManifest) {
|
|
13102
13220
|
response.statusCode = 200;
|
|
13103
13221
|
response.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
13104
13222
|
response.setHeader('Content-Length', snapshot.manifestBytes.length);
|
|
@@ -13178,6 +13296,7 @@ function miniappManifest() {
|
|
|
13178
13296
|
const sdkVersion = resolveSdkVersion();
|
|
13179
13297
|
const platforms = readMiniappPlatformsFromPackageJson(root);
|
|
13180
13298
|
const parsedPermissions = readMiniappPermissionsFromPackageJson(root, sdkVersion);
|
|
13299
|
+
const windowDeclaration = readMiniappWindowFromPackageJson(root);
|
|
13181
13300
|
const companionConfig = readMiniappCompanionsFromPackageJson(root);
|
|
13182
13301
|
const companionDeclarations = includeCompanions ? companionConfig.declarations : undefined;
|
|
13183
13302
|
if (!parsedPermissions.declared)
|
|
@@ -13207,6 +13326,7 @@ function miniappManifest() {
|
|
|
13207
13326
|
platforms,
|
|
13208
13327
|
...(parsedPermissions.permissions === undefined ? {} : { permissions: parsedPermissions.permissions }),
|
|
13209
13328
|
...(companions === undefined ? {} : { companions }),
|
|
13329
|
+
...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
|
|
13210
13330
|
}));
|
|
13211
13331
|
},
|
|
13212
13332
|
};
|
|
@@ -13215,6 +13335,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
|
|
|
13215
13335
|
const version = validateMiniappPackageVersionForBuild(readMiniappVersionFromPackageJson(root));
|
|
13216
13336
|
const sdkVersion = resolveSdkVersion();
|
|
13217
13337
|
const permissions = readMiniappPermissionsFromPackageJson(root, sdkVersion).permissions;
|
|
13338
|
+
const windowDeclaration = readMiniappWindowFromPackageJson(root);
|
|
13218
13339
|
if (declarations && !permissions?.companion) {
|
|
13219
13340
|
throw new Error('配置 companions 时必须声明 package.json#heybox.permissions.companion.enabled=true');
|
|
13220
13341
|
}
|
|
@@ -13238,6 +13359,7 @@ function prepareDevSnapshot(root, outDir, platforms, declarations, snapshotRoot,
|
|
|
13238
13359
|
platforms,
|
|
13239
13360
|
...(permissions === undefined ? {} : { permissions }),
|
|
13240
13361
|
...(companions === undefined ? {} : { companions }),
|
|
13362
|
+
...(windowDeclaration === undefined ? {} : { window: windowDeclaration }),
|
|
13241
13363
|
};
|
|
13242
13364
|
return { artifacts, manifestBytes: Buffer.from(renderMiniappManifest(manifest)) };
|
|
13243
13365
|
}
|
|
@@ -13286,11 +13408,12 @@ function isNumericLoopbackHost(host) {
|
|
|
13286
13408
|
const port = Number(match[1]);
|
|
13287
13409
|
return port >= 1 && port <= 65_535;
|
|
13288
13410
|
}
|
|
13289
|
-
|
|
13411
|
+
/** 两条本地调试链路共用的凭据形状:32 字节 base64url,恰好 43 个字符。 */
|
|
13412
|
+
function parseDevAccessToken(value) {
|
|
13290
13413
|
return value && /^[A-Za-z0-9_-]{43}$/.test(value) ? value : undefined;
|
|
13291
13414
|
}
|
|
13292
|
-
function
|
|
13293
|
-
const value = request.headers[
|
|
13415
|
+
function hasValidDevToken(request, header, expected) {
|
|
13416
|
+
const value = request.headers[header];
|
|
13294
13417
|
const candidate = Buffer.alloc(43);
|
|
13295
13418
|
if (typeof value === 'string')
|
|
13296
13419
|
Buffer.from(value).copy(candidate, 0, 0, candidate.length);
|
|
@@ -13339,4 +13462,4 @@ function resolveHmrWebSocketUrl(resolved) {
|
|
|
13339
13462
|
return `${protocol}://${host}${port ? `:${port}` : ''}`;
|
|
13340
13463
|
}
|
|
13341
13464
|
|
|
13342
|
-
export { HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV, MINIAPP_PLATFORM_VALUES, miniappManifest };
|
|
13465
|
+
export { HB_SDK_COMPANION_ARTIFACT_ACCESS_TOKEN_ENV, HB_SDK_MINI_PROGRAM_MANIFEST_ACCESS_TOKEN_ENV, MINIAPP_PLATFORM_VALUES, miniappManifest };
|