File size: 4,056 Bytes
f8b5d42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
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,
include = null
) {
try {
const results = await prisma.workspace_threads.findMany({
where: clause,
...(limit !== null ? { take: limit } : {}),
...(orderBy !== null ? { orderBy } : {}),
...(include !== null ? { include } : {}),
});
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 };
|