import { getAccountById, updateAccountTokens, type AccountRow } from "@/lib/db/repositories/accounts"; import type { MusicPlatformAdapter } from "@/lib/adapters/types"; import type { TokenSet } from "@/lib/types/model"; const REFRESH_MARGIN_MS = 60 * 1000; /** * Returns a fresh TokenSet for the account, refreshing (and persisting) it first * if it's within REFRESH_MARGIN_MS of expiry. */ export async function getFreshTokens( accountId: string, adapter: MusicPlatformAdapter ): Promise { const account = getAccountById(accountId); if (!account) throw new Error(`Unknown account: ${accountId}`); if (account.tokens.expiresAt - Date.now() > REFRESH_MARGIN_MS) { return account.tokens; } const refreshed = await adapter.refreshToken(account.tokens); updateAccountTokens(accountId, refreshed); return refreshed; } /** * Runs fn with fresh tokens; on a 401-shaped failure, force-refreshes once and retries. */ export async function withFreshTokens( account: AccountRow, adapter: MusicPlatformAdapter, fn: (tokens: TokenSet) => Promise ): Promise { const tokens = await getFreshTokens(account.id, adapter); try { return await fn(tokens); } catch (err) { const isUnauthorized = err instanceof Error && /\b401\b|unauthorized/i.test(err.message); if (!isUnauthorized) throw err; const refreshed = await adapter.refreshToken(tokens); updateAccountTokens(account.id, refreshed); return fn(refreshed); } }