Project Files
src / config.ts
import path from "node:path";
import os from "node:os";
import fs from "node:fs/promises";
import { existsSync } from "node:fs";
import type { PluginConfig } from "./types";
export const DEFAULT_CONFIG: PluginConfig = {
dataRoot: "~/.lmstudio/plugins/data-plugin/data",
csv: {
delimiter: ",",
encoding: "utf-8",
bom: true,
quoteChar: '"',
escapeChar: '"',
},
ui: {
locale: "en",
dateFormat: "ISO",
},
performance: {
cacheSize: 10,
maxRowsPerPage: 100,
maxBatchInsert: 1000,
},
};
let _cachedConfig: PluginConfig | null = null;
export function resolvePath(p: string): string {
if (p.startsWith("~/")) {
return path.join(os.homedir(), p.slice(2));
}
return path.resolve(p);
}
function dataRootParentDir(dataRoot: string): string {
return path.dirname(resolvePath(dataRoot));
}
function configFilePath(dataRoot: string): string {
return path.join(dataRootParentDir(dataRoot), "data-plugin.configon");
}
async function loadConfigFromFile(): Promise<PluginConfig | null> {
try {
const filePath = configFilePath(DEFAULT_CONFIG.dataRoot);
const raw = await fs.readFile(filePath, "utf-8");
return JSON.parse(raw) as PluginConfig;
} catch {
return null;
}
}
export async function loadConfig(): Promise<PluginConfig> {
const file = await loadConfigFromFile();
if (!file) return { ...DEFAULT_CONFIG };
return {
...DEFAULT_CONFIG,
...file,
csv: { ...DEFAULT_CONFIG.csv, ...(file.csv ?? {}) },
ui: { ...DEFAULT_CONFIG.ui, ...(file.ui ?? {}) },
performance: { ...DEFAULT_CONFIG.performance, ...(file.performance ?? {}) },
};
}
export function getConfig(): PluginConfig {
if (!_cachedConfig) {
_cachedConfig = { ...DEFAULT_CONFIG };
}
return _cachedConfig;
}
export async function saveConfig(config: PluginConfig): Promise<void> {
const filePath = configFilePath(config.dataRoot);
const dir = path.dirname(filePath);
if (!existsSync(dir)) {
await fs.mkdir(dir, { recursive: true });
}
await fs.writeFile(filePath, JSON.stringify(config, null, 2), "utf-8");
_cachedConfig = config;
}
export function getDataRoot(): string {
return resolvePath(getConfig().dataRoot);
}
export async function initDataRoot(dataRoot: string): Promise<void> {
const resolved = resolvePath(dataRoot);
const databasesDir = path.join(resolved, "databases");
if (!existsSync(resolved)) {
await fs.mkdir(resolved, { recursive: true });
}
if (!existsSync(databasesDir)) {
await fs.mkdir(databasesDir, { recursive: true });
}
}
export async function updateConfig(
updates: Partial<PluginConfig>,
): Promise<void> {
const current = { ...getConfig() };
const merged: PluginConfig = {
...current,
...updates,
csv: { ...current.csv, ...(updates.csv ?? {}) },
ui: { ...current.ui, ...(updates.ui ?? {}) },
performance: { ...current.performance, ...(updates.performance ?? {}) },
};
await saveConfig(merged);
}