Something went wrong. Try again.
Comail's webmail client, based on Bulwark. Public source mirror
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182import { readFile, writeFile, mkdir, rename, unlink } from 'node:fs/promises';import { existsSync } from 'node:fs';import path from 'node:path';import { logger } from '@/lib/logger';import { getConfigDir, assertWritable } from './paths';
function getPluginConfigDir(): string { return path.join(getConfigDir(), 'plugin-config');}
function configPath(pluginId: string): string { return path.join(getPluginConfigDir(), `${pluginId}.json`);}
async function ensureDir(dir: string): Promise<void> { if (!existsSync(dir)) { await mkdir(dir, { recursive: true }); }}
/** * Get all config for a plugin. */export async function getPluginConfig(pluginId: string): Promise<Record<string, unknown>> { try { const raw = await readFile(configPath(pluginId), 'utf-8'); return JSON.parse(raw); } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {}; logger.warn(`Failed to read plugin config for ${pluginId}`, { error: error instanceof Error ? error.message : 'Unknown error', }); return {}; }}
/** * Set a single config key for a plugin. */export async function setPluginConfig(pluginId: string, key: string, value: unknown): Promise<void> { assertWritable('update plugin config'); const dir = getPluginConfigDir(); await ensureDir(dir);
const config = await getPluginConfig(pluginId); config[key] = value;
const filePath = configPath(pluginId); const tmpPath = filePath + '.tmp'; await writeFile(tmpPath, JSON.stringify(config, null, 2), 'utf-8'); await rename(tmpPath, filePath);}
/** * Delete a single config key for a plugin. */export async function deletePluginConfigKey(pluginId: string, key: string): Promise<void> { assertWritable('delete plugin config key'); const config = await getPluginConfig(pluginId); delete config[key];
if (Object.keys(config).length === 0) { try { await unlink(configPath(pluginId)); } catch { /* ok if missing */ } return; }
const dir = getPluginConfigDir(); await ensureDir(dir); const filePath = configPath(pluginId); const tmpPath = filePath + '.tmp'; await writeFile(tmpPath, JSON.stringify(config, null, 2), 'utf-8'); await rename(tmpPath, filePath);}
/** * Delete all config for a plugin (used when uninstalling). */export async function deleteAllPluginConfig(pluginId: string): Promise<void> { assertWritable('delete plugin config'); try { await unlink(configPath(pluginId)); } catch { /* ok if missing */ }}