071faa482c
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口 完成项目 TypeScript/Prettier 与 Rust 全量格式化 修复 Pingora expected executable 门禁的空白敏感误报 同步开发运维文档与 AGC skill pack 格式化忽略规则
121 lines
2.7 KiB
TypeScript
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',
|
|
};
|
|
}
|