Files
Paperless-Contracts/src/settingsStore.ts

97 lines
2.5 KiB
TypeScript

import crypto from "node:crypto";
import db from "./db.js";
const getStmt = db.prepare("SELECT value FROM settings WHERE key = ?");
const upsertStmt = db.prepare("INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value, updated_at=excluded.updated_at");
const deleteStmt = db.prepare("DELETE FROM settings WHERE key = ?");
const listStmt = db.prepare("SELECT key, value FROM settings");
export type SettingKey =
| "paperlessBaseUrl"
| "paperlessExternalUrl"
| "paperlessWebhookUrl"
| "appExternalUrl"
| "appLocale"
| "paperlessToken"
| "schedulerIntervalMinutes"
| "alertDaysBefore"
| "mailServer"
| "mailPort"
| "mailUsername"
| "mailPassword"
| "mailUseTls"
| "mailFrom"
| "mailTo"
| "ntfyServerUrl"
| "ntfyTopic"
| "ntfyToken"
| "ntfyPriority"
| "authUsername"
| "authPassword"
| "icalSecret"
| "aiEnabled"
| "aiProvider"
| "aiBaseUrl"
| "aiModel"
| "aiApiKey"
| "aiSystemPrompt"
| "aiTimeoutSeconds"
| "aiMaxTokens"
| "paperlessWebhookSecret"
| "paperlessWorkflowId";
export type StoredSettings = Partial<Record<SettingKey, unknown>>;
export function getSetting<T = unknown>(key: SettingKey): T | undefined {
const row = getStmt.get(key) as { value: string } | undefined;
if (!row || typeof row.value !== "string") {
return undefined;
}
try {
return JSON.parse(row.value) as T;
} catch (_error) {
return undefined;
}
}
export function setSetting(key: SettingKey, value: unknown): void {
if (value === undefined || value === null || value === "") {
deleteStmt.run(key);
return;
}
const now = new Date().toISOString();
upsertStmt.run(key, JSON.stringify(value), now);
}
export function removeSetting(key: SettingKey): void {
deleteStmt.run(key);
}
export function listSettings(): StoredSettings {
const rows = listStmt.all() as Array<{ key: string; value: string }>;
const result: StoredSettings = {};
for (const row of rows) {
try {
result[row.key as SettingKey] = JSON.parse(row.value);
} catch (_error) {
// ignore bad data
}
}
return result;
}
export function ensureSetting(key: SettingKey, generator: () => unknown): unknown {
const existing = getSetting(key);
if (existing !== undefined) {
return existing;
}
const value = generator();
setSetting(key, value);
return value;
}
export function generateSecret(length = 32): string {
return crypto.randomBytes(length).toString("hex");
}