From 395bf9ea7fb60b46aee29958328b0263ae77861a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Nov 2024 13:33:10 +0100 Subject: [PATCH] lint:prettier --- .github/FUNDING.yml | 2 +- LICENSE.md | 2 +- README.md | 3 + components/AuthForm.vue | 56 +-- components/ChatMessage.vue | 127 +++--- components/ColorPicker.vue | 137 +++--- components/ColorPickerPill.vue | 36 +- components/CreateThreadModal.vue | 142 ++++--- components/DarkModeToggle.vue | 34 +- components/FileAttachments.vue | 47 ++- components/MessageInput.vue | 390 ++++++++++-------- components/MessageList.vue | 44 +- components/Sidebar.vue | 136 +++--- composables/useApp.ts | 28 +- composables/useAutoScroll.ts | 2 +- composables/useCustomModal.ts | 2 +- composables/useFileHandler.ts | 2 +- composables/useLoader.ts | 10 +- eslint.config.mjs | 7 +- middleware/guest.ts | 13 +- package.json | 4 +- pages/index.vue | 15 +- pages/login.vue | 106 +++-- pages/logs.vue | 136 +++--- pages/signup.vue | 126 +++--- pages/threads/[id].vue | 142 +++---- plugins/markdownit.client.ts | 52 +-- server/api/chat.post.ts | 4 +- server/api/logs/index.get.ts | 2 +- server/api/messages/[threadId].get.ts | 2 +- server/api/threads/[id]/index.delete.ts | 1 - server/api/threads/index.get.ts | 2 +- server/api/validations/auth.ts | 37 +- server/api/validations/chat.ts | 8 +- server/api/validations/thread.ts | 13 +- .../migrations/meta/0000_snapshot.json | 2 +- .../migrations/meta/0001_snapshot.json | 2 +- .../migrations/meta/0002_snapshot.json | 34 +- server/database/migrations/meta/_journal.json | 2 +- server/database/schema.ts | 23 +- server/plugins/db.ts | 6 +- server/utils/db.ts | 12 +- server/utils/fileParser.ts | 96 +++-- 43 files changed, 1142 insertions(+), 905 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 67c65df..7d26837 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: chihebnabil \ No newline at end of file +github: chihebnabil diff --git a/LICENSE.md b/LICENSE.md index b1232fd..0303f9a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index a4ccde6..81e8c0a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Claude UI + A modern chat interface for Anthropic's Claude AI models built with Nuxt.js. Experience seamless conversations with Claude in a clean user interface. ## Prerequisites @@ -12,6 +13,7 @@ A modern chat interface for Anthropic's Claude AI models built with Nuxt.js. Exp

