绑定原生壳能力真实链路

桌面壳门禁拒绝声明能力落入 fallback-only 分支

根级原生壳门禁登记 H5 受控原生路由链路

项目文档同步宿主能力声明验收约定
This commit is contained in:
2026-06-20 16:23:55 +08:00
parent 6f12b48ce1
commit 3661ca69ee
4 changed files with 178 additions and 1 deletions
+70 -1
View File
@@ -993,6 +993,17 @@ function extractDesktopHandledMethods(source) {
];
}
function extractDesktopUnsupportedHandledMethods(source, handledMethods) {
return handledMethods.filter((method) => {
const methodBody = extractDesktopHostBridgeMethodBody(source, method);
return (
methodBody.includes('"unsupported_method"') ||
methodBody.includes('"unsupported_capability"') ||
methodBody.includes('resolve_host_bridge_request(request)')
);
});
}
function extractDesktopHostBridgeMethodBody(source, method) {
const methodStart = source.indexOf(`"${method}" =>`);
if (methodStart < 0) {
@@ -1001,7 +1012,7 @@ function extractDesktopHostBridgeMethodBody(source, method) {
const nextMethodMatch = source
.slice(methodStart + method.length)
.match(/\n "[^"]+"\s*=>/);
.match(/\n (?:"[^"]+"|_)\s*=>/);
const nextMethodStart = nextMethodMatch
? methodStart + method.length + nextMethodMatch.index
: -1;
@@ -1518,9 +1529,35 @@ const desktopCapabilities = extractDesktopCapabilities(
const desktopHandledMethods = extractDesktopHandledMethods(
desktopHostBridgeDispatchSource,
);
const desktopUnsupportedHandledMethods = extractDesktopUnsupportedHandledMethods(
desktopHostBridgeDispatchSource,
desktopHandledMethods,
);
const hostBridgeAcceptedUnsupportedMethods = sharedMethods.filter(
(method) => !desktopCapabilities.includes(method),
);
const desktopCapabilityDelegationContracts = {
'host.getRuntime': 'desktop_host_bridge_runtime_response(&request)',
'appearance.getColorScheme': 'desktop_appearance_color_scheme(&app, &request)',
'share.open': 'open_desktop_host_bridge_share(&app, &request)',
'share.setTarget': 'set_desktop_host_bridge_share_target(&app, &request)',
'navigation.openNativePage': 'open_desktop_host_bridge_native_page(&app, &request)',
'app.reloadWebView': 'reload_desktop_host_bridge_webview(&app, &request)',
'app.openExternalUrl': 'open_desktop_host_bridge_external_url(&app, &request)',
'app.setTitle': 'set_desktop_host_bridge_window_title(&app, &request)',
'app.setBadgeCount': 'set_desktop_app_badge_count(&app, &request)',
'network.status': 'resolve_desktop_host_bridge_network_status(&request).await',
'clipboard.writeText': 'write_desktop_host_bridge_clipboard_text(&app, &request)',
'clipboard.readText': 'read_desktop_host_bridge_clipboard_text(&app, &request)',
'file.exportText': 'export_desktop_host_bridge_text_file(&app, &request).await',
'file.importText': 'import_desktop_host_bridge_text_file(&app, &request).await',
'file.importDocument': 'import_desktop_host_bridge_document_file(&app, &request).await',
'file.exportImage': 'export_desktop_host_bridge_image_file(&app, &request).await',
'file.importImage': 'import_desktop_host_bridge_image_file(&app, &request).await',
'file.importAudio': 'import_desktop_host_bridge_audio_file(&app, &request).await',
'file.exportAudio': 'export_desktop_host_bridge_audio_file(&app, &request).await',
'notification.showLocal': 'show_desktop_local_notification(&app, &request)',
};
if (desktopHostBridgeProtocol !== sharedHostBridgeProtocol) {
throw new Error(
`desktop shell HostBridge protocol drifted: expected ${sharedHostBridgeProtocol} but got ${desktopHostBridgeProtocol}`,
@@ -1792,6 +1829,38 @@ if (missingDesktopMethodHandlers.length > 0) {
);
}
const unsupportedDesktopCapabilities = desktopCapabilities.filter(
(capability) =>
sharedMethods.includes(capability) &&
desktopUnsupportedHandledMethods.includes(capability),
);
if (unsupportedDesktopCapabilities.length > 0) {
throw new Error(
`desktop shell declares request capabilities backed by fallback-only handlers: ${unsupportedDesktopCapabilities.join(', ')}`,
);
}
for (const capability of desktopCapabilities.filter((entry) =>
sharedMethods.includes(entry),
)) {
const requiredDelegation = desktopCapabilityDelegationContracts[capability];
if (!requiredDelegation) {
throw new Error(
`desktop shell declared request capability is missing a delegation contract: ${capability}`,
);
}
const methodBody = extractDesktopHostBridgeMethodBody(
desktopHostBridgeDispatchSource,
capability,
);
if (!methodBody.includes(requiredDelegation)) {
throw new Error(
`desktop shell ${capability} must delegate to ${requiredDelegation}`,
);
}
}
const undeclaredDesktopMethodHandlers = desktopHandledMethods.filter(
(method) =>
!desktopCapabilities.includes(method) &&