-
-
\ No newline at end of file
+
diff --git a/plugins/markdownit.client.ts b/plugins/markdownit.client.ts
index c2de073..09d8be4 100644
--- a/plugins/markdownit.client.ts
+++ b/plugins/markdownit.client.ts
@@ -1,6 +1,6 @@
import markdownit from "markdown-it";
-import hljs from 'highlight.js';
-import 'highlight.js/styles/github-dark.min.css';
+import hljs from "highlight.js";
+import "highlight.js/styles/github-dark.min.css";
export default defineNuxtPlugin((nuxtApp) => {
let codeBlockId = 0;
@@ -8,27 +8,32 @@ export default defineNuxtPlugin((nuxtApp) => {
const md = markdownit({
highlight: function (str, lang) {
const currentId = `code-block-${codeBlockId++}`;
-
+
if (lang && hljs.getLanguage(lang)) {
try {
- const highlighted = hljs.highlight(str, { language: lang, ignoreIllegals: true }).value;
+ const highlighted = hljs.highlight(str, {
+ language: lang,
+ ignoreIllegals: true,
+ }).value;
// Return without the surrounding pre/code tags since markdown-it will add them
return highlighted;
} catch (__) {}
}
return md.utils.escapeHtml(str);
- }
+ },
});
// Override the fence renderer to add our custom wrapper
md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
const token = tokens[idx];
- const info = token.info ? md.utils.unescapeAll(token.info).trim() : '';
- const lang = info ? info.split(/\s+/g)[0] : '';
+ const info = token.info ? md.utils.unescapeAll(token.info).trim() : "";
+ const lang = info ? info.split(/\s+/g)[0] : "";
const currentId = `code-block-${codeBlockId++}`;
- const code = options.highlight ? options.highlight(token.content, lang, '') : token.content;
+ const code = options.highlight
+ ? options.highlight(token.content, lang, "")
+ : token.content;
const codeBlock = `
@@ -54,32 +59,33 @@ export default defineNuxtPlugin((nuxtApp) => {
// Add the copy functionality to the window object
if (import.meta.client) {
- window.copyCode = async function(id: string) {
+ window.copyCode = async function (id: string) {
const codeBlock = document.getElementById(id);
if (!codeBlock) return;
- const code = codeBlock.textContent || '';
-
+ const code = codeBlock.textContent || "";
+
try {
await navigator.clipboard.writeText(code);
-
+
// Get the button associated with this code block
- const button = codeBlock.parentElement?.parentElement?.querySelector('.copy-button');
- const copyIcon = button?.querySelector('.copy-icon');
- const checkIcon = button?.querySelector('.check-icon');
-
+ const button =
+ codeBlock.parentElement?.parentElement?.querySelector(".copy-button");
+ const copyIcon = button?.querySelector(".copy-icon");
+ const checkIcon = button?.querySelector(".check-icon");
+
if (copyIcon && checkIcon) {
- copyIcon.classList.add('hidden');
- checkIcon.classList.remove('hidden');
-
+ copyIcon.classList.add("hidden");
+ checkIcon.classList.remove("hidden");
+
// Reset button after 2 seconds
setTimeout(() => {
- copyIcon.classList.remove('hidden');
- checkIcon.classList.add('hidden');
+ copyIcon.classList.remove("hidden");
+ checkIcon.classList.add("hidden");
}, 2000);
}
} catch (err) {
- console.error('Failed to copy code:', err);
+ console.error("Failed to copy code:", err);
}
};
}
@@ -89,4 +95,4 @@ export default defineNuxtPlugin((nuxtApp) => {
mdRenderer: md,
},
};
-});
\ No newline at end of file
+});
diff --git a/server/api/chat.post.ts b/server/api/chat.post.ts
index 57e9ab4..61e23bb 100644
--- a/server/api/chat.post.ts
+++ b/server/api/chat.post.ts
@@ -73,8 +73,8 @@ export default defineEventHandler(async (event: H3Event) => {
.where(
and(
eq(files.threadId, body.threadId),
- inArray(files.id, body.selectedFiles)
- )
+ inArray(files.id, body.selectedFiles),
+ ),
);
for (const file of selectedFiles) {
diff --git a/server/api/logs/index.get.ts b/server/api/logs/index.get.ts
index 6039acd..8d3d611 100644
--- a/server/api/logs/index.get.ts
+++ b/server/api/logs/index.get.ts
@@ -11,7 +11,7 @@ export default defineEventHandler(async (event) => {
const page = Math.max(1, parseInt(query.page as string) || 1);
const pageSize = Math.max(
1,
- Math.min(100, parseInt(query.pageSize as string) || 10)
+ Math.min(100, parseInt(query.pageSize as string) || 10),
);
const offset = (page - 1) * pageSize;
diff --git a/server/api/messages/[threadId].get.ts b/server/api/messages/[threadId].get.ts
index b39a830..a36e6f6 100644
--- a/server/api/messages/[threadId].get.ts
+++ b/server/api/messages/[threadId].get.ts
@@ -1,6 +1,6 @@
import db from "~/server/utils/db";
import { eq } from "drizzle-orm";
-import { messages , threads } from "~/server/database/schema";
+import { messages, threads } from "~/server/database/schema";
export default defineEventHandler(async (event) => {
try {
diff --git a/server/api/threads/[id]/index.delete.ts b/server/api/threads/[id]/index.delete.ts
index 9da28e7..1b0e0a7 100644
--- a/server/api/threads/[id]/index.delete.ts
+++ b/server/api/threads/[id]/index.delete.ts
@@ -24,7 +24,6 @@ export default defineEventHandler(async (event) => {
userId = thread.userId;
}
-
// Delete related records first (to maintain referential integrity)
await db.delete(messages).where(eq(messages.threadId, id));
// Delete files
diff --git a/server/api/threads/index.get.ts b/server/api/threads/index.get.ts
index 892b859..be0313e 100644
--- a/server/api/threads/index.get.ts
+++ b/server/api/threads/index.get.ts
@@ -24,7 +24,7 @@ export default defineEventHandler(async (event) => {
FROM threads t
WHERE t.user_id = ${session.user.id}
ORDER BY t.created_at DESC
- `
+ `,
);
// Parse the JSON string in files column
diff --git a/server/api/validations/auth.ts b/server/api/validations/auth.ts
index 448e81a..7f066b7 100644
--- a/server/api/validations/auth.ts
+++ b/server/api/validations/auth.ts
@@ -1,24 +1,23 @@
import { z } from "zod";
-
export const signInRequest = z.object({
- email: z.string().email(),
- password:
- z.string({
- errorMap: () => (
- { message: 'Password must be at least 6 characters long' }
- )
- })
- .min(6),
-})
+ email: z.string().email(),
+ password: z
+ .string({
+ errorMap: () => ({
+ message: "Password must be at least 6 characters long",
+ }),
+ })
+ .min(6),
+});
export const signUpRequest = z.object({
- email: z.string().email(),
- password:
- z.string({
- errorMap: () => (
- { message: 'Password must be at least 6 characters long' }
- )
- })
- .min(6),
-})
\ No newline at end of file
+ email: z.string().email(),
+ password: z
+ .string({
+ errorMap: () => ({
+ message: "Password must be at least 6 characters long",
+ }),
+ })
+ .min(6),
+});
diff --git a/server/api/validations/chat.ts b/server/api/validations/chat.ts
index 64797a7..e0c78ca 100644
--- a/server/api/validations/chat.ts
+++ b/server/api/validations/chat.ts
@@ -1,7 +1,7 @@
import { z } from "zod";
export const messageRequest = z.object({
- threadId: z.string(),
- prompt: z.string(),
- selectedFiles: z.array(z.number()).optional(),
-});
\ No newline at end of file
+ threadId: z.string(),
+ prompt: z.string(),
+ selectedFiles: z.array(z.number()).optional(),
+});
diff --git a/server/api/validations/thread.ts b/server/api/validations/thread.ts
index ffb34ba..de37f96 100644
--- a/server/api/validations/thread.ts
+++ b/server/api/validations/thread.ts
@@ -1,10 +1,9 @@
import { z } from "zod";
-
export const createThreadRequest = z.object({
- name: z.string().min(1),
- systemMessage: z.string().min(5),
- temperature: z.number().min(0).max(1),
- model: z.string(),
- maxTokens: z.number().min(1),
-});
\ No newline at end of file
+ name: z.string().min(1),
+ systemMessage: z.string().min(5),
+ temperature: z.number().min(0).max(1),
+ model: z.string(),
+ maxTokens: z.number().min(1),
+});
diff --git a/server/database/migrations/meta/0000_snapshot.json b/server/database/migrations/meta/0000_snapshot.json
index 3f94edf..d749cbd 100644
--- a/server/database/migrations/meta/0000_snapshot.json
+++ b/server/database/migrations/meta/0000_snapshot.json
@@ -247,4 +247,4 @@
"internal": {
"indexes": {}
}
-}
\ No newline at end of file
+}
diff --git a/server/database/migrations/meta/0001_snapshot.json b/server/database/migrations/meta/0001_snapshot.json
index d947ab8..ed72b1f 100644
--- a/server/database/migrations/meta/0001_snapshot.json
+++ b/server/database/migrations/meta/0001_snapshot.json
@@ -303,4 +303,4 @@
"internal": {
"indexes": {}
}
-}
\ No newline at end of file
+}
diff --git a/server/database/migrations/meta/0002_snapshot.json b/server/database/migrations/meta/0002_snapshot.json
index 1172623..6417328 100644
--- a/server/database/migrations/meta/0002_snapshot.json
+++ b/server/database/migrations/meta/0002_snapshot.json
@@ -70,12 +70,8 @@
"name": "files_user_id_users_id_fk",
"tableFrom": "files",
"tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -147,12 +143,8 @@
"name": "logs_users_id_users_id_fk",
"tableFrom": "logs",
"tableTo": "users",
- "columnsFrom": [
- "users_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["users_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -213,12 +205,8 @@
"name": "messages_user_id_users_id_fk",
"tableFrom": "messages",
"tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -296,12 +284,8 @@
"name": "threads_user_id_users_id_fk",
"tableFrom": "threads",
"tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@@ -366,4 +350,4 @@
"internal": {
"indexes": {}
}
-}
\ No newline at end of file
+}
diff --git a/server/database/migrations/meta/_journal.json b/server/database/migrations/meta/_journal.json
index 32a0e2c..28e5efc 100644
--- a/server/database/migrations/meta/_journal.json
+++ b/server/database/migrations/meta/_journal.json
@@ -24,4 +24,4 @@
"breakpoints": true
}
]
-}
\ No newline at end of file
+}
diff --git a/server/database/schema.ts b/server/database/schema.ts
index 195c452..09465ed 100644
--- a/server/database/schema.ts
+++ b/server/database/schema.ts
@@ -1,4 +1,4 @@
-import { sqliteTable, text, integer, real } from "drizzle-orm/sqlite-core";
+import { sqliteTable, text, integer, real } from "drizzle-orm/sqlite-core";
export const threads = sqliteTable("threads", {
id: integer("id").primaryKey(),
@@ -6,9 +6,9 @@ export const threads = sqliteTable("threads", {
systemMessage: text("system_message"),
createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
temperature: real("temperature").default(0.5),
- model : text('model').default('claude-3-5-sonnet-20241022'),
- maxTokens : integer('max_tokens').default(1024),
- userId : integer('user_id').references(() => users.id),
+ model: text("model").default("claude-3-5-sonnet-20241022"),
+ maxTokens: integer("max_tokens").default(1024),
+ userId: integer("user_id").references(() => users.id),
});
export const messages = sqliteTable("messages", {
@@ -24,8 +24,8 @@ export const files = sqliteTable("files", {
id: integer("id").primaryKey(),
name: text("name"),
path: text("path"),
- text : text("text"),
- tokens : integer('tokens'),
+ text: text("text"),
+ tokens: integer("tokens"),
createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
threadId: integer("thread_id").notNull(),
userId: integer("user_id").references(() => users.id),
@@ -39,13 +39,12 @@ export const users = sqliteTable("users", {
createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
});
-
export const logs = sqliteTable("logs", {
id: integer("id").primaryKey(),
- inputTokens : integer('input_tokens').default(0),
- outputTokens : integer('output_tokens').default(0),
- cacheCreationInputTokens : integer('cache_creation_input_tokens').default(0),
- cacheReadInputTokens : integer('cache_read_input_tokens').default(0),
+ inputTokens: integer("input_tokens").default(0),
+ outputTokens: integer("output_tokens").default(0),
+ cacheCreationInputTokens: integer("cache_creation_input_tokens").default(0),
+ cacheReadInputTokens: integer("cache_read_input_tokens").default(0),
createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
userId: integer("users_id").references(() => users.id),
-});
\ No newline at end of file
+});
diff --git a/server/plugins/db.ts b/server/plugins/db.ts
index cdf06fc..fbe9dc1 100644
--- a/server/plugins/db.ts
+++ b/server/plugins/db.ts
@@ -1,8 +1,8 @@
// server/plugins/db.ts
-import { getDb } from '../utils/db';
+import { getDb } from "../utils/db";
export default defineNitroPlugin(() => {
// Initialize DB connection once
getDb();
- console.log('Database initialized in Nitro plugin');
-});
\ No newline at end of file
+ console.log("Database initialized in Nitro plugin");
+});
diff --git a/server/utils/db.ts b/server/utils/db.ts
index 8bec5e1..264aae4 100644
--- a/server/utils/db.ts
+++ b/server/utils/db.ts
@@ -1,6 +1,6 @@
-import { drizzle } from 'drizzle-orm/better-sqlite3';
-import Database from 'better-sqlite3';
-import * as schema from '../database/schema';
+import { drizzle } from "drizzle-orm/better-sqlite3";
+import Database from "better-sqlite3";
+import * as schema from "../database/schema";
let db: ReturnType;
@@ -8,11 +8,11 @@ let db: ReturnType;
export function getDb() {
if (!db) {
const sqlite = new Database(useRuntimeConfig().databaseUrl);
- sqlite.pragma('foreign_keys = ON');
+ sqlite.pragma("foreign_keys = ON");
db = drizzle(sqlite, { schema });
- console.log('New database connection established');
+ console.log("New database connection established");
}
return db;
}
-export default getDb()
\ No newline at end of file
+export default getDb();
diff --git a/server/utils/fileParser.ts b/server/utils/fileParser.ts
index 124f2d2..29898fc 100644
--- a/server/utils/fileParser.ts
+++ b/server/utils/fileParser.ts
@@ -4,42 +4,90 @@ import { promisify } from "util";
const textractFromBuffer = promisify(textract.fromBufferWithName);
const TEXT_EXTENSIONS = new Set([
- 'txt', 'js', 'ts', 'json', 'html', 'htm', 'atom', 'rss', 'md', 'markdown',
- 'epub', 'xml', 'xsl', 'pdf', 'doc', 'docx', 'odt', 'ott', 'rtf',
- 'xls', 'xlsx', 'xlsb', 'xlsm', 'xltx', 'csv', 'ods', 'ots',
- 'pptx', 'potx', 'odp', 'otp', 'odg', 'otg', 'png', 'jpg', 'jpeg', 'gif', 'dxf'
+ "txt",
+ "js",
+ "ts",
+ "json",
+ "html",
+ "htm",
+ "atom",
+ "rss",
+ "md",
+ "markdown",
+ "epub",
+ "xml",
+ "xsl",
+ "pdf",
+ "doc",
+ "docx",
+ "odt",
+ "ott",
+ "rtf",
+ "xls",
+ "xlsx",
+ "xlsb",
+ "xlsm",
+ "xltx",
+ "csv",
+ "ods",
+ "ots",
+ "pptx",
+ "potx",
+ "odp",
+ "otp",
+ "odg",
+ "otg",
+ "png",
+ "jpg",
+ "jpeg",
+ "gif",
+ "dxf",
]);
const TEXT_MIMETYPES = new Set([
- 'text/html', 'text/htm', 'application/atom+xml', 'application/rss+xml',
- 'text/markdown', 'application/epub+zip', 'application/xml', 'text/xml',
- 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'application/vnd.oasis.opendocument.text', 'application/rtf',
- 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'text/csv', 'application/vnd.oasis.opendocument.spreadsheet',
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
- 'application/vnd.oasis.opendocument.presentation',
- 'application/vnd.oasis.opendocument.graphics',
- 'image/png', 'image/jpeg', 'image/gif',
- 'application/dxf', 'application/javascript'
+ "text/html",
+ "text/htm",
+ "application/atom+xml",
+ "application/rss+xml",
+ "text/markdown",
+ "application/epub+zip",
+ "application/xml",
+ "text/xml",
+ "application/pdf",
+ "application/msword",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.oasis.opendocument.text",
+ "application/rtf",
+ "application/vnd.ms-excel",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "text/csv",
+ "application/vnd.oasis.opendocument.spreadsheet",
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+ "application/vnd.oasis.opendocument.presentation",
+ "application/vnd.oasis.opendocument.graphics",
+ "image/png",
+ "image/jpeg",
+ "image/gif",
+ "application/dxf",
+ "application/javascript",
]);
export async function parseFile(
filename: string,
buffer: Buffer,
- mimeType?: string
+ mimeType?: string,
): Promise {
try {
- const ext = filename.split('.').pop()?.toLowerCase();
+ const ext = filename.split(".").pop()?.toLowerCase();
// Use buffer.toString() for plain text files and specific cases
if (
- mimeType?.startsWith('text/') ||
- mimeType === 'application/json' ||
- mimeType === 'application/javascript' ||
- ext === 'ts' ||
- ext === 'js' ||
- ext === 'json'
+ mimeType?.startsWith("text/") ||
+ mimeType === "application/json" ||
+ mimeType === "application/javascript" ||
+ ext === "ts" ||
+ ext === "js" ||
+ ext === "json"
) {
return buffer.toString();
}
@@ -59,4 +107,4 @@ export async function parseFile(
console.error("Error parsing file:", error);
throw new Error(`Failed to parse file: ${error.message}`);
}
-}
\ No newline at end of file
+}