## 🌟 Features + - 💾 Conversation history management - 🎭 Multiple Claude model support - 📝 Markdown and code syntax highlighting @@ -23,6 +25,7 @@ A modern chat interface for Anthropic's Claude AI models built with Nuxt.js. Exp - 📝🔍 Text extraction and parsing ## Tech Stack + - 🚀 Built with [Nuxt 3](https://nuxt.com/) - 💾 Database integration with [Drizzle ORM](https://orm.drizzle.team/) - 🎨 UI components from [@nuxt/ui](https://ui.nuxt.com/) diff --git a/components/AuthForm.vue b/components/AuthForm.vue index 97afc61..29a0b66 100644 --- a/components/AuthForm.vue +++ b/components/AuthForm.vue @@ -1,35 +1,41 @@ \ No newline at end of file + diff --git a/components/ChatMessage.vue b/components/ChatMessage.vue index f78c3fd..5b53eee 100644 --- a/components/ChatMessage.vue +++ b/components/ChatMessage.vue @@ -1,71 +1,84 @@ \ No newline at end of file + // For older messages, show the actual date + return createdAt.toLocaleDateString(); +}); + diff --git a/components/ColorPicker.vue b/components/ColorPicker.vue index 2c8229e..ba2e0b7 100644 --- a/components/ColorPicker.vue +++ b/components/ColorPicker.vue @@ -1,62 +1,99 @@ \ No newline at end of file + get() { + return grayColors.value.find( + (option) => option.value === appConfig.ui.gray, + ); + }, + set(option) { + appConfig.ui.gray = option.value; + + window.localStorage.setItem("nuxt-ui-gray", appConfig.ui.gray); + }, +}); + diff --git a/components/ColorPickerPill.vue b/components/ColorPickerPill.vue index 836d6e4..466266e 100644 --- a/components/ColorPickerPill.vue +++ b/components/ColorPickerPill.vue @@ -1,19 +1,31 @@ \ No newline at end of file +defineProps<{ + color: { value: string; hex: string }; + selected: { value: string }; +}>(); +defineEmits(["select"]); + diff --git a/components/CreateThreadModal.vue b/components/CreateThreadModal.vue index 1b4643b..21c504c 100644 --- a/components/CreateThreadModal.vue +++ b/components/CreateThreadModal.vue @@ -1,72 +1,92 @@ \ No newline at end of file + closeModal(); +}; + diff --git a/components/DarkModeToggle.vue b/components/DarkModeToggle.vue index b8f3c4f..ea297af 100644 --- a/components/DarkModeToggle.vue +++ b/components/DarkModeToggle.vue @@ -1,18 +1,18 @@ - - \ No newline at end of file + + + + diff --git a/components/FileAttachments.vue b/components/FileAttachments.vue index a12fbb3..7d2f496 100644 --- a/components/FileAttachments.vue +++ b/components/FileAttachments.vue @@ -1,31 +1,38 @@ diff --git a/components/MessageInput.vue b/components/MessageInput.vue index dca7c71..7b65c81 100644 --- a/components/MessageInput.vue +++ b/components/MessageInput.vue @@ -1,209 +1,233 @@ \ No newline at end of file + } catch (error) { + console.error("Error sending message:", error); + toast.add({ + title: "Error", + description: error.message || "Failed to send message", + color: "red", + timeout: 5000, + icon: "i-heroicons-exclamation-circle", + }); + // remove assistant message on error + messages.value.pop(); + } finally { + loader.value = false; + } +}; + diff --git a/components/MessageList.vue b/components/MessageList.vue index 6e5f54c..c399c03 100644 --- a/components/MessageList.vue +++ b/components/MessageList.vue @@ -1,26 +1,38 @@ diff --git a/components/Sidebar.vue b/components/Sidebar.vue index 6e1ea8f..bdbb1e2 100644 --- a/components/Sidebar.vue +++ b/components/Sidebar.vue @@ -1,72 +1,102 @@ \ No newline at end of file + navigateTo("/threads/" + threadId); +}; + diff --git a/composables/useApp.ts b/composables/useApp.ts index 44d1182..4a4faa5 100644 --- a/composables/useApp.ts +++ b/composables/useApp.ts @@ -1,16 +1,14 @@ - - export const useApp = () => { - const messages = useState>("messages", () => []); - const threads = useState>("threads",() => []); - - const getThread = async (id: any) => { - return threads.value.find(thread => thread.id === Number(id)); - }; - - return { - messages, - getThread, - threads - }; -}; \ No newline at end of file + const messages = useState>("messages", () => []); + const threads = useState>("threads", () => []); + + const getThread = async (id: any) => { + return threads.value.find((thread) => thread.id === Number(id)); + }; + + return { + messages, + getThread, + threads, + }; +}; diff --git a/composables/useAutoScroll.ts b/composables/useAutoScroll.ts index 7bb7497..e7fc4b1 100644 --- a/composables/useAutoScroll.ts +++ b/composables/useAutoScroll.ts @@ -1,4 +1,4 @@ -import { onMounted, onUpdated, ref, watch } from 'vue'; +import { onMounted, onUpdated, ref, watch } from "vue"; export function useAutoScroll(messagesRef) { const containerRef = ref(null); diff --git a/composables/useCustomModal.ts b/composables/useCustomModal.ts index fab04c9..68ef649 100644 --- a/composables/useCustomModal.ts +++ b/composables/useCustomModal.ts @@ -13,4 +13,4 @@ export const useCustomModal = () => { openModal, closeModal, }; -}; \ No newline at end of file +}; diff --git a/composables/useFileHandler.ts b/composables/useFileHandler.ts index 943b97f..17169ec 100644 --- a/composables/useFileHandler.ts +++ b/composables/useFileHandler.ts @@ -1,4 +1,4 @@ -import { ref } from 'vue'; +import { ref } from "vue"; export function useFileHandler() { const file = ref(null); diff --git a/composables/useLoader.ts b/composables/useLoader.ts index b4fabfb..8254ef8 100644 --- a/composables/useLoader.ts +++ b/composables/useLoader.ts @@ -1,6 +1,6 @@ export const useLoader = () => { - const loader = useState("loader", () => false); - const start = () => (loader.value = true); - const stop = () => (loader.value = false); - return { loader, start, stop }; -}; \ No newline at end of file + const loader = useState("loader", () => false); + const start = () => (loader.value = true); + const stop = () => (loader.value = false); + return { loader, start, stop }; +}; diff --git a/eslint.config.mjs b/eslint.config.mjs index 934c3a1..4b785f2 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,6 +1,5 @@ // @ts-check -import withNuxt from './.nuxt/eslint.config.mjs' +import withNuxt from "./.nuxt/eslint.config.mjs"; -export default withNuxt( - // Your custom configs here -) +export default withNuxt(); +// Your custom configs here diff --git a/middleware/guest.ts b/middleware/guest.ts index 8b771be..3ec0293 100644 --- a/middleware/guest.ts +++ b/middleware/guest.ts @@ -1,8 +1,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => { - const { loggedIn , fetch } = useUserSession(); - await fetch() - if (loggedIn.value) { - return navigateTo("/"); - } - }); - \ No newline at end of file + const { loggedIn, fetch } = useUserSession(); + await fetch(); + if (loggedIn.value) { + return navigateTo("/"); + } +}); diff --git a/package.json b/package.json index 76ed08c..612e7e4 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,9 @@ "postinstall": "nuxt prepare && npm run db:migrate", "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", - "lint": "yarn lint:eslint && yarn lint:prettier", + "lint": "npm run lint:eslint && npm run lint:prettier", "lint:eslint": "eslint .", - "lint:prettier": "prettier . --check", + "lint:prettier": "prettier . --check --write", "lint:fix": "eslint . --fix && prettier --write --list-different ." }, "dependencies": { diff --git a/pages/index.vue b/pages/index.vue index 8266188..bc5437e 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -1,12 +1,13 @@ diff --git a/pages/login.vue b/pages/login.vue index 12a2bc7..8eed479 100644 --- a/pages/login.vue +++ b/pages/login.vue @@ -1,58 +1,76 @@ diff --git a/pages/logs.vue b/pages/logs.vue index 282519d..b138a37 100644 --- a/pages/logs.vue +++ b/pages/logs.vue @@ -1,84 +1,90 @@ diff --git a/pages/signup.vue b/pages/signup.vue index 2c3e6d7..8a47333 100644 --- a/pages/signup.vue +++ b/pages/signup.vue @@ -1,66 +1,82 @@ \ No newline at end of file + diff --git a/pages/threads/[id].vue b/pages/threads/[id].vue index 88d85a4..1f2d970 100644 --- a/pages/threads/[id].vue +++ b/pages/threads/[id].vue @@ -1,100 +1,102 @@ \ 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 +}