126 lines
3.1 KiB
JavaScript
126 lines
3.1 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
const { app } = require('electron');
|
|
|
|
function dataDir() {
|
|
const dir = path.join(app.getPath('userData'), 'data');
|
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
return dir;
|
|
}
|
|
|
|
function providersPath() {
|
|
return path.join(dataDir(), 'providers.json');
|
|
}
|
|
|
|
function conversationsDir() {
|
|
const dir = path.join(dataDir(), 'conversations');
|
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
return dir;
|
|
}
|
|
|
|
function readJSON(file, fallback) {
|
|
try {
|
|
if (!fs.existsSync(file)) return fallback;
|
|
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
function writeJSON(file, data) {
|
|
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf8');
|
|
}
|
|
|
|
function getProviders() {
|
|
return readJSON(providersPath(), []);
|
|
}
|
|
|
|
function saveProviders(list) {
|
|
writeJSON(providersPath(), list);
|
|
}
|
|
|
|
function upsertProvider(provider) {
|
|
const list = getProviders();
|
|
if (!provider.id) provider.id = crypto.randomUUID();
|
|
const idx = list.findIndex((p) => p.id === provider.id);
|
|
if (idx >= 0) list[idx] = { ...list[idx], ...provider };
|
|
else list.push(provider);
|
|
saveProviders(list);
|
|
return provider;
|
|
}
|
|
|
|
function deleteProvider(id) {
|
|
saveProviders(getProviders().filter((p) => p.id !== id));
|
|
}
|
|
|
|
function getConversationList() {
|
|
const dir = conversationsDir();
|
|
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'));
|
|
const items = files.map((f) => {
|
|
try {
|
|
const c = JSON.parse(fs.readFileSync(path.join(dir, f), 'utf8'));
|
|
return {
|
|
id: c.id,
|
|
title: c.title,
|
|
providerId: c.providerId,
|
|
model: c.model,
|
|
createdAt: c.createdAt,
|
|
updatedAt: c.updatedAt,
|
|
messageCount: (c.messages || []).length,
|
|
};
|
|
} catch {
|
|
return null;
|
|
}
|
|
}).filter(Boolean);
|
|
items.sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0));
|
|
return items;
|
|
}
|
|
|
|
function getConversation(id) {
|
|
const file = path.join(conversationsDir(), `${id}.json`);
|
|
return readJSON(file, null);
|
|
}
|
|
|
|
function saveConversation(conv) {
|
|
if (!conv.id) conv.id = crypto.randomUUID();
|
|
const now = Date.now();
|
|
if (!conv.createdAt) conv.createdAt = now;
|
|
conv.updatedAt = now;
|
|
writeJSON(path.join(conversationsDir(), `${conv.id}.json`), conv);
|
|
return conv;
|
|
}
|
|
|
|
function deleteConversation(id) {
|
|
const file = path.join(conversationsDir(), `${id}.json`);
|
|
if (fs.existsSync(file)) fs.unlinkSync(file);
|
|
}
|
|
|
|
function clearAllConversations() {
|
|
const dir = conversationsDir();
|
|
fs.readdirSync(dir).filter((f) => f.endsWith('.json')).forEach((f) => {
|
|
fs.unlinkSync(path.join(dir, f));
|
|
});
|
|
}
|
|
|
|
function renameConversation(id, title) {
|
|
const conv = getConversation(id);
|
|
if (!conv) return null;
|
|
conv.title = title;
|
|
conv.updatedAt = Date.now();
|
|
writeJSON(path.join(conversationsDir(), `${id}.json`), conv);
|
|
return conv;
|
|
}
|
|
|
|
module.exports = {
|
|
getProviders,
|
|
upsertProvider,
|
|
deleteProvider,
|
|
getConversationList,
|
|
getConversation,
|
|
saveConversation,
|
|
deleteConversation,
|
|
clearAllConversations,
|
|
renameConversation,
|
|
};
|