1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
import { getDatabase } from "../db/index.js";
export interface StoredApiKey {
keyId: string;
provider: string;
apiKey: string;
importedAt: number;
updatedAt: number;
}
/**
* Store or update an API key in the database.
*/
export function setApiKey(keyId: string, provider: string, apiKey: string): void {
const db = getDatabase();
const now = Date.now();
db.query(
`INSERT INTO api_keys (key_id, provider, api_key, imported_at, updated_at)
VALUES ($keyId, $provider, $apiKey, $now, $now)
ON CONFLICT(key_id) DO UPDATE SET
api_key = $apiKey,
updated_at = $now`,
).run({
$keyId: keyId,
$provider: provider,
$apiKey: apiKey,
$now: now,
});
}
/**
* Get a stored API key by key ID. Returns the key string or null.
*/
export function getApiKey(keyId: string): string | null {
const db = getDatabase();
const row = db
.query("SELECT api_key FROM api_keys WHERE key_id = $keyId")
.get({ $keyId: keyId }) as { api_key: string } | null;
return row?.api_key ?? null;
}
/**
* Resolve an API key from the database, with env var fallback.
* Pass the env var name (e.g. "GOOGLE_API_KEY") to check process.env as well.
*/
export function resolveApiKey(keyId: string, envVar?: string): string | null {
const dbKey = getApiKey(keyId);
if (dbKey) return dbKey;
if (envVar) return process.env[envVar] ?? null;
return null;
}
/**
* Delete a stored API key.
*/
export function deleteApiKey(keyId: string): void {
const db = getDatabase();
db.query("DELETE FROM api_keys WHERE key_id = $keyId").run({ $keyId: keyId });
}
/**
* List all stored API keys with metadata (key value excluded for security).
*/
export function listApiKeys(): Array<{
keyId: string;
provider: string;
importedAt: number;
updatedAt: number;
}> {
const db = getDatabase();
const rows = db
.query("SELECT key_id, provider, imported_at, updated_at FROM api_keys ORDER BY key_id")
.all() as Array<Record<string, unknown>>;
return rows.map((row) => ({
keyId: row.key_id as string,
provider: row.provider as string,
importedAt: row.imported_at as number,
updatedAt: row.updated_at as number,
}));
}
|