|
|
const prisma = require("../utils/prisma");const slugifyModule = require("slugify");const { v4: uuidv4 } = require("uuid");
const WorkspaceThread = { defaultName: "Thread", writable: ["name"],
/** * The default Slugify module requires some additional mapping to prevent downstream issues * if the user is able to define a slug externally. We have to block non-escapable URL chars * so that is the slug is rendered it doesn't break the URL or UI when visited. * @param {...any} args - slugify args for npm package. * @returns {string} */ slugify: function (...args) { slugifyModule.extend({ "+": " plus ", "!": " bang ", "@": " at ", "*": " splat ", ".": " dot ", ":": "", "~": "", "(": "", ")": "", "'": "", '"': "", "|": "", }); return slugifyModule(...args); },
new: async function (workspace, userId = null, data = {}) { try { const thread = await prisma.workspace_threads.create({ data: { name: data.name ? String(data.name) : this.defaultName, slug: data.slug ? this.slugify(data.slug, { lowercase: true }) : uuidv4(), user_id: userId ? Number(userId) : null, workspace_id: workspace.id, }, });
return { thread, message: null }; } catch (error) { console.error(error.message); return { thread: null, message: error.message }; } },
update: async function (prevThread = null, data = {}) { if (!prevThread) throw new Error("No thread id provided for update");
const validData = {}; Object.entries(data).forEach(([key, value]) => { if (!this.writable.includes(key)) return; validData[key] = value; });
if (Object.keys(validData).length === 0) return { thread: prevThread, message: "No valid fields to update!" };
try { const thread = await prisma.workspace_threads.update({ where: { id: prevThread.id }, data: validData, }); return { thread, message: null }; } catch (error) { console.error(error.message); return { thread: null, message: error.message }; } },
get: async function (clause = {}) { try { const thread = await prisma.workspace_threads.findFirst({ where: clause, });
return thread || null; } catch (error) { console.error(error.message); return null; } },
delete: async function (clause = {}) { try { await prisma.workspace_threads.deleteMany({ where: clause, }); return true; } catch (error) { console.error(error.message); return false; } },
where: async function (clause = {}, limit = null, orderBy = null) { try { const results = await prisma.workspace_threads.findMany({ where: clause, ...(limit !== null ? { take: limit } : {}), ...(orderBy !== null ? { orderBy } : {}), }); return results; } catch (error) { console.error(error.message); return []; } },
// Will fire on first message (included or not) for a thread and rename the thread with the newName prop.
autoRenameThread: async function ({ workspace = null, thread = null, user = null, newName = null, onRename = null, }) { if (!workspace || !thread || !newName) return false; if (thread.name !== this.defaultName) return false; // don't rename if already named.
const { WorkspaceChats } = require("./workspaceChats"); const chatCount = await WorkspaceChats.count({ workspaceId: workspace.id, user_id: user?.id || null, thread_id: thread.id, }); if (chatCount !== 1) return { renamed: false, thread }; const { thread: updatedThread } = await this.update(thread, { name: newName, });
onRename?.(updatedThread); return true; },};
module.exports = { WorkspaceThread };
|