import { getTemporaryAPIKey } from './temp-api-keys-query' type ProjectRef = string const projectApiKeys = new Map>() export interface TemporaryApiKey { apiKey: string expiryTimeMs: number } export function createTemporaryApiKey(apiKey: string, expiryInSeconds: number): TemporaryApiKey { return { apiKey, expiryTimeMs: Date.now() + expiryInSeconds * 1000, } } export function isTemporaryApiKeyValid( key: TemporaryApiKey | null | undefined ): key is TemporaryApiKey { if (!key) return false const now = Date.now() const timeRemaining = key.expiryTimeMs - now // Consider the key invalid if it has less than 30 seconds remaining to avoid edge cases where the key // expires during use. return timeRemaining > 30_000 } const checkOrRefreshTemporaryApiKey = async ( projectRef: ProjectRef, existingKey: Promise | undefined ): Promise => { const resolvedKey = await existingKey if (isTemporaryApiKeyValid(resolvedKey)) { return resolvedKey } const expiryInSeconds = 60 const fetchedKey = getTemporaryAPIKey({ projectRef, expiry: expiryInSeconds, }).then((data) => createTemporaryApiKey(data.api_key, expiryInSeconds)) return fetchedKey } // This function should never be marked as async, it should always return a promise. export function getOrRefreshTemporaryApiKey(projectRef: ProjectRef): Promise { const existingKey = projectApiKeys.get(projectRef) const data = checkOrRefreshTemporaryApiKey(projectRef, existingKey) projectApiKeys.set(projectRef, data) return data }