diff --git a/.env.example b/.env.example index 7424f60..ff14524 100644 --- a/.env.example +++ b/.env.example @@ -1,13 +1,10 @@ # Random 32 characters long string NUXT_SESSION_PASSWORD= -# GitHub OAuth +# GitHub OAuth (optional) NUXT_OAUTH_GITHUB_CLIENT_ID= NUXT_OAUTH_GITHUB_CLIENT_SECRET= -# Google OAuth +# Google OAuth (optional) NUXT_OAUTH_GOOGLE_CLIENT_ID= NUXT_OAUTH_GOOGLE_CLIENT_SECRET= - -# Nuxt UI Pro License -NUXT_UI_PRO_LICENSE= diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b546b0a..76d24bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,5 @@ -name: Deploy to Cloudflare with NuxtHub Cli -on: - push: - branches: ['main'] +name: Deploy with NuxtHub CLI +on: push jobs: build-and-deploy: runs-on: ubuntu-latest @@ -31,9 +29,8 @@ jobs: - name: Install dependencies run: pnpm install - - name: Deploy with nuxt-hub cli + - name: Deploy with nuxthub run: npx nuxthub deploy env: NUXT_HUB_PROJECT_KEY: ${{ secrets.NUXT_HUB_PROJECT_KEY}} NUXT_HUB_USER_TOKEN: ${{ secrets.NUXT_HUB_USER_TOKEN }} - NUXT_UI_PRO_LICENSE: ${{ secrets.NUXT_UI_PRO_LICENSE }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..484e7b8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 SΓ©bastien Chopin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 0fe1d16..b7af8f8 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,133 @@ -# Atidraw +# Draw and share your Art with Atidraw 🎨✨ -Share your drawings with the world with this [Nuxt application](https://nuxt.com) using [NuxtHub Blob storage](https://hub.nuxt.com/docs/storage/blob) (Cloudflare R2) and deployed on the Edge (Cloudflare Pages). +Atidraw is a web application that lets you to create, enhance, and share your drawings with the world. Harnessing the power of Cloudflare R2 and Cloudflare AI to store and enhance your drawings. + +The application is running with server-side rendering on the edge using Cloudflare Pages. + +You can deploy it with zero configuration on your Cloudflare account using NuxtHub: [![Deploy to NuxtHub](https://hub.nuxt.com/button.svg)](https://hub.nuxt.com/new?repo=atinux/atidraw) -## Links +### πŸš€ Key Features -- [Demo](https://draw.nuxt.dev) -- [NuxtHub docs](https://hub.nuxt.com) -- [Nuxt docs](https://nuxt.com) +- **Intuitive Drawing**: User-friendly interface powered by [`signature_pad`](https://github.com/szimek/signature_pad) +- **AI-Powered Enhancements**: + - Automatic alt text generation for accessibility & SEO + - Generate an image of your drawing with Stable Diffusion +- **Global Storage**: Your creations are safely stored using [Cloudflare R2](https://www.cloudflare.com/developer-platform/r2/) +- **Flexible Authentication**: Sign in with Google, GitHub, or stay anonymous (local) +- **High-Performance**: Deployed on the edge with server-side rendering using Cloudflare Pages -## Too lazy to draw? +### πŸŽ₯ See It in Action https://github.com/Atinux/atidraw/assets/904724/85f79def-f633-40b7-97c2-3a8579e65af1 -Now it's your turn! https://draw.nuxt.dev +Ready to create? Visit [draw.nuxt.dev](https://draw.nuxt.dev) and share your best drawing! -## Features +## πŸ›  Tech Stack -- Image upload with [`hubBlob()`](https://hub.nuxt.com/docs/storage/blob) -- Auth with Google & GitHub based on [`nuxt-auth-utils`](https://github.com/Atinux/nuxt-auth-utils) -- Draw with [`signature_pad`](https://github.com/szimek/signature_pad) -- Deploy to the Edge with [nuxthub deploy](https://github.com/nuxt-hub/cli) using a [GitHub action](./.github/workflows/deploy.yml) +- [Nuxt](https://nuxt.com) - The Intuitive Vue Framework +- [Nuxt UI](https://github.com/nuxt/ui) - Beautiful UI library with TailwindCSS +- [Nuxt Auth Utils](https://github.com/Atinux/nuxt-auth-utils) - Simplified Authentication +- [NuxtHub](https://hub.nuxt.com) - Build & deploy to your Cloudflare account with zero configuration + - [`hubBlob()`](https://hub.nuxt.com/docs/features/blob) to store drawing on Cloudflare R2 + - [`hubAI()`](https://hub.nuxt.com/docs/features/ai) to run Cloudflare AI on user's drawing +- [`npx nuxthub deploy`](https://github.com/nuxt-hub/cli) - To deploy the app on your Cloudflare account for free -## Setup +## 🏎️ How does it work? -Make sure to install the dependencies: +I wrote two articles about how I created Atidraw: +- [Code, Draw, Deploy: A drawing app with Nuxt & Cloudflare R2](https://hub.nuxt.com/blog/drawing-app-with-nuxt-and-cloudflare-r2) +- [Using Cloudflare AI Models for User Experience](https://hub.nuxt.com/blog/cloudflare-ai-for-user-experience) -```bash -pnpm install -``` +## πŸš€ Quick Start -## Development Server +1. Install dependencies with [pnpm](https://pnpm.io) + ```bash + pnpm install + ``` +2. Set up your environment and fill the env variables + ```bash + cp .env.example .env + ``` + If you don't set the Google and GitHub credentials, anonymous sign-in will be enabled. +3. Create & link a NuxtHub project to enable running AI models on your Cloudflare account + ```bash + npx nuxthub link + ``` +4. Launch the dev server + ```bash + pnpm dev + ``` -Start the development server on `http://localhost:3000`: +Visit `http://localhost:3000` and start drawing! -```bash -pnpm dev -``` +## πŸ“ Manage Drawings + +You can manage the drawings (local or remote) within the Nuxt DevTools in the Hub Blob tab: + +![nuxt-devtools-blob](https://github.com/user-attachments/assets/152b0283-637b-41b3-990e-f25a73183c93) + +## πŸ€– Experiment with AI + +Unlock the full potential of Atidraw by enabling the AI image generation feature: + +1. Open `./app/pages/draw.vue` +2. Uncomment the `` component: + ```diff + - + + + ``` +3. Open http://localhost:3000/draw to draw something and click on "Draw with AI" -## Production +https://github.com/user-attachments/assets/1ff6b3fd-3dbb-45de-8c3a-648aee8b28b0 -Build the application for production: +## 🌐 Deploy to the World for Free + +Host your Atidraw instance on a **free Cloudflare account** and **free NuxtHub account**. + +Deploy it online in the NuxtHub UI: + +[![Deploy to NuxtHub](https://hub.nuxt.com/button.svg)](https://hub.nuxt.com/new?repo=atinux/atidraw) + +Or locally with the [NuxtHub CLI](https://github.com/nuxt-hub/cli): ```bash -pnpm build +npx nuxthub deploy ``` -## Environment Variables +This command will deploy your Atidraw instance to your Cloudflare account and provision a Cloudflare R2 bucket. You will also get a free `.nuxt.dev` domain. -Copy the `.env.example` file to `.env` and fill in the required environment variables: +Once deployed, you can manage your users' masterpieces in the [NuxtHub Admin](https://admin.hub.nuxt.com). ```bash -cp .env.example .env +npx nuxthub manage ``` -You may want to create Google and GitHub OAuth applications. +What's included in Cloudflare free plan: +- 100,000 requests/day +- 10 GB storage on Cloudflare R2 -## Deploy on the Edge +Read more about the pricing on our [detailed pricing page](https://hub.nuxt.com/pricing). -Deploy the application on the Edge with [NuxtHub](https://hub.nuxt.com): +You can also deploy using [Cloudflare Pages CI](https://hub.nuxt.com/docs/getting-started/deploy#cloudflare-pages-ci) or [GitHub actions](https://hub.nuxt.com/docs/getting-started/deploy#github-action). + +### Remote Storage + +Once your project is deployed, you can use [NuxtHub Remote Storage](https://hub.nuxt.com/docs/getting-started/remote-storage) to connect to your preview or production Cloudflare R2 bucket in development using the `--remote` flag: ```bash -npx nuxthub deploy +pnpm dev --remote ``` -Then manage the drawings of your users in the [NuxtHub Admin](https://admin.hub.nuxt.com). +## πŸ”— Useful Links + +- [Live Demo](https://draw.nuxt.dev) +- [NuxtHub Documentation](https://hub.nuxt.com) +- [Nuxt UI](https://ui.nuxt.com) +- [Nuxt Auth Utils](https://github.com/atinux/nuxt-auth-utils) +- [Nuxt](https://nuxt.com) + +## πŸ“ License -You can also deploy using [Cloudflare Pages CI](https://hub.nuxt.com/docs/getting-started/deploy#cloudflare-pages-ci). +Published under the [MIT license](./LICENSE). diff --git a/app/app.config.ts b/app/app.config.ts index 6087fa6..e629619 100644 --- a/app/app.config.ts +++ b/app/app.config.ts @@ -2,9 +2,5 @@ export default defineAppConfig({ ui: { primary: 'blue', gray: 'neutral', - header: { - wrapper: 'border-none md:pt-8 md:max-w-2xl mx-auto bg-transparent backdrop-blur-none', - container: 'bg-gray-400/5 md:rounded-full border-b md:border dark:border-gray-800 bg-gray-50 dark:bg-gray-950', - }, }, }) diff --git a/app/app.vue b/app/app.vue index f94bc2b..81dda0e 100644 --- a/app/app.vue +++ b/app/app.vue @@ -1,8 +1,8 @@ + + diff --git a/app/components/AppFooter.vue b/app/components/AppFooter.vue index b0b9292..2b422fc 100644 --- a/app/components/AppFooter.vue +++ b/app/components/AppFooter.vue @@ -1,51 +1,69 @@ diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue index 21e70a3..77abe0f 100644 --- a/app/components/AppHeader.vue +++ b/app/components/AppHeader.vue @@ -1,36 +1,37 @@ diff --git a/app/components/DrawPad.vue b/app/components/DrawPad.vue index 27816b4..962a000 100644 --- a/app/components/DrawPad.vue +++ b/app/components/DrawPad.vue @@ -15,7 +15,7 @@ const props = defineProps({ default: false, }, }) -const emit = defineEmits(['save']) +const emit = defineEmits(['draw', 'save']) const canPost = ref(false) const canvas = ref() @@ -39,6 +39,11 @@ onMounted(() => { signaturePad.value.addEventListener('afterUpdateStroke', () => { canPost.value = !signaturePad.value.isEmpty() }) + signaturePad.value.addEventListener('endStroke', () => { + if (!signaturePad.value || signaturePad.value.isEmpty() || props.saving) return + const dataURL = signaturePad.value.toDataURL(props.saveType) + emit('draw', dataURL) + }) }) onBeforeUnmount(() => { window.removeEventListener('resize', resizeCanvas) diff --git a/app/pages/draw.vue b/app/pages/draw.vue index b6319fc..bfd4801 100644 --- a/app/pages/draw.vue +++ b/app/pages/draw.vue @@ -1,27 +1,13 @@ diff --git a/app/pages/index.vue b/app/pages/index.vue index ad67e36..090eb6d 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -1,9 +1,10 @@ diff --git a/nuxt.config.ts b/nuxt.config.ts index fe3ad55..b5fdae4 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,22 +1,23 @@ // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ compatibilityDate: '2024-07-30', - extends: ['@nuxt/ui-pro'], + future: { compatibilityVersion: 4 }, modules: [ '@nuxthub/core', '@nuxt/ui', '@nuxt/eslint', 'nuxt-auth-utils', ], - future: { - // New directory structure - // https://nuxt.com/docs/getting-started/upgrade#testing-nuxt-4 - compatibilityVersion: 4, - }, hub: { ai: true, blob: true, }, + runtimeConfig: { + public: { + githubAuth: Boolean(process.env.NUXT_OAUTH_GITHUB_CLIENT_ID && process.env.NUXT_OAUTH_GITHUB_CLIENT_SECRET), + googleAuth: Boolean(process.env.NUXT_OAUTH_GOOGLE_CLIENT_ID && process.env.NUXT_OAUTH_GOOGLE_CLIENT_SECRET), + }, + }, // Development modules eslint: { config: { diff --git a/package.json b/package.json index 3bf42d9..7eaff53 100644 --- a/package.json +++ b/package.json @@ -2,34 +2,32 @@ "name": "atidraw", "private": true, "type": "module", - "packageManager": "pnpm@9.1.3", + "packageManager": "pnpm@9.7.1", "scripts": { "dev": "nuxt dev", "build": "nuxt build", "preview": "nuxt preview", - "deploy": "nuxthub deploy", "postinstall": "nuxt prepare", "lint": "eslint .", "typecheck": "nuxt typecheck" }, "dependencies": { - "@iconify-json/logos": "^1.1.43", - "@iconify-json/ph": "^1.1.13", - "@iconify-json/simple-icons": "^1.1.111", - "@nuxt/eslint": "^0.4.0", - "@nuxt/ui": "^2.18.3", - "@nuxt/ui-pro": "^1.4.0", + "@iconify-json/logos": "^1.1.44", + "@iconify-json/ph": "^1.1.14", + "@iconify-json/simple-icons": "^1.1.113", + "@nuxt/eslint": "^0.5.0", + "@nuxt/ui": "^2.18.4", "@nuxthub/core": "^0.7.3", - "@vueuse/components": "^10.11.0", - "@vueuse/core": "^10.11.0", + "@vueuse/components": "^10.11.1", + "@vueuse/core": "^10.11.1", "nuxt": "^3.12.4", - "nuxt-auth-utils": "^0.3.2", + "nuxt-auth-utils": "^0.3.4", "signature_pad": "^5.0.2" }, "devDependencies": { - "@nuxt/eslint-config": "^0.4.0", - "eslint": "^9.8.0", + "@nuxt/eslint-config": "^0.5.0", + "eslint": "^9.9.0", "vue-tsc": "^2.0.29", - "wrangler": "^3.67.1" + "wrangler": "^3.71.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3052bb0..b227c23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,54 +9,51 @@ importers: .: dependencies: '@iconify-json/logos': - specifier: ^1.1.43 - version: 1.1.43 + specifier: ^1.1.44 + version: 1.1.44 '@iconify-json/ph': - specifier: ^1.1.13 - version: 1.1.13 + specifier: ^1.1.14 + version: 1.1.14 '@iconify-json/simple-icons': - specifier: ^1.1.111 - version: 1.1.111 + specifier: ^1.1.113 + version: 1.1.113 '@nuxt/eslint': - specifier: ^0.4.0 - version: 0.4.0(eslint@9.8.0)(magicast@0.3.4)(rollup@4.19.1)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3)) + specifier: ^0.5.0 + version: 0.5.0(eslint@9.9.0(jiti@1.21.6))(magicast@0.3.4)(rollup@4.19.1)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3)) '@nuxt/ui': - specifier: ^2.18.3 - version: 2.18.3(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5)) - '@nuxt/ui-pro': - specifier: ^1.4.0 - version: 1.4.0(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5)) + specifier: ^2.18.4 + version: 2.18.4(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5)) '@nuxthub/core': specifier: ^0.7.3 version: 0.7.3(ioredis@5.4.1)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3)) '@vueuse/components': - specifier: ^10.11.0 - version: 10.11.0(vue@3.4.34(typescript@5.4.5)) + specifier: ^10.11.1 + version: 10.11.1(vue@3.4.34(typescript@5.4.5)) '@vueuse/core': - specifier: ^10.11.0 - version: 10.11.0(vue@3.4.34(typescript@5.4.5)) + specifier: ^10.11.1 + version: 10.11.1(vue@3.4.34(typescript@5.4.5)) nuxt: specifier: ^3.12.4 - version: 3.12.4(@parcel/watcher@2.4.1)(@types/node@22.0.0)(encoding@0.1.13)(eslint@9.8.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)) + version: 3.12.4(@parcel/watcher@2.4.1)(@types/node@22.0.0)(encoding@0.1.13)(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)) nuxt-auth-utils: - specifier: ^0.3.2 - version: 0.3.2(magicast@0.3.4)(rollup@4.19.1) + specifier: ^0.3.4 + version: 0.3.4(magicast@0.3.4)(rollup@4.19.1) signature_pad: specifier: ^5.0.2 version: 5.0.2 devDependencies: '@nuxt/eslint-config': - specifier: ^0.4.0 - version: 0.4.0(eslint@9.8.0)(typescript@5.4.5) + specifier: ^0.5.0 + version: 0.5.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) eslint: - specifier: ^9.8.0 - version: 9.8.0 + specifier: ^9.9.0 + version: 9.9.0(jiti@1.21.6) vue-tsc: specifier: ^2.0.29 version: 2.0.29(typescript@5.4.5) wrangler: - specifier: ^3.67.1 - version: 3.67.1(@cloudflare/workers-types@4.20240806.0) + specifier: ^3.71.0 + version: 3.72.0(@cloudflare/workers-types@4.20240806.0) packages: @@ -234,36 +231,40 @@ packages: resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} engines: {node: '>=16.13'} - '@cloudflare/workerd-darwin-64@1.20240718.0': - resolution: {integrity: sha512-BsPZcSCgoGnufog2GIgdPuiKicYTNyO/Dp++HbpLRH+yQdX3x4aWx83M+a0suTl1xv76dO4g9aw7SIB6OSgIyQ==} + '@cloudflare/workerd-darwin-64@1.20240806.0': + resolution: {integrity: sha512-FqcVBBCO//I39K5F+HqE/v+UkqY1UrRnS653Jv+XsNNH9TpX5fTs7VCKG4kDSnmxlAaKttyIN5sMEt7lpuNExQ==} engines: {node: '>=16'} cpu: [x64] os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20240718.0': - resolution: {integrity: sha512-nlr4gaOO5gcJerILJQph3+2rnas/nx/lYsuaot1ntHu4LAPBoQo1q/Pucj2cSIav4UiMzTbDmoDwPlls4Kteog==} + '@cloudflare/workerd-darwin-arm64@1.20240806.0': + resolution: {integrity: sha512-8c3KvmzYp/wg+82KHSOzDetJK+pThH4MTrU1OsjmsR2cUfedm5dk5Lah9/0Ld68+6A0umFACi4W2xJHs/RoBpA==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] - '@cloudflare/workerd-linux-64@1.20240718.0': - resolution: {integrity: sha512-LJ/k3y47pBcjax0ee4K+6ZRrSsqWlfU4lbU8Dn6u5tSC9yzwI4YFNXDrKWInB0vd7RT3w4Yqq1S6ZEbfRrqVUg==} + '@cloudflare/workerd-linux-64@1.20240806.0': + resolution: {integrity: sha512-/149Bpxw4e2p5QqnBc06g0mx+4sZYh9j0doilnt0wk/uqYkLp0DdXGMQVRB74sBLg2UD3wW8amn1w3KyFhK2tQ==} engines: {node: '>=16'} cpu: [x64] os: [linux] - '@cloudflare/workerd-linux-arm64@1.20240718.0': - resolution: {integrity: sha512-zBEZvy88EcAMGRGfuVtS00Yl7lJdUM9sH7i651OoL+q0Plv9kphlCC0REQPwzxrEYT1qibSYtWcD9IxQGgx2/g==} + '@cloudflare/workerd-linux-arm64@1.20240806.0': + resolution: {integrity: sha512-lacDWY3S1rKL/xT6iMtTQJEKmTTKrBavPczInEuBFXElmrS6IwVjZwv8hhVm32piyNt/AuFu9BYoJALi9D85/g==} engines: {node: '>=16'} cpu: [arm64] os: [linux] - '@cloudflare/workerd-windows-64@1.20240718.0': - resolution: {integrity: sha512-YpCRvvT47XanFum7C3SedOZKK6BfVhqmwdAAVAQFyc4gsCdegZo0JkUkdloC/jwuWlbCACOG2HTADHOqyeolzQ==} + '@cloudflare/workerd-windows-64@1.20240806.0': + resolution: {integrity: sha512-hC6JEfTSQK6//Lg+D54TLVn1ceTPY+fv4MXqDZIYlPP53iN+dL8Xd0utn2SG57UYdlL5FRAhm/EWHcATZg1RgA==} engines: {node: '>=16'} cpu: [x64] os: [win32] + '@cloudflare/workers-shared@0.2.0': + resolution: {integrity: sha512-tIWLooWkBMuoKRk72lr6YrEtVlVdUTtAGVmPOnUroMrnri/9YLx+mVawL0/egDgSGmPbmvkdBFsUGRuI+aZmxg==} + engines: {node: '>=16.7.0'} + '@cloudflare/workers-types@4.20240806.0': resolution: {integrity: sha512-8lvgrwXGTZEBsUQJ8YUnMk72Anh9omwr6fqWLw/EwVgcw1nQxs/bfdadBEbdP48l9fWXjE4E5XERLUrrFuEpsg==} @@ -877,6 +878,10 @@ packages: resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.9.0': + resolution: {integrity: sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/object-schema@2.1.4': resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -908,14 +913,14 @@ packages: '@iconify-json/heroicons@1.1.23': resolution: {integrity: sha512-LLev2ZBBDJKMzjnQgZRhEj0Nkz5m9O4UtQVH2TpPchdXSkxQUUOlPpsM4MVQCs49a2MaJfKiay+48WaZli5cNQ==} - '@iconify-json/logos@1.1.43': - resolution: {integrity: sha512-UtvL1yDHUr9dl1Tqihh6K9m5dmbYKOYyLf3i9aKhymSW76QjOCGjpgQc0PQ4GJCAdU1cAMu+WO61TgPxdonrlg==} + '@iconify-json/logos@1.1.44': + resolution: {integrity: sha512-sIc355/sSq4GihU4eFTDVbXoeg2rZD3yH6tNOJTNouDu9Fx259BSWH+XEEQwm/YImDIllcGqmJuNBjAu4UVs2g==} - '@iconify-json/ph@1.1.13': - resolution: {integrity: sha512-xtM4JJ63HCKj09WRqrBswXiHrpliBlqboWSZH8odcmqYXbvIFceU9/Til4V+MQr6+MoUC+KB72cxhky2+A6r/g==} + '@iconify-json/ph@1.1.14': + resolution: {integrity: sha512-s1hZVaxIpl40qLEhjqPRMcZl4A3M4fZ+77Fi+VuOb/eKkIHIMutAoBHIR+0a3l7psUweZQGj9hSyL2P5CIj6qA==} - '@iconify-json/simple-icons@1.1.111': - resolution: {integrity: sha512-9+d69tCopShQB4a/mlQjP6uqkzJnDfeLNVwly11QMvucLIFfCG08xBXcWSyPCnfsR2bX/G50e43LaUXubNyYuw==} + '@iconify-json/simple-icons@1.1.113': + resolution: {integrity: sha512-XnGdS+JExCxMN5N2r0FXA99NkYkgJUsqiU+7fUauWkImjLgail0OdNUQ2379yRY8wPSTqHxy9eCxaOAWzJ2ZWA==} '@iconify/collections@1.0.444': resolution: {integrity: sha512-3+dA5B8vs+qew23dwBAqv6M4LqtOHlYQiKCproN5o3lLelnA1fnWJMfv5f2RyPecaS9rZEGi1+eg8AFKF2sk1A==} @@ -1033,18 +1038,18 @@ packages: peerDependencies: vite: '*' - '@nuxt/eslint-config@0.4.0': - resolution: {integrity: sha512-1zipkTCSmr4dUHvhgygKVRmgOh73wwBkeZQgJXxB3N7r3FTJOulYfAp30nPLW0NYstyx3cthIJ0kX0KPnbxNVA==} + '@nuxt/eslint-config@0.5.0': + resolution: {integrity: sha512-jG+S9lLIpAHIngJNiEbEMsZlnLEichJ/dZJufPhX/nqZIvbgKNn2eGInbi0bJJbqMnm0qzk7458NUzOhek8ZVw==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@nuxt/eslint-plugin@0.4.0': - resolution: {integrity: sha512-PjNlf99AaSmIu/qwyXTwkEX+xl+RvvfRBvbU/FVDKxwVHH+lNmNM5qlRFf/5PUPAfaEEYUhXqkd/l1DI8hu4Ww==} + '@nuxt/eslint-plugin@0.5.0': + resolution: {integrity: sha512-p0HNkpNxur0DKW3euIR25FgYMSSRp7hkecA0vOdQo+4qTipYLznqj9MjUvRo10CZtS0g9D9Gv5NyIkjPLTMN8A==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@nuxt/eslint@0.4.0': - resolution: {integrity: sha512-UtAt159f3CaQ8RdIeQ01PPafDZR3rn0EdCCA9z7RORdlvLwd9mfea79QwxVccEvZ4cycTwiZWiS3bsd5Oi3Bww==} + '@nuxt/eslint@0.5.0': + resolution: {integrity: sha512-5VA79fN6Dm2N9Hs3921sGdFeWZlJtaf6aDHTGu/X67+hWQZND/KHYxBRx/ShxWlJV4P0JqKp1pHiJIOdopdd8g==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 eslint-webpack-plugin: ^4.1.0 @@ -1070,11 +1075,8 @@ packages: resolution: {integrity: sha512-KH6wxzsNys69daSO0xUv0LEBAfhwwjK1M+0Cdi1/vxmifCslMIY7lN11B4eywSfscbyVPAYJvANyc7XiVPImBQ==} hasBin: true - '@nuxt/ui-pro@1.4.0': - resolution: {integrity: sha512-xo6fbFhAocVgyvDbQK21P+0zQuy9XMNeW65O+czRvJDwlsf9QEqcCF5iGkYIB/5OXk9VYFgYMiHN4fNAyz36ZA==} - - '@nuxt/ui@2.18.3': - resolution: {integrity: sha512-bFy3K0cDPRlEYclQAjIgVFUGFb91sGYAtBmEzunFux85aUw0g4tI7vsWdyVijhKzGOyOjBuLGaG40kGl4AIXpA==} + '@nuxt/ui@2.18.4': + resolution: {integrity: sha512-NzFUzh5Izd7mduhYhFBlIOcqE8aY+9mbSQ0n8sIASpASv162VJ46OsR5Jm5sbfhKDrgv7UsBk6VKXJXiEI7ThQ==} engines: {node: '>=v16.20.2'} '@nuxt/vite-builder@3.12.4': @@ -1351,31 +1353,31 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} - '@stylistic/eslint-plugin-js@2.4.0': - resolution: {integrity: sha512-ScIYDFAwNz+ELr3KfAZMuYMCUq7Q6TdEEIq4RBRR77EHucpDrwi5Kx2d0VdYxb4s4o6nOtSkJmY9MCZupDYJow==} + '@stylistic/eslint-plugin-js@2.6.4': + resolution: {integrity: sha512-kx1hS3xTvzxZLdr/DCU/dLBE++vcP97sHeEFX2QXhk1Ipa4K1rzPOLw1HCbf4mU3s+7kHP5eYpDe+QteEOFLug==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' - '@stylistic/eslint-plugin-jsx@2.4.0': - resolution: {integrity: sha512-yaZXaRj9lOwrQd1YA1d1Ssz58IrDKDYTvLzlKcKED4NlpjDdMbj//Y4DlNhlW9M9v0ZsRsmKNQl2p5OWFfmdEw==} + '@stylistic/eslint-plugin-jsx@2.6.4': + resolution: {integrity: sha512-bIvVhdtjmyu3S10V7QRIuawtCZSq9gRmzAX23ucjCOdSFzEwlq+di0IM0riBAvvQerrJL4SM6G3xgyPs8BSXIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' - '@stylistic/eslint-plugin-plus@2.4.0': - resolution: {integrity: sha512-yqVZ2ps3lSzT3Atcx/jSbzTaRJfxtWeuPk1WvINUod1fRVxNlgKLDwiM+63Hq3Q7H4aM0lS5ccAbFlEGINNg0Q==} + '@stylistic/eslint-plugin-plus@2.6.4': + resolution: {integrity: sha512-EuRvtxhf7Hv8OoMIePulP/6rBJIgPTu1l5GAm1780WcF1Cl8bOZXIn84Pdac5pNv6lVlzCOFm8MD3VE+2YROuA==} peerDependencies: eslint: '*' - '@stylistic/eslint-plugin-ts@2.4.0': - resolution: {integrity: sha512-0zi3hHrrqaXPGZESTfPNUm4YMvxq+aqPGCUiZfEnn7l5VNC19oKaPonZ6LmKzoksebzpJ7w6nieZLVeQm4o7tg==} + '@stylistic/eslint-plugin-ts@2.6.4': + resolution: {integrity: sha512-yxL8Hj6WkObw1jfiLpBzKy5yfxY6vwlwO4miq34ySErUjUecPV5jxfVbOe4q1QDPKemQGPq93v7sAQS5PzM8lA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' - '@stylistic/eslint-plugin@2.4.0': - resolution: {integrity: sha512-GJ86m60wpKPm0m8sSuApOITjCvKUbyzhVO/BTQb7BNYXVUJMS3ql+uAro0V+4yoHwyBVXTB4EDy3UGkOqtEyyw==} + '@stylistic/eslint-plugin@2.6.4': + resolution: {integrity: sha512-euUGnjzH8EOqEYTGk9dB2OBINp0FX1nuO7/k4fO82zNRBIKZgJoDwTLM4Ce+Om6W1Qmh1PrZjCr4jh4tMEXGPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.40.0' @@ -1439,22 +1441,22 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - '@typescript-eslint/eslint-plugin@7.18.0': - resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/eslint-plugin@8.1.0': + resolution: {integrity: sha512-LlNBaHFCEBPHyD4pZXb35mzjGkuGKXU5eeCA1SxvHfiRES0E82dOounfVpL4DCqYvJEKab0bZIA0gCRpdLKkCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@7.18.0': - resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/parser@8.1.0': + resolution: {integrity: sha512-U7iTAtGgJk6DPX9wIWPPOlt1gO57097G06gIcl0N0EEnNw8RGD62c+2/DiP/zL7KrkqnnqF7gtFGR7YgzPllTA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: @@ -1464,11 +1466,14 @@ packages: resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@7.18.0': - resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.1.0': + resolution: {integrity: sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.1.0': + resolution: {integrity: sha512-oLYvTxljVvsMnldfl6jIKxTaU7ok7km0KDrwOt1RHYu6nxlhN3TIx8k5Q52L6wR33nOwDgM7VwW1fT1qMNfFIA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: @@ -1478,6 +1483,10 @@ packages: resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.1.0': + resolution: {integrity: sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@7.18.0': resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1487,16 +1496,35 @@ packages: typescript: optional: true + '@typescript-eslint/typescript-estree@8.1.0': + resolution: {integrity: sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/utils@7.18.0': resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 + '@typescript-eslint/utils@8.1.0': + resolution: {integrity: sha512-ypRueFNKTIFwqPeJBfeIpxZ895PQhNyH4YID6js0UoBImWYoSjBsahUn9KMiJXh94uOjVBgHD9AmkyPsPnFwJA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/visitor-keys@7.18.0': resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@8.1.0': + resolution: {integrity: sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@unhead/dom@1.9.16': resolution: {integrity: sha512-aZIAnnc89Csi1vV4mtlHYI765B7m1yuaXUuQiYHwr6glE9FLyy2X87CzEci4yPH/YbkKm0bGQRfcxXq6Eq0W7g==} @@ -1628,12 +1656,15 @@ packages: '@vue/shared@3.4.34': resolution: {integrity: sha512-x5LmiRLpRsd9KTjAB8MPKf0CDPMcuItjP0gbNqFCIgL1I8iYp4zglhj9w9FPCdIbHG2M91RVeIbArFfFTz9I3A==} - '@vueuse/components@10.11.0': - resolution: {integrity: sha512-ZvLZI23d5ZAtva5fGyYh/jQtZO8l+zJ5tAXyYNqHJZkq1o5yWyqZhENvSv5mfDmN5IuAOp4tq02mRmX/ipFGcg==} + '@vueuse/components@10.11.1': + resolution: {integrity: sha512-ThcreQCX/eq61sLkLKjigD4PQvs3Wy4zglICvQH9tP6xl87y5KsQEoizn6OI+R3hrOgwQHLJe7Y0wLLh3fBKcg==} '@vueuse/core@10.11.0': resolution: {integrity: sha512-x3sD4Mkm7PJ+pcq3HX8PLPBadXCAlSDR/waK87dz0gQE+qJnaaFhc/dZVfJz+IUYzTMVGum2QlR7ImiJQN4s6g==} + '@vueuse/core@10.11.1': + resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} + '@vueuse/integrations@10.11.0': resolution: {integrity: sha512-Pp6MtWEIr+NDOccWd8j59Kpjy5YDXogXI61Kb1JxvSfVBO8NzFQkmrKmSZz47i+ZqHnIzxaT38L358yDHTncZg==} peerDependencies: @@ -1681,9 +1712,15 @@ packages: '@vueuse/metadata@10.11.0': resolution: {integrity: sha512-kQX7l6l8dVWNqlqyN3ePW3KmjCQO3ZMgXuBMddIu83CmucrsBfXlH+JoviYyRBws/yLTQO8g3Pbw+bdIoVm4oQ==} + '@vueuse/metadata@10.11.1': + resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} + '@vueuse/shared@10.11.0': resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==} + '@vueuse/shared@10.11.1': + resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -2408,8 +2445,8 @@ packages: peerDependencies: eslint: ^8.56.0 || ^9.0.0-0 - eslint-plugin-jsdoc@48.10.1: - resolution: {integrity: sha512-dxV7ytazLW9CdPahds07FljQ960vLQG65mUnFi8/6Pc6u6miCZNGYrnKVHrnnrcj+LikhiKAayjrUiNttzRMEg==} + eslint-plugin-jsdoc@48.11.0: + resolution: {integrity: sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==} engines: {node: '>=18'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -2453,10 +2490,15 @@ packages: resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.8.0: - resolution: {integrity: sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==} + eslint@9.9.0: + resolution: {integrity: sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true espree@10.1.0: resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} @@ -2703,8 +2745,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.8.0: - resolution: {integrity: sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==} + globals@15.9.0: + resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} engines: {node: '>=18'} globby@11.1.0: @@ -3213,8 +3255,8 @@ packages: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true - miniflare@3.20240718.1: - resolution: {integrity: sha512-mn3MjGnpgYvarCRTfz4TQyVyY8yW0zz7f8LOAPVai78IGC/lcVcyskZcuIr7Zovb2i+IERmmsJAiEPeZHIIKbA==} + miniflare@3.20240806.1: + resolution: {integrity: sha512-wJq3YQYx9k83L2CNYtxvwWvXSi+uHrC6aFoXYSbzhxIDlUWvMEqippj+3HeKLgsggC31nHJab3b1Pifg9IxIFQ==} engines: {node: '>=16.13'} hasBin: true @@ -3382,8 +3424,8 @@ packages: engines: {node: ^16.10.0 || >=18.0.0} hasBin: true - nuxt-auth-utils@0.3.2: - resolution: {integrity: sha512-A2gRelkEQxLoosIUw6TFFsMaq06XJ6dVdUYKRSKzxfMepBUq5v7GXiw+gZ9TVAXb0YjN9obmqJOBzf2qNI77yw==} + nuxt-auth-utils@0.3.4: + resolution: {integrity: sha512-0CNREFADCyZtyAusV3n27y1jnvt2KjrZI2boaMbKPDWiyI8AcV1jESG1aBFOxyViKsF4YnXRY8QN3EJKYvxMjA==} nuxt@3.12.4: resolution: {integrity: sha512-/ddvyc2kgYYIN2UEjP8QIz48O/W3L0lZm7wChIDbOCj0vF/yLLeZHBaTb3aNvS9Hwp269nfjrm8j/mVxQK4RhA==} @@ -4088,9 +4130,6 @@ packages: smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} - smooth-dnd@0.12.1: - resolution: {integrity: sha512-Dndj/MOG7VP83mvzfGCLGzV2HuK1lWachMtWl/Iuk6zV7noDycIBnflwaPuDzoaapEl3Pc4+ybJArkkx9sxPZg==} - source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -4398,6 +4437,9 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} + unimport@3.10.0: + resolution: {integrity: sha512-/UvKRfWx3mNDWwWQhR62HsoM3wxHwYdTq8ellZzMOHnnw4Dp8tovgthyW7DjTrbjDL+i4idOp06voz2VKlvrLw==} + unimport@3.9.1: resolution: {integrity: sha512-4gtacoNH6YPx2Aa5Xfyrf8pU2RdXjWUACb/eF7bH1AcZtqs+6ijbNB0M3BPENbtVjnCcg8tw9UJ1jQGbCzKA6g==} @@ -4642,11 +4684,6 @@ packages: peerDependencies: typescript: '>=5.0.0' - vue3-smooth-dnd@0.0.6: - resolution: {integrity: sha512-CH9ZZhEfE7qU1ef2rlfgBG+nZtQX8PnWlspB2HDDz1uVGU7fXM0Pr65DftBMz4X81S+edw2H+ZFG6Dyb5J81KA==} - peerDependencies: - vue: ^3.0.11 - vue@3.4.34: resolution: {integrity: sha512-VZze05HWlA3ItreQ/ka7Sx7PoD0/3St8FEiSlSTVgb6l4hL+RjtP2/8g5WQBzZgyf8WG2f+g1bXzC7zggLhAJA==} peerDependencies: @@ -4685,17 +4722,17 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - workerd@1.20240718.0: - resolution: {integrity: sha512-w7lOLRy0XecQTg/ujTLWBiJJuoQvzB3CdQ6/8Wgex3QxFhV9Pbnh3UbwIuUfMw3OCCPQc4o7y+1P+mISAgp6yg==} + workerd@1.20240806.0: + resolution: {integrity: sha512-yyNtyzTMgVY0sgYijHBONqZFVXsOFGj2jDjS8MF/RbO2ZdGROvs4Hkc/9QnmqFWahE0STxXeJ1yW1yVotdF0UQ==} engines: {node: '>=16'} hasBin: true - wrangler@3.67.1: - resolution: {integrity: sha512-lLVJxq/OZMfntvZ79WQJNC1OKfxOCs6PLfogqDBuPFEQ3L/Mwqvd9IZ0bB8ahrwUN/K3lSdDPXynk9HfcGZxVw==} + wrangler@3.72.0: + resolution: {integrity: sha512-9sryHTCtCj48vUC5y/M3Dsx02U1bT6mK9E41TXBCpSJgWh8UvWG/xgmu2dY93Mqj9aJIvK/kwwIBRlNFRwF7Hw==} engines: {node: '>=16.17.0'} hasBin: true peerDependencies: - '@cloudflare/workers-types': ^4.20240718.0 + '@cloudflare/workers-types': ^4.20240806.0 peerDependenciesMeta: '@cloudflare/workers-types': optional: true @@ -5013,21 +5050,23 @@ snapshots: dependencies: mime: 3.0.0 - '@cloudflare/workerd-darwin-64@1.20240718.0': + '@cloudflare/workerd-darwin-64@1.20240806.0': optional: true - '@cloudflare/workerd-darwin-arm64@1.20240718.0': + '@cloudflare/workerd-darwin-arm64@1.20240806.0': optional: true - '@cloudflare/workerd-linux-64@1.20240718.0': + '@cloudflare/workerd-linux-64@1.20240806.0': optional: true - '@cloudflare/workerd-linux-arm64@1.20240718.0': + '@cloudflare/workerd-linux-arm64@1.20240806.0': optional: true - '@cloudflare/workerd-windows-64@1.20240718.0': + '@cloudflare/workerd-windows-64@1.20240806.0': optional: true + '@cloudflare/workers-shared@0.2.0': {} + '@cloudflare/workers-types@4.20240806.0': {} '@cspotcode/source-map-support@0.8.1': @@ -5334,9 +5373,9 @@ snapshots: '@esbuild/win32-x64@0.23.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.8.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.9.0(jiti@1.21.6))': dependencies: - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.11.0': {} @@ -5349,7 +5388,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-inspector@0.5.2(eslint@9.8.0)': + '@eslint/config-inspector@0.5.2(eslint@9.9.0(jiti@1.21.6))': dependencies: '@eslint/config-array': 0.17.1 '@voxpelli/config-array-find-files': 0.1.2(@eslint/config-array@0.17.1) @@ -5357,7 +5396,7 @@ snapshots: cac: 6.7.14 chokidar: 3.6.0 esbuild: 0.21.5 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) fast-glob: 3.3.2 find-up: 7.0.0 get-port-please: 3.1.2 @@ -5390,6 +5429,8 @@ snapshots: '@eslint/js@9.8.0': {} + '@eslint/js@9.9.0': {} + '@eslint/object-schema@2.1.4': {} '@fastify/busboy@2.1.1': {} @@ -5411,15 +5452,15 @@ snapshots: dependencies: '@iconify/types': 2.0.0 - '@iconify-json/logos@1.1.43': + '@iconify-json/logos@1.1.44': dependencies: '@iconify/types': 2.0.0 - '@iconify-json/ph@1.1.13': + '@iconify-json/ph@1.1.14': dependencies: '@iconify/types': 2.0.0 - '@iconify-json/simple-icons@1.1.111': + '@iconify-json/simple-icons@1.1.113': dependencies: '@iconify/types': 2.0.0 @@ -5626,56 +5667,56 @@ snapshots: - supports-color - utf-8-validate - '@nuxt/eslint-config@0.4.0(eslint@9.8.0)(typescript@5.4.5)': + '@nuxt/eslint-config@0.5.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: '@eslint/js': 9.8.0 - '@nuxt/eslint-plugin': 0.4.0(eslint@9.8.0)(typescript@5.4.5) + '@nuxt/eslint-plugin': 0.5.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) '@rushstack/eslint-patch': 1.10.4 - '@stylistic/eslint-plugin': 2.4.0(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - eslint: 9.8.0 + '@stylistic/eslint-plugin': 2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/parser': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + eslint: 9.9.0(jiti@1.21.6) eslint-config-flat-gitignore: 0.1.8 eslint-flat-config-utils: 0.3.0 - eslint-plugin-import-x: 3.1.0(eslint@9.8.0)(typescript@5.4.5) - eslint-plugin-jsdoc: 48.10.1(eslint@9.8.0) - eslint-plugin-regexp: 2.6.0(eslint@9.8.0) - eslint-plugin-unicorn: 55.0.0(eslint@9.8.0) - eslint-plugin-vue: 9.27.0(eslint@9.8.0) - globals: 15.8.0 + eslint-plugin-import-x: 3.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + eslint-plugin-jsdoc: 48.11.0(eslint@9.9.0(jiti@1.21.6)) + eslint-plugin-regexp: 2.6.0(eslint@9.9.0(jiti@1.21.6)) + eslint-plugin-unicorn: 55.0.0(eslint@9.9.0(jiti@1.21.6)) + eslint-plugin-vue: 9.27.0(eslint@9.9.0(jiti@1.21.6)) + globals: 15.9.0 local-pkg: 0.5.0 pathe: 1.1.2 tslib: 2.6.3 - vue-eslint-parser: 9.4.3(eslint@9.8.0) + vue-eslint-parser: 9.4.3(eslint@9.9.0(jiti@1.21.6)) transitivePeerDependencies: - supports-color - typescript - '@nuxt/eslint-plugin@0.4.0(eslint@9.8.0)(typescript@5.4.5)': + '@nuxt/eslint-plugin@0.5.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - eslint: 9.8.0 + '@typescript-eslint/types': 8.1.0 + '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + eslint: 9.9.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript - '@nuxt/eslint@0.4.0(eslint@9.8.0)(magicast@0.3.4)(rollup@4.19.1)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))': + '@nuxt/eslint@0.5.0(eslint@9.9.0(jiti@1.21.6))(magicast@0.3.4)(rollup@4.19.1)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))': dependencies: - '@eslint/config-inspector': 0.5.2(eslint@9.8.0) + '@eslint/config-inspector': 0.5.2(eslint@9.9.0(jiti@1.21.6)) '@nuxt/devtools-kit': 1.3.9(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3)) - '@nuxt/eslint-config': 0.4.0(eslint@9.8.0)(typescript@5.4.5) - '@nuxt/eslint-plugin': 0.4.0(eslint@9.8.0)(typescript@5.4.5) + '@nuxt/eslint-config': 0.5.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + '@nuxt/eslint-plugin': 0.5.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.19.1) chokidar: 3.6.0 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) eslint-flat-config-utils: 0.3.0 - eslint-typegen: 0.3.0(eslint@9.8.0) + eslint-typegen: 0.3.0(eslint@9.9.0(jiti@1.21.6)) find-up: 7.0.0 get-port-please: 3.1.2 mlly: 1.7.1 pathe: 1.1.2 - unimport: 3.9.1(rollup@4.19.1) + unimport: 3.10.0(rollup@4.19.1) transitivePeerDependencies: - bufferutil - magicast @@ -5774,40 +5815,7 @@ snapshots: - rollup - supports-color - '@nuxt/ui-pro@1.4.0(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5))': - dependencies: - '@nuxt/ui': 2.18.3(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5)) - '@vueuse/core': 10.11.0(vue@3.4.34(typescript@5.4.5)) - defu: 6.1.4 - git-url-parse: 14.1.0 - ofetch: 1.3.4 - parse-git-config: 3.0.0 - pathe: 1.1.2 - pkg-types: 1.1.3 - tailwind-merge: 2.4.0 - vue3-smooth-dnd: 0.0.6(vue@3.4.34(typescript@5.4.5)) - transitivePeerDependencies: - - '@vue/composition-api' - - async-validator - - axios - - change-case - - drauu - - focus-trap - - idb-keyval - - jwt-decode - - magicast - - nprogress - - qrcode - - rollup - - sortablejs - - supports-color - - ts-node - - uWebSockets.js - - universal-cookie - - vite - - vue - - '@nuxt/ui@2.18.3(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5))': + '@nuxt/ui@2.18.4(focus-trap@7.5.4)(magicast@0.3.4)(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue@3.4.34(typescript@5.4.5))': dependencies: '@headlessui/tailwindcss': 0.2.1(tailwindcss@3.4.7) '@headlessui/vue': 1.7.22(vue@3.4.34(typescript@5.4.5)) @@ -5821,7 +5829,7 @@ snapshots: '@tailwindcss/container-queries': 0.1.1(tailwindcss@3.4.7) '@tailwindcss/forms': 0.5.7(tailwindcss@3.4.7) '@tailwindcss/typography': 0.5.13(tailwindcss@3.4.7) - '@vueuse/core': 10.11.0(vue@3.4.34(typescript@5.4.5)) + '@vueuse/core': 10.11.1(vue@3.4.34(typescript@5.4.5)) '@vueuse/integrations': 10.11.0(focus-trap@7.5.4)(fuse.js@6.6.2)(vue@3.4.34(typescript@5.4.5)) '@vueuse/math': 10.11.0(vue@3.4.34(typescript@5.4.5)) defu: 6.1.4 @@ -5852,7 +5860,7 @@ snapshots: - vite - vue - '@nuxt/vite-builder@3.12.4(@types/node@22.0.0)(eslint@9.8.0)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vue-tsc@2.0.29(typescript@5.4.5))(vue@3.4.34(typescript@5.4.5))': + '@nuxt/vite-builder@3.12.4(@types/node@22.0.0)(eslint@9.9.0(jiti@1.21.6))(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vue-tsc@2.0.29(typescript@5.4.5))(vue@3.4.34(typescript@5.4.5))': dependencies: '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.19.1) '@rollup/plugin-replace': 5.0.7(rollup@4.19.1) @@ -5885,7 +5893,7 @@ snapshots: unplugin: 1.12.0 vite: 5.3.5(@types/node@22.0.0)(terser@5.31.3) vite-node: 2.0.4(@types/node@22.0.0)(terser@5.31.3) - vite-plugin-checker: 0.7.2(eslint@9.8.0)(optionator@0.9.4)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)) + vite-plugin-checker: 0.7.2(eslint@9.9.0(jiti@1.21.6))(optionator@0.9.4)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)) vue: 3.4.34(typescript@5.4.5) vue-bundle-renderer: 2.1.0 transitivePeerDependencies: @@ -6174,49 +6182,47 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} - '@stylistic/eslint-plugin-js@2.4.0(eslint@9.8.0)': + '@stylistic/eslint-plugin-js@2.6.4(eslint@9.9.0(jiti@1.21.6))': dependencies: '@types/eslint': 9.6.0 acorn: 8.12.1 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) eslint-visitor-keys: 4.0.0 espree: 10.1.0 - '@stylistic/eslint-plugin-jsx@2.4.0(eslint@9.8.0)': + '@stylistic/eslint-plugin-jsx@2.6.4(eslint@9.9.0(jiti@1.21.6))': dependencies: - '@stylistic/eslint-plugin-js': 2.4.0(eslint@9.8.0) + '@stylistic/eslint-plugin-js': 2.6.4(eslint@9.9.0(jiti@1.21.6)) '@types/eslint': 9.6.0 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 estraverse: 5.3.0 picomatch: 4.0.2 - '@stylistic/eslint-plugin-plus@2.4.0(eslint@9.8.0)(typescript@5.4.5)': + '@stylistic/eslint-plugin-plus@2.6.4(eslint@9.9.0(jiti@1.21.6))': dependencies: '@types/eslint': 9.6.0 - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - eslint: 9.8.0 - transitivePeerDependencies: - - supports-color - - typescript + eslint: 9.9.0(jiti@1.21.6) - '@stylistic/eslint-plugin-ts@2.4.0(eslint@9.8.0)(typescript@5.4.5)': + '@stylistic/eslint-plugin-ts@2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@stylistic/eslint-plugin-js': 2.4.0(eslint@9.8.0) + '@stylistic/eslint-plugin-js': 2.6.4(eslint@9.9.0(jiti@1.21.6)) '@types/eslint': 9.6.0 - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - eslint: 9.8.0 + '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + eslint: 9.9.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript - '@stylistic/eslint-plugin@2.4.0(eslint@9.8.0)(typescript@5.4.5)': + '@stylistic/eslint-plugin@2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@stylistic/eslint-plugin-js': 2.4.0(eslint@9.8.0) - '@stylistic/eslint-plugin-jsx': 2.4.0(eslint@9.8.0) - '@stylistic/eslint-plugin-plus': 2.4.0(eslint@9.8.0)(typescript@5.4.5) - '@stylistic/eslint-plugin-ts': 2.4.0(eslint@9.8.0)(typescript@5.4.5) + '@stylistic/eslint-plugin-js': 2.6.4(eslint@9.9.0(jiti@1.21.6)) + '@stylistic/eslint-plugin-jsx': 2.6.4(eslint@9.9.0(jiti@1.21.6)) + '@stylistic/eslint-plugin-plus': 2.6.4(eslint@9.9.0(jiti@1.21.6)) + '@stylistic/eslint-plugin-ts': 2.6.4(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) '@types/eslint': 9.6.0 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript @@ -6278,15 +6284,15 @@ snapshots: '@types/web-bluetooth@0.0.20': {} - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.8.0)(typescript@5.4.5))(eslint@9.8.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@8.1.0(@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5))(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 9.8.0 + '@typescript-eslint/parser': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/scope-manager': 8.1.0 + '@typescript-eslint/type-utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 8.1.0 + eslint: 9.9.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 @@ -6296,14 +6302,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@9.8.0)(typescript@5.4.5)': + '@typescript-eslint/parser@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.18.0 + '@typescript-eslint/scope-manager': 8.1.0 + '@typescript-eslint/types': 8.1.0 + '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 8.1.0 debug: 4.3.6 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: @@ -6314,20 +6320,27 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/type-utils@7.18.0(eslint@9.8.0)(typescript@5.4.5)': + '@typescript-eslint/scope-manager@8.1.0': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) + '@typescript-eslint/types': 8.1.0 + '@typescript-eslint/visitor-keys': 8.1.0 + + '@typescript-eslint/type-utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.4.5) + '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) debug: 4.3.6 - eslint: 9.8.0 ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: + - eslint - supports-color '@typescript-eslint/types@7.18.0': {} + '@typescript-eslint/types@8.1.0': {} + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.4.5)': dependencies: '@typescript-eslint/types': 7.18.0 @@ -6343,13 +6356,39 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@9.8.0)(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@8.1.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 8.1.0 + '@typescript-eslint/visitor-keys': 8.1.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.6)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.4.5) - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.6)) + '@typescript-eslint/scope-manager': 8.1.0 + '@typescript-eslint/types': 8.1.0 + '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.4.5) + eslint: 9.9.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript @@ -6359,6 +6398,11 @@ snapshots: '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@8.1.0': + dependencies: + '@typescript-eslint/types': 8.1.0 + eslint-visitor-keys: 3.4.3 + '@unhead/dom@1.9.16': dependencies: '@unhead/schema': 1.9.16 @@ -6579,10 +6623,10 @@ snapshots: '@vue/shared@3.4.34': {} - '@vueuse/components@10.11.0(vue@3.4.34(typescript@5.4.5))': + '@vueuse/components@10.11.1(vue@3.4.34(typescript@5.4.5))': dependencies: - '@vueuse/core': 10.11.0(vue@3.4.34(typescript@5.4.5)) - '@vueuse/shared': 10.11.0(vue@3.4.34(typescript@5.4.5)) + '@vueuse/core': 10.11.1(vue@3.4.34(typescript@5.4.5)) + '@vueuse/shared': 10.11.1(vue@3.4.34(typescript@5.4.5)) vue-demi: 0.14.10(vue@3.4.34(typescript@5.4.5)) transitivePeerDependencies: - '@vue/composition-api' @@ -6598,6 +6642,16 @@ snapshots: - '@vue/composition-api' - vue + '@vueuse/core@10.11.1(vue@3.4.34(typescript@5.4.5))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.11.1 + '@vueuse/shared': 10.11.1(vue@3.4.34(typescript@5.4.5)) + vue-demi: 0.14.10(vue@3.4.34(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + '@vueuse/integrations@10.11.0(focus-trap@7.5.4)(fuse.js@6.6.2)(vue@3.4.34(typescript@5.4.5))': dependencies: '@vueuse/core': 10.11.0(vue@3.4.34(typescript@5.4.5)) @@ -6620,6 +6674,8 @@ snapshots: '@vueuse/metadata@10.11.0': {} + '@vueuse/metadata@10.11.1': {} + '@vueuse/shared@10.11.0(vue@3.4.34(typescript@5.4.5))': dependencies: vue-demi: 0.14.10(vue@3.4.34(typescript@5.4.5)) @@ -6627,6 +6683,13 @@ snapshots: - '@vue/composition-api' - vue + '@vueuse/shared@10.11.1(vue@3.4.34(typescript@5.4.5))': + dependencies: + vue-demi: 0.14.10(vue@3.4.34(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + abbrev@1.1.1: {} abort-controller@3.0.0: @@ -7365,12 +7428,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import-x@3.1.0(eslint@9.8.0)(typescript@5.4.5): + eslint-plugin-import-x@3.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5): dependencies: - '@typescript-eslint/utils': 7.18.0(eslint@9.8.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.18.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.4.5) debug: 4.3.6 doctrine: 3.0.0 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 get-tsconfig: 4.7.6 is-glob: 4.0.3 @@ -7382,14 +7445,14 @@ snapshots: - supports-color - typescript - eslint-plugin-jsdoc@48.10.1(eslint@9.8.0): + eslint-plugin-jsdoc@48.11.0(eslint@9.9.0(jiti@1.21.6)): dependencies: '@es-joy/jsdoccomment': 0.46.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 debug: 4.3.6 escape-string-regexp: 4.0.0 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) espree: 10.1.0 esquery: 1.6.0 parse-imports: 2.1.1 @@ -7399,27 +7462,27 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-regexp@2.6.0(eslint@9.8.0): + eslint-plugin-regexp@2.6.0(eslint@9.9.0(jiti@1.21.6)): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.6)) '@eslint-community/regexpp': 4.11.0 comment-parser: 1.4.1 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) jsdoc-type-pratt-parser: 4.0.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-unicorn@55.0.0(eslint@9.8.0): + eslint-plugin-unicorn@55.0.0(eslint@9.9.0(jiti@1.21.6)): dependencies: '@babel/helper-validator-identifier': 7.24.7 - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.6)) ci-info: 4.0.0 clean-regexp: 1.0.0 core-js-compat: 3.37.1 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) esquery: 1.6.0 - globals: 15.8.0 + globals: 15.9.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 jsesc: 3.0.2 @@ -7430,16 +7493,16 @@ snapshots: semver: 7.6.3 strip-indent: 3.0.0 - eslint-plugin-vue@9.27.0(eslint@9.8.0): + eslint-plugin-vue@9.27.0(eslint@9.9.0(jiti@1.21.6)): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) - eslint: 9.8.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.6)) + eslint: 9.9.0(jiti@1.21.6) globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.1 semver: 7.6.3 - vue-eslint-parser: 9.4.3(eslint@9.8.0) + vue-eslint-parser: 9.4.3(eslint@9.9.0(jiti@1.21.6)) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -7454,10 +7517,10 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-typegen@0.3.0(eslint@9.8.0): + eslint-typegen@0.3.0(eslint@9.9.0(jiti@1.21.6)): dependencies: '@types/eslint': 9.6.0 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) json-schema-to-typescript-lite: 14.0.1 ohash: 1.1.3 @@ -7465,13 +7528,13 @@ snapshots: eslint-visitor-keys@4.0.0: {} - eslint@9.8.0: + eslint@9.9.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.0(jiti@1.21.6)) '@eslint-community/regexpp': 4.11.0 '@eslint/config-array': 0.17.1 '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.8.0 + '@eslint/js': 9.9.0 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 @@ -7501,6 +7564,8 @@ snapshots: optionator: 0.9.4 strip-ansi: 6.0.1 text-table: 0.2.0 + optionalDependencies: + jiti: 1.21.6 transitivePeerDependencies: - supports-color @@ -7785,7 +7850,7 @@ snapshots: globals@14.0.0: {} - globals@15.8.0: {} + globals@15.9.0: {} globby@11.1.0: dependencies: @@ -8279,7 +8344,7 @@ snapshots: mini-svg-data-uri@1.4.4: {} - miniflare@3.20240718.1: + miniflare@3.20240806.1: dependencies: '@cspotcode/source-map-support': 0.8.1 acorn: 8.12.1 @@ -8289,7 +8354,7 @@ snapshots: glob-to-regexp: 0.4.1 stoppable: 1.1.0 undici: 5.28.4 - workerd: 1.20240718.0 + workerd: 1.20240806.0 ws: 8.18.0 youch: 3.3.3 zod: 3.23.8 @@ -8517,7 +8582,7 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - nuxt-auth-utils@0.3.2(magicast@0.3.4)(rollup@4.19.1): + nuxt-auth-utils@0.3.4(magicast@0.3.4)(rollup@4.19.1): dependencies: '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.19.1) defu: 6.1.4 @@ -8531,14 +8596,14 @@ snapshots: - rollup - supports-color - nuxt@3.12.4(@parcel/watcher@2.4.1)(@types/node@22.0.0)(encoding@0.1.13)(eslint@9.8.0)(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)): + nuxt@3.12.4(@parcel/watcher@2.4.1)(@types/node@22.0.0)(encoding@0.1.13)(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)): dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/devtools': 1.3.9(rollup@4.19.1)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3)) '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.19.1) '@nuxt/schema': 3.12.4(rollup@4.19.1) '@nuxt/telemetry': 2.5.4(magicast@0.3.4)(rollup@4.19.1) - '@nuxt/vite-builder': 3.12.4(@types/node@22.0.0)(eslint@9.8.0)(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vue-tsc@2.0.29(typescript@5.4.5))(vue@3.4.34(typescript@5.4.5)) + '@nuxt/vite-builder': 3.12.4(@types/node@22.0.0)(eslint@9.9.0(jiti@1.21.6))(magicast@0.3.4)(optionator@0.9.4)(rollup@4.19.1)(terser@5.31.3)(typescript@5.4.5)(vue-tsc@2.0.29(typescript@5.4.5))(vue@3.4.34(typescript@5.4.5)) '@unhead/dom': 1.9.16 '@unhead/ssr': 1.9.16 '@unhead/vue': 1.9.16(vue@3.4.34(typescript@5.4.5)) @@ -9325,8 +9390,6 @@ snapshots: smob@1.5.0: {} - smooth-dnd@0.12.1: {} - source-map-js@1.2.0: {} source-map-support@0.5.21: @@ -9655,6 +9718,24 @@ snapshots: unicorn-magic@0.1.0: {} + unimport@3.10.0(rollup@4.19.1): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.19.1) + acorn: 8.12.1 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.11 + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.1.3 + scule: 1.3.0 + strip-literal: 2.1.0 + unplugin: 1.12.0 + transitivePeerDependencies: + - rollup + unimport@3.9.1(rollup@4.19.1): dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.19.1) @@ -9791,7 +9872,7 @@ snapshots: - supports-color - terser - vite-plugin-checker@0.7.2(eslint@9.8.0)(optionator@0.9.4)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)): + vite-plugin-checker@0.7.2(eslint@9.9.0(jiti@1.21.6))(optionator@0.9.4)(typescript@5.4.5)(vite@5.3.5(@types/node@22.0.0)(terser@5.31.3))(vue-tsc@2.0.29(typescript@5.4.5)): dependencies: '@babel/code-frame': 7.24.7 ansi-escapes: 4.3.2 @@ -9809,7 +9890,7 @@ snapshots: vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 optionalDependencies: - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) optionator: 0.9.4 typescript: 5.4.5 vue-tsc: 2.0.29(typescript@5.4.5) @@ -9890,10 +9971,10 @@ snapshots: vue-devtools-stub@0.1.0: {} - vue-eslint-parser@9.4.3(eslint@9.8.0): + vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6)): dependencies: debug: 4.3.6 - eslint: 9.8.0 + eslint: 9.9.0(jiti@1.21.6) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -9915,11 +9996,6 @@ snapshots: semver: 7.6.3 typescript: 5.4.5 - vue3-smooth-dnd@0.0.6(vue@3.4.34(typescript@5.4.5)): - dependencies: - smooth-dnd: 0.12.1 - vue: 3.4.34(typescript@5.4.5) - vue@3.4.34(typescript@5.4.5): dependencies: '@vue/compiler-dom': 3.4.34 @@ -9955,24 +10031,25 @@ snapshots: word-wrap@1.2.5: {} - workerd@1.20240718.0: + workerd@1.20240806.0: optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20240718.0 - '@cloudflare/workerd-darwin-arm64': 1.20240718.0 - '@cloudflare/workerd-linux-64': 1.20240718.0 - '@cloudflare/workerd-linux-arm64': 1.20240718.0 - '@cloudflare/workerd-windows-64': 1.20240718.0 + '@cloudflare/workerd-darwin-64': 1.20240806.0 + '@cloudflare/workerd-darwin-arm64': 1.20240806.0 + '@cloudflare/workerd-linux-64': 1.20240806.0 + '@cloudflare/workerd-linux-arm64': 1.20240806.0 + '@cloudflare/workerd-windows-64': 1.20240806.0 - wrangler@3.67.1(@cloudflare/workers-types@4.20240806.0): + wrangler@3.72.0(@cloudflare/workers-types@4.20240806.0): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 + '@cloudflare/workers-shared': 0.2.0 '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) blake3-wasm: 2.1.5 chokidar: 3.6.0 date-fns: 3.6.0 esbuild: 0.17.19 - miniflare: 3.20240718.1 + miniflare: 3.20240806.1 nanoid: 3.3.7 path-to-regexp: 6.2.2 resolve: 1.22.8 @@ -9980,7 +10057,7 @@ snapshots: selfsigned: 2.4.1 source-map: 0.6.1 unenv: unenv-nightly@1.10.0-1717606461.a117952 - workerd: 1.20240718.0 + workerd: 1.20240806.0 xxhash-wasm: 1.0.2 optionalDependencies: '@cloudflare/workers-types': 4.20240806.0 diff --git a/server/api/drawings.get.ts b/server/api/drawings.get.ts index 8a5dc9f..4fdca43 100644 --- a/server/api/drawings.get.ts +++ b/server/api/drawings.get.ts @@ -3,6 +3,7 @@ export default eventHandler(async (event) => { return hubBlob().list({ limit: 100, - cursor + cursor, + prefix: 'drawings/', }) }) diff --git a/server/api/generate.post.ts b/server/api/generate.post.ts new file mode 100644 index 0000000..5364bf6 --- /dev/null +++ b/server/api/generate.post.ts @@ -0,0 +1,30 @@ +/** + * Generate a new image based on the drawing using AI + * Used in the `` component. + * Uncomment it in pages/draw.vue to enable the AI description feature. + */ +export default eventHandler(async (event) => { + await requireUserSession(event) + + // Get the drawing and convert it to a array buffer + const form = await readFormData(event) + const drawing = form.get('drawing') as File + const arrayBuffer = await drawing.arrayBuffer() + + // Ask LLaVA to describe the drawing + const { description } = await hubAI().run('@cf/llava-hf/llava-1.5-7b-hf', { + prompt: 'Describe this drawing in one sentence.', + image: [...new Uint8Array(arrayBuffer)], + }).catch(() => { + return { description: '' } + }) + + setHeader(event, 'content-type', 'image/png') + setHeader(event, 'x-description', description) + return await hubAI().run('@cf/runwayml/stable-diffusion-v1-5-img2img', { + prompt: description || 'Make it a painting.', + guidance: 8, + strength: 0.75, + image: [...new Uint8Array(arrayBuffer)], + }) +}) diff --git a/server/api/upload.post.ts b/server/api/upload.post.ts index 1c65588..dc95c1d 100644 --- a/server/api/upload.post.ts +++ b/server/api/upload.post.ts @@ -3,8 +3,11 @@ export default eventHandler(async (event) => { const { user } = await requireUserSession(event) // Check last image author - const { blobs } = await hubBlob().list({ limit: 1 }) - if (blobs.length) { + const { blobs } = await hubBlob().list({ + prefix: 'drawings/', + limit: 1, + }) + if (!import.meta.dev && blobs.length) { const [lastDrawing] = blobs if (lastDrawing.customMetadata?.userId === user.id) { throw createError({ @@ -23,13 +26,45 @@ export default eventHandler(async (event) => { types: ['image/jpeg'], }) + // Ask LLaVA to describe the drawing + const { description } = await hubAI().run('@cf/llava-hf/llava-1.5-7b-hf', { + prompt: 'Describe this drawing in one sentence.', + image: [...new Uint8Array(await drawing.arrayBuffer())], + }).catch(() => { + return { description: '' } + }) + // Create a new pathname to be smaller than the last one uploaded // So the blob listing will send the last uploaded image at first // We use the timestamp in 2050 minus the current timestamp // So this project will start to be buggy in 2050, sorry for that - const pathname = `${new Date('2050-01-01').getTime() - Date.now()}.jpg` + const name = `${new Date('2050-01-01').getTime() - Date.now()}` + + // Generate an image with AI + const aiImage = await hubAI().run('@cf/runwayml/stable-diffusion-v1-5-img2img', { + prompt: description || 'A drawing', + guidance: 8, + strength: 0.75, + image: [...new Uint8Array(await drawing.arrayBuffer())], + }) + .then((blob: Blob | Uint8Array) => { + if (blob instanceof Uint8Array) { + blob = new Blob([blob]) + } + // If black image, skip + if (blob.size === 842) { + return null + } + return hubBlob().put(`${name}.png`, blob, { + prefix: 'ai/', + addRandomSuffix: true, + contentType: 'image/png', + }) + }) + .catch(() => null) - return hubBlob().put(pathname, drawing, { + return hubBlob().put(`${name}.jpg`, drawing, { + prefix: 'drawings/', addRandomSuffix: true, customMetadata: { userProvider: user.provider, @@ -37,6 +72,8 @@ export default eventHandler(async (event) => { userName: user.name, userAvatar: user.avatar, userUrl: user.url, + description: description.trim(), + aiImage: aiImage ? aiImage.pathname : '', }, }) }) diff --git a/server/routes/auth/anonymous.get.ts b/server/routes/auth/anonymous.get.ts new file mode 100644 index 0000000..317a49b --- /dev/null +++ b/server/routes/auth/anonymous.get.ts @@ -0,0 +1,25 @@ +export default eventHandler(async (event) => { + const runtimeConfig = useRuntimeConfig() + + if (runtimeConfig.public.googleAuth || runtimeConfig.public.githubAuth) { + throw createError({ + statusCode: 400, + message: 'Please use Google or GitHub auth', + }) + } + const fingerprint = await getRequestFingerprint(event, { + userAgent: true, + xForwardedFor: true, + }) + await setUserSession(event, { + user: { + provider: 'anonymous', + id: fingerprint || 'anonymous', + name: `${event.context.cf?.city}, ${event.context.cf?.country}`, + avatar: '', + url: '', + }, + }) + + return sendRedirect(event, '/draw') +}) diff --git a/types/auth.d.ts b/types/auth.d.ts index 9402b0f..78b3ba0 100644 --- a/types/auth.d.ts +++ b/types/auth.d.ts @@ -1,6 +1,6 @@ declare module '#auth-utils' { interface User { - provider: 'github' | 'google' + provider: 'github' | 'google' | 'anonymous' id: string name: string avatar: string