Files
Genarrative/apps/mobile-shell/src/host-bridge/protocol.ts
T
kdletters 071faa482c 统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口

完成项目 TypeScript/Prettier 与 Rust 全量格式化

修复 Pingora expected executable 门禁的空白敏感误报

同步开发运维文档与 AGC skill pack 格式化忽略规则
2026-09-01 16:28:34 +08:00

121 lines
2.7 KiB
TypeScript

import {
HOST_BRIDGE_PROTOCOL,
HOST_BRIDGE_VERSION,
type HostBridgeError,
type HostBridgeMethod,
type HostBridgeRequest,
type HostBridgeResponse,
isHostBridgeMethod,
normalizeHostBridgeRequestId,
} from '../../../../packages/shared/src/contracts/hostBridge';
import type {
MobileShellBaseWebUrlOptions,
MobileShellUrlOptions,
} from '../shell/url';
const HOST_BRIDGE_ERROR_CODES = new Set<HostBridgeError['code']>([
'invalid_request',
'unsupported_method',
'unsupported_capability',
'timeout',
'cancelled',
'host_error',
]);
export type MobileHostBridgeNavigation = {
allowedOrigin: string;
urlOptions: MobileShellUrlOptions;
baseWebUrlOptions?: MobileShellBaseWebUrlOptions;
openWebViewUrl: (url: string) => void;
reloadWebView: () => void;
};
export function unsupported(method: HostBridgeMethod): HostBridgeError {
return {
code: 'unsupported_method',
message: `${method} unsupported in mobile shell`,
};
}
export function invalidRequest(message: string): HostBridgeError {
return {
code: 'invalid_request',
message,
};
}
export function isHostBridgeRequest(
value: unknown,
): value is HostBridgeRequest {
if (!value || typeof value !== 'object') {
return false;
}
const candidate = value as Partial<HostBridgeRequest>;
const requestId = normalizeHostBridgeRequestId(candidate.id);
return (
candidate.bridge === HOST_BRIDGE_PROTOCOL &&
candidate.version === HOST_BRIDGE_VERSION &&
requestId !== null &&
isHostBridgeMethod(candidate.method)
);
}
export function parseRequest(raw: string) {
try {
return JSON.parse(raw) as unknown;
} catch {
return null;
}
}
export function ok<Result>(
request: HostBridgeRequest,
result?: Result,
): HostBridgeResponse<Result> {
return {
bridge: HOST_BRIDGE_PROTOCOL,
version: HOST_BRIDGE_VERSION,
id: request.id,
ok: true,
result,
};
}
export function failure(
request: Pick<HostBridgeRequest, 'id'>,
error: HostBridgeError,
): HostBridgeResponse {
return {
bridge: HOST_BRIDGE_PROTOCOL,
version: HOST_BRIDGE_VERSION,
id: request.id,
ok: false,
error,
};
}
export function normalizeMobileHostBridgeError(
error: unknown,
): HostBridgeError {
if (
error &&
typeof error === 'object' &&
'code' in error &&
'message' in error &&
typeof error.code === 'string' &&
HOST_BRIDGE_ERROR_CODES.has(error.code as HostBridgeError['code']) &&
typeof error.message === 'string'
) {
return {
code: error.code as HostBridgeError['code'],
message: error.message,
};
}
return {
code: 'host_error',
message: 'mobile host bridge request failed',
};
}