import { getENV } from './get-env' const env = getENV() export const VAULT_SERVICE = env.appName const VAULT_NAME = 'vault' const cache = new Map() const key = (service: string, name: string) => `${service}:${name}` let loaded = false let loadPromise: Promise | null = null let writeChain: Promise = Promise.resolve() async function ensureLoaded(): Promise { if (loaded) return if (!loadPromise) { loadPromise = (async () => { const raw = await Bun.secrets.get({ service: VAULT_SERVICE, name: VAULT_NAME, }) if (raw) { try { const data = JSON.parse(raw) as Record for (const [k, v] of Object.entries(data)) cache.set(k, v) } catch (e) { console.log('[secrets] vault parse error:', e) } } loaded = true })() } await loadPromise } async function persist(): Promise { const raw = JSON.stringify(Object.fromEntries(cache)) writeChain = writeChain.then(() => Bun.secrets.set({ service: VAULT_SERVICE, name: VAULT_NAME, value: raw, }), ) return writeChain } export async function getSecret( service: string, name: string, ): Promise { const k = key(service, name) await ensureLoaded() return cache.get(k) ?? null } export async function setSecret( service: string, name: string, value: string, ): Promise { await ensureLoaded() cache.set(key(service, name), value) await persist() } export async function deleteSecret( service: string, name: string, ): Promise { if (service === VAULT_SERVICE && name === VAULT_NAME) { cache.clear() loaded = false loadPromise = null await Bun.secrets.delete({ service, name }) return } await ensureLoaded() cache.delete(key(service, name)) await persist() } export function clearSecretsCache(): void { cache.clear() loaded = false loadPromise = null }