


























@@ -58,6 +58,10 @@ type PairingStore = {
5858requests: PairingRequest[];
5959};
606061+function isRecord(value: unknown): value is Record<string, unknown> {
62+return !!value && typeof value === "object" && !Array.isArray(value);
63+}
64+6165function resolvePairingPath(channel: PairingChannel, env: NodeJS.ProcessEnv = process.env): string {
6266return path.join(resolvePairingCredentialsDir(env), `${safeChannelKey(channel)}-pairing.json`);
6367}
@@ -86,7 +90,13 @@ async function readPairingRequests(filePath: string): Promise<PairingRequest[]>
8690version: 1,
8791requests: [],
8892});
89-return Array.isArray(value.requests) ? value.requests : [];
93+if (!Array.isArray(value.requests)) {
94+return [];
95+}
96+return value.requests.flatMap((request) => {
97+const normalized = normalizePersistedPairingRequest(request);
98+return normalized ? [normalized] : [];
99+});
90100}
9110192102async function readPrunedPairingRequests(filePath: string): Promise<{
@@ -126,6 +136,48 @@ function parseTimestamp(value: string | undefined): number | null {
126136return parsed;
127137}
128138139+function normalizePersistedPairingMeta(value: unknown): Record<string, string> | undefined {
140+if (!isRecord(value)) {
141+return undefined;
142+}
143+const out: Record<string, string> = {};
144+for (const [key, entry] of Object.entries(value)) {
145+const normalized = normalizeOptionalString(entry);
146+if (normalized) {
147+out[key] = normalized;
148+}
149+}
150+return Object.keys(out).length > 0 ? out : undefined;
151+}
152+153+function normalizePersistedPairingRequest(value: unknown): PairingRequest | undefined {
154+if (!isRecord(value)) {
155+return undefined;
156+}
157+const id = normalizeOptionalString(value.id);
158+const code = normalizeOptionalString(value.code);
159+const createdAt = normalizeOptionalString(value.createdAt);
160+const lastSeenAt = normalizeOptionalString(value.lastSeenAt) ?? createdAt;
161+if (
162+!id ||
163+!code ||
164+!createdAt ||
165+!lastSeenAt ||
166+parseTimestamp(createdAt) === null ||
167+parseTimestamp(lastSeenAt) === null
168+) {
169+return undefined;
170+}
171+const meta = normalizePersistedPairingMeta(value.meta);
172+return {
173+ id,
174+ code,
175+ createdAt,
176+ lastSeenAt,
177+ ...(meta ? { meta } : {}),
178+};
179+}
180+129181function isExpired(entry: PairingRequest, nowMs: number): boolean {
130182const createdAt = parseTimestamp(entry.createdAt);
131183if (!createdAt) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。