diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 026adb55..ce96f8de 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ on: branches: [main] env: - NODE_VER: 22.5 + NODE_VER: 22.11 CI: true jobs: @@ -37,6 +37,9 @@ jobs: # Check linting and typing - run: pnpm lint - run: pnpm typecheck + + # Run unit tests + - run: pnpm test:unit # Check building - run: pnpm build @@ -131,5 +134,5 @@ jobs: # start prod-app and curl from it - run: "timeout 60 pnpm start & (sleep 45 && curl --fail localhost:$PORT)" env: - AUTH_ORIGIN: "http://localhost:3001" + AUTH_ORIGIN: "http://localhost:3001/api/auth" PORT: 3001 diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 22dcdc09..796168d1 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: env: - NODE_VER: 22.5 + NODE_VER: 22.11 CI: true # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages diff --git a/.github/workflows/pkg.pr.new.yml b/.github/workflows/pkg.pr.new.yml index b18c86b2..f89ccab1 100644 --- a/.github/workflows/pkg.pr.new.yml +++ b/.github/workflows/pkg.pr.new.yml @@ -8,7 +8,7 @@ on: pull_request: env: - NODE_VER: 22.5 + NODE_VER: 22.11 jobs: build: diff --git a/docs/guide/application-side/protecting-pages.md b/docs/guide/application-side/protecting-pages.md index 0df29fd0..e8fe50e6 100644 --- a/docs/guide/application-side/protecting-pages.md +++ b/docs/guide/application-side/protecting-pages.md @@ -32,7 +32,7 @@ If the global middleware is disabled, you can manually add the middleware to ind ```vue diff --git a/package.json b/package.json index b3031ca8..08de9bc7 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "dev:prepare": "nuxt-module-build build --stub", "docs:dev": "vitepress dev docs", "docs:build": "vitepress build docs", - "docs:preview": "vitepress preview docs" + "docs:preview": "vitepress preview docs", + "test:unit": "vitest" }, "dependencies": { "@nuxt/kit": "^3.12.4", @@ -61,6 +62,7 @@ "ts-essentials": "^9.4.2", "typescript": "^5.5.4", "vitepress": "^1.3.1", + "vitest": "^1.6.0", "vue-tsc": "^2.0.29" }, "packageManager": "pnpm@9.6.0+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e" diff --git a/playground-authjs/nuxt.config.ts b/playground-authjs/nuxt.config.ts index b242884f..b48a7c7a 100644 --- a/playground-authjs/nuxt.config.ts +++ b/playground-authjs/nuxt.config.ts @@ -8,7 +8,7 @@ export default defineNuxtConfig({ globalAppMiddleware: { isEnabled: true }, - baseURL: `http://localhost:${process.env.PORT || 3000}` + baseURL: `http://localhost:${process.env.PORT || 3000}/api/auth` }, routeRules: { '/with-caching': { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf18e7e7..b9f03d36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@nuxt/kit': specifier: ^3.12.4 - version: 3.12.4(magicast@0.3.5)(rollup@4.25.0) + version: 3.12.4(magicast@0.3.5)(rollup@4.28.1) defu: specifier: ^6.1.4 version: 6.1.4 @@ -25,7 +25,7 @@ importers: version: 4.21.1(next@13.5.6(@babel/core@7.26.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) nitropack: specifier: ^2.10.4 - version: 2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3) + version: 2.10.4(encoding@0.1.13)(typescript@5.5.4) requrl: specifier: ^3.0.2 version: 3.0.2 @@ -41,10 +41,10 @@ importers: version: 2.25.0(@vue/compiler-sfc@3.4.35)(eslint@8.57.0)(typescript@5.5.4)(vitest@1.6.0(@types/node@18.19.42)(terser@5.30.3)) '@nuxt/module-builder': specifier: ^0.8.3 - version: 0.8.3(@nuxt/kit@3.12.4(magicast@0.3.5)(rollup@4.25.0))(nuxi@3.12.0)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4)) + version: 0.8.3(@nuxt/kit@3.12.4(magicast@0.3.5)(rollup@4.28.1))(nuxi@3.12.0)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4)) '@nuxt/schema': specifier: ^3.12.4 - version: 3.12.4(rollup@4.25.0) + version: 3.12.4(rollup@4.28.1) '@nuxtjs/eslint-config-typescript': specifier: ^12.1.0 version: 12.1.0(eslint@8.57.0)(typescript@5.5.4) @@ -56,7 +56,7 @@ importers: version: 8.57.0 nuxt: specifier: ^3.12.4 - version: 3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.42)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)) + version: 3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.42)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)) ofetch: specifier: ^1.3.4 version: 1.3.4 @@ -72,6 +72,9 @@ importers: vitepress: specifier: ^1.3.1 version: 1.3.1(@algolia/client-search@4.24.0)(@types/node@18.19.42)(postcss@8.4.40)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(search-insights@2.14.0)(terser@5.30.3)(typescript@5.5.4) + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@18.19.42)(terser@5.30.3) vue-tsc: specifier: ^2.0.29 version: 2.0.29(typescript@5.5.4) @@ -99,7 +102,7 @@ importers: devDependencies: '@nuxt/test-utils': specifier: ^3.14.1 - version: 3.14.1(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3))(playwright-core@1.46.1)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) + version: 3.14.1(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4))(playwright-core@1.46.1)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) '@playwright/test': specifier: ^1.46.0 version: 1.46.1 @@ -114,7 +117,7 @@ importers: version: 2.4.6 nuxt: specifier: ^3.12.4 - version: 3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.45)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)) + version: 3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.45)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)) typescript: specifier: ^5.5.4 version: 5.5.4 @@ -272,8 +275,8 @@ packages: resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.2': - resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} + '@babel/compat-data@7.26.3': + resolution: {integrity: sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==} engines: {node: '>=6.9.0'} '@babel/core@7.24.4': @@ -296,8 +299,8 @@ packages: resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.2': - resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} + '@babel/generator@7.26.3': + resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.24.7': @@ -481,8 +484,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.26.2': - resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + '@babel/parser@7.26.3': + resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} engines: {node: '>=6.0.0'} hasBin: true @@ -535,8 +538,8 @@ packages: resolution: {integrity: sha512-V4uqWeedadiuiCx5P5OHYJZ1PehdMpcBccNCEptKFGPiZIY3FI5f2ClxUl4r5wZ5U+ohcQ+4KW6jX2K6xXzq4Q==} engines: {node: '>=6.9.0'} - '@babel/standalone@7.26.2': - resolution: {integrity: sha512-i2VbegsRfwa9yq3xmfDX3tG2yh9K0cCqwpSyVG2nPxifh0EOnucAZUeO/g4lW2Zfg03aPJNtPfxQbDHzXc7H+w==} + '@babel/standalone@7.26.4': + resolution: {integrity: sha512-SF+g7S2mhTT1b7CHyfNjDkPU1corxg4LPYsyP0x5KuCl+EbtBQHRLqr9N3q7e7+x7NQ5LYxQf8mJ2PmzebLr0A==} engines: {node: '>=6.9.0'} '@babel/template@7.24.0': @@ -559,8 +562,8 @@ packages: resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.9': - resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} + '@babel/traverse@7.26.4': + resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} engines: {node: '>=6.9.0'} '@babel/types@7.24.0': @@ -571,8 +574,8 @@ packages: resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.0': - resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + '@babel/types@7.26.3': + resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} '@clack/core@0.3.4': @@ -1366,6 +1369,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1408,6 +1415,11 @@ packages: resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} hasBin: true + '@mapbox/node-pre-gyp@2.0.0-rc.0': + resolution: {integrity: sha512-nhSMNprz3WmeRvd8iUs5JqkKr0Ncx46JtPxM3AhXes84XpSJfmIwKeWXRpsr53S7kqPkQfPhzrMFUxSNb23qSA==} + engines: {node: '>=18'} + hasBin: true + '@netlify/functions@2.8.1': resolution: {integrity: sha512-+6wtYdoz0yE06dSa9XkP47tw5zm6g13QMeCwM3MmHx1vn8hzwFa51JtmfraprdkL7amvb7gaNM+OOhQU1h6T8A==} engines: {node: '>=14.0.0'} @@ -1738,11 +1750,11 @@ packages: '@redocly/ajv@8.11.2': resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==} - '@redocly/config@0.16.0': - resolution: {integrity: sha512-t9jnODbUcuANRSl/K4L9nb12V+U5acIHnVSl26NWrtSdDZVtoqUXk2yGFPZzohYf62cCfEQUT8ouJ3bhPfpnJg==} + '@redocly/config@0.17.1': + resolution: {integrity: sha512-CEmvaJuG7pm2ylQg53emPmtgm4nW2nxBgwXzbVEHpGas/lGnMyN8Zlkgiz6rPw0unASg6VW3wlz27SOL5XFHYQ==} - '@redocly/openapi-core@1.25.11': - resolution: {integrity: sha512-bH+a8izQz4fnKROKoX3bEU8sQ9rjvEIZOqU6qTmxlhOJ0NsKa5e+LmU18SV0oFeg5YhWQhhEDihXkvKJ1wMMNQ==} + '@redocly/openapi-core@1.26.0': + resolution: {integrity: sha512-8Ofu6WpBp7eoLmf1qQ4+T0W4LRr8es+4Drw/RJG+acPXmaT2TmHk2B2v+3+1R9GqSIj6kx3N7JmQkxAPCnvDLw==} engines: {node: '>=14.19.0', npm: '>=7.0.0'} '@rollup/plugin-alias@5.1.0': @@ -1876,8 +1888,8 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.25.0': - resolution: {integrity: sha512-CC/ZqFZwlAIbU1wUPisHyV/XRc5RydFrNLtgl3dGYskdwPZdt4HERtKm50a/+DtTlKeCq9IXFEWR+P6blwjqBA==} + '@rollup/rollup-android-arm-eabi@4.28.1': + resolution: {integrity: sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==} cpu: [arm] os: [android] @@ -1891,8 +1903,8 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.25.0': - resolution: {integrity: sha512-/Y76tmLGUJqVBXXCfVS8Q8FJqYGhgH4wl4qTA24E9v/IJM0XvJCGQVSW1QZ4J+VURO9h8YCa28sTFacZXwK7Rg==} + '@rollup/rollup-android-arm64@4.28.1': + resolution: {integrity: sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==} cpu: [arm64] os: [android] @@ -1906,8 +1918,8 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.25.0': - resolution: {integrity: sha512-YVT6L3UrKTlC0FpCZd0MGA7NVdp7YNaEqkENbWQ7AOVOqd/7VzyHpgIpc1mIaxRAo1ZsJRH45fq8j4N63I/vvg==} + '@rollup/rollup-darwin-arm64@4.28.1': + resolution: {integrity: sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==} cpu: [arm64] os: [darwin] @@ -1921,18 +1933,18 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.25.0': - resolution: {integrity: sha512-ZRL+gexs3+ZmmWmGKEU43Bdn67kWnMeWXLFhcVv5Un8FQcx38yulHBA7XR2+KQdYIOtD0yZDWBCudmfj6lQJoA==} + '@rollup/rollup-darwin-x64@4.28.1': + resolution: {integrity: sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.25.0': - resolution: {integrity: sha512-xpEIXhiP27EAylEpreCozozsxWQ2TJbOLSivGfXhU4G1TBVEYtUPi2pOZBnvGXHyOdLAUUhPnJzH3ah5cqF01g==} + '@rollup/rollup-freebsd-arm64@4.28.1': + resolution: {integrity: sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.25.0': - resolution: {integrity: sha512-sC5FsmZGlJv5dOcURrsnIK7ngc3Kirnx3as2XU9uER+zjfyqIjdcMVgzy4cOawhsssqzoAX19qmxgJ8a14Qrqw==} + '@rollup/rollup-freebsd-x64@4.28.1': + resolution: {integrity: sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==} cpu: [x64] os: [freebsd] @@ -1946,8 +1958,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.25.0': - resolution: {integrity: sha512-uD/dbLSs1BEPzg564TpRAQ/YvTnCds2XxyOndAO8nJhaQcqQGFgv/DAVko/ZHap3boCvxnzYMa3mTkV/B/3SWA==} + '@rollup/rollup-linux-arm-gnueabihf@4.28.1': + resolution: {integrity: sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==} cpu: [arm] os: [linux] @@ -1961,8 +1973,8 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.25.0': - resolution: {integrity: sha512-ZVt/XkrDlQWegDWrwyC3l0OfAF7yeJUF4fq5RMS07YM72BlSfn2fQQ6lPyBNjt+YbczMguPiJoCfaQC2dnflpQ==} + '@rollup/rollup-linux-arm-musleabihf@4.28.1': + resolution: {integrity: sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==} cpu: [arm] os: [linux] @@ -1976,8 +1988,8 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.25.0': - resolution: {integrity: sha512-qboZ+T0gHAW2kkSDPHxu7quaFaaBlynODXpBVnPxUgvWYaE84xgCKAPEYE+fSMd3Zv5PyFZR+L0tCdYCMAtG0A==} + '@rollup/rollup-linux-arm64-gnu@4.28.1': + resolution: {integrity: sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==} cpu: [arm64] os: [linux] @@ -1991,11 +2003,16 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.25.0': - resolution: {integrity: sha512-ndWTSEmAaKr88dBuogGH2NZaxe7u2rDoArsejNslugHZ+r44NfWiwjzizVS1nUOHo+n1Z6qV3X60rqE/HlISgw==} + '@rollup/rollup-linux-arm64-musl@4.28.1': + resolution: {integrity: sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-loongarch64-gnu@4.28.1': + resolution: {integrity: sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-powerpc64le-gnu@4.14.3': resolution: {integrity: sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==} cpu: [ppc64] @@ -2006,8 +2023,8 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.25.0': - resolution: {integrity: sha512-BVSQvVa2v5hKwJSy6X7W1fjDex6yZnNKy3Kx1JGimccHft6HV0THTwNtC2zawtNXKUu+S5CjXslilYdKBAadzA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.28.1': + resolution: {integrity: sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==} cpu: [ppc64] os: [linux] @@ -2021,8 +2038,8 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.25.0': - resolution: {integrity: sha512-G4hTREQrIdeV0PE2JruzI+vXdRnaK1pg64hemHq2v5fhv8C7WjVaeXc9P5i4Q5UC06d/L+zA0mszYIKl+wY8oA==} + '@rollup/rollup-linux-riscv64-gnu@4.28.1': + resolution: {integrity: sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==} cpu: [riscv64] os: [linux] @@ -2036,8 +2053,8 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.25.0': - resolution: {integrity: sha512-9T/w0kQ+upxdkFL9zPVB6zy9vWW1deA3g8IauJxojN4bnz5FwSsUAD034KpXIVX5j5p/rn6XqumBMxfRkcHapQ==} + '@rollup/rollup-linux-s390x-gnu@4.28.1': + resolution: {integrity: sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==} cpu: [s390x] os: [linux] @@ -2051,8 +2068,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.25.0': - resolution: {integrity: sha512-ThcnU0EcMDn+J4B9LD++OgBYxZusuA7iemIIiz5yzEcFg04VZFzdFjuwPdlURmYPZw+fgVrFzj4CA64jSTG4Ig==} + '@rollup/rollup-linux-x64-gnu@4.28.1': + resolution: {integrity: sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==} cpu: [x64] os: [linux] @@ -2066,8 +2083,8 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.25.0': - resolution: {integrity: sha512-zx71aY2oQxGxAT1JShfhNG79PnjYhMC6voAjzpu/xmMjDnKNf6Nl/xv7YaB/9SIa9jDYf8RBPWEnjcdlhlv1rQ==} + '@rollup/rollup-linux-x64-musl@4.28.1': + resolution: {integrity: sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==} cpu: [x64] os: [linux] @@ -2081,8 +2098,8 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.25.0': - resolution: {integrity: sha512-JT8tcjNocMs4CylWY/CxVLnv8e1lE7ff1fi6kbGocWwxDq9pj30IJ28Peb+Y8yiPNSF28oad42ApJB8oUkwGww==} + '@rollup/rollup-win32-arm64-msvc@4.28.1': + resolution: {integrity: sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==} cpu: [arm64] os: [win32] @@ -2096,8 +2113,8 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.25.0': - resolution: {integrity: sha512-dRLjLsO3dNOfSN6tjyVlG+Msm4IiZnGkuZ7G5NmpzwF9oOc582FZG05+UdfTbz5Jd4buK/wMb6UeHFhG18+OEg==} + '@rollup/rollup-win32-ia32-msvc@4.28.1': + resolution: {integrity: sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==} cpu: [ia32] os: [win32] @@ -2111,8 +2128,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.25.0': - resolution: {integrity: sha512-/RqrIFtLB926frMhZD0a5oDa4eFIbyNEwLLloMTEjmqfwZWXywwVVOVmwTsuyhC9HKkVEZcOOi+KV4U9wmOdlg==} + '@rollup/rollup-win32-x64-msvc@4.28.1': + resolution: {integrity: sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==} cpu: [x64] os: [win32] @@ -2401,8 +2418,8 @@ packages: engines: {node: '>=16'} hasBin: true - '@vercel/nft@0.27.6': - resolution: {integrity: sha512-mwuyUxskdcV8dd7N7JnxBgvFEz1D9UOePI/WyLLzktv6HSCwgPNQGit/UJ2IykAWGlypKw4pBQjOKWvIbXITSg==} + '@vercel/nft@0.27.9': + resolution: {integrity: sha512-pTs7OchHQmSYJPR0puVQCWw/NqzuvAtnAhBurz21lq4Y4KqWoMpYKqmikkETG5r1bHNCM/hQMZ5JiRr9mhOkyg==} engines: {node: '>=16'} hasBin: true @@ -2663,8 +2680,8 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} - agent-base@7.1.1: - resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} ajv@6.12.6: @@ -2918,8 +2935,8 @@ packages: caniuse-lite@1.0.30001646: resolution: {integrity: sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==} - caniuse-lite@1.0.30001680: - resolution: {integrity: sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==} + caniuse-lite@1.0.30001688: + resolution: {integrity: sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==} chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} @@ -2964,6 +2981,10 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + ci-info@3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} @@ -3392,8 +3413,8 @@ packages: electron-to-chromium@1.5.4: resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==} - electron-to-chromium@1.5.56: - resolution: {integrity: sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==} + electron-to-chromium@1.5.73: + resolution: {integrity: sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4179,8 +4200,8 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} - https-proxy-agent@7.0.5: - resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} httpxy@0.1.5: @@ -4428,8 +4449,8 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true - jiti@2.4.0: - resolution: {integrity: sha512-H5UpaUI+aHOqZXlYOaFP/8AzKsg+guWu+Pr3Y8i7+Y3zr1aXAvCvTAQ1RxSc6oVD8R8c7brgNtTVP91E7upH/g==} + jiti@2.4.1: + resolution: {integrity: sha512-yPBThwecp1wS9DmoA4x4KR2h3QoslacnDR8ypuFM962kI4/456Iy1oHx2RAgh4jfZNdn0bctsdadceiBUgpU1g==} hasBin: true jose@4.15.5: @@ -4457,6 +4478,9 @@ packages: js-tokens@9.0.0: resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -4575,6 +4599,10 @@ packages: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -4659,8 +4687,8 @@ packages: magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} - magic-string@0.30.12: - resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magic-string@0.30.15: + resolution: {integrity: sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==} magic-string@0.30.7: resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} @@ -4705,10 +4733,6 @@ packages: resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -4751,6 +4775,10 @@ packages: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -4770,6 +4798,10 @@ packages: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + minisearch@7.1.0: resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} @@ -4777,6 +4809,10 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -4785,6 +4821,11 @@ packages: engines: {node: '>=10'} hasBin: true + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mkdist@1.5.4: resolution: {integrity: sha512-GEmKYJG5K1YGFIq3t0K3iihZ8FTgXphLf/4UjbmpXIAtBFn4lEjXk3pXNTSfy7EtcEXhp2Nn1vzw5pIus6RY3g==} hasBin: true @@ -4925,6 +4966,11 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true + nopt@8.0.0: + resolution: {integrity: sha512-1L/fTJ4UmV/lUxT2Uf006pfZKTvAgCF+chz+0OgBHO8u2Z67pE7AaAUUj7CJy0lXqHmymUvGFt6NE9R3HER0yw==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -5051,8 +5097,8 @@ packages: resolution: {integrity: sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==} hasBin: true - openapi-typescript@7.4.3: - resolution: {integrity: sha512-xTIjMIIOv9kNhsr8JxaC00ucbIY/6ZwuJPJBZMSh5FA2dicZN5uM805DWVJojXdom8YI4AQTavPDPHMx/3g0vQ==} + openapi-typescript@7.4.4: + resolution: {integrity: sha512-7j3nktnRzlQdlHnHsrcr6Gqz8f80/RhfA2I8s1clPI+jkY0hLNmnYVKBfuUEli5EEgK1B6M+ibdS5REasPlsUw==} hasBin: true peerDependencies: typescript: ^5.x @@ -5595,6 +5641,10 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + rollup-plugin-dts@6.1.0: resolution: {integrity: sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==} engines: {node: '>=16'} @@ -5627,8 +5677,8 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.25.0: - resolution: {integrity: sha512-uVbClXmR6wvx5R1M3Od4utyLUxrmOcEm3pAtMphn73Apq19PDtHpgZoEvqH2YnnaNUuvKmg2DgRd2Sqv+odyqg==} + rollup@4.28.1: + resolution: {integrity: sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -5901,6 +5951,9 @@ packages: strip-literal@2.1.0: resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + strip-literal@2.1.1: + resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==} + styled-jsx@5.1.1: resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} @@ -5974,6 +6027,10 @@ packages: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + terser@5.30.3: resolution: {integrity: sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==} engines: {node: '>=10'} @@ -6087,8 +6144,8 @@ packages: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} - type-fest@4.26.1: - resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} + type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} type-level-regexp@0.1.17: @@ -6158,8 +6215,8 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} - unimport@3.13.1: - resolution: {integrity: sha512-nNrVzcs93yrZQOW77qnyOVHtb68LegvhYFwxFMfuuWScmwQmyVCG/NBuN8tYsaGzgQUVYv34E/af+Cc9u4og4A==} + unimport@3.14.5: + resolution: {integrity: sha512-tn890SwFFZxqaJSKQPPd+yygfKSATbM8BZWW1aCR2TJBTs1SDrmLamBueaFtYsGjHtQaRgqEbQflOjN2iW12gA==} unimport@3.9.1: resolution: {integrity: sha512-4gtacoNH6YPx2Aa5Xfyrf8pU2RdXjWUACb/eF7bH1AcZtqs+6ijbNB0M3BPENbtVjnCcg8tw9UJ1jQGbCzKA6g==} @@ -6187,14 +6244,9 @@ packages: resolution: {integrity: sha512-bEqQxeC7rxtxPZ3M5V4Djcc4lQqKPgGe3mAWZvxcSmX5jhGxll19NliaRzQSQPrk4xJZSGniK3puLWpRuZN7VQ==} engines: {node: '>=14.0.0'} - unplugin@1.15.0: - resolution: {integrity: sha512-jTPIs63W+DUEDW207ztbaoO7cQ4p5aVaB823LSlxpsFEU3Mykwxf3ZGC/wzxFJeZlASZYgVrWeo7LgOrqJZ8RA==} + unplugin@1.16.0: + resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==} engines: {node: '>=14.0.0'} - peerDependencies: - webpack-sources: ^3 - peerDependenciesMeta: - webpack-sources: - optional: true unstorage@1.10.2: resolution: {integrity: sha512-cULBcwDqrS8UhlIysUJs2Dk0Mmt8h7B0E6mtR+relW9nZvsf/u4SkAYyNliPiPW7XtFNb5u3IUMkxGxFTTRTgQ==} @@ -6687,6 +6739,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml-ast-parser@0.0.43: resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} @@ -6909,7 +6965,7 @@ snapshots: '@babel/compat-data@7.25.2': {} - '@babel/compat-data@7.26.2': {} + '@babel/compat-data@7.26.3': {} '@babel/core@7.24.4': dependencies: @@ -6955,14 +7011,14 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 + '@babel/generator': 7.26.3 '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) '@babel/helpers': 7.26.0 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 convert-source-map: 2.0.0 debug: 4.3.6(supports-color@9.4.0) gensync: 1.0.0-beta.2 @@ -6985,10 +7041,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - '@babel/generator@7.26.2': + '@babel/generator@7.26.3': dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 @@ -7015,7 +7071,7 @@ snapshots: '@babel/helper-compilation-targets@7.25.9': dependencies: - '@babel/compat-data': 7.26.2 + '@babel/compat-data': 7.26.3 '@babel/helper-validator-option': 7.25.9 browserslist: 4.24.2 lru-cache: 5.1.1 @@ -7069,8 +7125,8 @@ snapshots: '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 transitivePeerDependencies: - supports-color @@ -7098,7 +7154,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -7177,7 +7233,7 @@ snapshots: '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.3 '@babel/highlight@7.24.2': dependencies: @@ -7205,9 +7261,9 @@ snapshots: dependencies: '@babel/types': 7.25.2 - '@babel/parser@7.26.2': + '@babel/parser@7.26.3': dependencies: - '@babel/types': 7.26.0 + '@babel/types': 7.26.3 '@babel/plugin-proposal-decorators@7.24.7(@babel/core@7.25.2)': dependencies: @@ -7260,7 +7316,7 @@ snapshots: '@babel/standalone@7.24.4': {} - '@babel/standalone@7.26.2': {} + '@babel/standalone@7.26.4': {} '@babel/template@7.24.0': dependencies: @@ -7277,8 +7333,8 @@ snapshots: '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 '@babel/traverse@7.24.1': dependencies: @@ -7307,13 +7363,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@7.25.9': + '@babel/traverse@7.26.4': dependencies: '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/parser': 7.26.2 + '@babel/generator': 7.26.3 + '@babel/parser': 7.26.3 '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.3 debug: 4.3.6(supports-color@9.4.0) globals: 11.12.0 transitivePeerDependencies: @@ -7331,7 +7387,7 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 - '@babel/types@7.26.0': + '@babel/types@7.26.3': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 @@ -7793,6 +7849,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 @@ -7851,6 +7911,19 @@ snapshots: - encoding - supports-color + '@mapbox/node-pre-gyp@2.0.0-rc.0(encoding@0.1.13)': + dependencies: + consola: 3.2.3 + detect-libc: 2.0.3 + https-proxy-agent: 7.0.6(supports-color@9.4.0) + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 8.0.0 + semver: 7.6.3 + tar: 7.4.3 + transitivePeerDependencies: + - encoding + - supports-color + '@netlify/functions@2.8.1': dependencies: '@netlify/serverless-functions-api': 1.19.1 @@ -7925,10 +7998,10 @@ snapshots: - rollup - supports-color - '@nuxt/devtools-kit@1.3.9(magicast@0.3.4)(rollup@4.25.0)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))': + '@nuxt/devtools-kit@1.3.9(magicast@0.3.4)(rollup@4.28.1)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.25.0) - '@nuxt/schema': 3.12.4(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.28.1) + '@nuxt/schema': 3.12.4(rollup@4.28.1) execa: 7.2.0 vite: 5.3.3(@types/node@18.19.42)(terser@5.30.3) transitivePeerDependencies: @@ -7936,10 +8009,10 @@ snapshots: - rollup - supports-color - '@nuxt/devtools-kit@1.3.9(magicast@0.3.4)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))': + '@nuxt/devtools-kit@1.3.9(magicast@0.3.4)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.25.0) - '@nuxt/schema': 3.12.4(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.28.1) + '@nuxt/schema': 3.12.4(rollup@4.28.1) execa: 7.2.0 vite: 5.3.5(@types/node@18.19.45)(terser@5.30.3) transitivePeerDependencies: @@ -8006,12 +8079,12 @@ snapshots: - supports-color - utf-8-validate - '@nuxt/devtools@1.3.9(rollup@4.25.0)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))': + '@nuxt/devtools@1.3.9(rollup@4.28.1)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))': dependencies: '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.3.9(magicast@0.3.4)(rollup@4.25.0)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) + '@nuxt/devtools-kit': 1.3.9(magicast@0.3.4)(rollup@4.28.1)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) '@nuxt/devtools-wizard': 1.3.9 - '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.28.1) '@vue/devtools-core': 7.3.3(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) '@vue/devtools-kit': 7.3.3 birpc: 0.2.17 @@ -8040,9 +8113,9 @@ snapshots: semver: 7.6.3 simple-git: 3.25.0 sirv: 2.0.4 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) vite: 5.3.3(@types/node@18.19.42)(terser@5.30.3) - vite-plugin-inspect: 0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.25.0))(rollup@4.25.0)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) + vite-plugin-inspect: 0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.28.1))(rollup@4.28.1)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) vite-plugin-vue-inspector: 5.1.3(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) which: 3.0.1 ws: 8.18.0 @@ -8052,12 +8125,12 @@ snapshots: - supports-color - utf-8-validate - '@nuxt/devtools@1.3.9(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))': + '@nuxt/devtools@1.3.9(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))': dependencies: '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.3.9(magicast@0.3.4)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) + '@nuxt/devtools-kit': 1.3.9(magicast@0.3.4)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) '@nuxt/devtools-wizard': 1.3.9 - '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.28.1) '@vue/devtools-core': 7.3.3(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) '@vue/devtools-kit': 7.3.3 birpc: 0.2.17 @@ -8086,9 +8159,9 @@ snapshots: semver: 7.6.3 simple-git: 3.25.0 sirv: 2.0.4 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) vite: 5.3.5(@types/node@18.19.45)(terser@5.30.3) - vite-plugin-inspect: 0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.25.0))(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) + vite-plugin-inspect: 0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.28.1))(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) vite-plugin-vue-inspector: 5.1.3(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) which: 3.0.1 ws: 8.18.0 @@ -8125,9 +8198,9 @@ snapshots: - rollup - supports-color - '@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.25.0)': + '@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.28.1)': dependencies: - '@nuxt/schema': 3.12.4(rollup@4.25.0) + '@nuxt/schema': 3.12.4(rollup@4.28.1) c12: 1.11.1(magicast@0.3.4) consola: 3.2.3 defu: 6.1.4 @@ -8145,7 +8218,7 @@ snapshots: semver: 7.6.3 ufo: 1.5.4 unctx: 2.3.1 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) untyped: 1.4.2 transitivePeerDependencies: - magicast @@ -8179,9 +8252,9 @@ snapshots: - rollup - supports-color - '@nuxt/kit@3.12.4(magicast@0.3.5)(rollup@4.25.0)': + '@nuxt/kit@3.12.4(magicast@0.3.5)(rollup@4.28.1)': dependencies: - '@nuxt/schema': 3.12.4(rollup@4.25.0) + '@nuxt/schema': 3.12.4(rollup@4.28.1) c12: 1.11.1(magicast@0.3.5) consola: 3.2.3 defu: 6.1.4 @@ -8199,16 +8272,16 @@ snapshots: semver: 7.6.3 ufo: 1.5.4 unctx: 2.3.1 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) untyped: 1.4.2 transitivePeerDependencies: - magicast - rollup - supports-color - '@nuxt/module-builder@0.8.3(@nuxt/kit@3.12.4(magicast@0.3.5)(rollup@4.25.0))(nuxi@3.12.0)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))': + '@nuxt/module-builder@0.8.3(@nuxt/kit@3.12.4(magicast@0.3.5)(rollup@4.28.1))(nuxi@3.12.0)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) citty: 0.1.6 consola: 3.2.3 defu: 6.1.4 @@ -8243,7 +8316,7 @@ snapshots: - rollup - supports-color - '@nuxt/schema@3.12.4(rollup@4.25.0)': + '@nuxt/schema@3.12.4(rollup@4.28.1)': dependencies: compatx: 0.1.8 consola: 3.2.3 @@ -8255,7 +8328,7 @@ snapshots: std-env: 3.7.0 ufo: 1.5.4 uncrypto: 0.1.3 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) untyped: 1.4.2 transitivePeerDependencies: - rollup @@ -8285,9 +8358,9 @@ snapshots: - rollup - supports-color - '@nuxt/telemetry@2.5.4(magicast@0.3.5)(rollup@4.25.0)': + '@nuxt/telemetry@2.5.4(magicast@0.3.5)(rollup@4.28.1)': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) ci-info: 4.0.0 consola: 3.2.3 create-require: 1.1.1 @@ -8309,10 +8382,10 @@ snapshots: - rollup - supports-color - '@nuxt/test-utils@3.14.1(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3))(playwright-core@1.46.1)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4))': + '@nuxt/test-utils@3.14.1(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4))(playwright-core@1.46.1)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4))': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) - '@nuxt/schema': 3.12.4(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) + '@nuxt/schema': 3.12.4(rollup@4.28.1) c12: 1.11.1(magicast@0.3.5) consola: 3.2.3 defu: 6.1.4 @@ -8324,7 +8397,7 @@ snapshots: h3: 1.13.0 local-pkg: 0.5.0 magic-string: 0.30.11 - nitropack: 2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3) + nitropack: 2.10.4(encoding@0.1.13)(typescript@5.5.4) node-fetch-native: 1.6.4 ofetch: 1.3.4 pathe: 1.1.2 @@ -8336,7 +8409,7 @@ snapshots: unenv: 1.10.0 unplugin: 1.12.2 vite: 5.3.5(@types/node@18.19.45)(terser@5.30.3) - vitest-environment-nuxt: 1.0.0(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3))(playwright-core@1.46.1)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) + vitest-environment-nuxt: 1.0.0(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4))(playwright-core@1.46.1)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) vue: 3.4.35(typescript@5.5.4) vue-router: 4.4.2(vue@3.4.35(typescript@5.5.4)) optionalDependencies: @@ -8349,10 +8422,10 @@ snapshots: - rollup - supports-color - '@nuxt/vite-builder@3.12.4(@types/node@18.19.42)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4))': + '@nuxt/vite-builder@3.12.4(@types/node@18.19.42)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4))': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) - '@rollup/plugin-replace': 5.0.7(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) + '@rollup/plugin-replace': 5.0.7(rollup@4.28.1) '@vitejs/plugin-vue': 5.1.1(vite@5.3.5(@types/node@18.19.42)(terser@5.30.3))(vue@3.4.35(typescript@5.5.4)) '@vitejs/plugin-vue-jsx': 4.0.0(vite@5.3.5(@types/node@18.19.42)(terser@5.30.3))(vue@3.4.35(typescript@5.5.4)) autoprefixer: 10.4.19(postcss@8.4.40) @@ -8374,7 +8447,7 @@ snapshots: perfect-debounce: 1.0.0 pkg-types: 1.1.3 postcss: 8.4.40 - rollup-plugin-visualizer: 5.12.0(rollup@4.25.0) + rollup-plugin-visualizer: 5.12.0(rollup@4.28.1) std-env: 3.7.0 strip-literal: 2.1.0 ufo: 1.5.4 @@ -8407,10 +8480,10 @@ snapshots: - vti - vue-tsc - '@nuxt/vite-builder@3.12.4(@types/node@18.19.45)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4))': + '@nuxt/vite-builder@3.12.4(@types/node@18.19.45)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4))': dependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) - '@rollup/plugin-replace': 5.0.7(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) + '@rollup/plugin-replace': 5.0.7(rollup@4.28.1) '@vitejs/plugin-vue': 5.1.1(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vue@3.4.35(typescript@5.5.4)) '@vitejs/plugin-vue-jsx': 4.0.0(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vue@3.4.35(typescript@5.5.4)) autoprefixer: 10.4.19(postcss@8.4.40) @@ -8432,7 +8505,7 @@ snapshots: perfect-debounce: 1.0.0 pkg-types: 1.1.3 postcss: 8.4.40 - rollup-plugin-visualizer: 5.12.0(rollup@4.25.0) + rollup-plugin-visualizer: 5.12.0(rollup@4.28.1) std-env: 3.7.0 strip-literal: 2.1.0 ufo: 1.5.4 @@ -8662,14 +8735,14 @@ snapshots: require-from-string: 2.0.2 uri-js-replace: 1.0.1 - '@redocly/config@0.16.0': {} + '@redocly/config@0.17.1': {} - '@redocly/openapi-core@1.25.11(encoding@0.1.13)(supports-color@9.4.0)': + '@redocly/openapi-core@1.26.0(encoding@0.1.13)(supports-color@9.4.0)': dependencies: '@redocly/ajv': 8.11.2 - '@redocly/config': 0.16.0 + '@redocly/config': 0.17.1 colorette: 1.4.0 - https-proxy-agent: 7.0.5(supports-color@9.4.0) + https-proxy-agent: 7.0.6(supports-color@9.4.0) js-levenshtein: 1.1.6 js-yaml: 4.1.0 lodash.isequal: 4.5.0 @@ -8693,9 +8766,9 @@ snapshots: optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-alias@5.1.1(rollup@4.25.0)': + '@rollup/plugin-alias@5.1.1(rollup@4.28.1)': optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/plugin-commonjs@25.0.8(rollup@3.29.4)': dependencies: @@ -8719,51 +8792,51 @@ snapshots: optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-commonjs@28.0.1(rollup@4.25.0)': + '@rollup/plugin-commonjs@28.0.1(rollup@4.28.1)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/pluginutils': 5.1.3(rollup@4.28.1) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.4.2(picomatch@4.0.2) is-reference: 1.2.1 - magic-string: 0.30.12 + magic-string: 0.30.15 picomatch: 4.0.2 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/plugin-inject@5.0.5(rollup@4.19.2)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.19.2) + '@rollup/pluginutils': 5.1.0(rollup@4.19.2) estree-walker: 2.0.2 - magic-string: 0.30.12 + magic-string: 0.30.10 optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-inject@5.0.5(rollup@4.25.0)': + '@rollup/plugin-inject@5.0.5(rollup@4.28.1)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) estree-walker: 2.0.2 - magic-string: 0.30.12 + magic-string: 0.30.10 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/plugin-json@6.1.0(rollup@3.29.4)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@3.29.4) + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) optionalDependencies: rollup: 3.29.4 '@rollup/plugin-json@6.1.0(rollup@4.19.2)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.19.2) + '@rollup/pluginutils': 5.1.0(rollup@4.19.2) optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-json@6.1.0(rollup@4.25.0)': + '@rollup/plugin-json@6.1.0(rollup@4.28.1)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/plugin-node-resolve@15.2.3(rollup@3.29.4)': dependencies: @@ -8787,15 +8860,15 @@ snapshots: optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-node-resolve@15.3.0(rollup@4.25.0)': + '@rollup/plugin-node-resolve@15.3.0(rollup@4.28.1)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/pluginutils': 5.1.3(rollup@4.28.1) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/plugin-replace@5.0.7(rollup@3.29.4)': dependencies: @@ -8811,19 +8884,19 @@ snapshots: optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-replace@5.0.7(rollup@4.25.0)': + '@rollup/plugin-replace@5.0.7(rollup@4.28.1)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) magic-string: 0.30.10 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 - '@rollup/plugin-replace@6.0.1(rollup@4.25.0)': + '@rollup/plugin-replace@6.0.1(rollup@4.28.1)': dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) - magic-string: 0.30.12 + '@rollup/pluginutils': 5.1.3(rollup@4.28.1) + magic-string: 0.30.15 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/plugin-terser@0.4.4(rollup@4.19.2)': dependencies: @@ -8833,13 +8906,13 @@ snapshots: optionalDependencies: rollup: 4.19.2 - '@rollup/plugin-terser@0.4.4(rollup@4.25.0)': + '@rollup/plugin-terser@0.4.4(rollup@4.28.1)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 terser: 5.30.3 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/pluginutils@4.2.1': dependencies: @@ -8862,37 +8935,21 @@ snapshots: optionalDependencies: rollup: 4.19.2 - '@rollup/pluginutils@5.1.0(rollup@4.25.0)': + '@rollup/pluginutils@5.1.0(rollup@4.28.1)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 - '@rollup/pluginutils@5.1.3(rollup@3.29.4)': + '@rollup/pluginutils@5.1.3(rollup@4.28.1)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 3.29.4 - - '@rollup/pluginutils@5.1.3(rollup@4.19.2)': - dependencies: - '@types/estree': 1.0.5 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.19.2 - - '@rollup/pluginutils@5.1.3(rollup@4.25.0)': - dependencies: - '@types/estree': 1.0.5 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 '@rollup/rollup-android-arm-eabi@4.14.3': optional: true @@ -8900,7 +8957,7 @@ snapshots: '@rollup/rollup-android-arm-eabi@4.19.2': optional: true - '@rollup/rollup-android-arm-eabi@4.25.0': + '@rollup/rollup-android-arm-eabi@4.28.1': optional: true '@rollup/rollup-android-arm64@4.14.3': @@ -8909,7 +8966,7 @@ snapshots: '@rollup/rollup-android-arm64@4.19.2': optional: true - '@rollup/rollup-android-arm64@4.25.0': + '@rollup/rollup-android-arm64@4.28.1': optional: true '@rollup/rollup-darwin-arm64@4.14.3': @@ -8918,7 +8975,7 @@ snapshots: '@rollup/rollup-darwin-arm64@4.19.2': optional: true - '@rollup/rollup-darwin-arm64@4.25.0': + '@rollup/rollup-darwin-arm64@4.28.1': optional: true '@rollup/rollup-darwin-x64@4.14.3': @@ -8927,13 +8984,13 @@ snapshots: '@rollup/rollup-darwin-x64@4.19.2': optional: true - '@rollup/rollup-darwin-x64@4.25.0': + '@rollup/rollup-darwin-x64@4.28.1': optional: true - '@rollup/rollup-freebsd-arm64@4.25.0': + '@rollup/rollup-freebsd-arm64@4.28.1': optional: true - '@rollup/rollup-freebsd-x64@4.25.0': + '@rollup/rollup-freebsd-x64@4.28.1': optional: true '@rollup/rollup-linux-arm-gnueabihf@4.14.3': @@ -8942,7 +8999,7 @@ snapshots: '@rollup/rollup-linux-arm-gnueabihf@4.19.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.25.0': + '@rollup/rollup-linux-arm-gnueabihf@4.28.1': optional: true '@rollup/rollup-linux-arm-musleabihf@4.14.3': @@ -8951,7 +9008,7 @@ snapshots: '@rollup/rollup-linux-arm-musleabihf@4.19.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.25.0': + '@rollup/rollup-linux-arm-musleabihf@4.28.1': optional: true '@rollup/rollup-linux-arm64-gnu@4.14.3': @@ -8960,7 +9017,7 @@ snapshots: '@rollup/rollup-linux-arm64-gnu@4.19.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.25.0': + '@rollup/rollup-linux-arm64-gnu@4.28.1': optional: true '@rollup/rollup-linux-arm64-musl@4.14.3': @@ -8969,7 +9026,10 @@ snapshots: '@rollup/rollup-linux-arm64-musl@4.19.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.25.0': + '@rollup/rollup-linux-arm64-musl@4.28.1': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.28.1': optional: true '@rollup/rollup-linux-powerpc64le-gnu@4.14.3': @@ -8978,7 +9038,7 @@ snapshots: '@rollup/rollup-linux-powerpc64le-gnu@4.19.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.25.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.28.1': optional: true '@rollup/rollup-linux-riscv64-gnu@4.14.3': @@ -8987,7 +9047,7 @@ snapshots: '@rollup/rollup-linux-riscv64-gnu@4.19.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.25.0': + '@rollup/rollup-linux-riscv64-gnu@4.28.1': optional: true '@rollup/rollup-linux-s390x-gnu@4.14.3': @@ -8996,7 +9056,7 @@ snapshots: '@rollup/rollup-linux-s390x-gnu@4.19.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.25.0': + '@rollup/rollup-linux-s390x-gnu@4.28.1': optional: true '@rollup/rollup-linux-x64-gnu@4.14.3': @@ -9005,7 +9065,7 @@ snapshots: '@rollup/rollup-linux-x64-gnu@4.19.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.25.0': + '@rollup/rollup-linux-x64-gnu@4.28.1': optional: true '@rollup/rollup-linux-x64-musl@4.14.3': @@ -9014,7 +9074,7 @@ snapshots: '@rollup/rollup-linux-x64-musl@4.19.2': optional: true - '@rollup/rollup-linux-x64-musl@4.25.0': + '@rollup/rollup-linux-x64-musl@4.28.1': optional: true '@rollup/rollup-win32-arm64-msvc@4.14.3': @@ -9023,7 +9083,7 @@ snapshots: '@rollup/rollup-win32-arm64-msvc@4.19.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.25.0': + '@rollup/rollup-win32-arm64-msvc@4.28.1': optional: true '@rollup/rollup-win32-ia32-msvc@4.14.3': @@ -9032,7 +9092,7 @@ snapshots: '@rollup/rollup-win32-ia32-msvc@4.19.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.25.0': + '@rollup/rollup-win32-ia32-msvc@4.28.1': optional: true '@rollup/rollup-win32-x64-msvc@4.14.3': @@ -9041,7 +9101,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.19.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.25.0': + '@rollup/rollup-win32-x64-msvc@4.28.1': optional: true '@shikijs/core@1.12.0': @@ -9433,10 +9493,10 @@ snapshots: - encoding - supports-color - '@vercel/nft@0.27.6(encoding@0.1.13)': + '@vercel/nft@0.27.9(encoding@0.1.13)(rollup@4.28.1)': dependencies: - '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) - '@rollup/pluginutils': 4.2.1 + '@mapbox/node-pre-gyp': 2.0.0-rc.0(encoding@0.1.13) + '@rollup/pluginutils': 5.1.3(rollup@4.28.1) acorn: 8.12.1 acorn-import-attributes: 1.9.5(acorn@8.12.1) async-sema: 3.1.1 @@ -9444,11 +9504,12 @@ snapshots: estree-walker: 2.0.2 glob: 7.2.3 graceful-fs: 4.2.11 - micromatch: 4.0.8 node-gyp-build: 4.8.1 + picomatch: 4.0.2 resolve-from: 5.0.0 transitivePeerDependencies: - encoding + - rollup - supports-color '@vitejs/plugin-vue-jsx@4.0.0(vite@5.3.5(@types/node@18.19.42)(terser@5.30.3))(vue@3.4.35(typescript@5.5.4))': @@ -9555,10 +9616,10 @@ snapshots: transitivePeerDependencies: - rollup - '@vue-macros/common@1.12.0(rollup@4.25.0)(vue@3.4.35(typescript@5.5.4))': + '@vue-macros/common@1.12.0(rollup@4.28.1)(vue@3.4.35(typescript@5.5.4))': dependencies: '@babel/types': 7.25.2 - '@rollup/pluginutils': 5.1.0(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) '@vue/compiler-sfc': 3.4.35 ast-kit: 1.0.0 local-pkg: 0.5.0 @@ -9859,11 +9920,7 @@ snapshots: transitivePeerDependencies: - supports-color - agent-base@7.1.1(supports-color@9.4.0): - dependencies: - debug: 4.3.6(supports-color@9.4.0) - transitivePeerDependencies: - - supports-color + agent-base@7.1.3: {} ajv@6.12.6: dependencies: @@ -10082,8 +10139,8 @@ snapshots: browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001680 - electron-to-chromium: 1.5.56 + caniuse-lite: 1.0.30001688 + electron-to-chromium: 1.5.73 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -10153,7 +10210,7 @@ snapshots: defu: 6.1.4 dotenv: 16.4.5 giget: 1.2.3 - jiti: 2.4.0 + jiti: 2.4.1 mlly: 1.7.3 ohash: 1.1.4 pathe: 1.1.2 @@ -10195,7 +10252,7 @@ snapshots: caniuse-lite@1.0.30001646: {} - caniuse-lite@1.0.30001680: {} + caniuse-lite@1.0.30001688: {} chai@4.4.1: dependencies: @@ -10250,6 +10307,8 @@ snapshots: chownr@2.0.0: {} + chownr@3.0.0: {} + ci-info@3.8.0: {} ci-info@4.0.0: {} @@ -10578,7 +10637,7 @@ snapshots: dot-prop@9.0.0: dependencies: - type-fest: 4.26.1 + type-fest: 4.30.0 dotenv@16.4.5: {} @@ -10601,7 +10660,7 @@ snapshots: electron-to-chromium@1.5.4: {} - electron-to-chromium@1.5.56: {} + electron-to-chromium@1.5.73: {} emoji-regex@8.0.0: {} @@ -11533,7 +11592,7 @@ snapshots: dependencies: foreground-child: 3.1.1 jackspeak: 2.3.6 - minimatch: 9.0.5 + minimatch: 9.0.4 minipass: 7.0.4 path-scurry: 1.10.2 @@ -11710,9 +11769,9 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.5(supports-color@9.4.0): + https-proxy-agent@7.0.6(supports-color@9.4.0): dependencies: - agent-base: 7.1.1(supports-color@9.4.0) + agent-base: 7.1.3 debug: 4.3.6(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -11931,7 +11990,7 @@ snapshots: jiti@1.21.6: {} - jiti@2.4.0: {} + jiti@2.4.1: {} jose@4.15.5: {} @@ -11953,6 +12012,8 @@ snapshots: js-tokens@9.0.0: {} + js-tokens@9.0.1: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -12085,7 +12146,7 @@ snapshots: get-port-please: 3.1.2 h3: 1.13.0 http-shutdown: 1.2.2 - jiti: 2.4.0 + jiti: 2.4.1 mlly: 1.7.3 node-forge: 1.3.1 pathe: 1.1.2 @@ -12101,6 +12162,11 @@ snapshots: mlly: 1.7.1 pkg-types: 1.1.3 + local-pkg@0.5.1: + dependencies: + mlly: 1.7.3 + pkg-types: 1.2.1 + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -12179,7 +12245,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.12: + magic-string@0.30.15: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -12195,8 +12261,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 source-map-js: 1.2.0 make-dir@3.1.0: @@ -12237,11 +12303,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - mime@1.6.0: {} mime@3.0.0: {} @@ -12272,6 +12333,10 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -12286,6 +12351,8 @@ snapshots: minipass@7.0.4: {} + minipass@7.1.2: {} + minisearch@7.1.0: {} minizlib@2.1.2: @@ -12293,10 +12360,17 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + mitt@3.0.1: {} mkdirp@1.0.4: {} + mkdirp@3.0.1: {} + mkdist@1.5.4(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4)): dependencies: autoprefixer: 10.4.19(postcss@8.4.40) @@ -12390,20 +12464,20 @@ snapshots: - '@babel/core' - babel-plugin-macros - nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3): + nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@netlify/functions': 2.8.2 - '@rollup/plugin-alias': 5.1.1(rollup@4.25.0) - '@rollup/plugin-commonjs': 28.0.1(rollup@4.25.0) - '@rollup/plugin-inject': 5.0.5(rollup@4.25.0) - '@rollup/plugin-json': 6.1.0(rollup@4.25.0) - '@rollup/plugin-node-resolve': 15.3.0(rollup@4.25.0) - '@rollup/plugin-replace': 6.0.1(rollup@4.25.0) - '@rollup/plugin-terser': 0.4.4(rollup@4.25.0) - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) + '@rollup/plugin-alias': 5.1.1(rollup@4.28.1) + '@rollup/plugin-commonjs': 28.0.1(rollup@4.28.1) + '@rollup/plugin-inject': 5.0.5(rollup@4.28.1) + '@rollup/plugin-json': 6.1.0(rollup@4.28.1) + '@rollup/plugin-node-resolve': 15.3.0(rollup@4.28.1) + '@rollup/plugin-replace': 6.0.1(rollup@4.28.1) + '@rollup/plugin-terser': 0.4.4(rollup@4.28.1) + '@rollup/pluginutils': 5.1.3(rollup@4.28.1) '@types/http-proxy': 1.17.15 - '@vercel/nft': 0.27.6(encoding@0.1.13) + '@vercel/nft': 0.27.9(encoding@0.1.13)(rollup@4.28.1) archiver: 7.0.1 c12: 2.0.1(magicast@0.3.5) chokidar: 3.6.0 @@ -12428,25 +12502,25 @@ snapshots: hookable: 5.5.3 httpxy: 0.1.5 ioredis: 5.4.1 - jiti: 2.4.0 + jiti: 2.4.1 klona: 2.0.6 knitwork: 1.1.0 listhen: 1.9.0 - magic-string: 0.30.12 + magic-string: 0.30.15 magicast: 0.3.5 mime: 4.0.4 mlly: 1.7.3 node-fetch-native: 1.6.4 ofetch: 1.4.1 ohash: 1.1.4 - openapi-typescript: 7.4.3(encoding@0.1.13)(typescript@5.5.4) + openapi-typescript: 7.4.4(encoding@0.1.13)(typescript@5.5.4) pathe: 1.1.2 perfect-debounce: 1.0.0 pkg-types: 1.2.1 pretty-bytes: 6.1.1 radix3: 1.1.2 - rollup: 4.25.0 - rollup-plugin-visualizer: 5.12.0(rollup@4.25.0) + rollup: 4.28.1 + rollup-plugin-visualizer: 5.12.0(rollup@4.28.1) scule: 1.3.0 semver: 7.6.3 serve-placeholder: 2.0.2 @@ -12456,7 +12530,7 @@ snapshots: uncrypto: 0.1.3 unctx: 2.3.1 unenv: 1.10.0 - unimport: 3.13.1(rollup@4.25.0)(webpack-sources@3.2.3) + unimport: 3.14.5(rollup@4.28.1) unstorage: 1.13.1(ioredis@5.4.1) untyped: 1.5.1 unwasm: 0.3.9 @@ -12481,7 +12555,6 @@ snapshots: - mysql2 - supports-color - typescript - - webpack-sources nitropack@2.9.7(encoding@0.1.13)(magicast@0.3.5): dependencies: @@ -12596,6 +12669,10 @@ snapshots: dependencies: abbrev: 2.0.0 + nopt@8.0.0: + dependencies: + abbrev: 2.0.0 + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -12630,14 +12707,14 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - nuxt@3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.42)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)): + nuxt@3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.42)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.3.9(rollup@4.25.0)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) - '@nuxt/schema': 3.12.4(rollup@4.25.0) - '@nuxt/telemetry': 2.5.4(magicast@0.3.5)(rollup@4.25.0) - '@nuxt/vite-builder': 3.12.4(@types/node@18.19.42)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4)) + '@nuxt/devtools': 1.3.9(rollup@4.28.1)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) + '@nuxt/schema': 3.12.4(rollup@4.28.1) + '@nuxt/telemetry': 2.5.4(magicast@0.3.5)(rollup@4.28.1) + '@nuxt/vite-builder': 3.12.4(@types/node@18.19.42)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4)) '@unhead/dom': 1.9.16 '@unhead/ssr': 1.9.16 '@unhead/vue': 1.9.16(vue@3.4.35(typescript@5.5.4)) @@ -12682,9 +12759,9 @@ snapshots: uncrypto: 0.1.3 unctx: 2.3.1 unenv: 1.10.0 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) unplugin: 1.12.0 - unplugin-vue-router: 0.10.2(rollup@4.25.0)(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) + unplugin-vue-router: 0.10.2(rollup@4.28.1)(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) unstorage: 1.10.2(ioredis@5.4.1) untyped: 1.4.2 vue: 3.4.35(typescript@5.5.4) @@ -12736,14 +12813,14 @@ snapshots: - vue-tsc - xml2js - nuxt@3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.45)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)): + nuxt@3.12.4(@parcel/watcher@2.4.1)(@types/node@18.19.45)(encoding@0.1.13)(eslint@8.57.0)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vue-tsc@2.0.29(typescript@5.5.4)): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.3.9(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) - '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.25.0) - '@nuxt/schema': 3.12.4(rollup@4.25.0) - '@nuxt/telemetry': 2.5.4(magicast@0.3.5)(rollup@4.25.0) - '@nuxt/vite-builder': 3.12.4(@types/node@18.19.45)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.25.0)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4)) + '@nuxt/devtools': 1.3.9(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)) + '@nuxt/kit': 3.12.4(magicast@0.3.5)(rollup@4.28.1) + '@nuxt/schema': 3.12.4(rollup@4.28.1) + '@nuxt/telemetry': 2.5.4(magicast@0.3.5)(rollup@4.28.1) + '@nuxt/vite-builder': 3.12.4(@types/node@18.19.45)(eslint@8.57.0)(magicast@0.3.5)(optionator@0.9.3)(rollup@4.28.1)(terser@5.30.3)(typescript@5.5.4)(vue-tsc@2.0.29(typescript@5.5.4))(vue@3.4.35(typescript@5.5.4)) '@unhead/dom': 1.9.16 '@unhead/ssr': 1.9.16 '@unhead/vue': 1.9.16(vue@3.4.35(typescript@5.5.4)) @@ -12788,9 +12865,9 @@ snapshots: uncrypto: 0.1.3 unctx: 2.3.1 unenv: 1.10.0 - unimport: 3.9.1(rollup@4.25.0) + unimport: 3.9.1(rollup@4.28.1) unplugin: 1.12.0 - unplugin-vue-router: 0.10.2(rollup@4.25.0)(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) + unplugin-vue-router: 0.10.2(rollup@4.28.1)(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) unstorage: 1.10.2(ioredis@5.4.1) untyped: 1.4.2 vue: 3.4.35(typescript@5.5.4) @@ -13054,9 +13131,9 @@ snapshots: undici: 5.28.4 yargs-parser: 21.1.1 - openapi-typescript@7.4.3(encoding@0.1.13)(typescript@5.5.4): + openapi-typescript@7.4.4(encoding@0.1.13)(typescript@5.5.4): dependencies: - '@redocly/openapi-core': 1.25.11(encoding@0.1.13)(supports-color@9.4.0) + '@redocly/openapi-core': 1.26.0(encoding@0.1.13)(supports-color@9.4.0) ansi-colors: 4.1.3 change-case: 5.4.4 parse-json: 8.1.0 @@ -13151,7 +13228,7 @@ snapshots: dependencies: '@babel/code-frame': 7.24.7 index-to-position: 0.1.2 - type-fest: 4.26.1 + type-fest: 4.30.0 parse-path@7.0.0: dependencies: @@ -13588,6 +13665,10 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@5.0.10: + dependencies: + glob: 10.3.12 + rollup-plugin-dts@6.1.0(rollup@3.29.4)(typescript@5.5.4): dependencies: magic-string: 0.30.11 @@ -13605,14 +13686,14 @@ snapshots: optionalDependencies: rollup: 4.19.2 - rollup-plugin-visualizer@5.12.0(rollup@4.25.0): + rollup-plugin-visualizer@5.12.0(rollup@4.28.1): dependencies: open: 8.4.2 picomatch: 2.3.1 source-map: 0.7.4 yargs: 17.7.2 optionalDependencies: - rollup: 4.25.0 + rollup: 4.28.1 rollup@3.29.4: optionalDependencies: @@ -13662,28 +13743,29 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.19.2 fsevents: 2.3.3 - rollup@4.25.0: + rollup@4.28.1: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.25.0 - '@rollup/rollup-android-arm64': 4.25.0 - '@rollup/rollup-darwin-arm64': 4.25.0 - '@rollup/rollup-darwin-x64': 4.25.0 - '@rollup/rollup-freebsd-arm64': 4.25.0 - '@rollup/rollup-freebsd-x64': 4.25.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.25.0 - '@rollup/rollup-linux-arm-musleabihf': 4.25.0 - '@rollup/rollup-linux-arm64-gnu': 4.25.0 - '@rollup/rollup-linux-arm64-musl': 4.25.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.25.0 - '@rollup/rollup-linux-riscv64-gnu': 4.25.0 - '@rollup/rollup-linux-s390x-gnu': 4.25.0 - '@rollup/rollup-linux-x64-gnu': 4.25.0 - '@rollup/rollup-linux-x64-musl': 4.25.0 - '@rollup/rollup-win32-arm64-msvc': 4.25.0 - '@rollup/rollup-win32-ia32-msvc': 4.25.0 - '@rollup/rollup-win32-x64-msvc': 4.25.0 + '@rollup/rollup-android-arm-eabi': 4.28.1 + '@rollup/rollup-android-arm64': 4.28.1 + '@rollup/rollup-darwin-arm64': 4.28.1 + '@rollup/rollup-darwin-x64': 4.28.1 + '@rollup/rollup-freebsd-arm64': 4.28.1 + '@rollup/rollup-freebsd-x64': 4.28.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.28.1 + '@rollup/rollup-linux-arm-musleabihf': 4.28.1 + '@rollup/rollup-linux-arm64-gnu': 4.28.1 + '@rollup/rollup-linux-arm64-musl': 4.28.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.28.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.28.1 + '@rollup/rollup-linux-riscv64-gnu': 4.28.1 + '@rollup/rollup-linux-s390x-gnu': 4.28.1 + '@rollup/rollup-linux-x64-gnu': 4.28.1 + '@rollup/rollup-linux-x64-musl': 4.28.1 + '@rollup/rollup-win32-arm64-msvc': 4.28.1 + '@rollup/rollup-win32-ia32-msvc': 4.28.1 + '@rollup/rollup-win32-x64-msvc': 4.28.1 fsevents: 2.3.3 run-applescript@7.0.0: {} @@ -13999,6 +14081,10 @@ snapshots: dependencies: js-tokens: 9.0.0 + strip-literal@2.1.1: + dependencies: + js-tokens: 9.0.1 + styled-jsx@5.1.1(@babel/core@7.26.0)(react@18.2.0): dependencies: client-only: 0.0.1 @@ -14070,6 +14156,15 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + terser@5.30.3: dependencies: '@jridgewell/source-map': 0.3.6 @@ -14146,7 +14241,7 @@ snapshots: type-fest@3.13.1: {} - type-fest@4.26.1: {} + type-fest@4.30.0: {} type-level-regexp@0.1.17: {} @@ -14263,24 +14358,24 @@ snapshots: unicorn-magic@0.1.0: {} - unimport@3.13.1(rollup@4.25.0)(webpack-sources@3.2.3): + unimport@3.14.5(rollup@4.28.1): dependencies: - '@rollup/pluginutils': 5.1.3(rollup@4.25.0) - acorn: 8.12.1 + '@rollup/pluginutils': 5.1.3(rollup@4.28.1) + acorn: 8.14.0 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.12 + local-pkg: 0.5.1 + magic-string: 0.30.15 mlly: 1.7.3 pathe: 1.1.2 + picomatch: 4.0.2 pkg-types: 1.2.1 scule: 1.3.0 - strip-literal: 2.1.0 - unplugin: 1.15.0(webpack-sources@3.2.3) + strip-literal: 2.1.1 + unplugin: 1.16.0 transitivePeerDependencies: - rollup - - webpack-sources unimport@3.9.1(rollup@4.19.2): dependencies: @@ -14300,9 +14395,9 @@ snapshots: transitivePeerDependencies: - rollup - unimport@3.9.1(rollup@4.25.0): + unimport@3.9.1(rollup@4.28.1): dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) acorn: 8.12.1 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 @@ -14345,11 +14440,11 @@ snapshots: - rollup - vue - unplugin-vue-router@0.10.2(rollup@4.25.0)(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)): + unplugin-vue-router@0.10.2(rollup@4.28.1)(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)): dependencies: '@babel/types': 7.25.2 - '@rollup/pluginutils': 5.1.0(rollup@4.25.0) - '@vue-macros/common': 1.12.0(rollup@4.25.0)(vue@3.4.35(typescript@5.5.4)) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) + '@vue-macros/common': 1.12.0(rollup@4.28.1)(vue@3.4.35(typescript@5.5.4)) ast-walker-scope: 0.6.1 chokidar: 3.6.0 fast-glob: 3.3.2 @@ -14380,12 +14475,10 @@ snapshots: webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.2 - unplugin@1.15.0(webpack-sources@3.2.3): + unplugin@1.16.0: dependencies: acorn: 8.14.0 webpack-virtual-modules: 0.6.2 - optionalDependencies: - webpack-sources: 3.2.3 unstorage@1.10.2(ioredis@5.4.1): dependencies: @@ -14440,10 +14533,10 @@ snapshots: untyped@1.5.1: dependencies: '@babel/core': 7.26.0 - '@babel/standalone': 7.26.2 - '@babel/types': 7.26.0 + '@babel/standalone': 7.26.4 + '@babel/types': 7.26.3 defu: 6.1.4 - jiti: 2.4.0 + jiti: 2.4.1 mri: 1.2.0 scule: 1.3.0 transitivePeerDependencies: @@ -14517,7 +14610,6 @@ snapshots: - sugarss - supports-color - terser - optional: true vite-node@1.6.0(@types/node@18.19.45)(terser@5.30.3): dependencies: @@ -14674,10 +14766,10 @@ snapshots: - rollup - supports-color - vite-plugin-inspect@0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.25.0))(rollup@4.25.0)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)): + vite-plugin-inspect@0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.28.1))(rollup@4.28.1)(vite@5.3.3(@types/node@18.19.42)(terser@5.30.3)): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.0(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) debug: 4.3.6(supports-color@9.4.0) error-stack-parser-es: 0.1.5 fs-extra: 11.2.0 @@ -14687,15 +14779,15 @@ snapshots: sirv: 2.0.4 vite: 5.3.3(@types/node@18.19.42)(terser@5.30.3) optionalDependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.28.1) transitivePeerDependencies: - rollup - supports-color - vite-plugin-inspect@0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.25.0))(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)): + vite-plugin-inspect@0.8.5(@nuxt/kit@3.12.4(magicast@0.3.4)(rollup@4.28.1))(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3)): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.0(rollup@4.25.0) + '@rollup/pluginutils': 5.1.0(rollup@4.28.1) debug: 4.3.6(supports-color@9.4.0) error-stack-parser-es: 0.1.5 fs-extra: 11.2.0 @@ -14705,7 +14797,7 @@ snapshots: sirv: 2.0.4 vite: 5.3.5(@types/node@18.19.45)(terser@5.30.3) optionalDependencies: - '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.25.0) + '@nuxt/kit': 3.12.4(magicast@0.3.4)(rollup@4.28.1) transitivePeerDependencies: - rollup - supports-color @@ -14764,7 +14856,6 @@ snapshots: '@types/node': 18.19.42 fsevents: 2.3.3 terser: 5.30.3 - optional: true vite@5.2.9(@types/node@18.19.45)(terser@5.30.3): dependencies: @@ -14863,9 +14954,9 @@ snapshots: - typescript - universal-cookie - vitest-environment-nuxt@1.0.0(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3))(playwright-core@1.46.1)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)): + vitest-environment-nuxt@1.0.0(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4))(playwright-core@1.46.1)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)): dependencies: - '@nuxt/test-utils': 3.14.1(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4)(webpack-sources@3.2.3))(playwright-core@1.46.1)(rollup@4.25.0)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) + '@nuxt/test-utils': 3.14.1(@playwright/test@1.46.1)(@vue/test-utils@2.4.6)(h3@1.13.0)(magicast@0.3.5)(nitropack@2.10.4(encoding@0.1.13)(typescript@5.5.4))(playwright-core@1.46.1)(rollup@4.28.1)(vite@5.3.5(@types/node@18.19.45)(terser@5.30.3))(vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3))(vue-router@4.4.2(vue@3.4.35(typescript@5.5.4)))(vue@3.4.35(typescript@5.5.4)) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -14918,7 +15009,6 @@ snapshots: - sugarss - supports-color - terser - optional: true vitest@1.6.0(@types/node@18.19.45)(terser@5.30.3): dependencies: @@ -15127,6 +15217,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml-ast-parser@0.0.43: {} yaml-eslint-parser@1.2.3: diff --git a/src/module.ts b/src/module.ts index 16d727fc..b578366d 100644 --- a/src/module.ts +++ b/src/module.ts @@ -11,11 +11,10 @@ import { useLogger } from '@nuxt/kit' import { defu } from 'defu' -import { joinURL } from 'ufo' import { genInterface } from 'knitwork' import type { DeepRequired } from 'ts-essentials' import type { NuxtModule } from 'nuxt/schema' -import { getOriginAndPathnameFromURL, isProduction } from './runtime/helpers' +import { isProduction } from './runtime/helpers' import type { AuthProviders, ModuleOptions, @@ -26,6 +25,8 @@ import type { const topLevelDefaults = { isEnabled: true, + baseURL: '/api/auth', + disableInternalRouting: false as boolean, disableServerSideAuth: false, originEnvKey: 'AUTH_ORIGIN', sessionRefresh: { @@ -108,26 +109,16 @@ export default defineNuxtModule({ const logger = useLogger(PACKAGE_NAME) // 0. Assemble all options - const { origin, pathname = '/api/auth' } = getOriginAndPathnameFromURL( - userOptions.baseURL ?? '' - ) const selectedProvider = userOptions.provider?.type ?? 'authjs' - const options = { - ...defu(userOptions, topLevelDefaults, { - computed: { - origin, - pathname, - fullBaseUrl: joinURL(origin ?? '', pathname) - } - }), + const options = defu({ // We use `as` to infer backend types correctly for runtime-usage (everything is set, although for user everything was optional) provider: defu( userOptions.provider, defaultsByBackend[selectedProvider] ) as DeepRequired - } + }, userOptions, topLevelDefaults) // 1. Check if module should be enabled at all if (!options.isEnabled) { @@ -137,15 +128,23 @@ export default defineNuxtModule({ logger.info('`nuxt-auth` setup starting') - // 2. Set up runtime configuration + // 2.1. Disable internal routing for `local` provider when not specified otherwise + // https://github.com/sidebase/nuxt-auth/issues/797 + if (userOptions.disableInternalRouting === undefined && selectedProvider === 'local') { + options.disableInternalRouting = true + } + + // 2.2. Set up runtime configuration if (!isProduction) { - const authjsAddition - = selectedProvider === 'authjs' - ? ', ensure that `NuxtAuthHandler({ ... })` is there, see https://sidebase.io/nuxt-auth/configuration/nuxt-auth-handler' - : '' - logger.info( - `Selected provider: ${selectedProvider}. Auth API location is \`${options.computed.fullBaseUrl}\`${authjsAddition}` - ) + const loggerMessages = [ + `Selected provider: ${selectedProvider}.`, + `Auth API location is \`${options.baseURL}\`, if you would like to change this, see https://auth.sidebase.io/guide/application-side/configuration#baseurl.` + ] + if (selectedProvider === 'authjs') { + loggerMessages.push('Ensure that the `NuxtAuthHandler({ ... })` is there, see https://auth.sidebase.io/guide/authjs/nuxt-auth-handler') + } + + logger.info(loggerMessages.join(' ')) } nuxt.options.runtimeConfig = nuxt.options.runtimeConfig || { public: {} } @@ -242,8 +241,8 @@ export default defineNuxtModule({ // 6. Register middleware for autocomplete in definePageMeta addRouteMiddleware({ - name: 'auth', - path: resolve('./runtime/middleware/auth') + name: 'sidebase-auth', + path: resolve('./runtime/middleware/sidebase-auth') }) // 7. Add plugin for initial load diff --git a/src/runtime/composables/authjs/useAuth.ts b/src/runtime/composables/authjs/useAuth.ts index 78ceb585..85e1279d 100644 --- a/src/runtime/composables/authjs/useAuth.ts +++ b/src/runtime/composables/authjs/useAuth.ts @@ -2,13 +2,14 @@ import type { AppProvider, BuiltInProviderType } from 'next-auth/providers/index import { defu } from 'defu' import { type Ref, readonly } from 'vue' import { appendHeader } from 'h3' -import { determineCallbackUrl } from '../../utils/url' -import { getRequestURLWN, joinPathToApiURLWN, makeCWN, navigateToAuthPageWN } from '../../utils/callWithNuxt' +import { determineCallbackUrl, resolveApiUrlPath } from '../../utils/url' import { _fetch } from '../../utils/fetch' import { isNonEmptyObject } from '../../utils/checkSessionResult' import type { CommonUseAuthReturn, GetSessionOptions, SignInFunc, SignOutFunc } from '../../types' import { useTypedBackendConfig } from '../../helpers' +import { getRequestURLWN } from '../common/getRequestURL' import type { SessionData } from './useAuthState' +import { navigateToAuthPageWN } from './utils/navigateToAuthPage' import type { NuxtApp } from '#app/nuxt' import { callWithNuxt } from '#app/nuxt' import { createError, useAuthState, useNuxtApp, useRequestHeaders, useRuntimeConfig } from '#imports' @@ -49,7 +50,9 @@ async function getCsrfToken() { const headers = await getRequestCookies(nuxt) return _fetch<{ csrfToken: string }>(nuxt, '/csrf', { headers }).then(response => response.csrfToken) } -const getCsrfTokenWithNuxt = makeCWN(getCsrfToken) +function getCsrfTokenWithNuxt(nuxt: NuxtApp) { + return callWithNuxt(nuxt, getCsrfToken) +} /** * Trigger a sign in flow for the passed `provider`. If no provider is given the sign in page for all providers will be shown. @@ -61,17 +64,16 @@ const getCsrfTokenWithNuxt = makeCWN(getCsrfToken) type SignInResult = void | { error: string | null, status: number, ok: boolean, url: any } const signIn: SignInFunc = async (provider, options, authorizationParams) => { const nuxt = useNuxtApp() + const runtimeConfig = await callWithNuxt(nuxt, useRuntimeConfig) // 1. Lead to error page if no providers are available const configuredProviders = await getProviders() if (!configuredProviders) { - const errorUrl = await joinPathToApiURLWN(nuxt, 'error') + const errorUrl = resolveApiUrlPath('error', runtimeConfig) return navigateToAuthPageWN(nuxt, errorUrl) } // 2. If no `provider` was given, either use the configured `defaultProvider` or `undefined` (leading to a forward to the `/login` page with all providers) - const runtimeConfig = await callWithNuxt(nuxt, useRuntimeConfig) - const backendConfig = useTypedBackendConfig(runtimeConfig, 'authjs') if (typeof provider === 'undefined') { // NOTE: `provider` might be an empty string @@ -87,7 +89,7 @@ const signIn: SignInFunc = async (provider, op callbackUrl = await determineCallbackUrl(runtimeConfig.public.auth, () => getRequestURLWN(nuxt)) } - const signinUrl = await joinPathToApiURLWN(nuxt, 'signin') + const signinUrl = resolveApiUrlPath('signin', runtimeConfig) const queryParams = callbackUrl ? `?${new URLSearchParams({ callbackUrl })}` : '' const hrefSignInAllProviderPage = `${signinUrl}${queryParams}` @@ -140,7 +142,6 @@ const signIn: SignInFunc = async (provider, op // At this point the request succeeded (i.e., it went through) const error = new URL(data.url).searchParams.get('error') - // eslint-disable-next-line ts/no-use-before-define await getSessionWithNuxt(nuxt) return { @@ -163,7 +164,7 @@ function getProviders() { * * @param getSessionOptions - Options for getting the session, e.g., set `required: true` to enforce that a session _must_ exist, the user will be directed to a login page otherwise. */ -async function getSession(getSessionOptions?: GetSessionOptions): Promise { +async function getSession(getSessionOptions?: GetSessionOptions): Promise { const nuxt = useNuxtApp() const callbackUrlFallback = await getRequestURLWN(nuxt) @@ -222,7 +223,9 @@ async function getSession(getSessionOptions?: GetSessionOptions): Promise { + const encodedLoc = href.replace(/"/g, '%22') + const encodedHeader = new URL(href).toString() + nuxtApp.ssrContext!._renderResponse = { + statusCode: sanitizeStatusCode(302, 302), + body: ``, + headers: { location: encodedHeader }, + } + abortNavigation() + }) + } + } + + window.location.href = href + // If href contains a hash, the browser does not reload the page. We reload manually. + if (href.includes('#')) { + window.location.reload() + } + + // TODO: Sadly, we cannot directly import types from `vue-router` as it leads to build failures. Typing the router about should help us to avoid manually typing `route` below + const router = nuxtApp.$router as { push: (href: string) => void } + + // Wait for the `window.location.href` navigation from above to complete to avoid showing content. If that doesn't work fast enough, delegate navigation back to the `vue-router` (risking a vue-router 404 warning in the console, but still avoiding content-flashes of the protected target page) + const waitForNavigationWithFallbackToRouter = new Promise(resolve => setTimeout(resolve, 60 * 1000)) + .then(() => router.push(href)) + + return waitForNavigationWithFallbackToRouter as Promise +} diff --git a/src/runtime/composables/common/getRequestURL.ts b/src/runtime/composables/common/getRequestURL.ts new file mode 100644 index 00000000..413a32fc --- /dev/null +++ b/src/runtime/composables/common/getRequestURL.ts @@ -0,0 +1,10 @@ +import getURL from 'requrl' +import { type NuxtApp, callWithNuxt, useRequestEvent } from '#app' + +export function getRequestURL(includePath = true) { + return getURL(useRequestEvent()?.node.req, includePath) +} + +export function getRequestURLWN(nuxt: NuxtApp) { + return callWithNuxt(nuxt, getRequestURL) +} diff --git a/src/runtime/composables/commonAuthState.ts b/src/runtime/composables/commonAuthState.ts index 19c53d67..5e42b310 100644 --- a/src/runtime/composables/commonAuthState.ts +++ b/src/runtime/composables/commonAuthState.ts @@ -1,8 +1,6 @@ import { computed } from 'vue' -import getURL from 'requrl' -import { joinURL } from 'ufo' import type { SessionLastRefreshedAt, SessionStatus } from '../types' -import { useRequestEvent, useRuntimeConfig, useState } from '#imports' +import { useState } from '#imports' export function makeCommonAuthState() { const data = useState('auth:data', () => undefined) @@ -30,27 +28,10 @@ export function makeCommonAuthState() { return 'unauthenticated' }) - // Determine base url of app - let baseURL - const { origin, pathname, fullBaseUrl } = useRuntimeConfig().public.auth.computed - if (origin) { - // Case 1: An origin was supplied by the developer in the runtime-config. Use it by returning the already assembled full base url that contains it - baseURL = fullBaseUrl - } - else { - // Case 2: An origin was not supplied, we determine it from the request - const determinedOrigin = getURL(useRequestEvent()?.node.req, false) - baseURL = joinURL(determinedOrigin, pathname) - } - return { data, loading, lastRefreshedAt, status, - _internal: { - baseURL, - pathname - } } } diff --git a/src/runtime/composables/local/useAuth.ts b/src/runtime/composables/local/useAuth.ts index 60ce39ce..db3e4660 100644 --- a/src/runtime/composables/local/useAuth.ts +++ b/src/runtime/composables/local/useAuth.ts @@ -3,9 +3,9 @@ import { type Ref, readonly } from 'vue' import type { CommonUseAuthReturn, GetSessionOptions, SecondarySignInOptions, SignInFunc, SignOutFunc, SignUpOptions } from '../../types' import { jsonPointerGet, objectFromJsonPointer, useTypedBackendConfig } from '../../helpers' import { _fetch } from '../../utils/fetch' -import { getRequestURLWN } from '../../utils/callWithNuxt' import { determineCallbackUrl } from '../../utils/url' -import { formatToken } from '../../utils/local' +import { getRequestURLWN } from '../common/getRequestURL' +import { formatToken } from './utils/token' import { type UseAuthStateReturn, useAuthState } from './useAuthState' import { callWithNuxt } from '#app/nuxt' // @ts-expect-error - #auth not defined diff --git a/src/runtime/composables/local/useAuthState.ts b/src/runtime/composables/local/useAuthState.ts index 06ffe561..5dcb0c73 100644 --- a/src/runtime/composables/local/useAuthState.ts +++ b/src/runtime/composables/local/useAuthState.ts @@ -2,7 +2,7 @@ import { type ComputedRef, computed, getCurrentInstance, watch } from 'vue' import type { CommonUseAuthStateReturn } from '../../types' import { makeCommonAuthState } from '../commonAuthState' import { useTypedBackendConfig } from '../../helpers' -import { formatToken } from '../../utils/local' +import { formatToken } from './utils/token' import type { CookieRef } from '#app' import { onMounted, useCookie, useRuntimeConfig, useState } from '#imports' // @ts-expect-error - #auth not defined @@ -22,8 +22,6 @@ export interface UseAuthStateReturn extends CommonUseAuthStateReturn void clearToken: () => void _internal: { - baseURL: string - pathname: string rawTokenCookie: CookieRef } } @@ -108,7 +106,6 @@ export function useAuthState(): UseAuthStateReturn { setToken, clearToken, _internal: { - ...commonAuthState._internal, rawTokenCookie: _rawTokenCookie } } diff --git a/src/runtime/utils/local.ts b/src/runtime/composables/local/utils/token.ts similarity index 79% rename from src/runtime/utils/local.ts rename to src/runtime/composables/local/utils/token.ts index c4dc3ab1..c4d2652b 100644 --- a/src/runtime/utils/local.ts +++ b/src/runtime/composables/local/utils/token.ts @@ -1,4 +1,4 @@ -import type { ProviderLocalResolvedConfig } from '../helpers' +import type { ProviderLocalResolvedConfig } from '../../../helpers' export function formatToken(token: string | null | undefined, config: ProviderLocalResolvedConfig): string | null { if (token === null || token === undefined) { diff --git a/src/runtime/helpers.ts b/src/runtime/helpers.ts index 123c0b96..e5c21df7 100644 --- a/src/runtime/helpers.ts +++ b/src/runtime/helpers.ts @@ -1,26 +1,10 @@ // TODO: This should be merged into `./utils` -import { parseURL } from 'ufo' import type { DeepRequired } from 'ts-essentials' import type { ProviderAuthjs, ProviderLocal, SupportedAuthProviders } from './types' import type { useRuntimeConfig } from '#imports' export const isProduction = process.env.NODE_ENV === 'production' -export function getOriginAndPathnameFromURL(url: string) { - const { protocol, host, pathname } = parseURL(url) - - let origin - if (host && protocol) { - origin = `${protocol}//${host}` - } - - const pathname_ = pathname.length > 0 ? pathname : undefined - return { - origin, - pathname: pathname_ - } -} - // We use `DeepRequired` here because options are actually enriched using `defu` // but due to a build error we can't use `DeepRequired` inside runtime config definition. type RuntimeConfig = ReturnType diff --git a/src/runtime/middleware/auth.ts b/src/runtime/middleware/sidebase-auth.ts similarity index 89% rename from src/runtime/middleware/auth.ts rename to src/runtime/middleware/sidebase-auth.ts index b1cb4992..76409d69 100644 --- a/src/runtime/middleware/auth.ts +++ b/src/runtime/middleware/sidebase-auth.ts @@ -1,6 +1,6 @@ -import type { navigateToAuthPages } from '../utils/url' -import { determineCallbackUrl } from '../utils/url' +import { determineCallbackUrl, isExternalUrl } from '../utils/url' import { isProduction } from '../helpers' +import { ERROR_PREFIX } from '../utils/logger' import { defineNuxtRouteMiddleware, navigateTo, useAuth, useRuntimeConfig } from '#imports' type MiddlewareMeta = boolean | { @@ -74,7 +74,7 @@ export default defineNuxtRouteMiddleware((to) => { * We do not want to enforce protection on `404` pages (unless the user opts out of it by setting `allow404WithoutAuth: false`). * * This is to: - * - improve UX and DX: Having to log-in to see a `404` is not pleasent, + * - improve UX and DX: Having to log-in to see a `404` is not pleasant, * - avoid the `Error [ERR_HTTP_HEADERS_SENT]`-error that occurs when we redirect to the sign-in page when the original to-page does not exist. Likely related to https://github.com/nuxt/framework/issues/9438 * */ @@ -91,7 +91,7 @@ export default defineNuxtRouteMiddleware((to) => { const signInOptions: Parameters[1] = { error: 'SessionRequired', callbackUrl: determineCallbackUrl(authConfig, () => to.fullPath) } // eslint-disable-next-line ts/ban-ts-comment // @ts-ignore This is valid for a backend-type of `authjs`, where sign-in accepts a provider as a first argument - return signIn(undefined, signInOptions) as ReturnType + return signIn(undefined, signInOptions) as Promise } // Redirect path was provided @@ -99,7 +99,14 @@ export default defineNuxtRouteMiddleware((to) => { return navigateTo(options.navigateUnauthenticatedTo) } + const loginPage = authConfig.provider.pages.login + if (typeof loginPage !== 'string') { + console.warn(`${ERROR_PREFIX} provider.pages.login is misconfigured`) + return + } + // Default callback URL was provided + const external = isExternalUrl(loginPage) if (typeof globalAppMiddleware === 'object' && globalAppMiddleware.addDefaultCallbackUrl) { let redirectUrl: string = to.fullPath if (typeof globalAppMiddleware.addDefaultCallbackUrl === 'string') { @@ -107,15 +114,15 @@ export default defineNuxtRouteMiddleware((to) => { } return navigateTo({ - path: authConfig.provider.pages.login, + path: loginPage, query: { redirect: redirectUrl } - }) + }, { external }) } // Fall back to login page - return navigateTo(authConfig.provider.pages.login) + return navigateTo(loginPage, { external }) }) interface MiddlewareOptionsNormalized { @@ -147,7 +154,7 @@ function normalizeUserOptions(userOptions: MiddlewareMeta | undefined): Middlewa if (userOptions.unauthenticatedOnly === undefined) { if (!isProduction) { console.warn( - '[@sidebase/nuxt-auth] `unauthenticatedOnly` was not provided to `definePageMeta` - defaulting to Guest Mode enabled. ' + `${ERROR_PREFIX} \`unauthenticatedOnly\` was not provided to \`definePageMeta\` - defaulting to Guest Mode enabled. ` + 'Read more at https://auth.sidebase.io/guide/application-side/protecting-pages#middleware-options' ) } diff --git a/src/runtime/plugin.ts b/src/runtime/plugin.ts index 75952fad..b5d29a0f 100644 --- a/src/runtime/plugin.ts +++ b/src/runtime/plugin.ts @@ -1,6 +1,8 @@ import { getHeader } from 'h3' -import authMiddleware from './middleware/auth' +import authMiddleware from './middleware/sidebase-auth' import { getNitroRouteRules } from './utils/kit' +import { FetchConfigurationError } from './utils/fetch' +import { resolveApiBaseURL } from './utils/url' import { _refreshHandler, addRouteMiddleware, defineNuxtPlugin, useAuth, useAuthState, useRuntimeConfig } from '#imports' export default defineNuxtPlugin(async (nuxtApp) => { @@ -9,10 +11,18 @@ export default defineNuxtPlugin(async (nuxtApp) => { const { getSession } = useAuth() // use runtimeConfig - const runtimeConfig = useRuntimeConfig().public.auth + const wholeRuntimeConfig = useRuntimeConfig() + const runtimeConfig = wholeRuntimeConfig.public.auth + const globalAppMiddleware = runtimeConfig.globalAppMiddleware const routeRules = import.meta.server ? getNitroRouteRules(nuxtApp._route.path) : {} + // Set the correct `baseURL` on the server, + // because the client would not have access to environment variables + if (import.meta.server) { + runtimeConfig.baseURL = resolveApiBaseURL(wholeRuntimeConfig) + } + // Skip auth if we're prerendering let nitroPrerender = false if (nuxtApp.ssrContext) { @@ -30,8 +40,23 @@ export default defineNuxtPlugin(async (nuxtApp) => { } // Only fetch session if it was not yet initialized server-side - if (typeof data.value === 'undefined' && !nitroPrerender && !disableServerSideAuth) { - await getSession() + const isErrorUrl = nuxtApp.ssrContext?.error === true + const requireAuthOnErrorPage = globalAppMiddleware === true || (typeof globalAppMiddleware === 'object' && globalAppMiddleware.allow404WithoutAuth) + const shouldFetchSession = typeof data.value === 'undefined' + && !nitroPrerender + && !disableServerSideAuth + && !(isErrorUrl && requireAuthOnErrorPage) + + if (shouldFetchSession) { + try { + await getSession() + } + catch (e) { + // Do not throw the configuration error as it can lead to infinite recursion + if (!(e instanceof FetchConfigurationError)) { + throw e + } + } } // 2. Setup session maintanence, e.g., auto refreshing or refreshing on foux @@ -55,7 +80,6 @@ export default defineNuxtPlugin(async (nuxtApp) => { } // 3. Enable the middleware, either globally or as a named `auth` option - const { globalAppMiddleware } = useRuntimeConfig().public.auth if ( globalAppMiddleware === true || (typeof globalAppMiddleware === 'object' && globalAppMiddleware.isEnabled) diff --git a/src/runtime/server/services/authjs/nuxtAuthHandler.ts b/src/runtime/server/services/authjs/nuxtAuthHandler.ts index 82e845a6..7934054b 100644 --- a/src/runtime/server/services/authjs/nuxtAuthHandler.ts +++ b/src/runtime/server/services/authjs/nuxtAuthHandler.ts @@ -15,7 +15,7 @@ import { ERROR_MESSAGES } from '../errors' import { isNonEmptyObject } from '../../../utils/checkSessionResult' import { getServerOrigin } from '../utils' import { useTypedBackendConfig } from '../../../helpers' - +import { resolveApiBaseURL } from '../../../utils/url' import { useRuntimeConfig } from '#imports' let preparedAuthjsHandler: ((req: RequestInternal) => Promise) | undefined @@ -102,15 +102,15 @@ export function NuxtAuthHandler(nuxtAuthOptions?: AuthOptions) { /** Gets session on server-side */ export async function getServerSession(event: H3Event) { const runtimeConfig = useRuntimeConfig() - const authBasePath = runtimeConfig.public.auth.computed.pathname + const authBasePathname = resolveApiBaseURL(runtimeConfig, true) const trustHostUserPreference = useTypedBackendConfig(runtimeConfig, 'authjs').trustHost // avoid running auth middleware on auth middleware (see #186) - if (event.path && event.path.startsWith(authBasePath)) { + if (event.path && event.path.startsWith(authBasePathname)) { return null } - const sessionUrlPath = joinURL(authBasePath, '/session') + const sessionUrlPath = joinURL(authBasePathname, '/session') const headers = getHeaders(event) as HeadersInit if (!preparedAuthjsHandler) { // Edge-case: If no auth-endpoint was called yet, `preparedAuthHandler`-initialization was also not attempted as Nuxt lazily loads endpoints in production-mode. diff --git a/src/runtime/server/services/utils.ts b/src/runtime/server/services/utils.ts index a692e3ee..7cbe5446 100644 --- a/src/runtime/server/services/utils.ts +++ b/src/runtime/server/services/utils.ts @@ -1,7 +1,8 @@ import type { H3Event } from 'h3' import getURL from 'requrl' -import { camelCase } from 'scule' +import { parseURL } from 'ufo' import { isProduction } from '../../helpers' +import { resolveApiBaseURL } from '../../utils/url' import { ERROR_MESSAGES } from './errors' import { useRuntimeConfig } from '#imports' @@ -9,20 +10,17 @@ import { useRuntimeConfig } from '#imports' * Get `origin` and fallback to `x-forwarded-host` or `host` headers if not in production. */ export function getServerOrigin(event?: H3Event): string { - const config = useRuntimeConfig() + const runtimeConfig = useRuntimeConfig() // Prio 1: Environment variable - const envOriginKey = config.public.auth.originEnvKey - const envFromRuntimeConfig = extractFromRuntimeConfig(config, envOriginKey) - const envOrigin = envFromRuntimeConfig ?? process.env[envOriginKey] - if (envOrigin) { - return envOrigin - } - - // Prio 2: Computed origin - const runtimeConfigOrigin = config.public.auth.computed.origin - if (runtimeConfigOrigin) { - return runtimeConfigOrigin + // Prio 2: Static configuration + + // Resolve the value from runtime config/env. + // If the returned value has protocol and host, it is considered valid. + const baseURL = resolveApiBaseURL(runtimeConfig, false) + const parsed = parseURL(baseURL) + if (parsed.protocol && parsed.host) { + return `${parsed.protocol}//${parsed.host}` } // Prio 3: Try to infer the origin if we're not in production @@ -32,17 +30,3 @@ export function getServerOrigin(event?: H3Event): string { throw new Error(ERROR_MESSAGES.NO_ORIGIN) } - -type RuntimeConfig = ReturnType - -function extractFromRuntimeConfig(config: RuntimeConfig, envVariableName: string): string | undefined { - let normalized = envVariableName.startsWith('NUXT_') - ? envVariableName.slice(5) - : envVariableName - normalized = camelCase(normalized, { normalize: true }) - - const extracted = config[normalized] - return typeof extracted === 'string' - ? extracted - : undefined -} diff --git a/src/runtime/types.ts b/src/runtime/types.ts index dc225b69..9b037855 100644 --- a/src/runtime/types.ts +++ b/src/runtime/types.ts @@ -424,6 +424,21 @@ export interface ModuleOptions { * Whether the module is enabled at all */ isEnabled?: boolean + /** + * Disables the Nuxt `$fetch` optimization. Do so when your auth logic is not handled by a Nuxt server (e.g. when using an external backend). + * + * Disabling the optimisation means that NuxtAuth will prefer calling `baseURL` + path instead of just path, + * which would often translate to an HTTP call. + * + * By default, this option is set to `false` for `authjs` provider. + * For `local` provider `disableInternalRouting` will default to `true` unless explicitly changed by user. + * + * ## Example + * With `disableInternalRouting: true` and `baseURL: 'https://example.com/api/auth'` your calls would be made to `https://example.com/api/auth` endpoints instead of `/api/auth`. + * + * @see https://nuxt.com/docs/api/utils/dollarfetch + */ + disableInternalRouting?: boolean /** * Forces your server to send a "loading" status on all requests, prompting the client to fetch on the client. If your website has caching, this prevents the server from caching someone's authentication status. * @@ -537,10 +552,6 @@ export interface CommonUseAuthStateReturn { loading: Ref lastRefreshedAt: Ref status: ComputedRef - _internal: { - baseURL: string - pathname: string - } } // Common `useAuth` method-types @@ -604,15 +615,11 @@ export type SignInFunc = ( export interface ModuleOptionsNormalized extends ModuleOptions { isEnabled: boolean + baseURL: string + disableInternalRouting: boolean // Cannot use `DeepRequired` here because it leads to build issues provider: Required> sessionRefresh: NonNullable globalAppMiddleware: NonNullable originEnvKey: string - - computed: { - origin: string | undefined - pathname: string - fullBaseUrl: string - } } diff --git a/src/runtime/utils/callWithNuxt.ts b/src/runtime/utils/callWithNuxt.ts deleted file mode 100644 index 6f601782..00000000 --- a/src/runtime/utils/callWithNuxt.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { getRequestURL, joinPathToApiURL, navigateToAuthPages } from './url' -import type { NuxtApp } from '#app/nuxt' -import { callWithNuxt } from '#app/nuxt' - -export const navigateToAuthPageWN = (nuxt: NuxtApp, href: string) => callWithNuxt(nuxt, navigateToAuthPages, [href]) -export const getRequestURLWN = (nuxt: NuxtApp) => callWithNuxt(nuxt, getRequestURL) -export const joinPathToApiURLWN = (nuxt: NuxtApp, path: string) => callWithNuxt(nuxt, joinPathToApiURL, [path]) - -export const makeCWN = (func: (...args: any) => unknown) => (nuxt: NuxtApp) => callWithNuxt(nuxt, func) diff --git a/src/runtime/utils/extractFromRuntimeConfig.ts b/src/runtime/utils/extractFromRuntimeConfig.ts new file mode 100644 index 00000000..87daf4a1 --- /dev/null +++ b/src/runtime/utils/extractFromRuntimeConfig.ts @@ -0,0 +1,16 @@ +import { camelCase } from 'scule' +import type { useRuntimeConfig } from '#imports' + +type RuntimeConfig = ReturnType + +export function extractFromRuntimeConfig(config: RuntimeConfig, envVariableName: string): string | undefined { + let normalized = envVariableName.startsWith('NUXT_') + ? envVariableName.slice(5) + : envVariableName + normalized = camelCase(normalized, { normalize: true }) + + const extracted = config[normalized] + return typeof extracted === 'string' + ? extracted + : undefined +} diff --git a/src/runtime/utils/fetch.ts b/src/runtime/utils/fetch.ts index aa0e2488..f1eb8902 100644 --- a/src/runtime/utils/fetch.ts +++ b/src/runtime/utils/fetch.ts @@ -1,21 +1,37 @@ -import { joinPathToApiURL } from './url' -import { callWithNuxt } from '#app/nuxt' +import { resolveApiUrlPath } from './url' +import { ERROR_PREFIX } from './logger' +import { callWithNuxt, useRuntimeConfig } from '#app' import type { useNuxtApp } from '#imports' export async function _fetch(nuxt: ReturnType, path: string, fetchOptions?: Parameters[1]): Promise { + const runtimeConfig = await callWithNuxt(nuxt, useRuntimeConfig) + const joinedPath = resolveApiUrlPath(path, runtimeConfig) + + // Prevent callback recursion when doing internal routing + if (runtimeConfig.public.auth.disableInternalRouting === false) { + const currentPath = nuxt.ssrContext?.event?.path + if (currentPath?.startsWith(joinedPath)) { + console.error(`${ERROR_PREFIX} Recursion detected at ${joinedPath}. Have you set the correct \`auth.baseURL\`?`) + throw new FetchConfigurationError('Server configuration error') + } + } + try { - const joinedPath = await callWithNuxt(nuxt, () => joinPathToApiURL(path)) return $fetch(joinedPath, fetchOptions) } catch (error) { - // TODO: Adapt this error to be more generic - console.error( - 'Error in `nuxt-auth`-app-side data fetching: Have you added the authentication handler server-endpoint `[...].ts`? Have you added the authentication handler in a non-default location (default is `~/server/api/auth/[...].ts`) and not updated the module-setting `auth.basePath`? Error is:' - ) + let errorMessage = `${ERROR_PREFIX} Error while requesting ${joinedPath}.` + if (runtimeConfig.public.auth.provider.type === 'authjs') { + errorMessage += ' Have you added the authentication handler server-endpoint `[...].ts`? Have you added the authentication handler in a non-default location (default is `~/server/api/auth/[...].ts`) and not updated the module-setting `auth.basePath`?' + } + errorMessage += ' Error is:' + console.error(errorMessage) console.error(error) - throw new Error( - 'Runtime error, checkout the console logs to debug, open an issue at https://github.com/sidebase/nuxt-auth/issues/new/choose if you continue to have this problem' + throw new FetchConfigurationError( + 'Runtime error, check the console logs to debug, open an issue at https://github.com/sidebase/nuxt-auth/issues/new/choose if you continue to have this problem' ) } } + +export class FetchConfigurationError extends Error {} diff --git a/src/runtime/utils/logger.ts b/src/runtime/utils/logger.ts new file mode 100644 index 00000000..2a804260 --- /dev/null +++ b/src/runtime/utils/logger.ts @@ -0,0 +1 @@ +export const ERROR_PREFIX = '[@sidebase/nuxt-auth]' diff --git a/src/runtime/utils/url.ts b/src/runtime/utils/url.ts index 31219f65..847a3d73 100644 --- a/src/runtime/utils/url.ts +++ b/src/runtime/utils/url.ts @@ -1,77 +1,79 @@ -import { joinURL } from 'ufo' -import getURL from 'requrl' -import { sanitizeStatusCode } from 'h3' -import type { ModuleOptionsNormalized } from '../types' -import { abortNavigation, useAuthState, useNuxtApp, useRequestEvent } from '#imports' +import { joinURL, parseURL, withLeadingSlash } from 'ufo' -export const getRequestURL = (includePath = true) => getURL(useRequestEvent()?.node.req, includePath) -export function joinPathToApiURL(path: string) { - const authStateInternal = useAuthState()._internal +// Slimmed down type to allow easy unit testing +interface RuntimeConfig { + public: { + auth: { + baseURL: string + disableInternalRouting: boolean + originEnvKey: string + } + } +} - // For internal calls, use a different base - // https://github.com/sidebase/nuxt-auth/issues/742 - const base = path.startsWith('/') - ? authStateInternal.pathname - : authStateInternal.baseURL +/** https://auth.sidebase.io/guide/application-side/configuration#baseurl */ +export function resolveApiUrlPath( + endpointPath: string, + runtimeConfig: RuntimeConfig +): string { + // Fully-specified endpoint path - do not join with `baseURL` + if (isExternalUrl(endpointPath)) { + return endpointPath + } - return joinURL(base, path) + const baseURL = resolveApiBaseURL(runtimeConfig) + return joinURL(baseURL, endpointPath) } -/** - * Function to correctly navigate to auth-routes, necessary as the auth-routes are not part of the nuxt-app itself, so unknown to nuxt / vue-router. - * - * More specifically, we need this function to correctly handle the following cases: - * 1. On the client-side, returning `navigateTo(signInUrl)` leads to a `404` error as the next-auth-signin-page was not registered with the vue-router that is used for routing under the hood. For this reason we need to - * manually set `window.location.href` on the client **and then fake return a Promise that does not immediately resolve to block navigation (although it will not actually be fully awaited, but just be awaited long enough for the naviation to complete)**. - * 2. Additionally on the server-side, we cannot use `navigateTo(signInUrl)` as this uses `vue-router` internally which does not know the "external" sign-in page of next-auth and thus will log a warning which we want to avoid. - * - * Adapted from: https://github.com/nuxt/nuxt/blob/d188542a35bb541c7ed2e4502c687c2132979882/packages/nuxt/src/app/composables/router.ts#L161-L188 - * - * @param href HREF / URL to navigate to - */ -export function navigateToAuthPages(href: string) { - const nuxtApp = useNuxtApp() +export function resolveApiBaseURL(runtimeConfig: RuntimeConfig, returnOnlyPathname?: boolean): string { + const authRuntimeConfig = runtimeConfig.public.auth - if (import.meta.server) { - if (nuxtApp.ssrContext) { - // TODO: consider deprecating in favour of `app:rendered` and removing - return nuxtApp.callHook('app:redirected').then(() => { - const encodedLoc = href.replace(/"/g, '%22') - const encodedHeader = new URL(href).toString() - nuxtApp.ssrContext!._renderResponse = { - statusCode: sanitizeStatusCode(302, 302), - body: ``, - headers: { location: encodedHeader }, - } - abortNavigation() - }) + // If the user has not specified `returnOnlyPathname`, infer it automatically. + // When internal routing is enabled, drop everything except path. + if (returnOnlyPathname === undefined) { + returnOnlyPathname = !runtimeConfig.public.auth.disableInternalRouting + } + + // Default to static runtime config (still overridable using `NUXT_PUBLIC_AUTH_BASE_URL`) + let baseURL = authRuntimeConfig.baseURL + + // Note: the `server` condition is here because Nuxt explicitly filters out all the env variables for the Client build, + // thus the check can be safely dropped. Instead of it, the `runtime/plugin` would set the `baseURL` on the runtime config. + if (import.meta.server !== false && authRuntimeConfig.originEnvKey) { + // Override base URL using environment variable specified in `originEnvKey` if any. + // By default, would use `AUTH_ORIGIN`, can be changed by user + const envBaseURL = process.env[authRuntimeConfig.originEnvKey] + if (envBaseURL) { + baseURL = envBaseURL } } - window.location.href = href - // If href contains a hash, the browser does not reload the page. We reload manually. - if (href.includes('#')) { - window.location.reload() + if (returnOnlyPathname) { + baseURL = withLeadingSlash(parseURL(baseURL).pathname) } - // TODO: Sadly, we cannot directly import types from `vue-router` as it leads to build failures. Typing the router about should help us to avoid manually typing `route` below - const router = nuxtApp.$router as { push: (href: string) => void } + return baseURL +} - // Wait for the `window.location.href` navigation from above to complete to avoid showing content. If that doesn't work fast enough, delegate navigation back to the `vue-router` (risking a vue-router 404 warning in the console, but still avoiding content-flashes of the protected target page) - const waitForNavigationWithFallbackToRouter = new Promise(resolve => setTimeout(resolve, 60 * 1000)) - .then(() => router.push(href)) - return waitForNavigationWithFallbackToRouter as Promise +/** Slimmed down auth runtime config for `determineCallbackUrl` */ +interface AuthRuntimeConfigForCallbackUrl { + globalAppMiddleware: { + addDefaultCallbackUrl?: string | boolean + } | boolean } /** - * Determins the desired callback url based on the users desires. Either: + * Determines the desired callback url based on the users desires. Either: * - uses a hardcoded path the user provided, * - determines the callback based on the target the user wanted to reach * * @param authConfig Authentication runtime module config * @param getOriginalTargetPath Function that returns the original location the user wanted to reach */ -export function determineCallbackUrl>(authConfig: ModuleOptionsNormalized, getOriginalTargetPath: () => T): T | string | undefined { +export function determineCallbackUrl>( + authConfig: AuthRuntimeConfigForCallbackUrl, + getOriginalTargetPath: () => T +): T | string | undefined { const authConfigCallbackUrl = typeof authConfig.globalAppMiddleware === 'object' ? authConfig.globalAppMiddleware.addDefaultCallbackUrl : undefined @@ -93,3 +95,12 @@ export function determineCallbackUrl>(authCon return getOriginalTargetPath() } } + +/** + * Naively checks if a URL is external or not by comparing against its protocol. + * + * URL being valid is not a concern for this function as it is used with developer-controlled inputs. + */ +export function isExternalUrl(url: string): boolean { + return url.startsWith('http://') || url.startsWith('https://') +} diff --git a/tests/authjs.url.spec.ts b/tests/authjs.url.spec.ts new file mode 100644 index 00000000..82bd5e5f --- /dev/null +++ b/tests/authjs.url.spec.ts @@ -0,0 +1,231 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { resolveApiBaseURL, resolveApiUrlPath } from '../src/runtime/utils/url' + +/* + * This spec file covers usecases of the `authjs` provider. + * The main difference from `local.url.spec` is the `disableInternalRouting` flag being set to + * `false` in order to prioritize internal routing to the external one. + */ + +describe('endpoint path construction', () => { + describe('relative baseURL', () => { + it('default value', () => { + expect(testResolve('/api/auth')).toBe('/api/auth/signin') + }) + + it('default value with relative endpoint path', () => { + expect(testResolve('/api/auth', 'signin')).toBe('/api/auth/signin') + }) + + it('default value and long endpoint path', () => { + expect(testResolve('/api/auth', '/long/signin/path')).toBe('/api/auth/long/signin/path') + }) + + it('default value and long relative endpoint path', () => { + expect(testResolve('/api/auth', 'long/signin/path')).toBe('/api/auth/long/signin/path') + }) + + it('slash', () => { + expect(testResolve('/')).toBe('/signin') + }) + + it('slash with relative endpoint path', () => { + expect(testResolve('/', 'signin')).toBe('/signin') + }) + + it('empty', () => { + expect(testResolve('')).toBe('/signin') + }) + + it('empty with relative endpoint path', () => { + expect(testResolve('', 'signin')).toBe('/signin') + }) + }) + + // http://locahost:8080 + describe('localhost baseURL', () => { + it('only origin', () => { + expect(testResolve('http://localhost:8080')).toBe('/signin') + }) + + it('only origin with relative endpoint path', () => { + expect(testResolve('http://localhost:8080', 'signin')).toBe('/signin') + }) + + it('path', () => { + expect(testResolve('http://localhost:8080/auth')).toBe('/auth/signin') + }) + + it('path with relative endpoint path', () => { + expect(testResolve('http://localhost:8080/auth', 'signin')).toBe('/auth/signin') + }) + + it('path and slash', () => { + expect(testResolve('http://localhost:8080/auth/')).toBe('/auth/signin') + }) + + it('path and slash with relative endpoint path', () => { + expect(testResolve('http://localhost:8080/auth/', 'signin')).toBe('/auth/signin') + }) + + it('slash', () => { + expect(testResolve('http://localhost:8080/')).toBe('/signin') + }) + + it('slash with relative endpoint path', () => { + expect(testResolve('http://localhost:8080/', 'signin')).toBe('/signin') + }) + }) + + // https://example.com + describe('external baseURL', () => { + it('only origin', () => { + expect(testResolve('https://example.com')).toBe('/signin') + }) + + it('only origin with relative endpoint path', () => { + expect(testResolve('https://example.com', 'signin')).toBe('/signin') + }) + + it('path', () => { + expect(testResolve('https://example.com/auth')).toBe('/auth/signin') + }) + + it('path with relative endpoint path', () => { + expect(testResolve('https://example.com/auth', 'signin')).toBe('/auth/signin') + }) + + it('path and slash', () => { + expect(testResolve('https://example.com/auth/')).toBe('/auth/signin') + }) + + it('path and slash with relative endpoint path', () => { + expect(testResolve('https://example.com/auth/', 'signin')).toBe('/auth/signin') + }) + + it('slash', () => { + expect(testResolve('https://example.com/')).toBe('/signin') + }) + + it('slash with relative endpoint path', () => { + expect(testResolve('https://example.com/', 'signin')).toBe('/signin') + }) + }) + + // External endpoint paths should take priority over everything else + describe('external endpoint path', () => { + it ('http and https', () => { + expect(testResolve('/api/auth', 'http://example.com/signin')).toBe('http://example.com/signin') + expect(testResolve('/api/auth', 'https://example.com/signin')).toBe('https://example.com/signin') + }) + + it('disregards any values', () => { + const target = 'https://example.com/signin' + + expect(testResolve('', target)).toBe(target) + expect(testResolve('.', target)).toBe(target) + expect(testResolve('*', target)).toBe(target) + expect(testResolve('/', target)).toBe(target) + expect(testResolve('/api/auth', target)).toBe(target) + expect(testResolve('/api/auth/', target)).toBe(target) + expect(testResolve('http://localhost:8080', target)).toBe(target) + expect(testResolve('http://localhost:8080/', target)).toBe(target) + expect(testResolve('http://localhost:8080/auth', target)).toBe(target) + expect(testResolve('http://localhost:8080/auth/', target)).toBe(target) + expect(testResolve('https://example.com', target)).toBe(target) + expect(testResolve('https://example.com/', target)).toBe(target) + expect(testResolve('https://example.com/auth', target)).toBe(target) + expect(testResolve('https://example.com/auth/', target)).toBe(target) + }) + + it('does not consider malformed', () => { + expect(testResolve('/api/auth', 'example.com')).toBe('/api/auth/example.com') + expect(testResolve('/api/auth', 'example.com/signin')).toBe('/api/auth/example.com/signin') + }) + }) + + // Environment variables should take priority over `baseURL` + describe('env variables', () => { + afterEach(() => { + vi.unstubAllEnvs() + }) + + it('can override default', () => { + vi.stubEnv('AUTH_ORIGIN', '/other') + expect(testResolve('/api/auth')).toBe('/other/signin') + }) + + it('can override default with fully-specified URL', () => { + vi.stubEnv('AUTH_ORIGIN', 'https://example.com/auth') + expect(testResolve('/api/auth')).toBe('/auth/signin') + }) + + it('can override using different name', () => { + vi.stubEnv('OTHER_ENV', '/other') + expect(testResolve('/api/auth', undefined, 'OTHER_ENV')).toBe('/other/signin') + }) + + it('does not use AUTH_ORIGIN when other env key is given', () => { + vi.stubEnv('AUTH_ORIGIN', '/other') + expect(testResolve('/api/auth', undefined, 'OTHER_ENV')).toBe('/api/auth/signin') + }) + + it('can override using NUXT_PUBLIC_AUTH_BASE_URL', () => { + // Unfortunately, it is not really possible to unit test the way Nuxt sets values + // on runtime config with the simple testing setup here. + // We trust Nuxt to correctly set `runtimeConfig`: https://nuxt.com/docs/guide/going-further/runtime-config#environment-variables + vi.stubEnv('NUXT_PUBLIC_AUTH_BASE_URL', '/other') + expect(testResolve(process.env.NUXT_PUBLIC_AUTH_BASE_URL as string)).toBe('/other/signin') + }) + + it('works with double assignment', () => { + // This test case is made specifically to check how `resolveApiUrlPath` would behave + // when a default `baseURL` value is being overwritten by `runtime/plugin` with a value provided by `resolveApiBaseURL`. + + // 1. `baseURL` is set to a user-provided value `https://default.example.com/api/auth`; + const initialBaseURL = 'https://example.com/api/auth' + + // 2. User also provides `originEnvKey` and sets the env to a different value `https://changed.example.com/auth/v2`; + const newBaseURL = 'https://changed.example.com/auth/v2' + const expectedNewBaseURL = '/auth/v2' + const envName = 'AUTH_ORIGIN' + vi.stubEnv(envName, newBaseURL) + + const runtimeConfig = mockRuntimeConfig(initialBaseURL, envName) + + // 3. `runtime/plugin` tries to resolve the base and gets `https://changed.example.com/auth/v2` as a result; + const resolvedNewBaseURL = resolveApiBaseURL(runtimeConfig) + expect(resolvedNewBaseURL).toBe(expectedNewBaseURL) + + // Unstub the env to emulate the client and verify that the call produces a different result + vi.unstubAllEnvs() + expect(resolveApiBaseURL(runtimeConfig)).not.toBe(expectedNewBaseURL) + + // 4. `runtime/plugin` overwrites the `baseURL`; + runtimeConfig.public.auth.baseURL = resolvedNewBaseURL + + // 5. Another code calls `resolveApiUrlPath` / `resolveApiBaseURL` and should get the changed value exactly. + const resolvedBaseURL = resolveApiBaseURL(runtimeConfig) + expect(resolvedBaseURL).toBe(expectedNewBaseURL) + const resolvedApiUrlPath = resolveApiUrlPath('/', runtimeConfig) + expect(resolvedApiUrlPath).toBe(expectedNewBaseURL) + }) + }) +}) + +function testResolve(desiredBaseURL: string, endpointPath = '/signin', envVariableName = 'AUTH_ORIGIN'): string { + const runtimeConfig = mockRuntimeConfig(desiredBaseURL, envVariableName) + return resolveApiUrlPath(endpointPath, runtimeConfig) +} + +function mockRuntimeConfig(desiredBaseURL: string, envVariableName: string) { + return { + public: { + auth: { + baseURL: desiredBaseURL, + disableInternalRouting: false, + originEnvKey: envVariableName + } + } + } +} diff --git a/tests/local.url.spec.ts b/tests/local.url.spec.ts new file mode 100644 index 00000000..a91d0a68 --- /dev/null +++ b/tests/local.url.spec.ts @@ -0,0 +1,224 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { resolveApiBaseURL, resolveApiUrlPath } from '../src/runtime/utils/url' + +describe('endpoint path construction', () => { + describe('relative baseURL', () => { + it('default value', () => { + expect(testResolve('/api/auth')).toBe('/api/auth/signin') + }) + + it('default value with relative endpoint path', () => { + expect(testResolve('/api/auth', 'signin')).toBe('/api/auth/signin') + }) + + it('default value and long endpoint path', () => { + expect(testResolve('/api/auth', '/long/signin/path')).toBe('/api/auth/long/signin/path') + }) + + it('default value and long relative endpoint path', () => { + expect(testResolve('/api/auth', 'long/signin/path')).toBe('/api/auth/long/signin/path') + }) + + it('slash', () => { + expect(testResolve('/')).toBe('/signin') + }) + + it('slash with relative endpoint path', () => { + expect(testResolve('/', 'signin')).toBe('/signin') + }) + + it('empty', () => { + expect(testResolve('')).toBe('/signin') + }) + + it('empty with relative endpoint path', () => { + expect(testResolve('', 'signin')).toBe('signin') + }) + }) + + // http://locahost:8080 + describe('localhost baseURL', () => { + it('only origin', () => { + expect(testResolve('http://localhost:8080')).toBe('http://localhost:8080/signin') + }) + + it('only origin with relative endpoint path', () => { + expect(testResolve('http://localhost:8080', 'signin')).toBe('http://localhost:8080/signin') + }) + + it('path', () => { + expect(testResolve('http://localhost:8080/auth')).toBe('http://localhost:8080/auth/signin') + }) + + it('path with relative endpoint path', () => { + expect(testResolve('http://localhost:8080/auth', 'signin')).toBe('http://localhost:8080/auth/signin') + }) + + it('path and slash', () => { + expect(testResolve('http://localhost:8080/auth/')).toBe('http://localhost:8080/auth/signin') + }) + + it('path and slash with relative endpoint path', () => { + expect(testResolve('http://localhost:8080/auth/', 'signin')).toBe('http://localhost:8080/auth/signin') + }) + + it('slash', () => { + expect(testResolve('http://localhost:8080/')).toBe('http://localhost:8080/signin') + }) + + it('slash with relative endpoint path', () => { + expect(testResolve('http://localhost:8080/', 'signin')).toBe('http://localhost:8080/signin') + }) + }) + + // https://example.com + describe('external baseURL', () => { + it('only origin', () => { + expect(testResolve('https://example.com')).toBe('https://example.com/signin') + }) + + it('only origin with relative endpoint path', () => { + expect(testResolve('https://example.com', 'signin')).toBe('https://example.com/signin') + }) + + it('path', () => { + expect(testResolve('https://example.com/auth')).toBe('https://example.com/auth/signin') + }) + + it('path with relative endpoint path', () => { + expect(testResolve('https://example.com/auth', 'signin')).toBe('https://example.com/auth/signin') + }) + + it('path and slash', () => { + expect(testResolve('https://example.com/auth/')).toBe('https://example.com/auth/signin') + }) + + it('path and slash with relative endpoint path', () => { + expect(testResolve('https://example.com/auth/', 'signin')).toBe('https://example.com/auth/signin') + }) + + it('slash', () => { + expect(testResolve('https://example.com/')).toBe('https://example.com/signin') + }) + + it('slash with relative endpoint path', () => { + expect(testResolve('https://example.com/', 'signin')).toBe('https://example.com/signin') + }) + }) + + // External endpoint paths should take priority over everything else + describe('external endpoint path', () => { + it ('http and https', () => { + expect(testResolve('/api/auth', 'http://example.com/signin')).toBe('http://example.com/signin') + expect(testResolve('/api/auth', 'https://example.com/signin')).toBe('https://example.com/signin') + }) + + it('disregards any values', () => { + const target = 'https://example.com/signin' + + expect(testResolve('', target)).toBe(target) + expect(testResolve('.', target)).toBe(target) + expect(testResolve('*', target)).toBe(target) + expect(testResolve('/', target)).toBe(target) + expect(testResolve('/api/auth', target)).toBe(target) + expect(testResolve('/api/auth/', target)).toBe(target) + expect(testResolve('http://localhost:8080', target)).toBe(target) + expect(testResolve('http://localhost:8080/', target)).toBe(target) + expect(testResolve('http://localhost:8080/auth', target)).toBe(target) + expect(testResolve('http://localhost:8080/auth/', target)).toBe(target) + expect(testResolve('https://example.com', target)).toBe(target) + expect(testResolve('https://example.com/', target)).toBe(target) + expect(testResolve('https://example.com/auth', target)).toBe(target) + expect(testResolve('https://example.com/auth/', target)).toBe(target) + }) + + it('does not consider malformed', () => { + expect(testResolve('/api/auth', 'example.com')).toBe('/api/auth/example.com') + expect(testResolve('/api/auth', 'example.com/signin')).toBe('/api/auth/example.com/signin') + }) + }) + + // Environment variables should take priority over `baseURL` + describe('env variables', () => { + afterEach(() => { + vi.unstubAllEnvs() + }) + + it('can override default', () => { + vi.stubEnv('AUTH_ORIGIN', '/other') + expect(testResolve('/api/auth')).toBe('/other/signin') + }) + + it('can override default with fully-specified URL', () => { + vi.stubEnv('AUTH_ORIGIN', 'https://example.com/auth') + expect(testResolve('/api/auth')).toBe('https://example.com/auth/signin') + }) + + it('can override using different name', () => { + vi.stubEnv('OTHER_ENV', '/other') + expect(testResolve('/api/auth', undefined, 'OTHER_ENV')).toBe('/other/signin') + }) + + it('does not use AUTH_ORIGIN when other env key is given', () => { + vi.stubEnv('AUTH_ORIGIN', '/other') + expect(testResolve('/api/auth', undefined, 'OTHER_ENV')).toBe('/api/auth/signin') + }) + + it('can override using NUXT_PUBLIC_AUTH_BASE_URL', () => { + // Unfortunately, it is not really possible to unit test the way Nuxt sets values + // on runtime config with the simple testing setup here. + // We trust Nuxt to correctly set `runtimeConfig`: https://nuxt.com/docs/guide/going-further/runtime-config#environment-variables + vi.stubEnv('NUXT_PUBLIC_AUTH_BASE_URL', '/other') + expect(testResolve(process.env.NUXT_PUBLIC_AUTH_BASE_URL as string)).toBe('/other/signin') + }) + + it('works with double assignment', () => { + // This test case is made specifically to check how `resolveApiUrlPath` would behave + // when a default `baseURL` value is being overwritten by `runtime/plugin` with a value provided by `resolveApiBaseURL`. + + // 1. `baseURL` is set to a user-provided value `https://default.example.com/api/auth`; + const initialBaseURL = 'https://example.com/api/auth' + + // 2. User also provides `originEnvKey` and sets the env to a different value `https://changed.example.com/auth`; + const expectedNewBaseURL = 'https://changed.example.com/auth' + const envName = 'AUTH_ORIGIN' + vi.stubEnv(envName, expectedNewBaseURL) + + const runtimeConfig = mockRuntimeConfig(initialBaseURL, envName) + + // 3. `runtime/plugin` tries to resolve the base and gets `https://changed.example.com/auth` as a result; + const resolvedNewBaseURL = resolveApiBaseURL(runtimeConfig) + expect(resolvedNewBaseURL).toBe(expectedNewBaseURL) + + // Unstub the env to emulate the client and verify that the call produces a different result + vi.unstubAllEnvs() + expect(resolveApiBaseURL(runtimeConfig)).not.toBe(expectedNewBaseURL) + + // 4. `runtime/plugin` overwrites the `baseURL`; + runtimeConfig.public.auth.baseURL = resolvedNewBaseURL + + // 5. Another code calls `resolveApiUrlPath` / `resolveApiBaseURL` and should get the changed value exactly. + const resolvedBaseURL = resolveApiBaseURL(runtimeConfig) + expect(resolvedBaseURL).toBe(expectedNewBaseURL) + const resolvedApiUrlPath = resolveApiUrlPath('/', runtimeConfig) + expect(resolvedApiUrlPath).toBe(expectedNewBaseURL) + }) + }) +}) + +function testResolve(desiredBaseURL: string, endpointPath = '/signin', envVariableName = 'AUTH_ORIGIN'): string { + const runtimeConfig = mockRuntimeConfig(desiredBaseURL, envVariableName) + return resolveApiUrlPath(endpointPath, runtimeConfig) +} + +function mockRuntimeConfig(desiredBaseURL: string, envVariableName: string) { + return { + public: { + auth: { + baseURL: desiredBaseURL, + disableInternalRouting: true, + originEnvKey: envVariableName + } + } + } +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 00000000..843ed788 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + include: ['tests/*.spec.ts'] + } +})