diff --git a/electron/app.vue b/electron/app.vue index 3d44756..625182b 100644 --- a/electron/app.vue +++ b/electron/app.vue @@ -10,9 +10,7 @@
- +
Loading...
@@ -68,35 +66,82 @@ -
-
-
- - {{ selected_image?.directory }} - -
-
- - {{ selected_image?.filename }} - + +
+ +
+
+ + {{ tag.name }} + +
+ +
+
+ + + + +
+
@@ -107,87 +152,152 @@ diff --git a/electron/components/AppMenubar.vue b/electron/components/AppMenubar.vue index a7af6a9..63890f4 100644 --- a/electron/components/AppMenubar.vue +++ b/electron/components/AppMenubar.vue @@ -3,13 +3,27 @@ File - To be implemented + To be implemented Edit - To be implemented + +
+ New Tag + Ctrl + T +
+
+ + + + + Manage Tags + + + +
@@ -21,17 +35,27 @@ + diff --git a/electron/components/TagManager.vue b/electron/components/TagManager.vue new file mode 100644 index 0000000..dd37222 --- /dev/null +++ b/electron/components/TagManager.vue @@ -0,0 +1,47 @@ + + + diff --git a/electron/components/ui/command/Command.vue b/electron/components/ui/command/Command.vue new file mode 100644 index 0000000..d33ab38 --- /dev/null +++ b/electron/components/ui/command/Command.vue @@ -0,0 +1,30 @@ + + + diff --git a/electron/components/ui/command/CommandDialog.vue b/electron/components/ui/command/CommandDialog.vue new file mode 100644 index 0000000..6620ad3 --- /dev/null +++ b/electron/components/ui/command/CommandDialog.vue @@ -0,0 +1,21 @@ + + + diff --git a/electron/components/ui/command/CommandEmpty.vue b/electron/components/ui/command/CommandEmpty.vue new file mode 100644 index 0000000..cd097d7 --- /dev/null +++ b/electron/components/ui/command/CommandEmpty.vue @@ -0,0 +1,20 @@ + + + diff --git a/electron/components/ui/command/CommandGroup.vue b/electron/components/ui/command/CommandGroup.vue new file mode 100644 index 0000000..939b78e --- /dev/null +++ b/electron/components/ui/command/CommandGroup.vue @@ -0,0 +1,29 @@ + + + diff --git a/electron/components/ui/command/CommandInput.vue b/electron/components/ui/command/CommandInput.vue new file mode 100644 index 0000000..261fb95 --- /dev/null +++ b/electron/components/ui/command/CommandInput.vue @@ -0,0 +1,33 @@ + + + diff --git a/electron/components/ui/command/CommandItem.vue b/electron/components/ui/command/CommandItem.vue new file mode 100644 index 0000000..ec9dacf --- /dev/null +++ b/electron/components/ui/command/CommandItem.vue @@ -0,0 +1,26 @@ + + + diff --git a/electron/components/ui/command/CommandList.vue b/electron/components/ui/command/CommandList.vue new file mode 100644 index 0000000..679fe64 --- /dev/null +++ b/electron/components/ui/command/CommandList.vue @@ -0,0 +1,29 @@ + + + diff --git a/electron/components/ui/command/CommandSeparator.vue b/electron/components/ui/command/CommandSeparator.vue new file mode 100644 index 0000000..8f0cc1e --- /dev/null +++ b/electron/components/ui/command/CommandSeparator.vue @@ -0,0 +1,23 @@ + + + diff --git a/electron/components/ui/command/CommandShortcut.vue b/electron/components/ui/command/CommandShortcut.vue new file mode 100644 index 0000000..0d4da92 --- /dev/null +++ b/electron/components/ui/command/CommandShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/electron/components/ui/command/index.ts b/electron/components/ui/command/index.ts new file mode 100644 index 0000000..0e35f4b --- /dev/null +++ b/electron/components/ui/command/index.ts @@ -0,0 +1,9 @@ +export { default as Command } from './Command.vue' +export { default as CommandDialog } from './CommandDialog.vue' +export { default as CommandEmpty } from './CommandEmpty.vue' +export { default as CommandGroup } from './CommandGroup.vue' +export { default as CommandInput } from './CommandInput.vue' +export { default as CommandItem } from './CommandItem.vue' +export { default as CommandList } from './CommandList.vue' +export { default as CommandSeparator } from './CommandSeparator.vue' +export { default as CommandShortcut } from './CommandShortcut.vue' diff --git a/electron/components/ui/dialog/Dialog.vue b/electron/components/ui/dialog/Dialog.vue new file mode 100644 index 0000000..a04c026 --- /dev/null +++ b/electron/components/ui/dialog/Dialog.vue @@ -0,0 +1,14 @@ + + + diff --git a/electron/components/ui/dialog/DialogClose.vue b/electron/components/ui/dialog/DialogClose.vue new file mode 100644 index 0000000..a64703e --- /dev/null +++ b/electron/components/ui/dialog/DialogClose.vue @@ -0,0 +1,11 @@ + + + diff --git a/electron/components/ui/dialog/DialogContent.vue b/electron/components/ui/dialog/DialogContent.vue new file mode 100644 index 0000000..0de8451 --- /dev/null +++ b/electron/components/ui/dialog/DialogContent.vue @@ -0,0 +1,50 @@ + + + diff --git a/electron/components/ui/dialog/DialogDescription.vue b/electron/components/ui/dialog/DialogDescription.vue new file mode 100644 index 0000000..878ef2b --- /dev/null +++ b/electron/components/ui/dialog/DialogDescription.vue @@ -0,0 +1,24 @@ + + + diff --git a/electron/components/ui/dialog/DialogFooter.vue b/electron/components/ui/dialog/DialogFooter.vue new file mode 100644 index 0000000..ac2d0c1 --- /dev/null +++ b/electron/components/ui/dialog/DialogFooter.vue @@ -0,0 +1,19 @@ + + + diff --git a/electron/components/ui/dialog/DialogHeader.vue b/electron/components/ui/dialog/DialogHeader.vue new file mode 100644 index 0000000..b2c9085 --- /dev/null +++ b/electron/components/ui/dialog/DialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/electron/components/ui/dialog/DialogScrollContent.vue b/electron/components/ui/dialog/DialogScrollContent.vue new file mode 100644 index 0000000..0d44821 --- /dev/null +++ b/electron/components/ui/dialog/DialogScrollContent.vue @@ -0,0 +1,59 @@ + + + diff --git a/electron/components/ui/dialog/DialogTitle.vue b/electron/components/ui/dialog/DialogTitle.vue new file mode 100644 index 0000000..1f049e3 --- /dev/null +++ b/electron/components/ui/dialog/DialogTitle.vue @@ -0,0 +1,29 @@ + + + diff --git a/electron/components/ui/dialog/DialogTrigger.vue b/electron/components/ui/dialog/DialogTrigger.vue new file mode 100644 index 0000000..ee0c12f --- /dev/null +++ b/electron/components/ui/dialog/DialogTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/electron/components/ui/dialog/index.ts b/electron/components/ui/dialog/index.ts new file mode 100644 index 0000000..ca8cfea --- /dev/null +++ b/electron/components/ui/dialog/index.ts @@ -0,0 +1,9 @@ +export { default as Dialog } from './Dialog.vue' +export { default as DialogClose } from './DialogClose.vue' +export { default as DialogContent } from './DialogContent.vue' +export { default as DialogDescription } from './DialogDescription.vue' +export { default as DialogFooter } from './DialogFooter.vue' +export { default as DialogHeader } from './DialogHeader.vue' +export { default as DialogScrollContent } from './DialogScrollContent.vue' +export { default as DialogTitle } from './DialogTitle.vue' +export { default as DialogTrigger } from './DialogTrigger.vue' diff --git a/electron/components/ui/form/FormControl.vue b/electron/components/ui/form/FormControl.vue new file mode 100644 index 0000000..8459cab --- /dev/null +++ b/electron/components/ui/form/FormControl.vue @@ -0,0 +1,16 @@ + + + diff --git a/electron/components/ui/form/FormDescription.vue b/electron/components/ui/form/FormDescription.vue new file mode 100644 index 0000000..9300066 --- /dev/null +++ b/electron/components/ui/form/FormDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/electron/components/ui/form/FormItem.vue b/electron/components/ui/form/FormItem.vue new file mode 100644 index 0000000..699724e --- /dev/null +++ b/electron/components/ui/form/FormItem.vue @@ -0,0 +1,19 @@ + + + diff --git a/electron/components/ui/form/FormLabel.vue b/electron/components/ui/form/FormLabel.vue new file mode 100644 index 0000000..05a5192 --- /dev/null +++ b/electron/components/ui/form/FormLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/electron/components/ui/form/FormMessage.vue b/electron/components/ui/form/FormMessage.vue new file mode 100644 index 0000000..308755e --- /dev/null +++ b/electron/components/ui/form/FormMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/electron/components/ui/form/index.ts b/electron/components/ui/form/index.ts new file mode 100644 index 0000000..fca299e --- /dev/null +++ b/electron/components/ui/form/index.ts @@ -0,0 +1,7 @@ +export { default as FormControl } from './FormControl.vue' +export { default as FormDescription } from './FormDescription.vue' +export { default as FormItem } from './FormItem.vue' +export { default as FormLabel } from './FormLabel.vue' +export { default as FormMessage } from './FormMessage.vue' +export { FORM_ITEM_INJECTION_KEY } from './injectionKeys' +export { Field as FormField, Form } from 'vee-validate' diff --git a/electron/components/ui/form/injectionKeys.ts b/electron/components/ui/form/injectionKeys.ts new file mode 100644 index 0000000..b972d36 --- /dev/null +++ b/electron/components/ui/form/injectionKeys.ts @@ -0,0 +1,4 @@ +import type { InjectionKey } from 'vue' + +export const FORM_ITEM_INJECTION_KEY + = Symbol() as InjectionKey diff --git a/electron/components/ui/form/useFormField.ts b/electron/components/ui/form/useFormField.ts new file mode 100644 index 0000000..ed30a8a --- /dev/null +++ b/electron/components/ui/form/useFormField.ts @@ -0,0 +1,30 @@ +import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate' +import { inject } from 'vue' +import { FORM_ITEM_INJECTION_KEY } from './injectionKeys' + +export function useFormField() { + const fieldContext = inject(FieldContextKey) + const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY) + + if (!fieldContext) + throw new Error('useFormField should be used within ') + + const { name } = fieldContext + const id = fieldItemContext + + const fieldState = { + valid: useIsFieldValid(name), + isDirty: useIsFieldDirty(name), + isTouched: useIsFieldTouched(name), + error: useFieldError(name), + } + + return { + id, + name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} diff --git a/electron/components/ui/input/Input.vue b/electron/components/ui/input/Input.vue new file mode 100644 index 0000000..81140b4 --- /dev/null +++ b/electron/components/ui/input/Input.vue @@ -0,0 +1,24 @@ + + + diff --git a/electron/components/ui/input/index.ts b/electron/components/ui/input/index.ts new file mode 100644 index 0000000..a691dd6 --- /dev/null +++ b/electron/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from './Input.vue' diff --git a/electron/components/ui/label/Label.vue b/electron/components/ui/label/Label.vue new file mode 100644 index 0000000..5ad1568 --- /dev/null +++ b/electron/components/ui/label/Label.vue @@ -0,0 +1,27 @@ + + + diff --git a/electron/components/ui/label/index.ts b/electron/components/ui/label/index.ts new file mode 100644 index 0000000..572c2f0 --- /dev/null +++ b/electron/components/ui/label/index.ts @@ -0,0 +1 @@ +export { default as Label } from './Label.vue' diff --git a/electron/components/ui/tags-input/TagsInput.vue b/electron/components/ui/tags-input/TagsInput.vue new file mode 100644 index 0000000..435b378 --- /dev/null +++ b/electron/components/ui/tags-input/TagsInput.vue @@ -0,0 +1,22 @@ + + + diff --git a/electron/components/ui/tags-input/TagsInputInput.vue b/electron/components/ui/tags-input/TagsInputInput.vue new file mode 100644 index 0000000..4b1de4e --- /dev/null +++ b/electron/components/ui/tags-input/TagsInputInput.vue @@ -0,0 +1,19 @@ + + + diff --git a/electron/components/ui/tags-input/TagsInputItem.vue b/electron/components/ui/tags-input/TagsInputItem.vue new file mode 100644 index 0000000..54618f6 --- /dev/null +++ b/electron/components/ui/tags-input/TagsInputItem.vue @@ -0,0 +1,22 @@ + + + diff --git a/electron/components/ui/tags-input/TagsInputItemDelete.vue b/electron/components/ui/tags-input/TagsInputItemDelete.vue new file mode 100644 index 0000000..903d553 --- /dev/null +++ b/electron/components/ui/tags-input/TagsInputItemDelete.vue @@ -0,0 +1,24 @@ + + + diff --git a/electron/components/ui/tags-input/TagsInputItemText.vue b/electron/components/ui/tags-input/TagsInputItemText.vue new file mode 100644 index 0000000..2ce7a6d --- /dev/null +++ b/electron/components/ui/tags-input/TagsInputItemText.vue @@ -0,0 +1,19 @@ + + + diff --git a/electron/components/ui/tags-input/index.ts b/electron/components/ui/tags-input/index.ts new file mode 100644 index 0000000..31305f3 --- /dev/null +++ b/electron/components/ui/tags-input/index.ts @@ -0,0 +1,5 @@ +export { default as TagsInput } from './TagsInput.vue' +export { default as TagsInputInput } from './TagsInputInput.vue' +export { default as TagsInputItem } from './TagsInputItem.vue' +export { default as TagsInputItemDelete } from './TagsInputItemDelete.vue' +export { default as TagsInputItemText } from './TagsInputItemText.vue' diff --git a/electron/composables/fetch_tags.ts b/electron/composables/fetch_tags.ts new file mode 100644 index 0000000..4ababf7 --- /dev/null +++ b/electron/composables/fetch_tags.ts @@ -0,0 +1,16 @@ +const tags = ref([]); + +export async function fetchTags(): Promise { + const path = await window.ipcRenderer.invoke('get-user-data-path'); + const fetchedTags: any = await $fetch('/api/fetch_tags', { + query: { data: path } + }); + tags.value = fetchedTags.map((tag: Tag) => ({ + id: tag.id, + name: tag.name, + shorthand: tag.shorthand, + color: tag.color + })); + + return tags.value; +} diff --git a/electron/composables/types.ts b/electron/composables/types.ts new file mode 100644 index 0000000..97682ee --- /dev/null +++ b/electron/composables/types.ts @@ -0,0 +1,35 @@ +export interface Tag { + id: number; + name: string; + shorthand: string; + color: string; +} + +export interface FileData { + file_path: string; + file_size: string; +} + +export interface TagStackImageData { + url: string; + width: number; + height: number; + is_square: boolean; + directory: string; + filename: string; + extension: string; + size: string; +} + +interface IpcRenderer { + on(channel: string, listener: (...args: any[]) => void): this; + off(channel: string, listener: (...args: any[]) => void): this; + send(channel: string, ...args: any[]): void; + invoke(channel: string, ...args: any[]): Promise; +} + +declare global { + interface Window { + ipcRenderer: IpcRenderer; + } +} diff --git a/electron/dist-electron/main.js b/electron/dist-electron/main.js index 3b98e5f..959ce68 100644 --- a/electron/dist-electron/main.js +++ b/electron/dist-electron/main.js @@ -1 +1 @@ -"use strict";const e=require("electron"),n=require("node:path"),t=n.join(__dirname,".."),l=n.join(t,"dist-electron"),p=n.join(t,".output/public"),s=process.env.VITE_DEV_SERVER_URL?n.join(t,"public"):p;function r(){const o={width:1920,height:1080,center:!0,autoHideMenuBar:!0,webPreferences:{preload:n.join(l,"preload.js"),webSecurity:!1,allowRunningInsecureContent:!0}},i=new e.BrowserWindow(o),a=process.env.VITE_DEV_SERVER_URL||n.join(s,"index.html");i.loadURL(a)}async function c(){return(await e.dialog.showOpenDialog({properties:["openDirectory"]})).filePaths}function u(o){e.shell.openExternal(o)}function d(){e.ipcMain.handle("app-open-file-dialog",c),e.ipcMain.handle("app-open-url",(o,i)=>u(i))}function w(){e.app.on("window-all-closed",()=>{process.platform!=="darwin"&&e.app.quit()}),e.app.whenReady().then(()=>{d(),r(),e.app.on("activate",()=>{e.BrowserWindow.getAllWindows().length===0&&r()})})}w(); +"use strict";const e=require("electron"),s=require("node:path"),u=require("node:fs"),f=require("sqlite3"),p=s.join(__dirname,".."),g=s.join(p,"dist-electron"),b=s.join(p,".output/public"),D=process.env.VITE_DEV_SERVER_URL?s.join(p,"public"):b;function d(){const i={width:1920,height:1080,center:!0,autoHideMenuBar:!0,webPreferences:{preload:s.join(g,"preload.js"),webSecurity:!1,allowRunningInsecureContent:!0}},n=new e.BrowserWindow(i),a=process.env.VITE_DEV_SERVER_URL||s.join(D,"index.html");n.loadURL(a)}async function _(){return(await e.dialog.showOpenDialog({properties:["openDirectory"]})).filePaths}function E(i){e.shell.openExternal(i)}function R(i,n,a=[]){u.existsSync(`${e.app.getPath("userData")}/db`)||u.mkdirSync(`${e.app.getPath("userData")}/db`);const o=new f.Database(`${e.app.getPath("userData")}/db/tags.db`);return new Promise((h,r)=>{const l=(c,t)=>{c?r(c):h(t)};switch(i){case"run":o.run(n,a,function(t){l(t,{id:this.lastID,changes:this.changes})});break;case"get":o.get(n,a,l);break;case"each":console.log("Verifying insertion for:",n);const c=[];o.each(n,(t,w)=>{t?r(t):c.push(w)},t=>{t?r(t):l(null,c)});break;case"all":o.all(n,a,l);break;default:r(new Error("Unknown action"))}o.close()})}function P(){return e.app.getPath("userData")}function I(){e.ipcMain.handle("app-open-file-dialog",_),e.ipcMain.handle("app-open-url",(i,n)=>E(n)),e.ipcMain.handle("sqlite-operations",(i,n,a,o)=>R(n,a,o)),e.ipcMain.handle("get-user-data-path",P)}function V(){e.app.on("window-all-closed",()=>{process.platform!=="darwin"&&e.app.quit()}),e.app.whenReady().then(()=>{I(),d(),e.app.on("activate",()=>{e.BrowserWindow.getAllWindows().length===0&&d()})})}V(); diff --git a/electron/electron/main.ts b/electron/electron/main.ts index cfc6b67..0e7b314 100644 --- a/electron/electron/main.ts +++ b/electron/electron/main.ts @@ -1,5 +1,7 @@ import { app, BrowserWindow, dialog, ipcMain, shell } from 'electron'; +const sqlite3 = require('sqlite3'); import path from 'node:path'; +import fs from 'node:fs'; const APP_ROOT: string = path.join(__dirname, '..'); const MAIN_DIST: string = path.join(APP_ROOT, 'dist-electron'); @@ -25,7 +27,6 @@ function createWindow(): void { process.env.VITE_DEV_SERVER_URL || path.join(VITE_PUBLIC, 'index.html'); window.loadURL(url); } - async function handleFileDialog(): Promise { const files: Electron.OpenDialogReturnValue = await dialog.showOpenDialog({ properties: ['openDirectory'] @@ -33,16 +34,66 @@ async function handleFileDialog(): Promise { return files.filePaths; } - function openUrl(url: string): void { shell.openExternal(url); } +function sqliteOperations(action: any, sql: any, params = []) { + if (!fs.existsSync(`${app.getPath('userData')}/db`)) + fs.mkdirSync(`${app.getPath('userData')}/db`); + + const db = new sqlite3.Database(`${app.getPath('userData')}/db/tags.db`); + return new Promise((resolve, reject) => { + const callback = (error: any, result: unknown) => { + if (error) reject(error); + else resolve(result); + }; + + switch (action) { + case 'run': + db.run(sql, params, function (error: any) { + // @ts-ignore + callback(error, { id: this.lastID, changes: this.changes }); + }); + break; + case 'get': + db.get(sql, params, callback); + break; + case 'each': + console.log('Verifying insertion for:', sql); + const output: any[] = []; + db.each( + sql, + (error: any, row: any) => { + if (error) reject(error); + else output.push(row); + }, + (error: any) => { + if (error) reject(error); + else callback(null, output); // Resolve with the collected rows + } + ); + break; + case 'all': + db.all(sql, params, callback); + break; + default: + reject(new Error('Unknown action')); + } + db.close(); + }); +} +function getUserDataPath(): string { + return app.getPath('userData'); +} function setupIPC(): void { ipcMain.handle('app-open-file-dialog', handleFileDialog); ipcMain.handle('app-open-url', (_, url: string) => openUrl(url)); + ipcMain.handle('sqlite-operations', (_, action, sql, params) => + sqliteOperations(action, sql, params) + ); + ipcMain.handle('get-user-data-path', getUserDataPath); } - function initialzeApp(): void { app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); diff --git a/electron/lib/utils.ts b/electron/lib/utils.ts deleted file mode 100644 index d32b0fe..0000000 --- a/electron/lib/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type ClassValue, clsx } from 'clsx' -import { twMerge } from 'tailwind-merge' - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} diff --git a/electron/package-lock.json b/electron/package-lock.json index 4fcabae..84ee847 100644 --- a/electron/package-lock.json +++ b/electron/package-lock.json @@ -1,14 +1,16 @@ { - "name": "tag-stack", + "name": "tag-stack-electron", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "tag-stack", + "name": "tag-stack-electron", "hasInstallScript": true, "dependencies": { "@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/tailwindcss": "^6.12.2", + "@vee-validate/zod": "^4.15.0", + "@vueuse/core": "^12.3.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "jimp": "^1.6.0", @@ -16,14 +18,18 @@ "nuxt": "^3.14.1592", "radix-vue": "^1.9.11", "shadcn-nuxt": "^0.11.3", + "sqlite3": "^5.1.7", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", + "vee-validate": "^4.15.0", "vue": "latest", - "vue-router": "latest" + "vue-router": "latest", + "zod": "^3.24.1" }, "devDependencies": { "electron": "^33.2.1", "electron-builder": "^25.1.8", + "electron-rebuild": "^3.2.9", "nuxt-electron": "^0.7.0", "vite-plugin-electron": "^0.29.0", "vite-plugin-electron-renderer": "^0.14.6" @@ -1276,7 +1282,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@internationalized/date": { @@ -3647,6 +3653,19 @@ "vue": ">=2.7 || >=3" } }, + "node_modules/@vee-validate/zod": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@vee-validate/zod/-/zod-4.15.0.tgz", + "integrity": "sha512-MpvIKiyg9X5yD8bJW0no2AU7wtR2T5mrvD9tuPRiie951sU2n6QKgMV38qKKOiqFBCxsMSjIuLLLV3V5kVE4nQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^4.8.3", + "vee-validate": "4.15.0" + }, + "peerDependencies": { + "zod": "^3.24.0" + } + }, "node_modules/@vercel/nft": { "version": "0.27.9", "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.9.tgz", @@ -3902,9 +3921,9 @@ } }, "node_modules/@vue/devtools-shared": { - "version": "7.6.7", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.7.tgz", - "integrity": "sha512-QggO6SviAsolrePAXZ/sA1dSicSPt4TueZibCvydfhNDieL1lAuyMTgQDGst7TEvMGb4vgYv2I+1sDkO4jWNnw==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.8.tgz", + "integrity": "sha512-9MBPO5Z3X1nYGFqTJyohl6Gmf/J7UNN1oicHdyzBVZP4jnhZ4c20MgtaHDIzWmHDHCMYVS5bwKxT3jxh7gOOKA==", "license": "MIT", "dependencies": { "rfdc": "^1.4.1" @@ -3961,50 +3980,36 @@ "license": "MIT" }, "node_modules/@vueuse/core": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz", - "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.3.0.tgz", + "integrity": "sha512-cnV8QDKZrsyKC7tWjPbeEUz2cD9sa9faxF2YkR8QqNwfofgbOhmfIgvSYmkp+ttSvfOw4E6hLcQx15mRPr0yBA==", "license": "MIT", "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.11.1", - "@vueuse/shared": "10.11.1", - "vue-demi": ">=0.14.8" + "@vueuse/metadata": "12.3.0", + "@vueuse/shared": "12.3.0", + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "hasInstallScript": true, + "node_modules/@vueuse/core/node_modules/@vueuse/shared": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.3.0.tgz", + "integrity": "sha512-X3YD35GUeW0d5Gajcwv9jdLAJTV2Jdb/Ll6Ii2JIYcKLYZqv5wxyLeKtiQkqWmHg3v0J0ZWjDUMVOw2E7RCXfA==", "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "dependencies": { + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/@vueuse/metadata": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz", - "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.3.0.tgz", + "integrity": "sha512-M/iQHHjMffOv2npsw2ihlUx1CTiBwPEgb7DzByLq7zpg1+Ke8r7s9p5ybUWc5OIeGewtpY4Xy0R2cKqFqM8hFg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" @@ -4142,7 +4147,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" @@ -4155,7 +4160,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", @@ -4396,7 +4401,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/archiver": { @@ -4505,7 +4510,7 @@ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", "deprecated": "This package is no longer supported.", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "delegates": "^1.0.0", @@ -4519,7 +4524,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -4759,7 +4764,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -4771,7 +4775,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -4796,7 +4799,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -5415,7 +5417,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -5633,7 +5635,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "color-support": "bin.js" @@ -5816,7 +5818,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/content-disposition": { @@ -6241,7 +6243,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -6257,7 +6258,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -6272,6 +6272,15 @@ "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", "license": "MIT" }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -7011,6 +7020,61 @@ "node": ">=4.0.0" } }, + "node_modules/electron-rebuild": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-3.2.9.tgz", + "integrity": "sha512-FkEZNFViUem3P0RLYbZkUjC8LUFIK+wKq09GHoOITSJjfDAVQv964hwaNseTTWt58sITQX3/5fHNYcTefqaCWw==", + "deprecated": "Please use @electron/rebuild moving forward. There is no API change, just a package name change", + "dev": true, + "license": "MIT", + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "lzma-native": "^8.0.5", + "node-abi": "^3.0.0", + "node-api-version": "^0.1.4", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/src/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/electron-rebuild/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-rebuild/node_modules/node-api-version": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", + "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.72", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.72.tgz", @@ -7063,7 +7127,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -7098,7 +7161,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -7108,7 +7171,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/error-stack-parser-es": { @@ -7292,6 +7355,15 @@ "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, "node_modules/exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -7579,9 +7651,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fs-extra": { "version": "11.2.0", @@ -7661,7 +7731,7 @@ "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "deprecated": "This package is no longer supported.", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -7770,6 +7840,12 @@ "git-up": "^7.0.0" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8026,7 +8102,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/hash-sum": { @@ -8149,7 +8225,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause" }, "node_modules/http-errors": { @@ -8238,7 +8314,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ms": "^2.0.0" @@ -8350,7 +8426,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -8360,7 +8436,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -8382,7 +8458,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/inflight": { @@ -8439,7 +8515,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "jsbn": "1.1.0", @@ -8622,7 +8698,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/is-module": { @@ -8880,7 +8956,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jsesc": { @@ -9394,6 +9470,47 @@ "vue": ">=3.0.1" } }, + "node_modules/lzma-native": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", + "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^3.1.0", + "node-gyp-build": "^4.2.1", + "readable-stream": "^3.6.0" + }, + "bin": { + "lzmajs": "bin/lzmajs" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/lzma-native/node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/lzma-native/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/magic-string": { "version": "0.30.14", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.14.tgz", @@ -9710,7 +9827,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -9723,7 +9840,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -9736,7 +9853,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/minipass-fetch": { @@ -9781,7 +9898,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -9794,7 +9911,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -9807,14 +9924,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -9827,7 +9944,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -9840,14 +9957,14 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/minipass-sized": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -9860,7 +9977,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -9873,7 +9990,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/minizlib": { @@ -9925,6 +10042,12 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, "node_modules/mlly": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz", @@ -9996,11 +10119,17 @@ "integrity": "sha512-AiJsGsSF3O0havL1BydvI4+wR76sKT+okKRwWIaK96cZUnXqH0uNBOsHlbwZq3+m2BR1VKqHDVudl3gO4mYjpQ==", "license": "MIT" }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "license": "MIT" + }, "node_modules/negotiator": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -10149,7 +10278,6 @@ "version": "3.71.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", - "dev": true, "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -10386,7 +10514,7 @@ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "deprecated": "This package is no longer supported.", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "are-we-there-yet": "^3.0.0", @@ -10819,7 +10947,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" @@ -11868,6 +11996,32 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/pretty-bytes": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", @@ -11909,14 +12063,14 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "err-code": "^2.0.2", @@ -11949,7 +12103,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -12027,30 +12180,101 @@ "vue": ">= 3.2.0" } }, - "node_modules/radix3": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", - "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/radix-vue/node_modules/@vueuse/core": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz", + "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", "license": "MIT", "dependencies": { - "safe-buffer": "^5.1.0" + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.11.1", + "@vueuse/shared": "10.11.1", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/radix-vue/node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/radix-vue/node_modules/@vueuse/metadata": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz", + "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" } }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, "node_modules/rc9": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", @@ -12394,7 +12618,7 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 4" @@ -12811,7 +13035,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/setprototypeof": { @@ -12870,6 +13094,51 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-git": { "version": "3.27.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", @@ -12959,7 +13228,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 6.0.0", @@ -12976,7 +13245,7 @@ "version": "2.8.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ip-address": "^9.0.5", @@ -13065,9 +13334,349 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause" }, + "node_modules/sqlite3": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", + "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "bindings": "^1.5.0", + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.1", + "tar": "^6.1.11" + }, + "optionalDependencies": { + "node-gyp": "8.x" + }, + "peerDependencies": { + "node-gyp": "8.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/sqlite3/node_modules/@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "node_modules/sqlite3/node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "license": "MIT", + "optional": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sqlite3/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sqlite3/node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "license": "ISC", + "optional": true + }, + "node_modules/sqlite3/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/sqlite3/node_modules/cacache": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", + "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sqlite3/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sqlite3/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sqlite3/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sqlite3/node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "license": "ISC", + "optional": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sqlite3/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sqlite3/node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "license": "MIT", + "optional": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, + "node_modules/sqlite3/node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "license": "MIT", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/sqlite3/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sqlite3/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sqlite3/node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sqlite3/node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/sqlite3/node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/sqlite3/node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "license": "ISC", + "optional": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/sqlite3/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/sqlite3/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC", + "optional": true + }, "node_modules/ssri": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", @@ -13221,6 +13830,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-literal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz", @@ -13703,6 +14321,54 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tar-stream": { "version": "3.1.7", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", @@ -13935,6 +14601,18 @@ "node": ">=0.6.x" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-fest": { "version": "4.30.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.0.tgz", @@ -14485,6 +15163,43 @@ "node": ">= 0.8" } }, + "node_modules/vee-validate": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.15.0.tgz", + "integrity": "sha512-PGJh1QCFwCBjbHu5aN6vB8macYVWrajbDvgo1Y/8fz9n/RVIkLmZCJDpUgu7+mUmCOPMxeyq7vXUOhbwAqdXcA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.5.2", + "type-fest": "^4.8.3" + }, + "peerDependencies": { + "vue": "^3.4.26" + } + }, + "node_modules/vee-validate/node_modules/@vue/devtools-api": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.8.tgz", + "integrity": "sha512-ma6dY/sZR36zALVsV1W7eC57c6IJPXsy8SNgZn1PLVWU4z4dPn5TIBmnF4stmdJ4sQcixqKaQ8pwjbMPzEZwiA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.6.8" + } + }, + "node_modules/vee-validate/node_modules/@vue/devtools-kit": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.8.tgz", + "integrity": "sha512-JhJ8M3sPU+v0P2iZBF2DkdmR9L0dnT5RXJabJqX6o8KtFs3tebdvfoXV2Dm3BFuqeECuMJIfF1aCzSt+WQ4wrw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.6.8", + "birpc": "^0.2.19", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, "node_modules/verror": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", @@ -15411,7 +16126,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, + "devOptional": true, "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" diff --git a/electron/package.json b/electron/package.json index ec8bc3b..86867cd 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,16 +1,18 @@ { - "name": "tag-stack", + "name": "tag-stack-electron", "private": true, "scripts": { "build": "nuxt build", "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", - "postinstall": "nuxt prepare" + "postinstall": "install-app-deps && nuxt prepare" }, "dependencies": { "@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/tailwindcss": "^6.12.2", + "@vee-validate/zod": "^4.15.0", + "@vueuse/core": "^12.3.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "jimp": "^1.6.0", @@ -18,14 +20,18 @@ "nuxt": "^3.14.1592", "radix-vue": "^1.9.11", "shadcn-nuxt": "^0.11.3", + "sqlite3": "^5.1.7", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", + "vee-validate": "^4.15.0", "vue": "latest", - "vue-router": "latest" + "vue-router": "latest", + "zod": "^3.24.1" }, "devDependencies": { "electron": "^33.2.1", "electron-builder": "^25.1.8", + "electron-rebuild": "^3.2.9", "nuxt-electron": "^0.7.0", "vite-plugin-electron": "^0.29.0", "vite-plugin-electron-renderer": "^0.14.6" diff --git a/electron/server/api/fetch_files.ts b/electron/server/api/fetch_files.ts index 0b77222..a5fb544 100644 --- a/electron/server/api/fetch_files.ts +++ b/electron/server/api/fetch_files.ts @@ -22,7 +22,6 @@ async function getFileSize(image: fs.PathLike): Promise { return 'Unknown size'; } } - export default defineEventHandler(async (event) => { const query = getQuery(event); const directory: string = query.data as string; @@ -35,9 +34,10 @@ export default defineEventHandler(async (event) => { .map(async (file) => { const filePath = path.join(directory, file); const fileSize = await getFileSize(filePath); + return { - path: filePath, - size: fileSize + file_path: filePath, + file_size: fileSize }; }) ); @@ -45,7 +45,7 @@ export default defineEventHandler(async (event) => { return images; } catch (error) { console.error( - `Error reading directory: ${directory} | Error: ${error}` + `An error occurred while trying to read ${directory}: ${error}` ); return []; } diff --git a/electron/server/api/fetch_tags.ts b/electron/server/api/fetch_tags.ts new file mode 100644 index 0000000..95680f0 --- /dev/null +++ b/electron/server/api/fetch_tags.ts @@ -0,0 +1,39 @@ +import { defineEventHandler, getQuery } from 'h3'; +import sqlite3 from 'sqlite3'; +import path from 'path'; + +export default defineEventHandler(async (event) => { + const query = getQuery(event); + const directory: string = query.data as string; + const dbPath = path.join(directory, 'db', 'tags.db'); + const db = new sqlite3.Database(dbPath); + + return new Promise((resolve, reject) => { + const callback = (err: any, result: unknown) => { + if (err) reject(err); + else resolve(result); + }; + const output: any[] = []; + db.each( + 'SELECT * FROM tags', + (err: any, row: any) => { + if (err) { + reject(err); + } else { + output.push(row); + } + }, + (err: any) => { + if (err) reject(err); + else callback(null, output); // Resolve with the collected rows + } + ); + db.close((error) => { + if (error) { + console.error( + `An error occurred while trying to fetch tags: ${error}` + ); + } + }); + }); +}); diff --git a/electron/utils/palette.ts b/electron/utils/palette.ts new file mode 100644 index 0000000..33276b5 --- /dev/null +++ b/electron/utils/palette.ts @@ -0,0 +1,27 @@ +export const TAG_COLORS = { + RED: { + PRIMARY: '#E22C3C', + TEXT: '#440D12', + BORDER: '#E54252', + LIGHT_ACCENT: '#F39CAA', + DARK_ACCENT: '#440D12' + }, + MINT: { + PRIMARY: '#4AED90', + TEXT: '#164F3E', + BORDER: '#79F2B1', + LIGHT_ACCENT: '#C8FBE9', + DARK_ACCENT: '#164F3E' + }, + YELLOW: { + PRIMARY: '#FFD63D', + TEXT: '#754312', + BORDER: '#FFE071', + LIGHT_ACCENT: '#FFF3C4', + DARK_ACCENT: '#754312' + } +}; + +// TAG_COLORS.MINT.TEXT = TAG_COLORS.MINT.DARK_ACCENT; + +// export default TAG_COLORS; diff --git a/electron/utils/resize_image.ts b/electron/utils/resize_image.ts index 1dc6a49..137f1a3 100644 --- a/electron/utils/resize_image.ts +++ b/electron/utils/resize_image.ts @@ -27,9 +27,11 @@ export async function resizeImage(image: string): Promise { ); resized_image.setPixelColor(color, x, y); } - return resized_image.getBase64('image/png'); } catch (error) { + console.error( + `An error occurred while trying to resize ${image}: ${error}` + ); throw new Error(`Error resizing ${image}: ${error}`); } } diff --git a/tauri/app.vue b/tauri/app.vue index 8d9994b..2735148 100644 --- a/tauri/app.vue +++ b/tauri/app.vue @@ -10,9 +10,7 @@
- +
Loading...
@@ -68,35 +66,82 @@ -
-
-
- - {{ selected_image?.directory }} - -
-
- - {{ selected_image?.filename }} - + +
+ +
+
+ + {{ tag.name }} + +
+ +
+
+ + + + +
+
@@ -107,111 +152,161 @@ diff --git a/tauri/components/AppMenubar.vue b/tauri/components/AppMenubar.vue index 86783e2..474234b 100644 --- a/tauri/components/AppMenubar.vue +++ b/tauri/components/AppMenubar.vue @@ -3,13 +3,27 @@ File - To be implemented + To be implemented Edit - To be implemented + +
+ New Tag + Ctrl + T +
+
+ + + + + Manage Tags + + + +
@@ -21,19 +35,28 @@ + diff --git a/tauri/components/TagManager.vue b/tauri/components/TagManager.vue new file mode 100644 index 0000000..dd37222 --- /dev/null +++ b/tauri/components/TagManager.vue @@ -0,0 +1,47 @@ + + + diff --git a/tauri/components/ui/command/Command.vue b/tauri/components/ui/command/Command.vue new file mode 100644 index 0000000..d33ab38 --- /dev/null +++ b/tauri/components/ui/command/Command.vue @@ -0,0 +1,30 @@ + + + diff --git a/tauri/components/ui/command/CommandDialog.vue b/tauri/components/ui/command/CommandDialog.vue new file mode 100644 index 0000000..6620ad3 --- /dev/null +++ b/tauri/components/ui/command/CommandDialog.vue @@ -0,0 +1,21 @@ + + + diff --git a/tauri/components/ui/command/CommandEmpty.vue b/tauri/components/ui/command/CommandEmpty.vue new file mode 100644 index 0000000..cd097d7 --- /dev/null +++ b/tauri/components/ui/command/CommandEmpty.vue @@ -0,0 +1,20 @@ + + + diff --git a/tauri/components/ui/command/CommandGroup.vue b/tauri/components/ui/command/CommandGroup.vue new file mode 100644 index 0000000..939b78e --- /dev/null +++ b/tauri/components/ui/command/CommandGroup.vue @@ -0,0 +1,29 @@ + + + diff --git a/tauri/components/ui/command/CommandInput.vue b/tauri/components/ui/command/CommandInput.vue new file mode 100644 index 0000000..261fb95 --- /dev/null +++ b/tauri/components/ui/command/CommandInput.vue @@ -0,0 +1,33 @@ + + + diff --git a/tauri/components/ui/command/CommandItem.vue b/tauri/components/ui/command/CommandItem.vue new file mode 100644 index 0000000..ec9dacf --- /dev/null +++ b/tauri/components/ui/command/CommandItem.vue @@ -0,0 +1,26 @@ + + + diff --git a/tauri/components/ui/command/CommandList.vue b/tauri/components/ui/command/CommandList.vue new file mode 100644 index 0000000..889b8d0 --- /dev/null +++ b/tauri/components/ui/command/CommandList.vue @@ -0,0 +1,27 @@ + + + diff --git a/tauri/components/ui/command/CommandSeparator.vue b/tauri/components/ui/command/CommandSeparator.vue new file mode 100644 index 0000000..8f0cc1e --- /dev/null +++ b/tauri/components/ui/command/CommandSeparator.vue @@ -0,0 +1,23 @@ + + + diff --git a/tauri/components/ui/command/CommandShortcut.vue b/tauri/components/ui/command/CommandShortcut.vue new file mode 100644 index 0000000..0d4da92 --- /dev/null +++ b/tauri/components/ui/command/CommandShortcut.vue @@ -0,0 +1,14 @@ + + + diff --git a/tauri/components/ui/command/index.ts b/tauri/components/ui/command/index.ts new file mode 100644 index 0000000..0e35f4b --- /dev/null +++ b/tauri/components/ui/command/index.ts @@ -0,0 +1,9 @@ +export { default as Command } from './Command.vue' +export { default as CommandDialog } from './CommandDialog.vue' +export { default as CommandEmpty } from './CommandEmpty.vue' +export { default as CommandGroup } from './CommandGroup.vue' +export { default as CommandInput } from './CommandInput.vue' +export { default as CommandItem } from './CommandItem.vue' +export { default as CommandList } from './CommandList.vue' +export { default as CommandSeparator } from './CommandSeparator.vue' +export { default as CommandShortcut } from './CommandShortcut.vue' diff --git a/tauri/components/ui/dialog/Dialog.vue b/tauri/components/ui/dialog/Dialog.vue new file mode 100644 index 0000000..a04c026 --- /dev/null +++ b/tauri/components/ui/dialog/Dialog.vue @@ -0,0 +1,14 @@ + + + diff --git a/tauri/components/ui/dialog/DialogClose.vue b/tauri/components/ui/dialog/DialogClose.vue new file mode 100644 index 0000000..a64703e --- /dev/null +++ b/tauri/components/ui/dialog/DialogClose.vue @@ -0,0 +1,11 @@ + + + diff --git a/tauri/components/ui/dialog/DialogContent.vue b/tauri/components/ui/dialog/DialogContent.vue new file mode 100644 index 0000000..0de8451 --- /dev/null +++ b/tauri/components/ui/dialog/DialogContent.vue @@ -0,0 +1,50 @@ + + + diff --git a/tauri/components/ui/dialog/DialogDescription.vue b/tauri/components/ui/dialog/DialogDescription.vue new file mode 100644 index 0000000..878ef2b --- /dev/null +++ b/tauri/components/ui/dialog/DialogDescription.vue @@ -0,0 +1,24 @@ + + + diff --git a/tauri/components/ui/dialog/DialogFooter.vue b/tauri/components/ui/dialog/DialogFooter.vue new file mode 100644 index 0000000..ac2d0c1 --- /dev/null +++ b/tauri/components/ui/dialog/DialogFooter.vue @@ -0,0 +1,19 @@ + + + diff --git a/tauri/components/ui/dialog/DialogHeader.vue b/tauri/components/ui/dialog/DialogHeader.vue new file mode 100644 index 0000000..b2c9085 --- /dev/null +++ b/tauri/components/ui/dialog/DialogHeader.vue @@ -0,0 +1,16 @@ + + + diff --git a/tauri/components/ui/dialog/DialogScrollContent.vue b/tauri/components/ui/dialog/DialogScrollContent.vue new file mode 100644 index 0000000..0d44821 --- /dev/null +++ b/tauri/components/ui/dialog/DialogScrollContent.vue @@ -0,0 +1,59 @@ + + + diff --git a/tauri/components/ui/dialog/DialogTitle.vue b/tauri/components/ui/dialog/DialogTitle.vue new file mode 100644 index 0000000..1f049e3 --- /dev/null +++ b/tauri/components/ui/dialog/DialogTitle.vue @@ -0,0 +1,29 @@ + + + diff --git a/tauri/components/ui/dialog/DialogTrigger.vue b/tauri/components/ui/dialog/DialogTrigger.vue new file mode 100644 index 0000000..ee0c12f --- /dev/null +++ b/tauri/components/ui/dialog/DialogTrigger.vue @@ -0,0 +1,11 @@ + + + diff --git a/tauri/components/ui/dialog/index.ts b/tauri/components/ui/dialog/index.ts new file mode 100644 index 0000000..ca8cfea --- /dev/null +++ b/tauri/components/ui/dialog/index.ts @@ -0,0 +1,9 @@ +export { default as Dialog } from './Dialog.vue' +export { default as DialogClose } from './DialogClose.vue' +export { default as DialogContent } from './DialogContent.vue' +export { default as DialogDescription } from './DialogDescription.vue' +export { default as DialogFooter } from './DialogFooter.vue' +export { default as DialogHeader } from './DialogHeader.vue' +export { default as DialogScrollContent } from './DialogScrollContent.vue' +export { default as DialogTitle } from './DialogTitle.vue' +export { default as DialogTrigger } from './DialogTrigger.vue' diff --git a/tauri/components/ui/form/FormControl.vue b/tauri/components/ui/form/FormControl.vue new file mode 100644 index 0000000..8459cab --- /dev/null +++ b/tauri/components/ui/form/FormControl.vue @@ -0,0 +1,16 @@ + + + diff --git a/tauri/components/ui/form/FormDescription.vue b/tauri/components/ui/form/FormDescription.vue new file mode 100644 index 0000000..9300066 --- /dev/null +++ b/tauri/components/ui/form/FormDescription.vue @@ -0,0 +1,20 @@ + + + diff --git a/tauri/components/ui/form/FormItem.vue b/tauri/components/ui/form/FormItem.vue new file mode 100644 index 0000000..699724e --- /dev/null +++ b/tauri/components/ui/form/FormItem.vue @@ -0,0 +1,19 @@ + + + diff --git a/tauri/components/ui/form/FormLabel.vue b/tauri/components/ui/form/FormLabel.vue new file mode 100644 index 0000000..05a5192 --- /dev/null +++ b/tauri/components/ui/form/FormLabel.vue @@ -0,0 +1,23 @@ + + + diff --git a/tauri/components/ui/form/FormMessage.vue b/tauri/components/ui/form/FormMessage.vue new file mode 100644 index 0000000..308755e --- /dev/null +++ b/tauri/components/ui/form/FormMessage.vue @@ -0,0 +1,16 @@ + + + diff --git a/tauri/components/ui/form/index.ts b/tauri/components/ui/form/index.ts new file mode 100644 index 0000000..fca299e --- /dev/null +++ b/tauri/components/ui/form/index.ts @@ -0,0 +1,7 @@ +export { default as FormControl } from './FormControl.vue' +export { default as FormDescription } from './FormDescription.vue' +export { default as FormItem } from './FormItem.vue' +export { default as FormLabel } from './FormLabel.vue' +export { default as FormMessage } from './FormMessage.vue' +export { FORM_ITEM_INJECTION_KEY } from './injectionKeys' +export { Field as FormField, Form } from 'vee-validate' diff --git a/tauri/components/ui/form/injectionKeys.ts b/tauri/components/ui/form/injectionKeys.ts new file mode 100644 index 0000000..b972d36 --- /dev/null +++ b/tauri/components/ui/form/injectionKeys.ts @@ -0,0 +1,4 @@ +import type { InjectionKey } from 'vue' + +export const FORM_ITEM_INJECTION_KEY + = Symbol() as InjectionKey diff --git a/tauri/components/ui/form/useFormField.ts b/tauri/components/ui/form/useFormField.ts new file mode 100644 index 0000000..ed30a8a --- /dev/null +++ b/tauri/components/ui/form/useFormField.ts @@ -0,0 +1,30 @@ +import { FieldContextKey, useFieldError, useIsFieldDirty, useIsFieldTouched, useIsFieldValid } from 'vee-validate' +import { inject } from 'vue' +import { FORM_ITEM_INJECTION_KEY } from './injectionKeys' + +export function useFormField() { + const fieldContext = inject(FieldContextKey) + const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY) + + if (!fieldContext) + throw new Error('useFormField should be used within ') + + const { name } = fieldContext + const id = fieldItemContext + + const fieldState = { + valid: useIsFieldValid(name), + isDirty: useIsFieldDirty(name), + isTouched: useIsFieldTouched(name), + error: useFieldError(name), + } + + return { + id, + name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} diff --git a/tauri/components/ui/input/Input.vue b/tauri/components/ui/input/Input.vue new file mode 100644 index 0000000..81140b4 --- /dev/null +++ b/tauri/components/ui/input/Input.vue @@ -0,0 +1,24 @@ + + + diff --git a/tauri/components/ui/input/index.ts b/tauri/components/ui/input/index.ts new file mode 100644 index 0000000..a691dd6 --- /dev/null +++ b/tauri/components/ui/input/index.ts @@ -0,0 +1 @@ +export { default as Input } from './Input.vue' diff --git a/tauri/components/ui/label/Label.vue b/tauri/components/ui/label/Label.vue new file mode 100644 index 0000000..5ad1568 --- /dev/null +++ b/tauri/components/ui/label/Label.vue @@ -0,0 +1,27 @@ + + + diff --git a/tauri/components/ui/label/index.ts b/tauri/components/ui/label/index.ts new file mode 100644 index 0000000..572c2f0 --- /dev/null +++ b/tauri/components/ui/label/index.ts @@ -0,0 +1 @@ +export { default as Label } from './Label.vue' diff --git a/tauri/components/ui/tags-input/TagsInput.vue b/tauri/components/ui/tags-input/TagsInput.vue new file mode 100644 index 0000000..435b378 --- /dev/null +++ b/tauri/components/ui/tags-input/TagsInput.vue @@ -0,0 +1,22 @@ + + + diff --git a/tauri/components/ui/tags-input/TagsInputInput.vue b/tauri/components/ui/tags-input/TagsInputInput.vue new file mode 100644 index 0000000..4b1de4e --- /dev/null +++ b/tauri/components/ui/tags-input/TagsInputInput.vue @@ -0,0 +1,19 @@ + + + diff --git a/tauri/components/ui/tags-input/TagsInputItem.vue b/tauri/components/ui/tags-input/TagsInputItem.vue new file mode 100644 index 0000000..54618f6 --- /dev/null +++ b/tauri/components/ui/tags-input/TagsInputItem.vue @@ -0,0 +1,22 @@ + + + diff --git a/tauri/components/ui/tags-input/TagsInputItemDelete.vue b/tauri/components/ui/tags-input/TagsInputItemDelete.vue new file mode 100644 index 0000000..903d553 --- /dev/null +++ b/tauri/components/ui/tags-input/TagsInputItemDelete.vue @@ -0,0 +1,24 @@ + + + diff --git a/tauri/components/ui/tags-input/TagsInputItemText.vue b/tauri/components/ui/tags-input/TagsInputItemText.vue new file mode 100644 index 0000000..2ce7a6d --- /dev/null +++ b/tauri/components/ui/tags-input/TagsInputItemText.vue @@ -0,0 +1,19 @@ + + + diff --git a/tauri/components/ui/tags-input/index.ts b/tauri/components/ui/tags-input/index.ts new file mode 100644 index 0000000..31305f3 --- /dev/null +++ b/tauri/components/ui/tags-input/index.ts @@ -0,0 +1,5 @@ +export { default as TagsInput } from './TagsInput.vue' +export { default as TagsInputInput } from './TagsInputInput.vue' +export { default as TagsInputItem } from './TagsInputItem.vue' +export { default as TagsInputItemDelete } from './TagsInputItemDelete.vue' +export { default as TagsInputItemText } from './TagsInputItemText.vue' diff --git a/tauri/composables/fetch_tags.ts b/tauri/composables/fetch_tags.ts new file mode 100644 index 0000000..dc12846 --- /dev/null +++ b/tauri/composables/fetch_tags.ts @@ -0,0 +1,24 @@ +import * as sql from '@tauri-apps/plugin-sql'; + +const tags = ref([]); + +export async function fetchTags(): Promise { + const db = await sql.default.load('sqlite:db/tags.db'); + + try { + const result: any = await db.select('SELECT * FROM tags'); + tags.value = result.map((tag: Tag) => ({ + id: tag.id, + name: tag.name, + shorthand: tag.shorthand, + color: tag.color + })); + + return tags.value; + } catch (error) { + console.error(`An error occurred while trying to fetch tags: ${error}`); + throw new Error('Failed to fetch tags'); + } finally { + await db.close(); + } +} diff --git a/tauri/composables/types.ts b/tauri/composables/types.ts new file mode 100644 index 0000000..c15fdac --- /dev/null +++ b/tauri/composables/types.ts @@ -0,0 +1,22 @@ +export interface Tag { + id: number; + name: string; + shorthand: string; + color: string; +} + +export interface FileData { + file_path: string; + file_size: string; +} + +export interface TagStackImageData { + url: string; + width: number; + height: number; + is_square: boolean; + directory: string; + filename: string; + extension: string; + size: string; +} diff --git a/tauri/lib/utils.ts b/tauri/lib/utils.ts deleted file mode 100644 index d32b0fe..0000000 --- a/tauri/lib/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type ClassValue, clsx } from 'clsx' -import { twMerge } from 'tailwind-merge' - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} diff --git a/tauri/package-lock.json b/tauri/package-lock.json index a223284..3f303b5 100644 --- a/tauri/package-lock.json +++ b/tauri/package-lock.json @@ -1,17 +1,21 @@ { - "name": "tag-stack", + "name": "tag-stack-tauri", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "tag-stack", + "name": "tag-stack-tauri", "hasInstallScript": true, "dependencies": { "@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/tailwindcss": "^6.12.2", "@tauri-apps/api": "^2.1.1", "@tauri-apps/plugin-dialog": "^2.2.0", + "@tauri-apps/plugin-fs": "^2.2.0", "@tauri-apps/plugin-shell": "^2.2.0", + "@tauri-apps/plugin-sql": "^2.2.0", + "@vee-validate/zod": "^4.15.0", + "@vueuse/core": "^12.3.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "jimp": "^1.6.0", @@ -21,8 +25,10 @@ "shadcn-nuxt": "^0.11.3", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", + "vee-validate": "^4.15.0", "vue": "latest", - "vue-router": "latest" + "vue-router": "latest", + "zod": "^3.24.1" }, "devDependencies": { "@tauri-apps/cli": "^2.1.0" @@ -3200,6 +3206,15 @@ "@tauri-apps/api": "^2.0.0" } }, + "node_modules/@tauri-apps/plugin-fs": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.2.0.tgz", + "integrity": "sha512-+08mApuONKI8/sCNEZ6AR8vf5vI9DXD4YfrQ9NQmhRxYKMLVhRW164vdW5BSLmMpuevftpQ2FVoL9EFkfG9Z+g==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, "node_modules/@tauri-apps/plugin-shell": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.2.0.tgz", @@ -3209,6 +3224,15 @@ "@tauri-apps/api": "^2.0.0" } }, + "node_modules/@tauri-apps/plugin-sql": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-sql/-/plugin-sql-2.2.0.tgz", + "integrity": "sha512-yGdybpaMENe/p6lTXslvDHYNNvD9qB7palaBBF5fJHdYSkwd3vrLiYU9dFfLwUAwnsBylND55EiivWsjhazejA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, "node_modules/@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", @@ -3336,6 +3360,19 @@ "vue": ">=2.7 || >=3" } }, + "node_modules/@vee-validate/zod": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@vee-validate/zod/-/zod-4.15.0.tgz", + "integrity": "sha512-MpvIKiyg9X5yD8bJW0no2AU7wtR2T5mrvD9tuPRiie951sU2n6QKgMV38qKKOiqFBCxsMSjIuLLLV3V5kVE4nQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^4.8.3", + "vee-validate": "4.15.0" + }, + "peerDependencies": { + "zod": "^3.24.0" + } + }, "node_modules/@vercel/nft": { "version": "0.27.10", "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.10.tgz", @@ -3573,9 +3610,9 @@ } }, "node_modules/@vue/devtools-shared": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.8.tgz", - "integrity": "sha512-9MBPO5Z3X1nYGFqTJyohl6Gmf/J7UNN1oicHdyzBVZP4jnhZ4c20MgtaHDIzWmHDHCMYVS5bwKxT3jxh7gOOKA==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.0.tgz", + "integrity": "sha512-jtlQY26R5thQxW9YQTpXbI0HoK0Wf9Rd4ekidOkRvSy7ChfK0kIU6vvcBtjj87/EcpeOSK49fZAicaFNJcoTcQ==", "license": "MIT", "dependencies": { "rfdc": "^1.4.1" @@ -3632,50 +3669,36 @@ "license": "MIT" }, "node_modules/@vueuse/core": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz", - "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.3.0.tgz", + "integrity": "sha512-cnV8QDKZrsyKC7tWjPbeEUz2cD9sa9faxF2YkR8QqNwfofgbOhmfIgvSYmkp+ttSvfOw4E6hLcQx15mRPr0yBA==", "license": "MIT", "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.11.1", - "@vueuse/shared": "10.11.1", - "vue-demi": ">=0.14.8" + "@vueuse/metadata": "12.3.0", + "@vueuse/shared": "12.3.0", + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "hasInstallScript": true, + "node_modules/@vueuse/core/node_modules/@vueuse/shared": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.3.0.tgz", + "integrity": "sha512-X3YD35GUeW0d5Gajcwv9jdLAJTV2Jdb/Ll6Ii2JIYcKLYZqv5wxyLeKtiQkqWmHg3v0J0ZWjDUMVOw2E7RCXfA==", "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "dependencies": { + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/@vueuse/metadata": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz", - "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.3.0.tgz", + "integrity": "sha512-M/iQHHjMffOv2npsw2ihlUx1CTiBwPEgb7DzByLq7zpg1+Ke8r7s9p5ybUWc5OIeGewtpY4Xy0R2cKqFqM8hFg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" @@ -8988,6 +9011,56 @@ "vue": ">= 3.2.0" } }, + "node_modules/radix-vue/node_modules/@vueuse/core": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz", + "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.11.1", + "@vueuse/shared": "10.11.1", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/radix-vue/node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/radix-vue/node_modules/@vueuse/metadata": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz", + "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/radix3": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", @@ -11066,6 +11139,43 @@ "node": ">= 0.8" } }, + "node_modules/vee-validate": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.15.0.tgz", + "integrity": "sha512-PGJh1QCFwCBjbHu5aN6vB8macYVWrajbDvgo1Y/8fz9n/RVIkLmZCJDpUgu7+mUmCOPMxeyq7vXUOhbwAqdXcA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.5.2", + "type-fest": "^4.8.3" + }, + "peerDependencies": { + "vue": "^3.4.26" + } + }, + "node_modules/vee-validate/node_modules/@vue/devtools-api": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.0.tgz", + "integrity": "sha512-bHEv6kT85BHtyGgDhE07bAUMAy7zpv6nnR004nSTd0wWMrAOtcrYoXO5iyr20Hkf5jR8obQOfS3byW+I3l2CCA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.0" + } + }, + "node_modules/vee-validate/node_modules/@vue/devtools-kit": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.0.tgz", + "integrity": "sha512-5cvZ+6SA88zKC8XiuxUfqpdTwVjJbvYnQZY5NReh7qlSGPvVDjjzyEtW+gdzLXNSd8tStgOjAdMCpvDQamUXtA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.0", + "birpc": "^0.2.19", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, "node_modules/vite": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.6.tgz", diff --git a/tauri/package.json b/tauri/package.json index e573655..d23f8bd 100644 --- a/tauri/package.json +++ b/tauri/package.json @@ -1,5 +1,5 @@ { - "name": "tag-stack", + "name": "tag-stack-tauri", "private": true, "type": "module", "scripts": { @@ -14,7 +14,11 @@ "@nuxtjs/tailwindcss": "^6.12.2", "@tauri-apps/api": "^2.1.1", "@tauri-apps/plugin-dialog": "^2.2.0", + "@tauri-apps/plugin-fs": "^2.2.0", "@tauri-apps/plugin-shell": "^2.2.0", + "@tauri-apps/plugin-sql": "^2.2.0", + "@vee-validate/zod": "^4.15.0", + "@vueuse/core": "^12.3.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "jimp": "^1.6.0", @@ -24,10 +28,12 @@ "shadcn-nuxt": "^0.11.3", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", + "vee-validate": "^4.15.0", "vue": "latest", - "vue-router": "latest" + "vue-router": "latest", + "zod": "^3.24.1" }, "devDependencies": { "@tauri-apps/cli": "^2.1.0" } -} \ No newline at end of file +} diff --git a/tauri/server/api/fetch_files.ts b/tauri/server/api/fetch_files.ts index 0b77222..a5fb544 100644 --- a/tauri/server/api/fetch_files.ts +++ b/tauri/server/api/fetch_files.ts @@ -22,7 +22,6 @@ async function getFileSize(image: fs.PathLike): Promise { return 'Unknown size'; } } - export default defineEventHandler(async (event) => { const query = getQuery(event); const directory: string = query.data as string; @@ -35,9 +34,10 @@ export default defineEventHandler(async (event) => { .map(async (file) => { const filePath = path.join(directory, file); const fileSize = await getFileSize(filePath); + return { - path: filePath, - size: fileSize + file_path: filePath, + file_size: fileSize }; }) ); @@ -45,7 +45,7 @@ export default defineEventHandler(async (event) => { return images; } catch (error) { console.error( - `Error reading directory: ${directory} | Error: ${error}` + `An error occurred while trying to read ${directory}: ${error}` ); return []; } diff --git a/tauri/src-tauri/Cargo.lock b/tauri/src-tauri/Cargo.lock index e482383..13c3066 100644 --- a/tauri/src-tauri/Cargo.lock +++ b/tauri/src-tauri/Cargo.lock @@ -52,6 +52,12 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -101,8 +107,10 @@ dependencies = [ "tauri", "tauri-build", "tauri-plugin-dialog", + "tauri-plugin-fs", "tauri-plugin-log", "tauri-plugin-shell", + "tauri-plugin-sql", ] [[package]] @@ -274,6 +282,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -313,6 +330,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" @@ -667,6 +690,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "convert_case" version = "0.4.0" @@ -732,6 +761,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -750,6 +794,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -838,6 +891,17 @@ dependencies = [ "syn 2.0.92", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -879,7 +943,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -952,6 +1018,12 @@ dependencies = [ "syn 2.0.92", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -994,6 +1066,15 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +dependencies = [ + "serde", +] + [[package]] name = "embed-resource" version = "2.5.1" @@ -1086,6 +1167,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "5.3.1" @@ -1151,12 +1243,29 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "foreign-types" version = "0.5.0" @@ -1216,6 +1325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -1235,6 +1345,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -1602,6 +1723,20 @@ name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.2", +] [[package]] name = "heck" @@ -1627,6 +1762,33 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "html5ever" version = "0.26.0" @@ -2086,6 +2248,9 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] [[package]] name = "libappindicator" @@ -2127,6 +2292,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + [[package]] name = "libredox" version = "0.1.3" @@ -2137,6 +2308,17 @@ dependencies = [ "libc", ] +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2203,6 +2385,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "memchr" version = "2.7.4" @@ -2319,12 +2511,49 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2332,6 +2561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2704,6 +2934,15 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -2867,6 +3106,27 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.31" @@ -3282,6 +3542,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "rsa" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rust_decimal" version = "1.36.0" @@ -3610,6 +3890,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -3642,6 +3932,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -3701,6 +3994,216 @@ dependencies = [ "system-deps", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlx" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4410e73b3c0d8442c5f99b425d7a435b5ee0ae4167b3196771dd3f7a01be745f" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0" +dependencies = [ + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.2", + "hashlink", + "indexmap 2.7.0", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.9", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3112e2ad78643fef903618d78cf0aec1cb3134b019730edb039b69eaf531f310" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.92", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad" +dependencies = [ + "dotenvy", + "either", + "heck 0.5.0", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.92", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.6.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa 1.0.14", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.9", + "time", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b98a57f363ed6764d5b3a12bfedf62f07aa16e1856a7ddc2a0bb190a959613" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.6.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa 1.0.14", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.9", + "time", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "time", + "tracing", + "url", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3739,12 +4242,29 @@ dependencies = [ "quote", ] +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "swift-rs" version = "1.0.7" @@ -4100,6 +4620,25 @@ dependencies = [ "tokio", ] +[[package]] +name = "tauri-plugin-sql" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ccca89ded6bd2ff49fdad9a5b34bcd624aa223fdfddbab83c85706ee3a4948" +dependencies = [ + "futures-core", + "indexmap 2.7.0", + "log", + "serde", + "serde_json", + "sqlx", + "tauri", + "tauri-plugin", + "thiserror 2.0.9", + "time", + "tokio", +] + [[package]] name = "tauri-runtime" version = "2.2.0" @@ -4337,6 +4876,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.13" @@ -4442,6 +4992,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4558,12 +5109,33 @@ dependencies = [ "unic-common", ] +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + [[package]] name = "unicode-segmentation" version = "1.12.0" @@ -4634,6 +5206,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version-compare" version = "0.2.0" @@ -4697,6 +5275,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.99" @@ -4927,6 +5511,16 @@ dependencies = [ "windows-core 0.58.0", ] +[[package]] +name = "whoami" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +dependencies = [ + "redox_syscall", + "wasite", +] + [[package]] name = "winapi" version = "0.3.9" @@ -5518,6 +6112,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + [[package]] name = "zerovec" version = "0.10.4" diff --git a/tauri/src-tauri/Cargo.toml b/tauri/src-tauri/Cargo.toml index 783681b..07f3461 100644 --- a/tauri/src-tauri/Cargo.toml +++ b/tauri/src-tauri/Cargo.toml @@ -26,3 +26,5 @@ tauri-plugin-log = "2.0.0-rc" chrono = "0.4.39" tauri-plugin-dialog = "2" tauri-plugin-shell = "2" +tauri-plugin-sql = { version = "2", features = ["sqlite"] } +tauri-plugin-fs = "2" diff --git a/tauri/src-tauri/capabilities/default.json b/tauri/src-tauri/capabilities/default.json index fbfd3a9..cd90b30 100644 --- a/tauri/src-tauri/capabilities/default.json +++ b/tauri/src-tauri/capabilities/default.json @@ -8,6 +8,20 @@ "permissions": [ "core:default", "dialog:default", - "shell:default" + "shell:default", + "sql:default", + "sql:allow-execute", + "fs:default", + { + "identifier": "fs:scope", + "allow": [ + { + "path": "$APPDATA" + }, + { + "path": "$APPDATA/**" + } + ] + } ] } \ No newline at end of file diff --git a/tauri/src-tauri/src/lib.rs b/tauri/src-tauri/src/lib.rs index 3936a46..394a964 100644 --- a/tauri/src-tauri/src/lib.rs +++ b/tauri/src-tauri/src/lib.rs @@ -1,6 +1,8 @@ #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() + .plugin(tauri_plugin_fs::init()) + .plugin(tauri_plugin_sql::Builder::new().build()) .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_dialog::init()) .setup(|app| { diff --git a/tauri/src-tauri/tauri.conf.json b/tauri/src-tauri/tauri.conf.json index a957514..49e220c 100644 --- a/tauri/src-tauri/tauri.conf.json +++ b/tauri/src-tauri/tauri.conf.json @@ -2,7 +2,7 @@ "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "productName": "tag-stack", "version": "0.1.0", - "identifier": "com.tauri.dev", + "identifier": "com.smokeystack.tag-stack", "build": { "frontendDist": "../dist", "devUrl": "http://localhost:3000", diff --git a/tauri/utils/palette.ts b/tauri/utils/palette.ts new file mode 100644 index 0000000..33276b5 --- /dev/null +++ b/tauri/utils/palette.ts @@ -0,0 +1,27 @@ +export const TAG_COLORS = { + RED: { + PRIMARY: '#E22C3C', + TEXT: '#440D12', + BORDER: '#E54252', + LIGHT_ACCENT: '#F39CAA', + DARK_ACCENT: '#440D12' + }, + MINT: { + PRIMARY: '#4AED90', + TEXT: '#164F3E', + BORDER: '#79F2B1', + LIGHT_ACCENT: '#C8FBE9', + DARK_ACCENT: '#164F3E' + }, + YELLOW: { + PRIMARY: '#FFD63D', + TEXT: '#754312', + BORDER: '#FFE071', + LIGHT_ACCENT: '#FFF3C4', + DARK_ACCENT: '#754312' + } +}; + +// TAG_COLORS.MINT.TEXT = TAG_COLORS.MINT.DARK_ACCENT; + +// export default TAG_COLORS; diff --git a/tauri/utils/resize_image.ts b/tauri/utils/resize_image.ts index cbb0661..783f34e 100644 --- a/tauri/utils/resize_image.ts +++ b/tauri/utils/resize_image.ts @@ -30,6 +30,11 @@ export async function resizeImage(image: string): Promise { } return resized_image.getBase64('image/png'); } catch (error) { + console.error( + `An error occurred while trying to resize ${core.convertFileSrc( + image + )}: ${error}` + ); throw new Error( `Error resizing ${core.convertFileSrc(image)}: ${error}` );