50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import type { ProjectContext, ProtocolVersion, Session, SessionContext } from "./protocol.js";
|
||
|
||
export class ProtocolParseError extends Error {
|
||
constructor(message: string) {
|
||
super(message);
|
||
this.name = "ProtocolParseError";
|
||
}
|
||
}
|
||
|
||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||
}
|
||
|
||
function hasString(value: Record<string, unknown>, key: string): boolean {
|
||
return typeof value[key] === "string" && value[key] !== "";
|
||
}
|
||
|
||
export function isProtocolVersion(value: unknown): value is ProtocolVersion {
|
||
return isRecord(value) && ["major", "minor", "patch"].every(
|
||
(key) => Number.isInteger(value[key]) && (value[key] as number) >= 0,
|
||
);
|
||
}
|
||
|
||
export function isProjectContext(value: unknown): value is ProjectContext {
|
||
return isRecord(value) && hasString(value, "server_id") && hasString(value, "project_id");
|
||
}
|
||
|
||
export function isSessionContext(value: unknown): value is SessionContext {
|
||
return isProjectContext(value) && hasString(value, "session_id");
|
||
}
|
||
|
||
export function isSession(value: unknown): value is Session {
|
||
if (!isRecord(value) || !isSessionContext(value)) return false;
|
||
return hasString(value, "name")
|
||
&& hasString(value, "state")
|
||
&& hasString(value, "first_seen_at")
|
||
&& hasString(value, "last_active_at")
|
||
&& Array.isArray(value.tags)
|
||
&& value.tags.every((tag) => typeof tag === "string")
|
||
&& Array.isArray(value.capabilities)
|
||
&& value.capabilities.every((capability) => typeof capability === "string");
|
||
}
|
||
|
||
export function parseSession(value: unknown): Session {
|
||
if (!isSession(value)) {
|
||
throw new ProtocolParseError("无效的 Session:缺少上下文字段或标准字段类型错误");
|
||
}
|
||
return value;
|
||
}
|