收口宿主事件白名单

新增共享 HostBridge event 白名单与类型守卫

让 H5、Expo 和 Tauri 只分发白名单宿主事件

补齐移动端、桌面端和根级原生壳门禁

更新宿主壳方案文档和项目决策记录
This commit is contained in:
2026-06-19 02:18:36 +08:00
parent 75cd4f1abc
commit 429e65952d
12 changed files with 192 additions and 16 deletions
@@ -481,6 +481,10 @@ const sharedMethods = extractStringArrayExport(
sharedContractSource,
'HOST_BRIDGE_METHODS',
);
const sharedEvents = extractStringArrayExport(
sharedContractSource,
'HOST_BRIDGE_EVENTS',
);
const sharedMobileBaseCapabilities = extractStringArrayExport(
sharedContractSource,
'HOST_BRIDGE_EXPO_MOBILE_BASE_CAPABILITIES',
@@ -571,6 +575,15 @@ if (
throw new Error('mobile shell must not redeclare HostBridge capability profiles');
}
const unknownSharedEvents = sharedEvents.filter(
(eventName) => !sharedCapabilities.includes(eventName),
);
if (unknownSharedEvents.length > 0) {
throw new Error(
`shared HostBridge events must also be capabilities: ${unknownSharedEvents.join(', ')}`,
);
}
const unknownHandledMobileMethods = handledMobileMethods.filter(
(method) => !sharedMethods.includes(method),
);
@@ -878,6 +891,26 @@ for (const snippet of [
}
}
for (const snippet of [
'type HostBridgeEventName',
'(event: HostBridgeEventName, payload: unknown)',
]) {
if (!shellAppSource.includes(snippet)) {
throw new Error(`mobile shell HostBridge event injection missing ${snippet}`);
}
}
for (const eventName of sharedEvents) {
if (
mobileCapabilitySet.has(eventName) &&
!shellAppSource.includes(`'${eventName}'`)
) {
throw new Error(
`mobile shell advertises HostBridge event ${eventName} but ShellApp does not inject it`,
);
}
}
for (const snippet of [
'MobileShellLoadFailureInput',
'normalizeMobileShellLoadFailure',