From 7793f2efd5c4b8681043ca7015a8b11494b4ebaf Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 06:10:13 +0000 Subject: [PATCH] refactor(pairing): dedupe allow-from store updates --- src/pairing/pairing-store.ts | 112 +++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 45 deletions(-) diff --git a/src/pairing/pairing-store.ts b/src/pairing/pairing-store.ts index d6a83133782..d7fe3379a90 100644 --- a/src/pairing/pairing-store.ts +++ b/src/pairing/pairing-store.ts @@ -213,6 +213,57 @@ function normalizeAllowFromInput(channel: PairingChannel, entry: string | number return normalizeAllowEntry(channel, normalizeId(entry)); } +async function readAllowFromState(params: { + channel: PairingChannel; + entry: string | number; + filePath: string; +}): Promise<{ current: string[]; normalized: string | null }> { + const { value } = await readJsonFile(params.filePath, { + version: 1, + allowFrom: [], + }); + const current = normalizeAllowFromList(params.channel, value); + const normalized = normalizeAllowFromInput(params.channel, params.entry); + return { current, normalized: normalized || null }; +} + +async function writeAllowFromState(filePath: string, allowFrom: string[]): Promise { + await writeJsonFile(filePath, { + version: 1, + allowFrom, + } satisfies AllowFromStore); +} + +async function updateAllowFromStoreEntry(params: { + channel: PairingChannel; + entry: string | number; + env?: NodeJS.ProcessEnv; + apply: (current: string[], normalized: string) => string[] | null; +}): Promise<{ changed: boolean; allowFrom: string[] }> { + const env = params.env ?? process.env; + const filePath = resolveAllowFromPath(params.channel, env); + return await withFileLock( + filePath, + { version: 1, allowFrom: [] } satisfies AllowFromStore, + async () => { + const { current, normalized } = await readAllowFromState({ + channel: params.channel, + entry: params.entry, + filePath, + }); + if (!normalized) { + return { changed: false, allowFrom: current }; + } + const next = params.apply(current, normalized); + if (!next) { + return { changed: false, allowFrom: current }; + } + await writeAllowFromState(filePath, next); + return { changed: true, allowFrom: next }; + }, + ); +} + export async function readChannelAllowFromStore( channel: PairingChannel, env: NodeJS.ProcessEnv = process.env, @@ -230,32 +281,17 @@ export async function addChannelAllowFromStoreEntry(params: { entry: string | number; env?: NodeJS.ProcessEnv; }): Promise<{ changed: boolean; allowFrom: string[] }> { - const env = params.env ?? process.env; - const filePath = resolveAllowFromPath(params.channel, env); - return await withFileLock( - filePath, - { version: 1, allowFrom: [] } satisfies AllowFromStore, - async () => { - const { value } = await readJsonFile(filePath, { - version: 1, - allowFrom: [], - }); - const current = normalizeAllowFromList(params.channel, value); - const normalized = normalizeAllowFromInput(params.channel, params.entry); - if (!normalized) { - return { changed: false, allowFrom: current }; - } + return await updateAllowFromStoreEntry({ + channel: params.channel, + entry: params.entry, + env: params.env, + apply: (current, normalized) => { if (current.includes(normalized)) { - return { changed: false, allowFrom: current }; + return null; } - const next = [...current, normalized]; - await writeJsonFile(filePath, { - version: 1, - allowFrom: next, - } satisfies AllowFromStore); - return { changed: true, allowFrom: next }; + return [...current, normalized]; }, - ); + }); } export async function removeChannelAllowFromStoreEntry(params: { @@ -263,32 +299,18 @@ export async function removeChannelAllowFromStoreEntry(params: { entry: string | number; env?: NodeJS.ProcessEnv; }): Promise<{ changed: boolean; allowFrom: string[] }> { - const env = params.env ?? process.env; - const filePath = resolveAllowFromPath(params.channel, env); - return await withFileLock( - filePath, - { version: 1, allowFrom: [] } satisfies AllowFromStore, - async () => { - const { value } = await readJsonFile(filePath, { - version: 1, - allowFrom: [], - }); - const current = normalizeAllowFromList(params.channel, value); - const normalized = normalizeAllowFromInput(params.channel, params.entry); - if (!normalized) { - return { changed: false, allowFrom: current }; - } + return await updateAllowFromStoreEntry({ + channel: params.channel, + entry: params.entry, + env: params.env, + apply: (current, normalized) => { const next = current.filter((entry) => entry !== normalized); if (next.length === current.length) { - return { changed: false, allowFrom: current }; + return null; } - await writeJsonFile(filePath, { - version: 1, - allowFrom: next, - } satisfies AllowFromStore); - return { changed: true, allowFrom: next }; + return next; }, - ); + }); } export async function listChannelPairingRequests(