import { invoke } from "@tauri-apps/api/core"; import { getProvider, KEYRING_SERVICE, PROVIDERS, providerSupportsKey, type ProviderId, } from "../config"; export type ProviderKeys = Record; export const EMPTY_PROVIDER_KEYS: ProviderKeys = { openai: null, anthropic: null, google: null, xai: null, cerebras: null, groq: null, deepseek: null, openrouter: null, "openai-compatible": null, lmstudio: null, }; export async function getKey(provider: ProviderId): Promise { if (!providerSupportsKey(provider)) return null; try { const v = await invoke("secrets_get", { service: KEYRING_SERVICE, account: getProvider(provider).keyringAccount, }); return v && v.length > 0 ? v : null; } catch { return null; } } export async function setKey(provider: ProviderId, key: string): Promise { if (!providerSupportsKey(provider)) { throw new Error(`${provider} does not use an API key`); } const trimmed = key.trim(); if (!trimmed) throw new Error("API key is empty"); await invoke("secrets_set", { service: KEYRING_SERVICE, account: getProvider(provider).keyringAccount, password: trimmed, }); } export async function clearKey(provider: ProviderId): Promise { if (!providerSupportsKey(provider)) return; try { await invoke("secrets_delete", { service: KEYRING_SERVICE, account: getProvider(provider).keyringAccount, }); } catch { // already absent — fine } } export async function getAllKeys(): Promise { const out = { ...EMPTY_PROVIDER_KEYS }; const need = PROVIDERS.filter((p) => providerSupportsKey(p.id)); try { const results = await invoke<(string | null)[]>("secrets_get_all", { service: KEYRING_SERVICE, accounts: need.map((p) => p.keyringAccount), }); need.forEach((p, i) => { const v = results[i]; out[p.id] = v && v.length > 0 ? v : null; }); return out; } catch { const entries = await Promise.all( need.map(async (p) => [p.id, await getKey(p.id)] as const), ); for (const [id, v] of entries) out[id] = v; return out; } } export function hasAnyKey(keys: ProviderKeys): boolean { return PROVIDERS.some((p) => providerSupportsKey(p.id) && !!keys[p.id]); }