@reliverse/rse
Version:
@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power
134 lines (133 loc) • 4.4 kB
JavaScript
import path from "@reliverse/pathkit";
import { ensuredir } from "@reliverse/relifso";
import fs from "@reliverse/relifso";
import { relinka } from "@reliverse/relinka";
import { eq } from "drizzle-orm";
import { memoryPath } from "../constants.js";
import { db } from "../db/client.js";
import { encrypt, decrypt } from "../db/config.js";
import { configKeysTable, userDataTable } from "../db/schema.js";
export async function getOrCreateReliverseMemory() {
if (!await fs.pathExists(path.dirname(memoryPath))) {
await ensuredir(path.dirname(memoryPath));
}
try {
const configRows = await db.select().from(configKeysTable);
const configData = {};
for (const row of configRows) {
try {
const decrypted = await decrypt(row.value);
try {
if (decrypted.startsWith("{") || decrypted.startsWith("[")) {
configData[row.key] = JSON.parse(decrypted);
} else {
configData[row.key] = decrypted;
}
} catch {
configData[row.key] = decrypted;
}
} catch {
configData[row.key] = "";
}
}
const userRows = await db.select().from(userDataTable);
const userData = userRows.reduce((acc, row) => {
try {
if (row.value.startsWith("{") || row.value.startsWith("[")) {
acc[row.key] = JSON.parse(row.value);
} else {
acc[row.key] = row.value;
}
} catch {
acc[row.key] = row.value;
}
return acc;
}, {});
return {
// Encrypted data
code: configData.code ?? "",
key: configData.key ?? "",
githubKey: configData.githubKey ?? "",
vercelKey: configData.vercelKey ?? "",
openaiKey: configData.openaiKey ?? "",
// Non-encrypted data
name: userData.name ?? "",
email: userData.email ?? "",
githubUsername: userData.githubUsername ?? "",
vercelTeamId: userData.vercelTeamId ?? "",
vercelTeamSlug: userData.vercelTeamSlug ?? ""
};
} catch (error) {
relinka(
"error",
"Error reading memory:",
error instanceof Error ? error.message : String(error)
);
return {
code: "",
key: "",
githubKey: "",
vercelKey: "",
openaiKey: "",
name: "",
email: "",
githubUsername: "",
vercelTeamSlug: "",
vercelTeamId: ""
};
}
}
export async function updateReliverseMemory(data) {
try {
const encryptedEntries = Object.entries(data).filter(
([key]) => ["code", "key", "githubKey", "vercelKey", "openaiKey"].includes(key)
).filter(([_, value]) => value !== null && value !== void 0);
const configUpdates = [];
for (const [key, value] of encryptedEntries) {
const stringValue = typeof value === "object" ? JSON.stringify(value) : typeof value === "undefined" ? "" : String(value);
const encryptedValue = await encrypt(stringValue);
configUpdates.push({
key,
value: encryptedValue
});
}
const userDataUpdates = Object.entries(data).filter(
([key]) => [
"name",
"email",
"githubUsername",
"vercelTeamSlug",
"vercelTeamId"
].includes(key)
).filter(([_, value]) => value !== null && value !== void 0).map(([key, value]) => ({
key,
value: typeof value === "object" ? JSON.stringify(value) : typeof value === "undefined" ? "" : String(value)
}));
const keysToDelete = Object.entries(data).filter(
([key]) => ["code", "key", "githubKey", "vercelKey", "openaiKey"].includes(key)
).filter(([_, value]) => value === null).map(([key]) => key);
for (const key of keysToDelete) {
await db.delete(configKeysTable).where(eq(configKeysTable.key, key));
}
for (const update of configUpdates) {
await db.insert(configKeysTable).values(update).onConflictDoUpdate({
target: configKeysTable.key,
set: { value: update.value }
});
}
for (const update of userDataUpdates) {
await db.insert(userDataTable).values(update).onConflictDoUpdate({
target: userDataTable.key,
set: { value: update.value }
});
}
relinka("verbose", "Memory updated successfully");
} catch (error) {
relinka(
"error",
"Error updating memory:",
error instanceof Error ? error.message : String(error)
);
throw error;
}
}