ai_api / src /lib /compliance /noLog.ts
Yogesh
initial deploy
cd8bd0a
Raw
History Blame Contribute Delete
2.35 kB
import type { SqliteAdapter } from "@/lib/db/adapters/types";
import { getDbInstance } from "../db/core";
// #2650: extracted from compliance/index.ts to break the
// callLogs.ts → compliance/index.ts → callLogs.ts cycle that deadlocks
// the bundled MCP server under Node.js 24's stricter ESM evaluation.
function getDb(): SqliteAdapter | null {
try {
return getDbInstance();
} catch {
return null;
}
}
const noLogKeys = new Set<string>();
const noLogDbCache = new Map<string, { value: boolean; timestamp: number }>();
let noLogColumnVerified = false;
let hasNoLogColumn = false;
const NO_LOG_CACHE_TTL_MS = 30_000;
const noLogIdsFromEnv = (process.env.NO_LOG_API_KEY_IDS || "")
.split(",")
.map((value) => value.trim())
.filter(Boolean);
for (const id of noLogIdsFromEnv) {
noLogKeys.add(id);
}
export function setNoLog(apiKeyId: string, noLog: boolean): void {
if (noLog) {
noLogKeys.add(apiKeyId);
} else {
noLogKeys.delete(apiKeyId);
}
noLogDbCache.set(apiKeyId, { value: noLog, timestamp: Date.now() });
}
function ensureNoLogColumn(db: SqliteAdapter): boolean {
if (noLogColumnVerified) {
return hasNoLogColumn;
}
try {
const columns = db.prepare("PRAGMA table_info(api_keys)").all() as Array<{ name: string }>;
hasNoLogColumn = columns.some((column) => column.name === "no_log");
} catch {
hasNoLogColumn = false;
}
noLogColumnVerified = true;
return hasNoLogColumn;
}
function readNoLogFromDb(apiKeyId: string): boolean {
const db = getDb();
if (!db || !apiKeyId) return false;
if (!ensureNoLogColumn(db)) return false;
const cached = noLogDbCache.get(apiKeyId);
if (cached && Date.now() - cached.timestamp < NO_LOG_CACHE_TTL_MS) {
return cached.value;
}
try {
const row = db.prepare("SELECT no_log FROM api_keys WHERE id = ?").get(apiKeyId) as
| { no_log?: number }
| undefined;
const value = Boolean(row && Number(row.no_log) === 1);
noLogDbCache.set(apiKeyId, { value, timestamp: Date.now() });
return value;
} catch {
return false;
}
}
export function isNoLog(apiKeyId: string): boolean {
if (!apiKeyId) return false;
if (noLogKeys.has(apiKeyId)) return true;
const persistedNoLog = readNoLogFromDb(apiKeyId);
if (persistedNoLog) {
noLogKeys.add(apiKeyId);
}
return persistedNoLog;
}