From ac547bbf7c70394e1afee13b36c4b90957efeae8 Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Fri, 12 Jun 2026 13:38:32 +0200 Subject: [PATCH 01/34] feat: oauth integration (#2659) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add Google OAuth login support (#2625) * 🔧 Add login via google * 🔧 Update code style and docs * Add fix for db migrate * 🔧 Update docker-compose * 🔧 Fix sqlite" * 🔧 Update docker-compose * ⚰️ Remove environments * 🔧 Fix: remove ensureGoogleIdColumn workaround from sqlite.ts * 🔧 Remove space * move oauth section * add openid client * wip make oauth more generic * properly allow multiple providers * fix type import * github login flow * adjust github logo with theme * move docs to own page * nullable password, prevent timing attack this prevents timing attacks by always checking hash even if there is none prevents using basic auth if 2fa is enabled * support generic oidc * add ability to set password for oidc users this allows oidc users to add password login cant be removed after * move password login route move password login route from /api/session to /api/auth/password align with oauth * unique index on oauth * link/unlink logic * improve docs * support allowed domains * support auto register * refactoring * disable pw auth * move 2fa to its own page * 2fa for oauth, rework 2fa system * fix design, fix link Closes #2650 * add auto launch * improve docs * improvements --------- Co-authored-by: Daniel Molenda --- .../config/external-authentication.md | 182 +++ .../examples/tutorials/basic-installation.md | 2 +- .../components/Base/FormSecondaryButton.vue | 26 + .../components/Form/SecondaryActionField.vue | 5 +- src/app/components/Header/LangSelector.vue | 6 +- src/app/components/Icons/Brands/GitHub.vue | 23 + src/app/components/Icons/Brands/Google.vue | 247 ++++ src/app/components/Icons/Brands/Provider.vue | 10 + src/app/components/Ui/LoginOauthButton.vue | 21 + src/app/layouts/default.vue | 4 +- src/app/middleware/auth.global.ts | 6 +- src/app/pages/login.vue | 118 +- src/app/pages/login/2fa.vue | 100 ++ src/app/pages/login/index.vue | 147 +++ src/app/pages/me.vue | 102 +- src/app/stores/auth.ts | 1 - src/app/utils/types.ts | 2 + src/i18n/locales/en.json | 12 +- src/i18n/locales/pl.json | 1 + src/package.json | 1 + src/pnpm-lock.yaml | 21 + .../api/auth/[provider]/callback.get.ts | 87 ++ src/server/api/auth/[provider]/index.get.ts | 50 + src/server/api/auth/[provider]/link.get.ts | 36 + src/server/api/auth/cancel.post.ts | 10 + src/server/api/auth/methods.get.ts | 18 + .../password.post.ts} | 24 +- src/server/api/auth/pending.get.ts | 14 + src/server/api/auth/unlink.post.ts | 11 + src/server/api/auth/verify-2fa.post.ts | 50 + src/server/api/session.get.ts | 12 +- .../database/migrations/0005_clumsy_korg.sql | 23 + .../migrations/meta/0005_snapshot.json | 1009 +++++++++++++++++ .../database/migrations/meta/_journal.json | 7 + .../database/repositories/user/schema.ts | 50 +- .../database/repositories/user/service.ts | 273 ++++- .../database/repositories/user/types.ts | 3 +- src/server/plugins/manager.ts | 18 +- src/server/utils/config.ts | 28 + src/server/utils/oauth.ts | 258 +++++ src/server/utils/password.ts | 15 +- src/server/utils/session.ts | 24 +- src/shared/utils/permissions.ts | 9 +- src/test/unit/password.spec.ts | 4 + 44 files changed, 2848 insertions(+), 222 deletions(-) create mode 100644 docs/content/advanced/config/external-authentication.md create mode 100644 src/app/components/Base/FormSecondaryButton.vue create mode 100644 src/app/components/Icons/Brands/GitHub.vue create mode 100644 src/app/components/Icons/Brands/Google.vue create mode 100644 src/app/components/Icons/Brands/Provider.vue create mode 100644 src/app/components/Ui/LoginOauthButton.vue create mode 100644 src/app/pages/login/2fa.vue create mode 100644 src/app/pages/login/index.vue create mode 100644 src/server/api/auth/[provider]/callback.get.ts create mode 100644 src/server/api/auth/[provider]/index.get.ts create mode 100644 src/server/api/auth/[provider]/link.get.ts create mode 100644 src/server/api/auth/cancel.post.ts create mode 100644 src/server/api/auth/methods.get.ts rename src/server/api/{session.post.ts => auth/password.post.ts} (70%) create mode 100644 src/server/api/auth/pending.get.ts create mode 100644 src/server/api/auth/unlink.post.ts create mode 100644 src/server/api/auth/verify-2fa.post.ts create mode 100644 src/server/database/migrations/0005_clumsy_korg.sql create mode 100644 src/server/database/migrations/meta/0005_snapshot.json create mode 100644 src/server/utils/oauth.ts diff --git a/docs/content/advanced/config/external-authentication.md b/docs/content/advanced/config/external-authentication.md new file mode 100644 index 00000000..420c3275 --- /dev/null +++ b/docs/content/advanced/config/external-authentication.md @@ -0,0 +1,182 @@ +--- +title: External Authentication +--- + +## OAuth + +### Setup + +To enable OAuth set the env var `OAUTH_PROVIDERS` to any of the following providers: + +| Provider | Value | +| ----------------------------- | -------- | +| [Google](#google) | `google` | +| [GitHub](#github) | `github` | +| [Generic OIDC](#generic-oidc) | `oidc` | + +You can enable multiple providers by separating them with a comma: + +e.g. `google,github` + +### Auto Register + +To automatically register users that log in with an OAuth provider, set the following environment variable to `true`: + +| Env | Required | Default | Description | +| --------------------- | -------- | ------- | ------------------------ | +| `OAUTH_AUTO_REGISTER` | ✖️ | `false` | Enable auto-registration | + +When enabled: + +- If a user logs in with an email address that is not yet registered, a new account will be created for them. + +- If a user logs in with an email address that is already registered, their account will be linked to the OAuth provider (if not already linked), regardless of the value of `OAUTH_AUTO_REGISTER`. + +/// warning | Security + +Users will be created with Admin Permissions, as the permissions system is not yet implemented. Only enable this if you trust all users that can log in with the OAuth provider. + +Use [Allowed Domains](#allowed-domains) to restrict which users can log in. + +/// + +### Allowed Domains + +To only allow users with an email address from a specific domain to log in, set the following environment variable to the allowed domain. + +| Env | Required | Default | Description | +| ----------------------- | -------- | ------- | --------------------- | +| `OAUTH_ALLOWED_DOMAINS` | ✖️ | - | Allowed email domains | + +You can allow multiple domains by separating them with a comma: + +e.g. `example.com,example.org` + +### Auto Launch + +To automatically launch the OAuth login flow when visiting the login page, set the following environment variable to the provider you want to launch: + +| Env | Required | Default | Description | +| ------------------- | -------- | ------- | ----------------------------- | +| `OAUTH_AUTO_LAUNCH` | ✖️ | - | Auto launch an OAuth provider | + +When enabled: + +- Visiting the login page will automatically redirect to the selected provider's login page +- The user can still access the normal login page by visiting `/login?auto_launch=false` +- You can auto launch any provider by visiting `/login?auto_launch=` + +### Redirect URIs + +You have to configure the following redirect URIs in your OAuth provider: + +- `https:///api/auth//callback` + Used to log in to with the provider +- `https:///api/auth//link` + Used to link an existing account to the provider + +If your provider does not support multiple redirect URIs (e.g. GitHub) but allows multiple URIs under the same base, then configure: + +- `https:///api/auth//` + +### Provider Configuration + +#### Google + +| Env | Required | Description | +| ---------------------------- | -------- | -------------------- | +| `OAUTH_GOOGLE_CLIENT_ID` | ✔️ | Google Client ID | +| `OAUTH_GOOGLE_CLIENT_SECRET` | ✔️ | Google Client Secret | + +
Setup
+ +1. Go to [Google Cloud Console](https://console.cloud.google.com/apis/credentials) +2. Create an OAuth 2.0 Client ID (Web application) +3. Add Authorized redirect URI: See [Redirect URIs](#redirect-uris) +4. Copy the Client ID and Client Secret to the environment variables + +#### GitHub + +| Env | Required | Description | +| ---------------------------- | -------- | -------------------- | +| `OAUTH_GITHUB_CLIENT_ID` | ✔️ | GitHub Client ID | +| `OAUTH_GITHUB_CLIENT_SECRET` | ✔️ | GitHub Client Secret | + +
Setup
+ +1. Go to [GitHub Developer Settings](https://github.com/settings/developers) +2. Create a new OAuth App +3. Add Authorization callback URL: See [Redirect URIs](#redirect-uris) +4. Create a new client secret +5. Copy the Client ID and Client Secret to the environment variables + +#### Generic OIDC + +This supports generic OIDC providers like Authelia, Authentik, etc. + +The provider needs to support: + +- PKCE +- default scopes: `openid email profile` +- Client Secret Authentication `client_secret_post` + +The provider needs to be available with HTTPS and have a valid certificate. + +| Env | Required | Default | Example | Description | +| -------------------------- | -------- | ------- | -------------------------- | ------------------ | +| `OAUTH_OIDC_SERVER` | ✔️ | - | `https://auth.example.com` | OIDC Server | +| `OAUTH_OIDC_CLIENT_ID` | ✔️ | - | - | OIDC Client ID | +| `OAUTH_OIDC_CLIENT_SECRET` | ✔️ | - | - | OIDC Client Secret | +| `OAUTH_OIDC_NAME` | ✖️ | OIDC | `Authelia` | Provider Name | + +##### Authelia Setup + +Generate Client ID and Secret: + +```shell +# Client ID +docker run --rm authelia/authelia:latest authelia crypto rand --length 72 --charset rfc3986 +# Client Secret +docker run --rm authelia/authelia:latest authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986 +``` + +```yaml +- client_id: '...' + client_name: wg-easy + client_secret: '$pbkdf2-...' + redirect_uris: + - https:///api/auth/oidc/callback + - https:///api/auth/oidc/link + scopes: + - openid + - profile + - email + authorization_policy: one_factor + pre_configured_consent_duration: 1 week + require_pkce: true + token_endpoint_auth_method: client_secret_post +``` + +#### Generic OAuth + +Not currently supported + +### Disable Password Authentication + +To disable password-based authentication and only allow login via OAuth providers, set the following environment variable to `true`: + +| Env | Required | Default | Description | +| ----------------------- | -------- | ------- | ------------------------------- | +| `DISABLE_PASSWORD_AUTH` | ✖️ | `false` | Disable password authentication | + +When enabled: + +- Users will not be able to log in with a password + +/// warning | Access Recovery + +Before disabling password authentication, ensure that at least one OAuth provider is configured and that you have successfully linked an administrator account. + +If no login method is available, you will not be able to log in to the application and will need to reset the configuration to regain access. + +/// diff --git a/docs/content/examples/tutorials/basic-installation.md b/docs/content/examples/tutorials/basic-installation.md index 0ef8cddb..8df9f905 100644 --- a/docs/content/examples/tutorials/basic-installation.md +++ b/docs/content/examples/tutorials/basic-installation.md @@ -2,7 +2,7 @@ title: Basic Installation --- - + ## Requirements diff --git a/src/app/components/Base/FormSecondaryButton.vue b/src/app/components/Base/FormSecondaryButton.vue new file mode 100644 index 00000000..d9c6c71a --- /dev/null +++ b/src/app/components/Base/FormSecondaryButton.vue @@ -0,0 +1,26 @@ + + + diff --git a/src/app/components/Form/SecondaryActionField.vue b/src/app/components/Form/SecondaryActionField.vue index 7d8cefaf..94878c55 100644 --- a/src/app/components/Form/SecondaryActionField.vue +++ b/src/app/components/Form/SecondaryActionField.vue @@ -1,8 +1,9 @@ diff --git a/src/app/components/Header/LangSelector.vue b/src/app/components/Header/LangSelector.vue index c0452def..1d302e9e 100644 --- a/src/app/components/Header/LangSelector.vue +++ b/src/app/components/Header/LangSelector.vue @@ -1,12 +1,14 @@ - - diff --git a/src/app/pages/login/2fa.vue b/src/app/pages/login/2fa.vue new file mode 100644 index 00000000..5910ce07 --- /dev/null +++ b/src/app/pages/login/2fa.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/app/pages/login/index.vue b/src/app/pages/login/index.vue new file mode 100644 index 00000000..39657322 --- /dev/null +++ b/src/app/pages/login/index.vue @@ -0,0 +1,147 @@ + + + diff --git a/src/app/pages/me.vue b/src/app/pages/me.vue index b0bb54a7..52a666e6 100644 --- a/src/app/pages/me.vue +++ b/src/app/pages/me.vue @@ -27,6 +27,7 @@ {{ $t('general.password') }} {{ $t('general.2fa') }} -
+

@@ -93,7 +95,7 @@

@@ -113,6 +115,60 @@

+ + + {{ $t('general.externalAuth') }} + + + + + @@ -123,8 +179,18 @@ import { encodeQR } from 'qr'; const authStore = useAuthStore(); +const { data: authMethods } = await useFetch('/api/auth/methods'); + const name = ref(authStore.userData?.name); const email = ref(authStore.userData?.email); +const hasPassword = computed(() => authStore.userData?.hasPassword); +const oauthProvider = computed(() => authStore.userData?.oauthProvider); +const oauthProviderInfo = computed(() => { + if (!authStore.userData?.oauthProvider) { + return null; + } + return authMethods.value?.providers?.[authStore.userData.oauthProvider]; +}); const _submit = useSubmit( (data) => @@ -158,13 +224,14 @@ const _updatePassword = useSubmit( currentPassword.value = ''; newPassword.value = ''; confirmPassword.value = ''; + return authStore.update(); }, } ); function updatePassword() { return _updatePassword({ - currentPassword: currentPassword.value, + currentPassword: hasPassword.value ? currentPassword.value : null, newPassword: newPassword.value, confirmPassword: confirmPassword.value, }); @@ -249,4 +316,21 @@ async function disable2fa() { currentPassword: disable2faPassword.value, }); } + +const _unlinkOauth = useSubmit( + (data) => + $fetch(`/api/auth/unlink`, { + method: 'post', + body: data, + }), + { + revert: async () => { + return authStore.update(); + }, + } +); + +async function unlinkOauth() { + return _unlinkOauth({}); +} diff --git a/src/app/stores/auth.ts b/src/app/stores/auth.ts index 64bac790..64aeb889 100644 --- a/src/app/stores/auth.ts +++ b/src/app/stores/auth.ts @@ -1,5 +1,4 @@ import type { H3Event } from 'h3'; -import type { SharedPublicUser } from '~~/shared/utils/permissions'; export const useAuthStore = defineStore('Auth', () => { const userData = useState('user-data', () => null); diff --git a/src/app/utils/types.ts b/src/app/utils/types.ts index 0736ab97..b293ce98 100644 --- a/src/app/utils/types.ts +++ b/src/app/utils/types.ts @@ -4,3 +4,5 @@ export type ToastParams = { title: string; message: string; }; + +export type OAUTH_PROVIDER = 'google' | 'github' | 'oidc'; diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 86120f19..6a863f7d 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -20,7 +20,11 @@ "2faKey": "TOTP Key", "2faCodeDesc": "Enter the code from your authenticator app.", "disable2fa": "Disable Two Factor Authentication", - "disable2faDesc": "Enter your password to disable Two Factor Authentication." + "disable2faDesc": "Enter your password to disable Two Factor Authentication.", + "linkOauth": "Link your account with an external provider", + "unlinkOauth": "Unlink", + "linkedWith": "Linked with {0}", + "providerDisabled": "Your currently linked provider is not enabled" }, "general": { "name": "Name", @@ -28,6 +32,7 @@ "password": "Password", "newPassword": "New Password", "updatePassword": "Update Password", + "addPassword": "Add Password", "mtu": "MTU", "allowedIps": "Allowed IPs", "dns": "DNS", @@ -41,7 +46,8 @@ "confirmPassword": "Confirm Password", "loading": "Loading...", "2fa": "Two Factor Authentication", - "2faCode": "TOTP Code" + "2faCode": "TOTP Code", + "externalAuth": "External Authentication" }, "setup": { "welcome": "Welcome to your first setup of wg-easy", @@ -72,6 +78,8 @@ }, "login": { "signIn": "Sign In", + "signInWith": "Sign in with {0}", + "or": "or", "rememberMe": "Remember me", "rememberMeDesc": "Stay logged after closing the browser", "insecure": "You can't log in with an insecure connection. Use HTTPS.", diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json index 2d572eaa..be500131 100644 --- a/src/i18n/locales/pl.json +++ b/src/i18n/locales/pl.json @@ -72,6 +72,7 @@ }, "login": { "signIn": "Zaloguj się", + "or": "lub", "rememberMe": "Zapamiętaj mnie", "rememberMeDesc": "Pozostań zalogowany po zamknięciu przeglądarki", "insecure": "Nie możesz zalogować się przez niezabezpieczone połączenie. Użyj HTTPS.", diff --git a/src/package.json b/src/package.json index 96429ef1..031e5971 100644 --- a/src/package.json +++ b/src/package.json @@ -44,6 +44,7 @@ "js-sha256": "^0.11.1", "nuxt": "^3.21.6", "obug": "^2.1.1", + "openid-client": "^6.8.4", "otpauth": "^9.5.1", "pinia": "^3.0.4", "qr": "^0.6.0", diff --git a/src/pnpm-lock.yaml b/src/pnpm-lock.yaml index fdd1ecbf..008219ff 100644 --- a/src/pnpm-lock.yaml +++ b/src/pnpm-lock.yaml @@ -77,6 +77,9 @@ importers: obug: specifier: ^2.1.1 version: 2.1.1 + openid-client: + specifier: ^6.8.4 + version: 6.8.4 otpauth: specifier: ^9.5.1 version: 9.5.1 @@ -4452,6 +4455,9 @@ packages: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true + jose@6.2.3: + resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} + js-base64@3.7.8: resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} @@ -4839,6 +4845,9 @@ packages: engines: {node: '>=18'} hasBin: true + oauth4webapi@3.8.6: + resolution: {integrity: sha512-iwemM91xz8nryHti2yTmg5fhyEMVOkOXwHNqbvcATjyajb5oQxCQzrNOA6uElRHuMhQQTKUyFKV9y/CNyg25BQ==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -4888,6 +4897,9 @@ packages: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} + openid-client@6.8.4: + resolution: {integrity: sha512-QSw0BA08piujetEwfZsHoTrDpMEha7GDZDicQqVwX4u0ChCjefvjDB++TZ8BTg76UpwhzIQgdvvfgfl3HpCSAw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -10475,6 +10487,8 @@ snapshots: jiti@2.7.0: {} + jose@6.2.3: {} + js-base64@3.7.8: {} js-sha256@0.11.1: {} @@ -11076,6 +11090,8 @@ snapshots: pathe: 2.0.3 tinyexec: 1.2.3 + oauth4webapi@3.8.6: {} + object-assign@4.1.1: {} object-deep-merge@2.0.1: {} @@ -11124,6 +11140,11 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 + openid-client@6.8.4: + dependencies: + jose: 6.2.3 + oauth4webapi: 3.8.6 + optionator@0.9.4: dependencies: deep-is: 0.1.4 diff --git a/src/server/api/auth/[provider]/callback.get.ts b/src/server/api/auth/[provider]/callback.get.ts new file mode 100644 index 00000000..2d710f3f --- /dev/null +++ b/src/server/api/auth/[provider]/callback.get.ts @@ -0,0 +1,87 @@ +export default defineEventHandler(async (event) => { + const { config, provider, providerConfig } = await buildOauthConfig(event); + + const session = await useWGSession(event); + if ( + !session.data.oauth_nonce || + !session.data.oauth_verifier || + !session.data.oauth_state + ) { + throw createError({ + statusCode: 400, + statusMessage: 'Missing OAuth State', + }); + } + + const userInfo = await getUserInfo( + event, + config, + { + oauth_nonce: session.data.oauth_nonce, + oauth_verifier: session.data.oauth_verifier, + oauth_state: session.data.oauth_state, + }, + providerConfig + ); + + const result = await Database.users.loginWithOAuth( + provider, + userInfo.sub, + userInfo.preferred_username || userInfo.email, + userInfo.email, + userInfo.name || 'User' + ); + + if (!result.success) { + switch (result.error) { + case 'TOTP_REQUIRED': + await session.update({ + pendingLogin: { + type: 'oauth', + userId: result.userId, + remember: false, + }, + oauth_nonce: undefined, + oauth_state: undefined, + oauth_verifier: undefined, + }); + return sendRedirect(event, '/login/2fa'); + case 'USER_DISABLED': + throw createError({ + statusCode: 401, + statusMessage: 'User disabled', + }); + case 'USER_ALREADY_LINKED': + throw createError({ + statusCode: 401, + statusMessage: + 'User already linked with different account or provider', + }); + case 'AUTO_REGISTER_DISABLED': + throw createError({ + statusCode: 401, + statusMessage: 'Auto registration is disabled', + }); + case 'UNEXPECTED_ERROR': + throw createError({ + statusCode: 500, + statusMessage: 'Unexpected error', + }); + } + assertUnreachable(result); + } + + // Create session + const data = await session.update({ + userId: result.user.id, + oauth_nonce: undefined, + oauth_state: undefined, + oauth_verifier: undefined, + }); + + SERVER_DEBUG( + `New OAuth Session: ${data.id} for ${result.user.id} (${result.user.username}) with ${provider}` + ); + + return sendRedirect(event, '/'); +}); diff --git a/src/server/api/auth/[provider]/index.get.ts b/src/server/api/auth/[provider]/index.get.ts new file mode 100644 index 00000000..dd973195 --- /dev/null +++ b/src/server/api/auth/[provider]/index.get.ts @@ -0,0 +1,50 @@ +import * as client from 'openid-client'; +import { z } from 'zod'; + +const OauthQuerySchema = z.object({ + link: z.coerce.boolean().optional(), +}); + +export default defineEventHandler(async (event) => { + const params = await getValidatedQuery( + event, + validateZod(OauthQuerySchema, event) + ); + + const { config, provider, providerConfig } = await buildOauthConfig(event); + + const host = getRequestHost(event); + const protocol = WG_ENV.INSECURE ? 'http' : 'https'; + const baseUri = `${protocol}://${host}/api/auth/${provider}`; + + let redirectUri = `${baseUri}/callback`; + if (params.link) { + redirectUri = `${baseUri}/link`; + } + + const codeVerifier = client.randomPKCECodeVerifier(); + const codeChallenge = await client.calculatePKCECodeChallenge(codeVerifier); + const nonce = client.randomNonce(); + const state = client.randomState(); + + const parameters: Record = { + ...providerConfig.params, + redirect_uri: redirectUri, + scope: providerConfig.scope, + code_challenge: codeChallenge, + code_challenge_method: 'S256', + nonce: nonce, + state: state, + }; + + const session = await useWGSession(event); + await session.update({ + oauth_nonce: nonce, + oauth_verifier: codeVerifier, + oauth_state: state, + }); + + const redirectTo = client.buildAuthorizationUrl(config, parameters); + + return sendRedirect(event, redirectTo.toString()); +}); diff --git a/src/server/api/auth/[provider]/link.get.ts b/src/server/api/auth/[provider]/link.get.ts new file mode 100644 index 00000000..51b6191d --- /dev/null +++ b/src/server/api/auth/[provider]/link.get.ts @@ -0,0 +1,36 @@ +export default definePermissionEventHandler( + 'me', + 'update', + async ({ event, user, checkPermissions }) => { + checkPermissions(user); + + const { config, provider, providerConfig } = await buildOauthConfig(event); + + const session = await useWGSession(event); + if ( + !session.data.oauth_nonce || + !session.data.oauth_verifier || + !session.data.oauth_state + ) { + throw createError({ + statusCode: 400, + statusMessage: 'Missing OAuth State', + }); + } + + const userInfo = await getUserInfo( + event, + config, + { + oauth_nonce: session.data.oauth_nonce, + oauth_verifier: session.data.oauth_verifier, + oauth_state: session.data.oauth_state, + }, + providerConfig + ); + + await Database.users.linkOauth(user.id, provider, userInfo.sub); + + return sendRedirect(event, '/me'); + } +); diff --git a/src/server/api/auth/cancel.post.ts b/src/server/api/auth/cancel.post.ts new file mode 100644 index 00000000..2f0c2fcd --- /dev/null +++ b/src/server/api/auth/cancel.post.ts @@ -0,0 +1,10 @@ +export default defineEventHandler(async (event) => { + const session = await useWGSession(event, false); + await session.update({ + pendingLogin: undefined, + oauth_nonce: undefined, + oauth_state: undefined, + oauth_verifier: undefined, + }); + return { success: true as const }; +}); diff --git a/src/server/api/auth/methods.get.ts b/src/server/api/auth/methods.get.ts new file mode 100644 index 00000000..48b9fb2e --- /dev/null +++ b/src/server/api/auth/methods.get.ts @@ -0,0 +1,18 @@ +export default defineEventHandler(() => { + return { + providers: WG_ENV.OAUTH_PROVIDERS?.reduce( + (acc, curr) => { + acc[curr] = { + enabled: true, + friendlyName: OAUTH_PROVIDERS[curr].friendlyName, + }; + return acc; + }, + {} as Record + ), + oauthEnabled: + WG_ENV.OAUTH_PROVIDERS !== undefined && WG_ENV.OAUTH_PROVIDERS.length > 0, + passwordDisabled: WG_ENV.DISABLE_PASSWORD_AUTH, + autoLaunchProvider: WG_ENV.OAUTH_AUTO_LAUNCH, + }; +}); diff --git a/src/server/api/session.post.ts b/src/server/api/auth/password.post.ts similarity index 70% rename from src/server/api/session.post.ts rename to src/server/api/auth/password.post.ts index 07a46021..14829ce8 100644 --- a/src/server/api/session.post.ts +++ b/src/server/api/auth/password.post.ts @@ -1,12 +1,21 @@ import { UserLoginSchema } from '#db/repositories/user/types'; export default defineEventHandler(async (event) => { - const { username, password, remember, totpCode } = await readValidatedBody( + if (WG_ENV.DISABLE_PASSWORD_AUTH) { + throw createError({ + statusCode: 403, + statusMessage: 'Password authentication is disabled', + }); + } + + const { username, password, remember } = await readValidatedBody( event, validateZod(UserLoginSchema, event) ); - const result = await Database.users.login(username, password, totpCode); + const result = await Database.users.login(username, password); + + const session = await useWGSession(event, remember); // TODO: add localization support @@ -18,6 +27,13 @@ export default defineEventHandler(async (event) => { statusMessage: 'Invalid username or password', }); case 'TOTP_REQUIRED': + await session.update({ + pendingLogin: { + type: 'password', + userId: result.userId, + remember, + }, + }); return { status: 'TOTP_REQUIRED' as const }; case 'INVALID_TOTP_CODE': return { status: 'INVALID_TOTP_CODE' as const }; @@ -32,13 +48,11 @@ export default defineEventHandler(async (event) => { statusMessage: 'Unexpected error', }); } - assertUnreachable(result.error); + assertUnreachable(result); } const user = result.user; - const session = await useWGSession(event, remember); - const data = await session.update({ userId: user.id, }); diff --git a/src/server/api/auth/pending.get.ts b/src/server/api/auth/pending.get.ts new file mode 100644 index 00000000..623817ce --- /dev/null +++ b/src/server/api/auth/pending.get.ts @@ -0,0 +1,14 @@ +export default defineEventHandler(async (event) => { + const session = await useWGSession(event); + + if (!session.data.pendingLogin) { + throw createError({ + statusCode: 401, + statusMessage: 'No pending authentication', + }); + } + + return { + type: session.data.pendingLogin.type, + }; +}); diff --git a/src/server/api/auth/unlink.post.ts b/src/server/api/auth/unlink.post.ts new file mode 100644 index 00000000..6be0e644 --- /dev/null +++ b/src/server/api/auth/unlink.post.ts @@ -0,0 +1,11 @@ +export default definePermissionEventHandler( + 'me', + 'update', + async ({ user, checkPermissions }) => { + checkPermissions(user); + + await Database.users.unlinkOauth(user.id); + + return { success: true }; + } +); diff --git a/src/server/api/auth/verify-2fa.post.ts b/src/server/api/auth/verify-2fa.post.ts new file mode 100644 index 00000000..2fa19d86 --- /dev/null +++ b/src/server/api/auth/verify-2fa.post.ts @@ -0,0 +1,50 @@ +import { z } from 'zod'; + +const Verify2faSchema = z.object({ + totpCode: z.string().min(6).max(6), +}); + +export default defineEventHandler(async (event) => { + const { totpCode } = await readValidatedBody( + event, + validateZod(Verify2faSchema, event) + ); + const session = await useWGSession(event); + + const pendingLogin = session.data.pendingLogin; + if (!pendingLogin) { + throw createError({ + statusCode: 401, + statusMessage: 'No pending authentication', + }); + } + + const totpStatus = await Database.users.validateTotpCode( + pendingLogin.userId, + totpCode + ); + + switch (totpStatus) { + case 'INVALID_TOTP_CODE': + return { status: 'INVALID_TOTP_CODE' as const }; + case 'USER_DISABLED': + throw createError({ + statusCode: 401, + statusMessage: 'User disabled', + }); + case 'success': + break; + default: + assertUnreachable(totpStatus); + } + + await session.update({ + userId: pendingLogin.userId, + pendingLogin: undefined, + oauth_nonce: undefined, + oauth_state: undefined, + oauth_verifier: undefined, + }); + + return { status: 'success' as const }; +}); diff --git a/src/server/api/session.get.ts b/src/server/api/session.get.ts index 5d975ee5..7cb38bb6 100644 --- a/src/server/api/session.get.ts +++ b/src/server/api/session.get.ts @@ -1,9 +1,7 @@ -import type { SharedPublicUser } from '~~/shared/utils/permissions'; - export default defineEventHandler(async (event) => { const session = await useWGSession(event); - if (!session.data.userId) { + if (!session.data.userId || session.data.pendingLogin) { // not logged in throw createError({ statusCode: 401, @@ -18,6 +16,12 @@ export default defineEventHandler(async (event) => { statusMessage: 'Not found in Database', }); } + if (!user.enabled) { + throw createError({ + statusCode: 403, + statusMessage: 'User is disabled', + }); + } return { id: user.id, @@ -26,5 +30,7 @@ export default defineEventHandler(async (event) => { name: user.name, email: user.email, totpVerified: user.totpVerified, + oauthProvider: user.oauthProvider, + hasPassword: user.password !== null, } satisfies SharedPublicUser; }); diff --git a/src/server/database/migrations/0005_clumsy_korg.sql b/src/server/database/migrations/0005_clumsy_korg.sql new file mode 100644 index 00000000..315ed5ed --- /dev/null +++ b/src/server/database/migrations/0005_clumsy_korg.sql @@ -0,0 +1,23 @@ +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_users_table` ( + `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, + `username` text NOT NULL, + `password` text, + `email` text, + `name` text NOT NULL, + `role` integer NOT NULL, + `totp_key` text, + `totp_verified` integer NOT NULL, + `enabled` integer NOT NULL, + `oauth_provider` text, + `oauth_id` text, + `created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL, + `updated_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL +); +--> statement-breakpoint +INSERT INTO `__new_users_table`("id", "username", "password", "email", "name", "role", "totp_key", "totp_verified", "enabled", "created_at", "updated_at") SELECT "id", "username", "password", "email", "name", "role", "totp_key", "totp_verified", "enabled", "created_at", "updated_at" FROM `users_table`;--> statement-breakpoint +DROP TABLE `users_table`;--> statement-breakpoint +ALTER TABLE `__new_users_table` RENAME TO `users_table`;--> statement-breakpoint +PRAGMA foreign_keys=ON;--> statement-breakpoint +CREATE UNIQUE INDEX `users_table_username_unique` ON `users_table` (`username`);--> statement-breakpoint +CREATE UNIQUE INDEX `oauth_provider_id_unique` ON `users_table` (`oauth_provider`,`oauth_id`); \ No newline at end of file diff --git a/src/server/database/migrations/meta/0005_snapshot.json b/src/server/database/migrations/meta/0005_snapshot.json new file mode 100644 index 00000000..acb5a605 --- /dev/null +++ b/src/server/database/migrations/meta/0005_snapshot.json @@ -0,0 +1,1009 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "d41b21e2-3977-4e94-8250-d26a26678703", + "prevId": "0f072f91-cd10-4702-ae7b-245255d69d1e", + "tables": { + "clients_table": { + "name": "clients_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "interface_id": { + "name": "interface_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv4_address": { + "name": "ipv4_address", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv6_address": { + "name": "ipv6_address", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pre_up": { + "name": "pre_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "post_up": { + "name": "post_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "pre_down": { + "name": "pre_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "post_down": { + "name": "post_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pre_shared_key": { + "name": "pre_shared_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "allowed_ips": { + "name": "allowed_ips", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "server_allowed_ips": { + "name": "server_allowed_ips", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "firewall_ips": { + "name": "firewall_ips", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "persistent_keepalive": { + "name": "persistent_keepalive", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mtu": { + "name": "mtu", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "j_c": { + "name": "j_c", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "j_min": { + "name": "j_min", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "j_max": { + "name": "j_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i1": { + "name": "i1", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i2": { + "name": "i2", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i3": { + "name": "i3", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i4": { + "name": "i4", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i5": { + "name": "i5", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "dns": { + "name": "dns", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "server_endpoint": { + "name": "server_endpoint", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "clients_table_ipv4_address_unique": { + "name": "clients_table_ipv4_address_unique", + "columns": [ + "ipv4_address" + ], + "isUnique": true + }, + "clients_table_ipv6_address_unique": { + "name": "clients_table_ipv6_address_unique", + "columns": [ + "ipv6_address" + ], + "isUnique": true + } + }, + "foreignKeys": { + "clients_table_user_id_users_table_id_fk": { + "name": "clients_table_user_id_users_table_id_fk", + "tableFrom": "clients_table", + "tableTo": "users_table", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "clients_table_interface_id_interfaces_table_name_fk": { + "name": "clients_table_interface_id_interfaces_table_name_fk", + "tableFrom": "clients_table", + "tableTo": "interfaces_table", + "columnsFrom": [ + "interface_id" + ], + "columnsTo": [ + "name" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "general_table": { + "name": "general_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "setup_step": { + "name": "setup_step", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_password": { + "name": "session_password", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_timeout": { + "name": "session_timeout", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metrics_prometheus": { + "name": "metrics_prometheus", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metrics_json": { + "name": "metrics_json", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "metrics_password": { + "name": "metrics_password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "hooks_table": { + "name": "hooks_table", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "pre_up": { + "name": "pre_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "post_up": { + "name": "post_up", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "pre_down": { + "name": "pre_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "post_down": { + "name": "post_down", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "hooks_table_id_interfaces_table_name_fk": { + "name": "hooks_table_id_interfaces_table_name_fk", + "tableFrom": "hooks_table", + "tableTo": "interfaces_table", + "columnsFrom": [ + "id" + ], + "columnsTo": [ + "name" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "interfaces_table": { + "name": "interfaces_table", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "device": { + "name": "device", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv4_cidr": { + "name": "ipv4_cidr", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "ipv6_cidr": { + "name": "ipv6_cidr", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "mtu": { + "name": "mtu", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "j_c": { + "name": "j_c", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 7 + }, + "j_min": { + "name": "j_min", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 10 + }, + "j_max": { + "name": "j_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 1000 + }, + "s1": { + "name": "s1", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 128 + }, + "s2": { + "name": "s2", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 56 + }, + "s3": { + "name": "s3", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "s4": { + "name": "s4", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "h1": { + "name": "h1", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "h2": { + "name": "h2", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "h3": { + "name": "h3", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "h4": { + "name": "h4", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i1": { + "name": "i1", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i2": { + "name": "i2", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i3": { + "name": "i3", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i4": { + "name": "i4", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "i5": { + "name": "i5", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "firewall_enabled": { + "name": "firewall_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "interfaces_table_port_unique": { + "name": "interfaces_table_port_unique", + "columns": [ + "port" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "one_time_links_table": { + "name": "one_time_links_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "one_time_link": { + "name": "one_time_link", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "one_time_links_table_one_time_link_unique": { + "name": "one_time_links_table_one_time_link_unique", + "columns": [ + "one_time_link" + ], + "isUnique": true + } + }, + "foreignKeys": { + "one_time_links_table_id_clients_table_id_fk": { + "name": "one_time_links_table_id_clients_table_id_fk", + "tableFrom": "one_time_links_table", + "tableTo": "clients_table", + "columnsFrom": [ + "id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "users_table": { + "name": "users_table", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "totp_key": { + "name": "totp_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "totp_verified": { + "name": "totp_verified", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "oauth_provider": { + "name": "oauth_provider", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "oauth_id": { + "name": "oauth_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "users_table_username_unique": { + "name": "users_table_username_unique", + "columns": [ + "username" + ], + "isUnique": true + }, + "oauth_provider_id_unique": { + "name": "oauth_provider_id_unique", + "columns": [ + "oauth_provider", + "oauth_id" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user_configs_table": { + "name": "user_configs_table", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "default_mtu": { + "name": "default_mtu", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_persistent_keepalive": { + "name": "default_persistent_keepalive", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_dns": { + "name": "default_dns", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_allowed_ips": { + "name": "default_allowed_ips", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default_j_c": { + "name": "default_j_c", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 7 + }, + "default_j_min": { + "name": "default_j_min", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 10 + }, + "default_j_max": { + "name": "default_j_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 1000 + }, + "default_i1": { + "name": "default_i1", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_i2": { + "name": "default_i2", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_i3": { + "name": "default_i3", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_i4": { + "name": "default_i4", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_i5": { + "name": "default_i5", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": {}, + "foreignKeys": { + "user_configs_table_id_interfaces_table_name_fk": { + "name": "user_configs_table_id_interfaces_table_name_fk", + "tableFrom": "user_configs_table", + "tableTo": "interfaces_table", + "columnsFrom": [ + "id" + ], + "columnsTo": [ + "name" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/src/server/database/migrations/meta/_journal.json b/src/server/database/migrations/meta/_journal.json index fefdc1c9..4650fa31 100644 --- a/src/server/database/migrations/meta/_journal.json +++ b/src/server/database/migrations/meta/_journal.json @@ -36,6 +36,13 @@ "when": 1771352889394, "tag": "0004_optimal_mandrill", "breakpoints": true + }, + { + "idx": 5, + "version": "6", + "when": 1780035570366, + "tag": "0005_clumsy_korg", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/server/database/repositories/user/schema.ts b/src/server/database/repositories/user/schema.ts index 77eb13e2..ede3d577 100644 --- a/src/server/database/repositories/user/schema.ts +++ b/src/server/database/repositories/user/schema.ts @@ -1,26 +1,38 @@ import { sql, relations } from 'drizzle-orm'; -import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core'; +import { int, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core'; import { client } from '../../schema'; -export const user = sqliteTable('users_table', { - id: int().primaryKey({ autoIncrement: true }), - username: text().notNull().unique(), - password: text().notNull(), - email: text(), - name: text().notNull(), - role: int().$type().notNull(), - totpKey: text('totp_key'), - totpVerified: int('totp_verified', { mode: 'boolean' }).notNull(), - enabled: int({ mode: 'boolean' }).notNull(), - createdAt: text('created_at') - .notNull() - .default(sql`(CURRENT_TIMESTAMP)`), - updatedAt: text('updated_at') - .notNull() - .default(sql`(CURRENT_TIMESTAMP)`) - .$onUpdate(() => sql`(CURRENT_TIMESTAMP)`), -}); +export const user = sqliteTable( + 'users_table', + { + id: int().primaryKey({ autoIncrement: true }), + username: text().notNull().unique(), + /** `password == null` means password login disabled */ + password: text(), + email: text(), + name: text().notNull(), + role: int().$type().notNull(), + totpKey: text('totp_key'), + totpVerified: int('totp_verified', { mode: 'boolean' }).notNull(), + enabled: int({ mode: 'boolean' }).notNull(), + oauthProvider: text('oauth_provider').$type(), + oauthId: text('oauth_id'), + createdAt: text('created_at') + .notNull() + .default(sql`(CURRENT_TIMESTAMP)`), + updatedAt: text('updated_at') + .notNull() + .default(sql`(CURRENT_TIMESTAMP)`) + .$onUpdate(() => sql`(CURRENT_TIMESTAMP)`), + }, + (table) => [ + uniqueIndex('oauth_provider_id_unique').on( + table.oauthProvider, + table.oauthId + ), + ] +); export const usersRelations = relations(user, ({ many }) => ({ clients: many(client), diff --git a/src/server/database/repositories/user/service.ts b/src/server/database/repositories/user/service.ts index cecf0df8..e3526315 100644 --- a/src/server/database/repositories/user/service.ts +++ b/src/server/database/repositories/user/service.ts @@ -1,4 +1,4 @@ -import { eq, sql } from 'drizzle-orm'; +import { eq, sql, and } from 'drizzle-orm'; import { TOTP } from 'otpauth'; import { user } from './schema'; import type { UserType } from './types'; @@ -13,10 +13,33 @@ type LoginResult = success: false; error: | 'INCORRECT_CREDENTIALS' - | 'TOTP_REQUIRED' | 'USER_DISABLED' | 'INVALID_TOTP_CODE' | 'UNEXPECTED_ERROR'; + } + | { + success: false; + error: 'TOTP_REQUIRED'; + userId: ID; + }; + +type LoginWithOAuthResult = + | { + success: true; + user: UserType; + } + | { + success: false; + error: + | 'USER_DISABLED' + | 'USER_ALREADY_LINKED' + | 'UNEXPECTED_ERROR' + | 'AUTO_REGISTER_DISABLED'; + } + | { + success: false; + error: 'TOTP_REQUIRED'; + userId: ID; }; function createPreparedStatement(db: DBType) { @@ -113,7 +136,11 @@ export class UserService { return this.#statements.update.execute({ id, name, email }); } - async updatePassword(id: ID, currentPassword: string, newPassword: string) { + async updatePassword( + id: ID, + currentPassword: string | null, + newPassword: string + ) { const hash = await hashPassword(newPassword); return this.#db.transaction(async (tx) => { @@ -126,13 +153,20 @@ export class UserService { throw new Error('User not found'); } - const passwordValid = await isPasswordValid( - currentPassword, - txUser.password - ); + // only check password if already set + if (txUser.password !== null) { + if (!currentPassword) { + throw new Error('Invalid password'); + } - if (!passwordValid) { - throw new Error('Invalid password'); + const passwordValid = await isPasswordValid( + currentPassword, + txUser.password + ); + + if (!passwordValid) { + throw new Error('Invalid password'); + } } await tx @@ -147,42 +181,32 @@ export class UserService { return this.#statements.updateKey.execute({ id, key }); } - login(username: string, password: string, code: string | undefined) { + login(username: string, password: string) { return this.#db.transaction(async (tx): Promise => { const txUser = await tx.query.user .findFirst({ where: eq(user.username, username) }) .execute(); - if (!txUser) { + // always check to avoid timing attack + const userHashPassword = txUser?.password ?? null; + const passwordValid = await isPasswordValid(password, userHashPassword); + + if (!txUser || !passwordValid) { return { success: false, error: 'INCORRECT_CREDENTIALS' }; } - const passwordValid = await isPasswordValid(password, txUser.password); - - if (!passwordValid) { - return { success: false, error: 'INCORRECT_CREDENTIALS' }; - } - - if (txUser.totpVerified) { - if (!code) { - return { success: false, error: 'TOTP_REQUIRED' }; - } else { - const totpKey = txUser.totpKey; - if (!totpKey) { - return { success: false, error: 'UNEXPECTED_ERROR' }; - } - - const totp = this.#createTotp({ username: txUser.username, totpKey }); - if (totp.validate({ token: code, window: 1 }) === null) { - return { success: false, error: 'INVALID_TOTP_CODE' }; - } - } - } - if (!txUser.enabled) { return { success: false, error: 'USER_DISABLED' }; } + if (txUser.totpVerified) { + return { + success: false, + error: 'TOTP_REQUIRED', + userId: txUser.id, + }; + } + return { success: true, user: txUser }; }); } @@ -241,4 +265,187 @@ export class UserService { .execute(); }); } + + async validateTotpCode(id: ID, code: string) { + const txUser = await this.#db.query.user + .findFirst({ where: eq(user.id, id) }) + .execute(); + + if (!txUser || !txUser.totpVerified || !txUser.totpKey) { + return 'INVALID_TOTP_CODE' as const; + } + + const totp = this.#createTotp({ + username: txUser.username, + totpKey: txUser.totpKey, + }); + const isValid = totp.validate({ token: code, window: 1 }) !== null; + + if (!isValid) { + return 'INVALID_TOTP_CODE' as const; + } + + if (!txUser.enabled) { + return 'USER_DISABLED' as const; + } + + return 'success' as const; + } + + /** + * Login or register user with OAuth provider. + * If user with the same email already exists, link account with OAuth provider. + * Otherwise, create new user. + */ + async loginWithOAuth( + provider: OAUTH_PROVIDER, + oauthId: string, + username: string, + email: string, + name: string + ): Promise { + return this.#db.transaction(async (tx) => { + const userById = await tx.query.user + .findFirst({ + where: and( + eq(user.oauthProvider, provider), + eq(user.oauthId, oauthId) + ), + }) + .execute(); + + if (userById) { + if (!userById.enabled) { + return { success: false, error: 'USER_DISABLED' }; + } + if (userById.totpVerified) { + return { + success: false, + error: 'TOTP_REQUIRED', + userId: userById.id, + }; + } + return { success: true, user: userById }; + } + + const userByEmail = await tx.query.user + .findFirst({ + where: eq(user.email, email), + }) + .execute(); + + if (userByEmail) { + if (!userByEmail.enabled) { + return { success: false, error: 'USER_DISABLED' }; + } + if (userByEmail.oauthProvider && userByEmail.oauthId) { + return { + success: false, + error: 'USER_ALREADY_LINKED', + }; + } + + await tx + .update(user) + .set({ oauthProvider: provider, oauthId: oauthId }) + .where(eq(user.id, userByEmail.id)) + .execute(); + + if (userByEmail.totpVerified) { + return { + success: false, + error: 'TOTP_REQUIRED', + userId: userByEmail.id, + }; + } + + // TODO: return updated user + return { success: true, user: userByEmail }; + } + + if (!WG_ENV.OAUTH_AUTO_REGISTER) { + return { success: false, error: 'AUTO_REGISTER_DISABLED' }; + } + + // Create new user + const newUsers = await tx + .insert(user) + .values({ + username, + password: null, + email, + name, + role: roles.ADMIN, + totpVerified: false, + enabled: true, + oauthProvider: provider, + oauthId, + }) + .returning(); + const newUser = newUsers[0]; + + if (!newUser) { + return { success: false as const, error: 'UNEXPECTED_ERROR' as const }; + } + return { success: true as const, user: newUser }; + }); + } + + unlinkOauth(id: ID) { + return this.#db.transaction(async (tx) => { + const txUser = await tx.query.user + .findFirst({ where: eq(user.id, id) }) + .execute(); + + if (!txUser) { + throw new Error('User not found'); + } + + // can't unlink if no way to log back in + if (!txUser.password) { + throw new Error('Password login not enabled'); + } + + await tx + .update(user) + .set({ oauthProvider: null, oauthId: null }) + .where(eq(user.id, id)) + .execute(); + }); + } + + async linkOauth(id: ID, provider: OAUTH_PROVIDER, oauthId: string) { + return this.#db.transaction(async (tx) => { + const txUser = await tx.query.user + .findFirst({ where: eq(user.id, id) }) + .execute(); + + if (!txUser) { + throw new Error('User not found'); + } + + if (txUser.oauthProvider || txUser.oauthId) { + throw new Error('User already linked with an OAuth provider'); + } + + const existingUser = await tx.query.user + .findFirst({ + where: and( + eq(user.oauthProvider, provider), + eq(user.oauthId, oauthId) + ), + }) + .execute(); + + if (existingUser) { + throw new Error('OAuth account already linked with another user'); + } + + await tx + .update(user) + .set({ oauthProvider: provider, oauthId: oauthId }) + .where(eq(user.id, id)) + .execute(); + }); + } } diff --git a/src/server/database/repositories/user/types.ts b/src/server/database/repositories/user/types.ts index 4743be73..bb5a7290 100644 --- a/src/server/database/repositories/user/types.ts +++ b/src/server/database/repositories/user/types.ts @@ -25,7 +25,6 @@ export const UserLoginSchema = z.object({ username: username, password: password, remember: remember, - totpCode: totpCode.optional(), }); export const UserSetupSchema = z @@ -57,7 +56,7 @@ export const UserUpdateSchema = z.object({ export const UserUpdatePasswordSchema = z .object({ - currentPassword: password, + currentPassword: password.nullable(), newPassword: password, confirmPassword: password, }) diff --git a/src/server/plugins/manager.ts b/src/server/plugins/manager.ts index 701e052e..f12811b5 100644 --- a/src/server/plugins/manager.ts +++ b/src/server/plugins/manager.ts @@ -1,12 +1,14 @@ export default defineNitroPlugin((nitroApp) => { - console.log(`====================================================`); - console.log(` wg-easy - https://github.com/wg-easy/wg-easy `); - console.log(`====================================================`); - console.log(`| wg-easy: ${RELEASE.padEnd(38)} |`); - console.log(`| Node: ${process.version.padEnd(38)} |`); - console.log(`| Platform: ${process.platform.padEnd(38)} |`); - console.log(`| Arch: ${process.arch.padEnd(38)} |`); - console.log(`====================================================`); + console.log(` +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ wg-easy - https://github.com/wg-easy/wg-easy ┃ +┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ +┃ wg-easy: ${RELEASE.padEnd(38)} ┃ +┃ Node: ${process.version.padEnd(38)} ┃ +┃ Platform: ${process.platform.padEnd(38)} ┃ +┃ Arch: ${process.arch.padEnd(38)} ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +`); nitroApp.hooks.hook('close', async () => { console.log('Shutting down'); await WireGuard.Shutdown(); diff --git a/src/server/utils/config.ts b/src/server/utils/config.ts index 4498442a..4e3b5121 100644 --- a/src/server/utils/config.ts +++ b/src/server/utils/config.ts @@ -30,6 +30,11 @@ const detectAwg = async (): Promise<'awg' | 'wg'> => { } else return 'wg'; }; +const oauthProviders = process.env.OAUTH_PROVIDERS?.split(',') + .map((v) => v.trim()) + .filter((v) => isValidOauthProvider(v)) + .filter((v) => isConfiguredOauthProvider(OAUTH_PROVIDERS[v])); + export const WG_ENV = { /** UI is hosted on HTTP instead of HTTPS */ INSECURE: process.env.INSECURE === 'true', @@ -39,8 +44,31 @@ export const WG_ENV = { DISABLE_IPV6: process.env.DISABLE_IPV6 === 'true', WG_EXECUTABLE: await detectAwg(), DISABLE_VERSION_CHECK: process.env.DISABLE_VERSION_CHECK === 'true', + /** List of enabled OAuth providers */ + OAUTH_PROVIDERS: oauthProviders, + /** List of allowed OAuth domains */ + OAUTH_ALLOWED_DOMAINS: process.env.OAUTH_ALLOWED_DOMAINS?.split(',').map( + (v) => v.trim() + ), + /** Automatically register users that log in with an OAuth provider */ + OAUTH_AUTO_REGISTER: process.env.OAUTH_AUTO_REGISTER === 'true', + /** Which OAuth provider to automatically launch */ + OAUTH_AUTO_LAUNCH: + oauthProviders?.find((p) => p === process.env.OAUTH_AUTO_LAUNCH) ?? null, + /** Disable password authentication */ + DISABLE_PASSWORD_AUTH: process.env.DISABLE_PASSWORD_AUTH === 'true', }; +if (WG_ENV.OAUTH_PROVIDERS && WG_ENV.OAUTH_PROVIDERS.length > 0) { + SERVER_DEBUG(` +Enabled OAuth providers: ${WG_ENV.OAUTH_PROVIDERS.join(', ')} +Allowed OAuth domains: ${WG_ENV.OAUTH_ALLOWED_DOMAINS?.join(', ') ?? 'All'} +OAuth auto register: ${WG_ENV.OAUTH_AUTO_REGISTER ? 'Enabled' : 'Disabled'} +Password authentication: ${WG_ENV.DISABLE_PASSWORD_AUTH ? 'Disabled' : 'Enabled'} +Auto launch OAuth provider: ${WG_ENV.OAUTH_AUTO_LAUNCH ?? 'None'} +`); +} + export const WG_INITIAL_ENV = { ENABLED: process.env.INIT_ENABLED === 'true', USERNAME: process.env.INIT_USERNAME, diff --git a/src/server/utils/oauth.ts b/src/server/utils/oauth.ts new file mode 100644 index 00000000..d334fe00 --- /dev/null +++ b/src/server/utils/oauth.ts @@ -0,0 +1,258 @@ +import type { H3Event } from 'h3'; +import * as client from 'openid-client'; + +type OAuthConfig = { + friendlyName: string; + server: string; + scope: string; + clientId: string | undefined; + clientSecret: string | undefined; + params: Record; + isOIDC?: false; + userInfoFlow?: 'github'; +}; + +const GoogleConfig: OAuthConfig = { + friendlyName: 'Google', + server: 'https://accounts.google.com', + scope: 'openid email profile', + clientId: process.env.OAUTH_GOOGLE_CLIENT_ID, + clientSecret: process.env.OAUTH_GOOGLE_CLIENT_SECRET, + params: { + access_type: 'online', + prompt: 'select_account', + }, +}; +const GithubConfig: OAuthConfig = { + friendlyName: 'GitHub', + server: 'https://github.com/login/oauth', + scope: 'read:user user:email', + clientId: process.env.OAUTH_GITHUB_CLIENT_ID, + clientSecret: process.env.OAUTH_GITHUB_CLIENT_SECRET, + params: { + allow_signup: 'false', + prompt: 'select_account', + }, + isOIDC: false, + userInfoFlow: 'github', +}; +const OidcConfig: OAuthConfig = { + friendlyName: process.env.OAUTH_OIDC_NAME ?? 'OIDC', + server: process.env.OAUTH_OIDC_SERVER ?? '', + scope: 'openid email profile', + clientId: process.env.OAUTH_OIDC_CLIENT_ID, + clientSecret: process.env.OAUTH_OIDC_CLIENT_SECRET, + params: {}, +}; + +export const OAUTH_PROVIDERS = { + google: GoogleConfig, + github: GithubConfig, + oidc: OidcConfig, +}; + +export type OAUTH_PROVIDER = keyof typeof OAUTH_PROVIDERS; + +export function isValidOauthProvider( + provider: string +): provider is OAUTH_PROVIDER { + if (provider in OAUTH_PROVIDERS) { + return true; + } + return false; +} + +export function isConfiguredOauthProvider( + oauthProvider: (typeof OAUTH_PROVIDERS)[OAUTH_PROVIDER] +): oauthProvider is (typeof OAUTH_PROVIDERS)[OAUTH_PROVIDER] & { + clientId: string; + clientSecret: string; +} { + if (!oauthProvider.clientId || !oauthProvider.clientSecret) { + return false; + } + return true; +} + +function isEnabledProvider(provider: OAUTH_PROVIDER) { + return WG_ENV.OAUTH_PROVIDERS?.includes(provider); +} + +// TODO: simplify logic between WG_ENV.OAUTH_PROVIDERS and buildOauthConfig +export async function buildOauthConfig(event: H3Event) { + const provider = getRouterParam(event, 'provider'); + if (!provider || !isValidOauthProvider(provider)) { + throw createError({ + statusCode: 400, + statusMessage: 'Invalid provider', + }); + } + + if (!isEnabledProvider(provider)) { + throw createError({ + statusCode: 403, + statusMessage: 'Provider is not enabled', + }); + } + + const oauthProvider = OAUTH_PROVIDERS[provider]; + + if (!isConfiguredOauthProvider(oauthProvider)) { + throw createError({ + statusCode: 500, + statusMessage: 'Provider is not configured', + }); + } + + const config = await client.discovery( + new URL(oauthProvider.server), + oauthProvider.clientId, + { + client_secret: oauthProvider.clientSecret, + } + ); + + return { config, providerConfig: oauthProvider, provider }; +} + +export async function githubUserInfoFlow(accessToken: string) { + const OAUTH_GITHUB_FLOW = { + userinfo_endpoint: 'https://api.github.com/user', + email_endpoint: 'https://api.github.com/user/emails', + }; + type OAUTH_GITHUB_USERINFO = { + id: number; + login: string; + avatar_url: string; + email: string | null; + name: string | null; + }; + type OAUTH_GITHUB_EMAIL = { + email: string; + primary: boolean; + verified: boolean; + visibility: string | null; + }[]; + + const response = await $fetch( + OAUTH_GITHUB_FLOW.userinfo_endpoint, + { + headers: { + 'User-Agent': 'wg-easy', + Authorization: `Bearer ${accessToken}`, + }, + } + ); + if (!response.email) { + const emailResponse = await $fetch( + OAUTH_GITHUB_FLOW.email_endpoint, + { + headers: { + 'User-Agent': 'wg-easy', + Authorization: `Bearer ${accessToken}`, + }, + } + ); + const primaryEmail = emailResponse.find((v) => v.primary && v.verified); + response.email = primaryEmail?.email || null; + } + return { + sub: response.id.toString(), + email: response.email ?? undefined, + email_verified: true, + preferred_username: response.login, + name: response.name || response.login, + }; +} + +type OauthState = { + oauth_nonce: string; + oauth_verifier: string; + oauth_state: string; +}; + +export async function getUserInfo( + event: H3Event, + config: client.Configuration, + state: OauthState, + providerConfig: OAuthConfig +) { + const currentUrl = getRequestURL(event); + + const tokens = await client.authorizationCodeGrant(config, currentUrl, { + pkceCodeVerifier: state.oauth_verifier, + expectedNonce: + providerConfig.isOIDC === false ? undefined : state.oauth_nonce, + expectedState: state.oauth_state, + idTokenExpected: providerConfig.isOIDC ?? true, + }); + + type SubjectType = string | undefined | typeof client.skipSubjectCheck; + let subject: SubjectType = tokens.claims()?.sub; + if (providerConfig.isOIDC === false) { + subject = client.skipSubjectCheck; + } + + if (!subject) { + throw createError({ + statusCode: 400, + statusMessage: "Can't get subject", + }); + } + + let userInfo: client.UserInfoResponse; + if (providerConfig.userInfoFlow === 'github') { + userInfo = await githubUserInfoFlow(tokens.access_token); + } else { + userInfo = await client.fetchUserInfo(config, tokens.access_token, subject); + } + + assertHasOauthProps(userInfo); + + if (!isAllowedDomain(userInfo.email)) { + throw createError({ + statusCode: 401, + statusMessage: 'Email domain not allowed', + }); + } + + return userInfo; +} + +type RequireKeys = Required>; + +function assertHasOauthProps( + userInfo: T +): asserts userInfo is T & RequireKeys { + if (!userInfo.sub) { + throw createError({ + statusCode: 400, + statusMessage: 'No sub set', + }); + } + + if (!userInfo.email) { + throw createError({ + statusCode: 400, + statusMessage: 'No email set', + }); + } + + if (!userInfo.email_verified) { + throw createError({ + statusCode: 401, + statusMessage: 'Email is not verified', + }); + } +} + +function isAllowedDomain(email: string) { + const emailDomain = email.slice(email.lastIndexOf('@') + 1); + if ( + WG_ENV.OAUTH_ALLOWED_DOMAINS && + !WG_ENV.OAUTH_ALLOWED_DOMAINS.includes(emailDomain) + ) { + return false; + } + return true; +} diff --git a/src/server/utils/password.ts b/src/server/utils/password.ts index 915795c7..0a4e0c62 100644 --- a/src/server/utils/password.ts +++ b/src/server/utils/password.ts @@ -3,13 +3,22 @@ import argon2 from 'argon2'; import { deserialize } from '@phc/format'; +const DUMMY_HASH = + '$argon2id$v=19$m=65536,t=3,p=4$jsh6z1/SbZHYAiO/Ww9HZw$ikzkoXWqc2b0Pc4O8ZNJjp1xKZSb7SNM/3dPMNUPk9Y'; + /** - * Checks if `password` matches the hash. + * Checks if `password` matches the `hash`. + * + * Checks against `DUMMY_HASH` and returns false if `hash` is null */ -export function isPasswordValid( +export async function isPasswordValid( password: string, - hash: string + hash: string | null ): Promise { + if (hash === null) { + await argon2.verify(DUMMY_HASH, password); + return false; + } return argon2.verify(hash, password); } diff --git a/src/server/utils/session.ts b/src/server/utils/session.ts index 1a144cea..5c697e85 100644 --- a/src/server/utils/session.ts +++ b/src/server/utils/session.ts @@ -3,6 +3,15 @@ import type { UserType } from '#db/repositories/user/types'; export type WGSession = Partial<{ userId: ID; + // TODO: add pending login expiration + pendingLogin: { + type: 'password' | 'oauth'; + userId: ID; + remember: boolean; + }; + oauth_verifier: string; + oauth_nonce: string; + oauth_state: string; }>; const name = 'wg-easy'; @@ -70,21 +79,14 @@ export async function getCurrentUser(event: H3Event) { }); } - // TODO: timing can be used to enumerate usernames - const foundUser = await Database.users.getByUsername(username); - if (!foundUser) { - throw createError({ - statusCode: 401, - statusMessage: 'Session failed', - }); - } - - const userHashPassword = foundUser.password; + // always check to avoid timing attack + const userHashPassword = foundUser?.password ?? null; const passwordValid = await isPasswordValid(password, userHashPassword); - if (!passwordValid) { + // can't login through basic auth if 2fa enabled + if (!foundUser || !passwordValid || foundUser.totpVerified) { throw createError({ statusCode: 401, statusMessage: 'Session failed', diff --git a/src/shared/utils/permissions.ts b/src/shared/utils/permissions.ts index 12fd5570..e9f5fc18 100644 --- a/src/shared/utils/permissions.ts +++ b/src/shared/utils/permissions.ts @@ -47,8 +47,8 @@ type SharedUserType = export type SharedPublicUser = Pick< UserType, - 'id' | 'username' | 'name' | 'email' | 'totpVerified' -> & { role: BrandedNumber }; + 'id' | 'username' | 'name' | 'email' | 'totpVerified' | 'oauthProvider' +> & { role: BrandedNumber; hasPassword: boolean }; type PermissionCheck = | boolean @@ -144,7 +144,10 @@ export function hasPermissionsWithData( const isAllowed = hasPermissions(user, resource, action, data); if (!isAllowed) { - throw new Error('Permission denied'); + throw createError({ + statusCode: 403, + statusMessage: 'Permission denied', + }); } return isAllowed; diff --git a/src/test/unit/password.spec.ts b/src/test/unit/password.spec.ts index 855c5f24..5f404530 100644 --- a/src/test/unit/password.spec.ts +++ b/src/test/unit/password.spec.ts @@ -17,4 +17,8 @@ describe('password', () => { expect(isValidPasswordHash(hash.replace('argon2', 'argon3'))).toBe(false); }); + + test('missing password hash is never valid', async () => { + await expect(isPasswordValid('password', null)).resolves.toBe(false); + }); }); From 8add67a4ccdae5dcd6c2f7f293f7b1ca8a7b805b Mon Sep 17 00:00:00 2001 From: Bernd Storath Date: Fri, 12 Jun 2026 15:24:52 +0200 Subject: [PATCH 02/34] update packages --- src/package.json | 28 +- src/pnpm-lock.yaml | 2498 ++++++++++++++++++++++---------------------- 2 files changed, 1277 insertions(+), 1249 deletions(-) diff --git a/src/package.json b/src/package.json index 031e5971..5e7b89ec 100644 --- a/src/package.json +++ b/src/package.json @@ -31,25 +31,25 @@ "@tailwindcss/forms": "^0.5.11", "@vueuse/core": "^14.3.0", "@vueuse/nuxt": "^14.3.0", - "apexcharts": "^5.13.0", + "apexcharts": "^5.15.0", "argon2": "^0.44.0", - "cidr-tools": "^12.0.2", + "cidr-tools": "^12.0.3", "citty": "^0.2.2", "consola": "^3.4.2", "crc-32": "^1.2.2", "drizzle-orm": "^0.45.2", - "ip-bigint": "^9.0.5", + "ip-bigint": "^9.0.6", "is-cidr": "^7.0.0", "is-ip": "^5.0.1", "js-sha256": "^0.11.1", - "nuxt": "^3.21.6", - "obug": "^2.1.1", + "nuxt": "^3.21.8", + "obug": "^2.1.2", "openid-client": "^6.8.4", "otpauth": "^9.5.1", "pinia": "^3.0.4", "qr": "^0.6.0", "radix-vue": "^1.9.17", - "semver": "^7.8.1", + "semver": "^7.8.4", "tailwindcss": "^3.4.19", "timeago.js": "^4.0.2", "vue": "latest", @@ -57,22 +57,22 @@ "zod": "^4.4.3" }, "devDependencies": { - "@nuxt/eslint": "^1.15.2", + "@nuxt/eslint": "^1.16.0", "@nuxt/test-utils": "^4.0.3", "@types/phc__format": "^1.0.1", "@types/semver": "^7.7.1", - "@vitest/coverage-v8": "^4.1.7", - "@vitest/ui": "^4.1.7", + "@vitest/coverage-v8": "^4.1.8", + "@vitest/ui": "^4.1.8", "drizzle-kit": "^0.31.10", "esbuild": "^0.28.0", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", - "prettier": "^3.8.3", + "prettier": "^3.8.4", "prettier-plugin-tailwindcss": "^0.8.0", - "tsx": "^4.22.3", + "tsx": "^4.22.4", "typescript": "^6.0.3", - "vitest": "^4.1.7", - "vue-tsc": "^3.3.3" + "vitest": "^4.1.8", + "vue-tsc": "^3.3.4" }, - "packageManager": "pnpm@11.5.0" + "packageManager": "pnpm@11.5.3" } diff --git a/src/pnpm-lock.yaml b/src/pnpm-lock.yaml index 008219ff..a144ffde 100644 --- a/src/pnpm-lock.yaml +++ b/src/pnpm-lock.yaml @@ -13,40 +13,40 @@ importers: version: 1.2.0(magicast@0.5.3) '@heroicons/vue': specifier: ^2.2.0 - version: 2.2.0(vue@3.5.35(typescript@6.0.3)) + version: 2.2.0(vue@3.5.38(typescript@6.0.3)) '@libsql/client': specifier: ^0.17.3 version: 0.17.3 '@nuxtjs/i18n': specifier: ^10.4.0 - version: 10.4.0(@vue/compiler-dom@3.5.35)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(rollup@4.60.4)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) + version: 10.4.0(@vue/compiler-dom@3.5.38)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)))(rollup@4.61.1)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) '@nuxtjs/tailwindcss': specifier: ^6.14.0 - version: 6.14.0(magicast@0.5.3)(tsx@4.22.3)(yaml@2.9.0) + version: 6.14.0(magicast@0.5.3)(tsx@4.22.4)(yaml@2.9.0) '@phc/format': specifier: ^1.0.0 version: 1.0.0 '@pinia/nuxt': specifier: ^0.11.3 - version: 0.11.3(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3))) + version: 0.11.3(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3))) '@tailwindcss/forms': specifier: ^0.5.11 - version: 0.5.11(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)) + version: 0.5.11(tailwindcss@3.4.19(tsx@4.22.4)(yaml@2.9.0)) '@vueuse/core': specifier: ^14.3.0 - version: 14.3.0(vue@3.5.35(typescript@6.0.3)) + version: 14.3.0(vue@3.5.38(typescript@6.0.3)) '@vueuse/nuxt': specifier: ^14.3.0 - version: 14.3.0(magicast@0.5.3)(nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) + version: 14.3.0(magicast@0.5.3)(nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) apexcharts: - specifier: ^5.13.0 - version: 5.13.0 + specifier: ^5.15.0 + version: 5.15.0 argon2: specifier: ^0.44.0 version: 0.44.0 cidr-tools: - specifier: ^12.0.2 - version: 12.0.2 + specifier: ^12.0.3 + version: 12.0.3 citty: specifier: ^0.2.2 version: 0.2.2 @@ -60,8 +60,8 @@ importers: specifier: ^0.45.2 version: 0.45.2(@libsql/client@0.17.3) ip-bigint: - specifier: ^9.0.5 - version: 9.0.5 + specifier: ^9.0.6 + version: 9.0.6 is-cidr: specifier: ^7.0.0 version: 7.0.0 @@ -72,11 +72,11 @@ importers: specifier: ^0.11.1 version: 0.11.1 nuxt: - specifier: ^3.21.6 - version: 3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0) + specifier: ^3.21.8 + version: 3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0) obug: - specifier: ^2.1.1 - version: 2.1.1 + specifier: ^2.1.2 + version: 2.1.2 openid-client: specifier: ^6.8.4 version: 6.8.4 @@ -85,38 +85,38 @@ importers: version: 9.5.1 pinia: specifier: ^3.0.4 - version: 3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)) + version: 3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)) qr: specifier: ^0.6.0 version: 0.6.0 radix-vue: specifier: ^1.9.17 - version: 1.9.17(vue@3.5.35(typescript@6.0.3)) + version: 1.9.17(vue@3.5.38(typescript@6.0.3)) semver: - specifier: ^7.8.1 - version: 7.8.1 + specifier: ^7.8.4 + version: 7.8.4 tailwindcss: specifier: ^3.4.19 - version: 3.4.19(tsx@4.22.3)(yaml@2.9.0) + version: 3.4.19(tsx@4.22.4)(yaml@2.9.0) timeago.js: specifier: ^4.0.2 version: 4.0.2 vue: specifier: latest - version: 3.5.35(typescript@6.0.3) + version: 3.5.38(typescript@6.0.3) vue3-apexcharts: specifier: ^1.11.1 - version: 1.11.1(apexcharts@5.13.0)(vue@3.5.35(typescript@6.0.3)) + version: 1.11.1(apexcharts@5.15.0)(vue@3.5.38(typescript@6.0.3)) zod: specifier: ^4.4.3 version: 4.4.3 devDependencies: '@nuxt/eslint': - specifier: ^1.15.2 - version: 1.15.2(@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.35)(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + specifier: ^1.16.0 + version: 1.16.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.38)(crossws@0.4.6(srvx@0.11.16))(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(oxc-parser@0.132.0)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) '@nuxt/test-utils': specifier: ^4.0.3 - version: 4.0.3(@vitest/ui@4.1.7)(crossws@0.4.5(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7) + version: 4.0.3(@vitest/ui@4.1.8)(crossws@0.4.6(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vitest@4.1.8) '@types/phc__format': specifier: ^1.0.1 version: 1.0.1 @@ -124,11 +124,11 @@ importers: specifier: ^7.7.1 version: 7.7.1 '@vitest/coverage-v8': - specifier: ^4.1.7 - version: 4.1.7(vitest@4.1.7) + specifier: ^4.1.8 + version: 4.1.8(vitest@4.1.8) '@vitest/ui': - specifier: ^4.1.7 - version: 4.1.7(vitest@4.1.7) + specifier: ^4.1.8 + version: 4.1.8(vitest@4.1.8) drizzle-kit: specifier: ^0.31.10 version: 0.31.10 @@ -142,23 +142,23 @@ importers: specifier: ^10.1.8 version: 10.1.8(eslint@9.39.4(jiti@1.21.7)) prettier: - specifier: ^3.8.3 - version: 3.8.3 + specifier: ^3.8.4 + version: 3.8.4 prettier-plugin-tailwindcss: specifier: ^0.8.0 - version: 0.8.0(prettier@3.8.3) + version: 0.8.0(prettier@3.8.4) tsx: - specifier: ^4.22.3 - version: 4.22.3 + specifier: ^4.22.4 + version: 4.22.4 typescript: specifier: ^6.0.3 version: 6.0.3 vitest: - specifier: ^4.1.7 - version: 4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(@vitest/ui@4.1.7)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + specifier: ^4.1.8 + version: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(@vitest/ui@4.1.8)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) vue-tsc: - specifier: ^3.3.3 - version: 3.3.3(typescript@6.0.3) + specifier: ^3.3.4 + version: 3.3.4(typescript@6.0.3) packages: @@ -335,15 +335,15 @@ packages: '@clack/core@1.2.0': resolution: {integrity: sha512-qfxof/3T3t9DPU/Rj3OmcFyZInceqj/NVtO9rwIuJqCUgh32gwPjpFQQp/ben07qKlhpwq7GzfWpST4qdJ5Drg==} - '@clack/core@1.4.0': - resolution: {integrity: sha512-7Wctjq6f7c1CPz8sPpkwUnz8yRgVANkpNupb81q432FjcJg4l+Sw7XANdNSdWfAKq0IHI0JTcUeK5dxs/HrGPw==} + '@clack/core@1.4.1': + resolution: {integrity: sha512-FILJa1gGKEFTGZAJE9RpVhrjKz3c3h4ar60dSv6cGuDqufQ84YEIS3GAGvZiN+H6yaLbbvTFNejjCC4tXpZEuw==} engines: {node: '>= 20.12.0'} '@clack/prompts@1.2.0': resolution: {integrity: sha512-4jmztR9fMqPMjz6H/UZXj0zEmE43ha1euENwkckKKel4XpSfokExPo5AiVStdHSAlHekz4d0CA/r45Ok1E4D3w==} - '@clack/prompts@1.5.0': - resolution: {integrity: sha512-wKh+wTjmrUoUdkZg8KpJO5X+p9PWV+KE9mePseq9UYWkukgTKsGS47RRL2HstwVcvDQH+PenrPJWII8+MfiiyA==} + '@clack/prompts@1.5.1': + resolution: {integrity: sha512-zccHj2z2oCCO4yrDiRSlFOxWerGqRiysP7a5jPK6uoI9URKAquwY42Dd/iUP8JWHxEzdRe4TlbvZCo8z1/mhrw==} engines: {node: '>= 20.12.0'} '@cloudflare/kv-asset-handler@0.4.2': @@ -391,8 +391,8 @@ packages: '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} - '@es-joy/jsdoccomment@0.86.0': - resolution: {integrity: sha512-ukZmRQ81WiTpDWO6D/cTBM7XbrNtutHKvAVnZN/8pldAwLoJArGOvkNyxPTBGsPjsoaQBJxlH+tE2TNA/92Qgw==} + '@es-joy/jsdoccomment@0.87.0': + resolution: {integrity: sha512-mFXZloZMzuJZXSHUmAFu/pXTk0ZJTJBluuAkrvbzidpTN8W6F2bpRFuedSH+85kbdlRLJqc+gfN+kD3JOLJK5g==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@es-joy/resolve.exports@1.2.0': @@ -1041,8 +1041,9 @@ packages: resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-inspector@1.5.0': - resolution: {integrity: sha512-YK/VdQ+pibx5pcCI2GPZVO6vFemf/pkB662HuFtc5AA4WLQ9upb3fAoZSjOAYoDJx58qGTDp6xq9ldd/vluNxQ==} + '@eslint/config-inspector@3.0.4': + resolution: {integrity: sha512-qyb1cjiiwD2mlg5GJC4JiO/EOO/rvEtm+GgLtgJ054bu8ZPj6hK1PLCRzxOnBghlPKWVqSjs4i+fXoPkt488Yw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: eslint: ^8.50.0 || ^9.0.0 || ^10.0.0 @@ -1059,6 +1060,15 @@ packages: resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@10.0.1': + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + '@eslint/js@9.39.4': resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1126,28 +1136,28 @@ packages: vue-i18n: optional: true - '@intlify/core-base@11.4.4': - resolution: {integrity: sha512-w/vItlylrAmhebkIbVl5YY8XMCtj8Mb2g70ttxktMYuf5AuRahgEHL2iLgLIsZBIbTSgs4hkUo7ucCL0uTJvOg==} + '@intlify/core-base@11.4.5': + resolution: {integrity: sha512-lja3F/iKVIvTa48mIwmrIeDcQUFZ0F0drvFvT8AwINOvbwnAzl/S/p8p2DxILZpWEUHRi1qewfWNIkMvhD3kKA==} engines: {node: '>= 22'} - '@intlify/core@11.4.4': - resolution: {integrity: sha512-ssSzH1odmyDx+n9l9e9jX1OhxSlealuIoHweHkvyMFKaYNRhzk1R/JICmsTWIIBcgoad4Sd8HrGqRmS8pU2ung==} + '@intlify/core@11.4.5': + resolution: {integrity: sha512-aA17hLi0mJOAR/RNG1CiN0qywuV7jnctjOm0o5bYZ2dZTOTKEGJdfuMxDQJ/MioK6w8ZHMJ1h/lENBfmgLD+ew==} engines: {node: '>= 22'} - '@intlify/devtools-types@11.4.4': - resolution: {integrity: sha512-PcBLmGmDQsTSVV911P8upzpcLJO1CNVYi/IH6bGnLR2nA+0L963+kXN1ZrisTEnbtw2ewN6HMMSldqzjronA0Q==} + '@intlify/devtools-types@11.4.5': + resolution: {integrity: sha512-W5vydP9Yq3t82IyWqCM6aR0BTWCZrN5RAwjZEPpH8I2OQWp2RLy03Evh2ANZlSMhcvGAoyDg25k0so85Kwncpw==} engines: {node: '>= 22'} '@intlify/h3@0.7.4': resolution: {integrity: sha512-BtL5+U3Dd9Qz6so+ArOMQWZ+nV21rOqqYUXnqwvW6J3VUXr66A9+9+vUFb/NAQvOU4kdfkO3c/9LMRGU9WZ8vw==} engines: {node: '>= 20'} - '@intlify/message-compiler@11.4.4': - resolution: {integrity: sha512-vn0OAV9pYkJlPPmgnsSm5eAG3mL0+9C/oaded2JY9jmxBbhmUXT3TcAUY8WRgLY9Hte7lkUJKpXrVlYjMXBD2w==} + '@intlify/message-compiler@11.4.5': + resolution: {integrity: sha512-IEOZiHtbQopyPc/Dz2M869lOlZYX1SdcniNJwphATDYHhovvIneEKf1EFF37DE7NAABZtza1FNtnwwqZWInfpw==} engines: {node: '>= 22'} - '@intlify/shared@11.4.4': - resolution: {integrity: sha512-QRUCHqda1U6aR14FR0vvXD4+4gj6+fm0AhAozvSuRCw0fCvrmCugWpgiR4xH2NI6s8am6N9p5OhirplsX8ZS3g==} + '@intlify/shared@11.4.5': + resolution: {integrity: sha512-g/i5mtdUa9ia/8BaJ4w6ZRHgAXYQd9XyCaQPRMvsd8d5qmZwkjoTmHrNsI28Q/7I8h+2ijUkI4uEnnMCziKupQ==} engines: {node: '>= 22'} '@intlify/unplugin-vue-i18n@11.2.3': @@ -1300,8 +1310,8 @@ packages: peerDependencies: rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 @@ -1362,8 +1372,8 @@ packages: '@vitejs/devtools': optional: true - '@nuxt/eslint-config@1.15.2': - resolution: {integrity: sha512-vS6mWB87tYjB8h3TxG/QziaZ6CGJpEOBd7N/j+64/tjNipUJzNgKwDzyGoOifNqyDDnlvgi6T3m9XpeYm4qRaA==} + '@nuxt/eslint-config@1.16.0': + resolution: {integrity: sha512-YWEqctFWoKOUTaHWXe6TaUgZ1ewN7jeKz/ni4JopxDGIQ8AIMMST6VMWryybHqbPzEfpx8sEcAAFGM4W4quYhQ==} peerDependencies: eslint: ^9.0.0 || ^10.0.0 eslint-plugin-format: '*' @@ -1371,13 +1381,13 @@ packages: eslint-plugin-format: optional: true - '@nuxt/eslint-plugin@1.15.2': - resolution: {integrity: sha512-LZ4gEcPP5GjzAkb6Kk04a4v0vvkTLOpmnEvdDatnkSlxtQLUSwX8v11vcDGXL92ZQ98dFoC1Q1IA6Tz3jdFIig==} + '@nuxt/eslint-plugin@1.16.0': + resolution: {integrity: sha512-vbX9EsJqTqIRwf3+sv9mJ/OtFKhH8o8NIbNF9Q6weQZY1MRf8jGEvLnjsyJa5VEEHl5TXSXsPcyrmIK58jsRpw==} peerDependencies: eslint: ^9.0.0 || ^10.0.0 - '@nuxt/eslint@1.15.2': - resolution: {integrity: sha512-LwDavQoLl+y0sIDqWEYbOnM6FOmXVIYSEjuvkO1hgAqhb0CvG3hgTnfE1qkf1jOAZp3CZGP+6rxRAJ0dxhueIQ==} + '@nuxt/eslint@1.16.0': + resolution: {integrity: sha512-VlZBHG86xUY72pZMcZ98cDtsUj972vZ23Pd4wqpxMLgLJ3RtHxQke0vgD/6PZ6uJsRjh7CAUGpsp2+d26ZdaSA==} peerDependencies: eslint: ^9.0.0 || ^10.0.0 eslint-webpack-plugin: ^4.1.0 @@ -1388,22 +1398,22 @@ packages: vite-plugin-eslint2: optional: true - '@nuxt/kit@3.21.6': - resolution: {integrity: sha512-5VOwxUcoM/z6w4c75hQrikHpY+TzjTLZQ+QnuO7KajyGx0IJBLVy1lw25oy79leF+GgyjJJO1cHfUfWeuEDCzA==} + '@nuxt/kit@3.21.8': + resolution: {integrity: sha512-kg63DUPY5AHPn+9XM7u8rYcdWHXjzwfUscgRDuiC5YUciQ+xdLRhdwXelYFxEAx2nxJHossliiQXbMm/Fleivw==} engines: {node: '>=18.12.0'} - '@nuxt/kit@4.4.6': - resolution: {integrity: sha512-AzsqBJeG7b3whIciyzkz4nBossEotM314KzKAptc8kH07ORBIR8Qh3QYKepo2YZwtxiDP2Y9aqzAztwpSEDHtw==} + '@nuxt/kit@4.4.8': + resolution: {integrity: sha512-ZUlZ5iYfyfJFDPluhn6ZxFWcsuxWbLnZBc8w3MAROcQ4lYfZ+qFpALBLSNlpc0zhOa++33EE+5PEbOAdVIY+dw==} engines: {node: '>=18.12.0'} - '@nuxt/nitro-server@3.21.6': - resolution: {integrity: sha512-tcSZauVgyUNZRCC0zYqauRJpEiHS8In3mXkupDlCYhQQmVNTxzxvBim3U4rR0Ww50ZJzOAtFOADeWTjLjYd3GQ==} + '@nuxt/nitro-server@3.21.8': + resolution: {integrity: sha512-GWYO2vdZhWekQHFEP7SLNzqHkQ1bVdjFtfJF4SXpl4v3w0jMa2JGIQkuQ0x/YpY1Yt0jAgqJREX8lFud8Cy2gQ==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - nuxt: ^3.21.6 + nuxt: ^3.21.8 - '@nuxt/schema@3.21.6': - resolution: {integrity: sha512-/1m3/q2QtLQ+c+4CDrlwGtNC5nJ3KdK+MTeaRhMN+fNavqeQFdqArfXVYdzUX+ZeqOL0Pt00vJnwKm0VM1I8mQ==} + '@nuxt/schema@3.21.8': + resolution: {integrity: sha512-BMxtf2x0E9sFji4Txz1boeMiwkhjQQFixdB6+lZXvCGpExZou4TLz82LDcIAZkpJVL0IEcfs96hTLVVBkjGulQ==} engines: {node: ^14.18.0 || >=16.10.0} '@nuxt/telemetry@2.8.0': @@ -1449,11 +1459,11 @@ packages: vitest: optional: true - '@nuxt/vite-builder@3.21.6': - resolution: {integrity: sha512-JjUJzo/KXgHnpI/podDCBGn93QyfKjcxrFzZkXRXsaUSIXMncrQK4Bs9OKBIWxcpsWxs93a130w1i7qjd2qizA==} + '@nuxt/vite-builder@3.21.8': + resolution: {integrity: sha512-aapUWCQGuLEzUj5hx+J/lfpzqt/fBYV8hmCQ930R4SM4BvEzqMR0wVkbU0ry0CDK+uQzb/2n50qIHcEp0ywc0Q==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - nuxt: 3.21.6 + nuxt: 3.21.8 rolldown: ^1.0.0-beta.38 rollup-plugin-visualizer: ^6.0.0 || ^7.0.1 vue: ^3.3.4 @@ -1470,129 +1480,129 @@ packages: '@nuxtjs/tailwindcss@6.14.0': resolution: {integrity: sha512-30RyDK++LrUVRgc2A85MktGWIZoRQgeQKjE4CjjD64OXNozyl+4ScHnnYgqVToMM6Ch2ZG2W4wV2J0EN6F0zkQ==} - '@oxc-minify/binding-android-arm-eabi@0.131.0': - resolution: {integrity: sha512-yLa7y9jjJgUeUUMm6AtjmBIQzK1YU5sYcNJnVVtr6WtoWu5SpuNDZ8u6cl/dhn0g/oQgVlf+E+8WJfsExt8R+Q==} + '@oxc-minify/binding-android-arm-eabi@0.132.0': + resolution: {integrity: sha512-NXxgL3FNGEBz8r+8iSl8wSdyCEMGisVmn2GVuJc5GycWgGzxiP9V9/svgD039JnO9nRAi0j+hP3FNAuDCP4aQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-minify/binding-android-arm64@0.131.0': - resolution: {integrity: sha512-ShZDYFEVd46qCc9L0D3ZTPLXe/DezTedEj7g6x1Bdlm1WwgQ1pQJgWkqpMGlQhUet5wq4WUpQB/P6afK470Ydg==} + '@oxc-minify/binding-android-arm64@0.132.0': + resolution: {integrity: sha512-XYogHG1aSjNEMKWUfWmBWtN9rnpQ2nA4MiecdiAOfofDHTQiU5ybrPH6VvDAtRXf2kr8WtPNX7eenhC3uWFWoA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-minify/binding-darwin-arm64@0.131.0': - resolution: {integrity: sha512-h+5iCSKxpK7SJdAHmY4I+0BBxR+pJQVNJvAIB3KcOVyz8/ybaO2r41URCwV1N3FnPYkIIiMokZ24YYMB6/GrRw==} + '@oxc-minify/binding-darwin-arm64@0.132.0': + resolution: {integrity: sha512-gm/M5dgm7IvA/g9tweMqiFyD15yKrxGUX3myjFP+EYIYVW+RYuvwU5MAIZUOxXY0GnjU1/iRN/JkLhwvhZVsDQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-minify/binding-darwin-x64@0.131.0': - resolution: {integrity: sha512-EIP8KmjqfZeDdhrbG+0GDsiw1/Bi3415uCFokhOm6b8tGG0UdiemVHAz9IQE/sIJgwguXYtg5ydz9oFYVOlOfA==} + '@oxc-minify/binding-darwin-x64@0.132.0': + resolution: {integrity: sha512-s7ecbOJeLccy3nqQlkiq9cV0D0q8j1OyHmxRz22m8qZlcKrc3s4gmhwj5ertipA8ePn3FOXv4azf8b5gatDDug==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-minify/binding-freebsd-x64@0.131.0': - resolution: {integrity: sha512-2/xcCZfVm24sLFHbI5Rg/t6Ec93pth0NvTgy/J8vXjIOy8Yf5kkO/K1KVtdZBHW+cyLPe7YLLybxMF/BeqM8Kg==} + '@oxc-minify/binding-freebsd-x64@0.132.0': + resolution: {integrity: sha512-pdYVNmY9NgKetEWzXlVIUlPm4Z3Gz979nTbZUpHlqpjU/rtulpm0fgROo6rlTk+W0HhZCCZ0Jzy1LBKgn5g3mg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-minify/binding-linux-arm-gnueabihf@0.131.0': - resolution: {integrity: sha512-LDQ1Y+QfL5lN54ib1Je2paoh4EsQmmDRvB5Bd9AQIGCP16LI+8jZnB8cjTT3GD1acITDg1aiaBKk9JpBjBA4iw==} + '@oxc-minify/binding-linux-arm-gnueabihf@0.132.0': + resolution: {integrity: sha512-QdV2II2mrbygZO/D+umhb+jMs+kmNO2pvQ+kahY8DN7qZVvaR2CiWBQaAxi3yuI0JvmymcUBEFhRrXsaL/lUqg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-minify/binding-linux-arm-musleabihf@0.131.0': - resolution: {integrity: sha512-mz99O2sZoyHnMoksxlZ5Mc+USS/w/uIp1LWQAn42RHAvVdIyQsqPRmTD/pJtW/KnjgpgaB0yDCpI6Xa3ivJppQ==} + '@oxc-minify/binding-linux-arm-musleabihf@0.132.0': + resolution: {integrity: sha512-6OJMBb53luST+xxNSzzg/rRkxMnR4NFQegdu3PCuDEUtP2OEgjmpvvBrHghITpzRsUqnQ/YTl/ItDiLVeoslUA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-minify/binding-linux-arm64-gnu@0.131.0': - resolution: {integrity: sha512-QjS1N4FwCV67ZylGyfTWoqURzar48dN5WTq/JVrGsiShFKlT9SpuyRsoUGMGJhiKNiI39MsLIHBlBWvoRQG+ng==} + '@oxc-minify/binding-linux-arm64-gnu@0.132.0': + resolution: {integrity: sha512-ND2GZp6StGQWhSBwOfX13kCCG7O/Z6sEL/dBsWSIgZaetEDUPLOWtKIm2f+TuYUSSmU5nJTSSE5psh9kGcCweQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-arm64-musl@0.131.0': - resolution: {integrity: sha512-HGzqTov5sAzXyaNfRkQEpl0fRs+PrMYjT8b5jZAw8foQ/qnW+VMWgAr80Q+2j79T5nhXfboSF5SUgB8mcisgHw==} + '@oxc-minify/binding-linux-arm64-musl@0.132.0': + resolution: {integrity: sha512-3k8ezEKmxs9Wel4N4vfF/8u764mA57j065P8nB4cU2PO/lLKloN0OA41ynfDUrSM1f5jBuF8+mLOj++aNnu4OA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-minify/binding-linux-ppc64-gnu@0.131.0': - resolution: {integrity: sha512-zpUZ4pmbDBqaZmRYacxeLHUBxA3fs5K7hi1WSXRVMXC4OjWuVcLsNxeavenKF9i0YtP7Q5n2z12Rz7eEnNWoDA==} + '@oxc-minify/binding-linux-ppc64-gnu@0.132.0': + resolution: {integrity: sha512-vM6jZIxoHoIS5rPb3K3Di0IureL4oU+wOWBy6tLSrjwW2IHqy0442CzO/Ks2U9VCuHV1q0bUGCF0H6AxCEjJHQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-riscv64-gnu@0.131.0': - resolution: {integrity: sha512-CYrC4tpW1wolbw/Fox+T0hxW92s1aG/WLi+htkk02JMiCHOWqGQKxUnm37lLiODKR/OwTYht3LB4xNrsS0RtCg==} + '@oxc-minify/binding-linux-riscv64-gnu@0.132.0': + resolution: {integrity: sha512-KburrmtWpeZg58uo275QRwy5bbNOXQd1WDI2tGxkY2dJBlO7N5V9+Uthvqn6KI/6RBtjd2T5NO4dCC0fgUxGvw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-riscv64-musl@0.131.0': - resolution: {integrity: sha512-ZQNur0zujUjNYgjFF4mcNaeEKWuerY9XkaALYtBsHqNetkj55w0ZwCKYfYKLH2JAdyNF2LuS0s7VGgjXP9EvWA==} + '@oxc-minify/binding-linux-riscv64-musl@0.132.0': + resolution: {integrity: sha512-MnahA2MNEtEdxWdUy24JXkMUNgGPqH285GL2L22Zz7k9ixsguFD+bTbbcR88pNqdb075nazozzv3edF83+azCA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-minify/binding-linux-s390x-gnu@0.131.0': - resolution: {integrity: sha512-tR8oiFSNpcS1mfGY1N3/Hy6TxP2wr5X9FFdn/y8GarN8ST/JMLY5SUiwPiU35NKiC69CDaAsLHXoIKUxK/r8Pw==} + '@oxc-minify/binding-linux-s390x-gnu@0.132.0': + resolution: {integrity: sha512-VE99UPZyQO2MAG4gLGXzrBumD5PGNaiWe+EakaROGCVbT0YH/d9z2ByYqbdWAMEBiTHjthyZp6UUEFVda+LnpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-x64-gnu@0.131.0': - resolution: {integrity: sha512-KodzbW12zmT/C/w4bGv2aWN7Q5+KVJKbNoAv5hooYeSujj8xSPGWl8pnyj7dJ9nd8j0CVjubEvHQ86rtzV99OA==} + '@oxc-minify/binding-linux-x64-gnu@0.132.0': + resolution: {integrity: sha512-FKxBkYrSAWNF4V6MacAJ/1E2SJobKKQ2CtW6Aq+pLzzEOjgk2SmxnK7I0bATlFH/O70tbTKDzWb17bySGYRcog==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-x64-musl@0.131.0': - resolution: {integrity: sha512-CNG3/hPE6MxdLikfLq5l0aZMvJ3W5AP1aoVjzQ1Itokv5sbfBcW0fp6Srn8mB86CyAqO9e7dbffZVOWBDVkhgw==} + '@oxc-minify/binding-linux-x64-musl@0.132.0': + resolution: {integrity: sha512-W8IqA2XRvg/b6l/f+2SdV45/KKmpmwTabrjiMtpg/wzJU5cmKUoHihtJXPc9NA0Ls9S/oP0wB3PMCRQoNr5J1A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-minify/binding-openharmony-arm64@0.131.0': - resolution: {integrity: sha512-UyfimTwMLitJ0+5i5fL9M9U4E+DcIQJpGZWbVxxD3Mp9f7CTyQBIHnS68VEGZe+KQL/Y3IIb3AJ7cZB+ICgTVQ==} + '@oxc-minify/binding-openharmony-arm64@0.132.0': + resolution: {integrity: sha512-X1BL65pI9bfOesLdVUcErjbEAUA3qmzjXCwXPCYsFZT7ela7SsK85+sN3m2TJNxmX1mrFKNg5g8bH+d2zHresw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-minify/binding-wasm32-wasi@0.131.0': - resolution: {integrity: sha512-fH7sy51iYnmGv2pEPsS9KEVExHDKI1/nfy/OqYnStW2E5di41CQ1qBjVIvxHOMHcPD8RmKEBCf0zng6d9/vGDg==} + '@oxc-minify/binding-wasm32-wasi@0.132.0': + resolution: {integrity: sha512-QcIiwBOj+bV5ub5x39Xb+v0boviykxUtVvVJaIEbG/IH97avFzZcBXec8awYlemLDvgG4WKQwr17x7COR5zwFg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@oxc-minify/binding-win32-arm64-msvc@0.131.0': - resolution: {integrity: sha512-C05v+5eIdvF4YXQ4t+U0JQDl8IWoIabxsmh4inBSGOL0VziELmis3lb5X6JMj208RbQdKhZGJbUkmNWq2B5Kxw==} + '@oxc-minify/binding-win32-arm64-msvc@0.132.0': + resolution: {integrity: sha512-ahFMaa84QVTIROWpLhZcS9jKIv+CXzsJaMmgje7JtlVp1Kaar6tzVCt3EH2aPhSc8RvbGqfmnGdQu/kGwPAZVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-minify/binding-win32-ia32-msvc@0.131.0': - resolution: {integrity: sha512-bZio0euDmT6Er00I6jng66ftGw5doP/UmCAr2XtBooZMdr7ofTJ4+Bpp+ufguVIeVk5i1vgMPsq7g6FTcxHevg==} + '@oxc-minify/binding-win32-ia32-msvc@0.132.0': + resolution: {integrity: sha512-tpBkLklqOnaYtlIh6gjmL60pP0Kn2hwaw1Fw3sJyIKwdkCPHsOPy/MRgBUpM0a/SeGFbsZRQkHnWfZXS1GTbbQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-minify/binding-win32-x64-msvc@0.131.0': - resolution: {integrity: sha512-Lih6D0rjXStl0eUjzlcCiqr60AI/LuE+Zy29beEeXrXqTjOf8t0mcDX/MN3TZBBncxwUNi6osAEsKj4FRnItmQ==} + '@oxc-minify/binding-win32-x64-msvc@0.132.0': + resolution: {integrity: sha512-a69yKrBl2p9O8cdAHbHih56eKhcpKJRVkRu/S+CwCdR2Zsh4nnqYIllF96Lxg3jDjRQNL3t0xZNdYBDG5Vgq+w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1603,8 +1613,8 @@ packages: cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm-eabi@0.131.0': - resolution: {integrity: sha512-t2xicr9pfzkSRYx5aPqZqlLaayIwJTqgQ81Jor31Xep2nGyL2Aq3d0K5wOfeR7VevaSdxaS9dzSQP9xDwn8fDg==} + '@oxc-parser/binding-android-arm-eabi@0.132.0': + resolution: {integrity: sha512-KrLaPWa5c9Y7LkW+rKkaUE3y7DBDrQtaf7rlsSDfv6KAHUjgzAIRA761Lrrp6//Yd/Rlie/yEOt9YENCoJnOcw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] @@ -1615,8 +1625,8 @@ packages: cpu: [arm64] os: [android] - '@oxc-parser/binding-android-arm64@0.131.0': - resolution: {integrity: sha512-nlGIod6gw75x1aEDgLS+srj+JRGY0HHm9MI9YgzE/B64l6d6+H3MSP9NOgp0+HTg8tp4vV9rVfgQGgd+TfVZcA==} + '@oxc-parser/binding-android-arm64@0.132.0': + resolution: {integrity: sha512-SThDrSeamB/kG2+NxcJ5/wSLcV6dUqDknrPLqFYQ0ST/55mtBP4M7Q/f3QbubH6aAd11wpzZn/nwbVRSdobOpg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -1627,8 +1637,8 @@ packages: cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-arm64@0.131.0': - resolution: {integrity: sha512-jukuV6xe5RbQKFo7QD34NDCLDZp4PSOm8rmckhNdH/60ymG5zXbDzGBEyc+nTkuLQNama2aSGCt+CPfpjNTqyw==} + '@oxc-parser/binding-darwin-arm64@0.132.0': + resolution: {integrity: sha512-Lc0f/TYoKBghE5/2Gsv7bLXk+TJZunx2Tf61X8hG4ARXdc8UYI26dCGccFSd1AyFbK3jfaNXtMnupggDbjPXdQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -1639,8 +1649,8 @@ packages: cpu: [x64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.131.0': - resolution: {integrity: sha512-g3JOo4khe9rslHm5WYaVDWb0HS/M1MLR3I9S8560MkKIcC96VQY00QjOlsuRyfSj/JDXj8i9T7ryPO2RidiXVg==} + '@oxc-parser/binding-darwin-x64@0.132.0': + resolution: {integrity: sha512-RG2eJIpf7C21z9HSSXFw1bTArdpKe7Y4fwcJTwRq1yCSe1vSavaN9GA1sm9KqzemTLAGVktQ+7qBTGp0vQeUZg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -1651,8 +1661,8 @@ packages: cpu: [x64] os: [freebsd] - '@oxc-parser/binding-freebsd-x64@0.131.0': - resolution: {integrity: sha512-1hziITDTxjMePnX+dR9ocVT+EuZkQ8wm4FPAbmbEiKG+Phbo73J1ZnPAA6Y/aGsWF3McOFnQuZIktAFwalkfJQ==} + '@oxc-parser/binding-freebsd-x64@0.132.0': + resolution: {integrity: sha512-wQIPntPLtJ8NcBpvKPbEv3NqzV6k8eP8tP/jE9Rg8HTg/j7urZGFSsTCPCW5k77Qfw2DM4vRvc9p3I4yq/Shvw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -1663,8 +1673,8 @@ packages: cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-gnueabihf@0.131.0': - resolution: {integrity: sha512-9uRxfXwyKG9+MwmGQBo2ncPNwZH5HTmCETFM2WiuDBNDCW4NC5ttSQkwCAMrTAWgwMzVBH1CP8pM0v7nebCWXQ==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.132.0': + resolution: {integrity: sha512-PixKEpeSe3yxQWqNyOCBALRYc72+Tj7ILDofUl3iXo25cVOzLA6jHUhmOINRtWIPh7dbUie3QNeabwaQpZTw6w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -1675,8 +1685,8 @@ packages: cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.131.0': - resolution: {integrity: sha512-mgbLvzRShXOLBdWGInf08Af4q+pfj1xD8hSgLClDZ9of/BXkB6+LIhTH7fihiDUipqB3yoSkKBWaZ3Ejlf5Yag==} + '@oxc-parser/binding-linux-arm-musleabihf@0.132.0': + resolution: {integrity: sha512-sCR+DzGHlyHKnbA2z9zWjTUhIo8Sy0enJl4RDsBwPmkxYynPatpwOAWe8W5127SlW0boqUWHGtr1NWn5UwIhXQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -1688,8 +1698,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-gnu@0.131.0': - resolution: {integrity: sha512-OPT8++4aN6j2GJ8+3IZHS/byXoZP4aSBn+FoG6rgBJ2fKwPKXWF3MqrFMNW7NKHM28FLY579xYLxJSfgobEqPA==} + '@oxc-parser/binding-linux-arm64-gnu@0.132.0': + resolution: {integrity: sha512-sQBix5P2cW+IpzTcCwYxnh9yALrKSIkKJThspBvMGcygSMnbzkSvhN7SfuX1hvBk8y1XEChsdkU3ET0V5DmzUw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -1702,8 +1712,8 @@ packages: os: [linux] libc: [musl] - '@oxc-parser/binding-linux-arm64-musl@0.131.0': - resolution: {integrity: sha512-vtPiwmfVTAXzaxDKsOXG+LwgRAA7WEnaeHzhS5z0GE89gAK18KSXnly7Z6saXXq6L3dVMyK44uoTI03zKxrpmw==} + '@oxc-parser/binding-linux-arm64-musl@0.132.0': + resolution: {integrity: sha512-WozHg3Kc//8Sk756HXXgMbEAvqtG+Lzb9JOojwQzIGDtN78Az2dLttkb71akWYUF/8IgYfDSlfKh4Uot8is5Vw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -1716,8 +1726,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-ppc64-gnu@0.131.0': - resolution: {integrity: sha512-8AW8L7w5cGHSdZPcyZX2yR0+GUODsT15rbRjfdD54rv6DMbtuEB19ysLOpKJlRGfH6UNYNpCHaU1uJWgTWf1/w==} + '@oxc-parser/binding-linux-ppc64-gnu@0.132.0': + resolution: {integrity: sha512-CmX/ulNBOEwWTyVRmcpYKAcAizW6+OjtLJgo7fXoL9OqQvjF4VER8tPomv44vwzfSCy1BHbsB0ZlZYzYJNj4cA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] @@ -1730,8 +1740,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.131.0': - resolution: {integrity: sha512-vvpjkjEOUsPcsYf8evE4MO3aGx9+3wodXEBOicGNnOwTuAik8eBONNkgSdhkGsAblQmfVHJyanRnpxglddTXIA==} + '@oxc-parser/binding-linux-riscv64-gnu@0.132.0': + resolution: {integrity: sha512-j9oQS+hM90SdhviNGWbPgT4+Rlq+ac++q/zjgwPD1mVHgxHzATvoRGtDx0sXGmFOQ9J9YkwAhYGb5MAHL6TAsA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] @@ -1744,8 +1754,8 @@ packages: os: [linux] libc: [musl] - '@oxc-parser/binding-linux-riscv64-musl@0.131.0': - resolution: {integrity: sha512-AqmcNC3fClXX+fxQ6VGEN1667xVFiRBkY0CZmDMSiaeFUsv1+UkBPYYi48IUKcA9/ivvoKNRzQl2I4//kT9F/w==} + '@oxc-parser/binding-linux-riscv64-musl@0.132.0': + resolution: {integrity: sha512-bLz+Xi+Agnfmd7kWPEsSVwCn2k4EyIalZkNBcQ0OGIv9rqn8VgCPLNd03tM9mKX/5TdlvDXalz0q71BIrOPNqg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] @@ -1758,8 +1768,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-s390x-gnu@0.131.0': - resolution: {integrity: sha512-7d3jOMKy7RSQCcDLIci+ySll2FgsOMl/GiRux4q2JNv0zg4EdhFISa9idvrdN/HEUIQQJNg6dmveUeJl2YErGA==} + '@oxc-parser/binding-linux-s390x-gnu@0.132.0': + resolution: {integrity: sha512-U6t2qbJU0ypTfyj9QV3W1Y6mITDTL8ai/OR6NUn85vyHthOvobKWgXzU4tu0EskSzlpuVFz1g0jFGulDIUKHxQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] @@ -1772,8 +1782,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.131.0': - resolution: {integrity: sha512-JHK/h95qVqVQ+ITER837kcTdwBDFpFaNnOTYGCP0zdUSX/mLKC7tXOoyrTb6vG7iRPwGlcgBil3v2IjYw1FqJA==} + '@oxc-parser/binding-linux-x64-gnu@0.132.0': + resolution: {integrity: sha512-WcEaSNHFk8yz5YFlQQAlhq6jOFmZBB/RKE7uzhyCIf+pF1Lmv9gUH4221mle2Gd9iHyWT3ySNph8yZgb1xYdWg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -1786,8 +1796,8 @@ packages: os: [linux] libc: [musl] - '@oxc-parser/binding-linux-x64-musl@0.131.0': - resolution: {integrity: sha512-b2BO82O8azXAyf7EUgOPKu145nWypbNyk07HbU09fkzhm9lEA5oPvaN/M8Nlo7tOErVTa2WOgS4QbOnxAPXdDQ==} + '@oxc-parser/binding-linux-x64-musl@0.132.0': + resolution: {integrity: sha512-iQrV4iJzQgRwK3BWRmQl1C3C6g3wYpXN2WLdQdyR+efoUnncdShZAVp9OgcojtlD3MDRbuOMGG3SjxF4fL4nlQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -1799,8 +1809,8 @@ packages: cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-openharmony-arm64@0.131.0': - resolution: {integrity: sha512-GHO9glZaX7LkX/OGfluEPf1yjg+ehiFbUdowbX6uNWOQhmwKWU4m4+nZ9FJkrHNKuxyI1KKertMdGjVKCApKWA==} + '@oxc-parser/binding-openharmony-arm64@0.132.0': + resolution: {integrity: sha512-FWzmUGrZ6GUby4U7WIwcCtab6tdmlTO3xTRRKyb5kjIJVEiaUAT8animUG/nK8ZCA8gkRkPOTId4rl6uTqUmJQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -1810,8 +1820,8 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@oxc-parser/binding-wasm32-wasi@0.131.0': - resolution: {integrity: sha512-3SkikPaEFoih1N83qLVEDLRLeY4nYsf6JT9SnWiMCQ5lGQdKup6bEuKCqkRiG9dD1IIaFeYz9RjlciPmYoFIWA==} + '@oxc-parser/binding-wasm32-wasi@0.132.0': + resolution: {integrity: sha512-TlbMppxJI5CjWDes0QaP6G3aneVg1yikBu5QYI+DUShF9WDL66ccgKFNNGmi/Wybtszw6hxwAvv76T4DaPKnHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] @@ -1821,8 +1831,8 @@ packages: cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-arm64-msvc@0.131.0': - resolution: {integrity: sha512-Os5bEhryeA2jkH+ZrnZyAC1EP5gs+X4YB1Fjqml7UPD5kU7ecsK1MPEVMfCrdt/GDNpDbavYXiOXOdyJ5b3OPw==} + '@oxc-parser/binding-win32-arm64-msvc@0.132.0': + resolution: {integrity: sha512-RH/NbFjGKqdUAUi7Oh3LQPxUk2hsWFEEQ38HSnbRQT8QjBZFKqL1fMbmsB3N4jy/KPh9iX94+9dmkEMBBbambw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -1833,8 +1843,8 @@ packages: cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.131.0': - resolution: {integrity: sha512-m+jNz9EuF0NXoiptc6B9h5yompZQVW/a5MJeOu5zojfH5yWk82tvF2ccrHkfhgtrS9h9DD5l1Qv8dWlfY7Nz8g==} + '@oxc-parser/binding-win32-ia32-msvc@0.132.0': + resolution: {integrity: sha512-JUr4jQY9jxoIB/YTLXr6XofSi5xikj6p5/Ns1h0VOBDT0j1jKU+kMsv2xxv51RwnETcXpA1Yw/9oUAfcqfaqEA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] @@ -1845,8 +1855,8 @@ packages: cpu: [x64] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.131.0': - resolution: {integrity: sha512-o14Hk8dAyiEUMFEWEgmAwFZvBt1RzAYLM3xeQ+5315JXgVYhoemivgYcbYVRbsFkS71ShMGlAFE0kPnr460rww==} + '@oxc-parser/binding-win32-x64-msvc@0.132.0': + resolution: {integrity: sha512-2dapgHpA5X8DSXF4AU36hJWYf6zP0tKjMXFRAZFBD62pkevW/uhFDXoFH9Y/3Fd2EtDrw5ByNnR1wVE9X9y0SQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1854,8 +1864,8 @@ packages: '@oxc-project/types@0.128.0': resolution: {integrity: sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ==} - '@oxc-project/types@0.131.0': - resolution: {integrity: sha512-PgnWDfV0h+b16XNKbXU7Daib/BFSt/J2mEzfYIBu6JB/wNdlU+kVYXCkGA1A9fWkTbOgbjh4e6NhPeQOYvFhEA==} + '@oxc-project/types@0.132.0': + resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} '@oxc-transform/binding-android-arm-eabi@0.128.0': resolution: {integrity: sha512-qVO4izEs88ZSo7KOK4P+O5nAXXJmkSadInvFjGkhVnm2R2Wr8trU/GLhjAK0S0u8Qv9bkXspNhgpECk+CTQ/ew==} @@ -1863,8 +1873,8 @@ packages: cpu: [arm] os: [android] - '@oxc-transform/binding-android-arm-eabi@0.131.0': - resolution: {integrity: sha512-rcNvLlbNnxTfYVlZVF+Rev2AyCpJDpwVPphG4HOJxauaT1+w5VxL+kRdxCReof4A8ZsszbvIYlvkqvaJKO4Mog==} + '@oxc-transform/binding-android-arm-eabi@0.132.0': + resolution: {integrity: sha512-UEC6fwIer1e2H8+KYXfhfYMsDgqxrG93lCj3FkrKkJ2O05rikqiJLYGd9ZntmKne+9bOMMuznVKLGErub++mAg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] @@ -1875,8 +1885,8 @@ packages: cpu: [arm64] os: [android] - '@oxc-transform/binding-android-arm64@0.131.0': - resolution: {integrity: sha512-/y+EH6QYQB2ZDQNvMlzItc36mw16GZwCDlvGYbQ4GCTE+7ZtSmx9E/rJOYzYyzMghz0c5dhJquRKScXdOZHpnQ==} + '@oxc-transform/binding-android-arm64@0.132.0': + resolution: {integrity: sha512-sr2BbEHtc5OkAN2nt5BpWGg/MnDkyQKf6tSjaZZ6k7Bb2FOa2CzZDy2pvH6tYdg+Ch/p/OGXXhENFVV9GU7ASw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -1887,8 +1897,8 @@ packages: cpu: [arm64] os: [darwin] - '@oxc-transform/binding-darwin-arm64@0.131.0': - resolution: {integrity: sha512-x1Va8zFomdYghAI0Zkt7kUmG50S65XH1u0EbIDr80M9idfXrQgd08ZGl3ejwRGLBrkbA8tkkmeOu1rWVFf7BXg==} + '@oxc-transform/binding-darwin-arm64@0.132.0': + resolution: {integrity: sha512-yjL1GbN9Bb1HqjE8CS8NSwoZtDWgUGy43VbuFhmT4LEDx4Ph0guzVAyUKhc2CqqA4/x60qDvcH6QxwrguaqEVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -1899,8 +1909,8 @@ packages: cpu: [x64] os: [darwin] - '@oxc-transform/binding-darwin-x64@0.131.0': - resolution: {integrity: sha512-EwacackWpYYXGZsl0Aj4NKvDdLuxWZg7LQDneFyMwuftpAxPQLRkHFwZib7r6wpIJm4NELhHW261A4vZ8OQqXQ==} + '@oxc-transform/binding-darwin-x64@0.132.0': + resolution: {integrity: sha512-e3vVXEbNw93aHr3si8eVpUgl+jWF6Ry8RgUihgSxiI+2c/VMxiPsEDghkqPcjujqsMYDRdISWJi23xk+PP72ow==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -1911,8 +1921,8 @@ packages: cpu: [x64] os: [freebsd] - '@oxc-transform/binding-freebsd-x64@0.131.0': - resolution: {integrity: sha512-EhXqWOtL1PWcJ3ktdplV4Wrez2PRuTBSDdB7KF6CN4zuZhohUjxC1bxqDNRbNSX46yaZ27IzJLafah1J6mSA8Q==} + '@oxc-transform/binding-freebsd-x64@0.132.0': + resolution: {integrity: sha512-dIhAhkX8/It4IaKI944fN3jmfzunqv2sEG2G4fQdP5/1psycdqUHoVaY23DbpuYRIu4sWAdn/e1zQFP0GMkQOQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -1923,8 +1933,8 @@ packages: cpu: [arm] os: [linux] - '@oxc-transform/binding-linux-arm-gnueabihf@0.131.0': - resolution: {integrity: sha512-NfNACr3aqBKeeUh6HCoGGPSjdMkLvyXUZQywCg/DwRkEpqZo55KX65saW1sQdgBcu0SKXrAReTjIm/HDO/OI0Q==} + '@oxc-transform/binding-linux-arm-gnueabihf@0.132.0': + resolution: {integrity: sha512-eR0dfj1us7DNbGZ6eBdAqWnLZRkLqHFqewSHudX4gV7di3By8E05+M+qsGTB/zq/78Z0BYJeK1zGWu9un6jocw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -1935,8 +1945,8 @@ packages: cpu: [arm] os: [linux] - '@oxc-transform/binding-linux-arm-musleabihf@0.131.0': - resolution: {integrity: sha512-ABp6KGhbYFGDaAdB4gGZW12DYa55OF/Cu+6Rw6/Di0skuwpiDwnBOLHWz9VBq0QTcREy/qIUOnKW+vZHQLOT8A==} + '@oxc-transform/binding-linux-arm-musleabihf@0.132.0': + resolution: {integrity: sha512-naNx0WaV70hKtgQ5LUS/jzRTy6XEQZ1krK7KTFZQLI1mEz+GqLrwsLCqEmtrQ6HcqLhvGvA6GAWfFrc/0mWryA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -1948,8 +1958,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-arm64-gnu@0.131.0': - resolution: {integrity: sha512-4nKYkHHjRela+jpt+VO4++jxgHoJQFxAeAGtfQ4x11dQMJllzqo3Yu8gfcfLEMsAfflwN/gY+KBbMD/y0exitg==} + '@oxc-transform/binding-linux-arm64-gnu@0.132.0': + resolution: {integrity: sha512-TWk1p0tbtE1tkMEABftfgXhMEfuoz3QieqBtMBXXyijizw/2YKNzbVSndG+vV73cSZgbyfoZ346pmuz0tQMzyw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -1962,8 +1972,8 @@ packages: os: [linux] libc: [musl] - '@oxc-transform/binding-linux-arm64-musl@0.131.0': - resolution: {integrity: sha512-cW0Ab1s0sxfiyP1+gdd94f0vUjwGzJF4F3DepF3VnR9nFTGMmFLugwtrBS3DYjTnbugiUH3Fp+16yys1FhNzIA==} + '@oxc-transform/binding-linux-arm64-musl@0.132.0': + resolution: {integrity: sha512-LxURDI0Wm2KCQm/3ynNlI+nTgPdfmAfmrl54XPx+gaIqty8S/XWNCCTvLJWaCb0e5eKqnzrcTuhMDOdawqoYIA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -1976,8 +1986,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-ppc64-gnu@0.131.0': - resolution: {integrity: sha512-wunAU/lzE1nPGKL47uI0g+4Nsv/12xveOXNu4M70xe85kNBm7mQdMpZIeoVYCxtXew0iHxFKJDT6qK5mYFSA3w==} + '@oxc-transform/binding-linux-ppc64-gnu@0.132.0': + resolution: {integrity: sha512-eKEeG6SLtj01iDvi5QgMNzyEXt/K2BNWafZ0jGECmvqTWWaO2l4qBxUW+X+sAXp5vZBoT2WO3ZnshvIWXWjtKw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] @@ -1990,8 +2000,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-riscv64-gnu@0.131.0': - resolution: {integrity: sha512-r4sMt4OB4TryDcVWW9KnsXOf/ea7tIGX2QASNrpetzPocsBZqhHIFDbZ8EkBDjmlmWGHg6BgjVx6lLcMXX4Dcw==} + '@oxc-transform/binding-linux-riscv64-gnu@0.132.0': + resolution: {integrity: sha512-Kz6tg1Msra7+2iGV8K5xANLO2SmpP6n+91/Yy+JJh9EagU4hvMm7loReszzz2bwhs6Xs4HPrglxIngMdqnHpXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] @@ -2004,8 +2014,8 @@ packages: os: [linux] libc: [musl] - '@oxc-transform/binding-linux-riscv64-musl@0.131.0': - resolution: {integrity: sha512-/rLVLItsBjKrnZFLiGrwRB3fs0dAjXZLqY7F42omvacFJjZsceQ3481oQX1bBs3RwoDDyDy/9ZkIN7kYIkv5Gw==} + '@oxc-transform/binding-linux-riscv64-musl@0.132.0': + resolution: {integrity: sha512-dtUSp80ElrxUhfBNmFWGkFQQ51j3tRoZkKBXxEWh+hb+S6bbEdZCW/VuCYo/gCTH3DywwyTeWiG+dtZfJiHKvg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] @@ -2018,8 +2028,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-s390x-gnu@0.131.0': - resolution: {integrity: sha512-fUprJgJauI1A7e7cDgY/Z3mwLVtE3aswB4lvS96KpRNDHrwOh8bnCJOWf+0CYveDQzghDVFiZWVDo56pO4Wr9Q==} + '@oxc-transform/binding-linux-s390x-gnu@0.132.0': + resolution: {integrity: sha512-9qVyCbYSs8dwVPpqKKWxuUAnLJ1+LyC5A4oNMZTzymRhuQr3coqAP/XWfJ8LlhQqI9GvhK0SWCOK0iM3HFUAnA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] @@ -2032,8 +2042,8 @@ packages: os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-x64-gnu@0.131.0': - resolution: {integrity: sha512-XdbvDT1GPNxrTLXSRt4RU2uCH112q3nINTT05DZqTYYcAxaCPImnMoZe2TlBv5j2376Gk+2pcVnJs6xut47aSw==} + '@oxc-transform/binding-linux-x64-gnu@0.132.0': + resolution: {integrity: sha512-dUtJkDCYndDaxcuiSMyRoSb7sXmTbcJ61rDsUjIakghP6BkKwH57lyHYvSUhT1ZswXWwCjf3ksxlT8nA0iU6ag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -2046,8 +2056,8 @@ packages: os: [linux] libc: [musl] - '@oxc-transform/binding-linux-x64-musl@0.131.0': - resolution: {integrity: sha512-Du2CxlBfC98EV3hOAmLVSUgP0JgqM9F47lRv9v43T4sGPcQVOjs9wffUybGUUraG9unmBZ4dgpMAqlCq0k3dGw==} + '@oxc-transform/binding-linux-x64-musl@0.132.0': + resolution: {integrity: sha512-I7BkkktnrriiO7o1dF3RDgKZoSmFKX9IE0W2LE1WdfmpZcAa3fbv5BW6oVbzk40iD29hWSP69A65WT9l6dxuzg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -2059,8 +2069,8 @@ packages: cpu: [arm64] os: [openharmony] - '@oxc-transform/binding-openharmony-arm64@0.131.0': - resolution: {integrity: sha512-wTj2FkOgNhgdisnA0a15QQksyj6AH2snmpgYgAtj098i477x5LpHHdqfuk60jsA/QHSjmUc6dm4P88yI5GY4xA==} + '@oxc-transform/binding-openharmony-arm64@0.132.0': + resolution: {integrity: sha512-yiXaRYqgySJguURNZUFLDzSI1NTkP1jJKrowr8lQCKwY5N8DsESbQJ1RpSlEbeXGiy201puA+QC2fdr+ywQM/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -2070,8 +2080,8 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@oxc-transform/binding-wasm32-wasi@0.131.0': - resolution: {integrity: sha512-lE9UaZL0KomAlbATiB6FKoJ9no6W49yXs/MujJqY75AkHHMeOCsHSN9HvriyWz2FOIQgV7C5cmNj0jf+IaBtQg==} + '@oxc-transform/binding-wasm32-wasi@0.132.0': + resolution: {integrity: sha512-KNago0Mv+zl2yl5hK2G9V4Yb7Tgpn+z6lgzgaHXkGp7S+iuUtN3av+QqPCD/J+Odq6EjjyXJrFPfmyjbXXbf4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] @@ -2081,8 +2091,8 @@ packages: cpu: [arm64] os: [win32] - '@oxc-transform/binding-win32-arm64-msvc@0.131.0': - resolution: {integrity: sha512-8KUfPnuxbEfa9H+OQ5XNPFq9JIEWVCg8kczJaD8PvTprr515mz1lmSLSUoOW8mrLaN0mZaGg6pemuvTawOLoPg==} + '@oxc-transform/binding-win32-arm64-msvc@0.132.0': + resolution: {integrity: sha512-3fprECrLHwPP809a1SRzszDxp8Fpp8IOg0V2EO49wS+3JmRFOo090h5c37faZvym5VnRZ12DH2tkT6ZVXwlOsA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -2093,8 +2103,8 @@ packages: cpu: [ia32] os: [win32] - '@oxc-transform/binding-win32-ia32-msvc@0.131.0': - resolution: {integrity: sha512-pXSu2A7L6H//1Uvsg5RJHb91BDZpCTho0r9oAwxPqKJM2LWV7Zph/ikWEIXt/YLbKF3WpkHrKQ5hbQGP9gWmHg==} + '@oxc-transform/binding-win32-ia32-msvc@0.132.0': + resolution: {integrity: sha512-n616QqZ3hXasHytVoFjo6pLzIfo6hQwBEir0kOcaObKaAw0ZbncIe1h5a6IMnCOJGLP30WwnhwLW20tIV78MAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] @@ -2105,8 +2115,8 @@ packages: cpu: [x64] os: [win32] - '@oxc-transform/binding-win32-x64-msvc@0.131.0': - resolution: {integrity: sha512-VXgk106WLl3NpBO/6G2gxkWBHguCJm01mGqAq2Q0l2o7hnbglsND0UWSCtM3a9MlsDimfJkLWFQveZu4UtnRvA==} + '@oxc-transform/binding-win32-x64-msvc@0.132.0': + resolution: {integrity: sha512-P7A4Cz/0C0Oxa2zH/oCruzA/5EHr5RRz0x6KXYz3wwhS+dFqIBxP9yo8FKjXhKXHRKa+M+QHo+bqYiqqlVsEQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2317,141 +2327,141 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} + '@rollup/rollup-android-arm-eabi@4.61.1': + resolution: {integrity: sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} + '@rollup/rollup-android-arm64@4.61.1': + resolution: {integrity: sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} + '@rollup/rollup-darwin-arm64@4.61.1': + resolution: {integrity: sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} + '@rollup/rollup-darwin-x64@4.61.1': + resolution: {integrity: sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} + '@rollup/rollup-freebsd-arm64@4.61.1': + resolution: {integrity: sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} + '@rollup/rollup-freebsd-x64@4.61.1': + resolution: {integrity: sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} + '@rollup/rollup-linux-arm-gnueabihf@4.61.1': + resolution: {integrity: sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} + '@rollup/rollup-linux-arm-musleabihf@4.61.1': + resolution: {integrity: sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} + '@rollup/rollup-linux-arm64-gnu@4.61.1': + resolution: {integrity: sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} + '@rollup/rollup-linux-arm64-musl@4.61.1': + resolution: {integrity: sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} + '@rollup/rollup-linux-loong64-gnu@4.61.1': + resolution: {integrity: sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} + '@rollup/rollup-linux-loong64-musl@4.61.1': + resolution: {integrity: sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} + '@rollup/rollup-linux-ppc64-gnu@4.61.1': + resolution: {integrity: sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} + '@rollup/rollup-linux-ppc64-musl@4.61.1': + resolution: {integrity: sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} + '@rollup/rollup-linux-riscv64-gnu@4.61.1': + resolution: {integrity: sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} + '@rollup/rollup-linux-riscv64-musl@4.61.1': + resolution: {integrity: sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} + '@rollup/rollup-linux-s390x-gnu@4.61.1': + resolution: {integrity: sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} + '@rollup/rollup-linux-x64-gnu@4.61.1': + resolution: {integrity: sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} + '@rollup/rollup-linux-x64-musl@4.61.1': + resolution: {integrity: sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} + '@rollup/rollup-openbsd-x64@4.61.1': + resolution: {integrity: sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} + '@rollup/rollup-openharmony-arm64@4.61.1': + resolution: {integrity: sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} + '@rollup/rollup-win32-arm64-msvc@4.61.1': + resolution: {integrity: sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} + '@rollup/rollup-win32-ia32-msvc@4.61.1': + resolution: {integrity: sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} + '@rollup/rollup-win32-x64-gnu@4.61.1': + resolution: {integrity: sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} + '@rollup/rollup-win32-x64-msvc@4.61.1': + resolution: {integrity: sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==} cpu: [x64] os: [win32] @@ -2473,8 +2483,8 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@speed-highlight/core@1.2.15': - resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==} + '@speed-highlight/core@1.2.16': + resolution: {integrity: sha512-yNm/fYEcnpRjYduLMaddTK9XKYil6xB88+qFg79ZdZhHu1PadfoQmFW7pVTx7FZqMBNcUuThiAhxhENgtAO2/w==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -2493,11 +2503,11 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' - '@tanstack/virtual-core@3.16.0': - resolution: {integrity: sha512-Er2N7q3WOiH6y2JLxsxNX+u2/sLqSsL0bxFgDjuiPiA7vKhZRm+IzcS17vRee3GNXr64UsesA5CAp9yTiIYw9A==} + '@tanstack/virtual-core@3.17.0': + resolution: {integrity: sha512-gOxY/hFkPh/XQYhnThBHzkbkX3Ed+z/iushyz+R+JAr213aXxUDgQoTgTdrDpBSRsjFM73P/KfUyWmaF9WHMkQ==} - '@tanstack/vue-virtual@3.13.26': - resolution: {integrity: sha512-4TmREKi8rKiQC8E2XVEMMgzWbrgHNYolkBgYTXVK1kqXmXRGz6xPWgBq20GUYWUDDhit94+g0ricUQKpZhWRmg==} + '@tanstack/vue-virtual@3.13.28': + resolution: {integrity: sha512-A+jWpXtMpWXKhGLKQrXeC9mk1VgYeMWSJ+o0CTCEi+HLYMSQFdVmPG9lJz7d4XJyIkc5xVwZU9QY67QpScqnxA==} peerDependencies: vue: ^2.7.0 || ^3.0.0 @@ -2513,9 +2523,6 @@ packages: '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} @@ -2525,8 +2532,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@25.9.1': - resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + '@types/node@25.9.3': + resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==} '@types/phc__format@1.0.1': resolution: {integrity: sha512-hoAQFKcP3voXk/ZEl3jrvS63o/HYLszq4nA2mqjytaSEHEy3j3t0gSFtPLnfKtX34k/xfath7etOoGw5ukoqXQ==} @@ -2546,63 +2553,63 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.60.0': - resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==} + '@typescript-eslint/eslint-plugin@8.61.0': + resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.60.0 + '@typescript-eslint/parser': ^8.61.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.60.0': - resolution: {integrity: sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==} + '@typescript-eslint/parser@8.61.0': + resolution: {integrity: sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.60.0': - resolution: {integrity: sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==} + '@typescript-eslint/project-service@8.61.0': + resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.60.0': - resolution: {integrity: sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==} + '@typescript-eslint/scope-manager@8.61.0': + resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.60.0': - resolution: {integrity: sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==} + '@typescript-eslint/tsconfig-utils@8.61.0': + resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.60.0': - resolution: {integrity: sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==} + '@typescript-eslint/type-utils@8.61.0': + resolution: {integrity: sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.60.0': - resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} + '@typescript-eslint/types@8.61.0': + resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.60.0': - resolution: {integrity: sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==} + '@typescript-eslint/typescript-estree@8.61.0': + resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.60.0': - resolution: {integrity: sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==} + '@typescript-eslint/utils@8.61.0': + resolution: {integrity: sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.60.0': - resolution: {integrity: sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==} + '@typescript-eslint/visitor-keys@8.61.0': + resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unhead/vue@2.1.15': @@ -2730,6 +2737,11 @@ packages: cpu: [x64] os: [win32] + '@valibot/to-json-schema@1.7.1': + resolution: {integrity: sha512-3qkmU6KXWh8GIThEAW3kuRHPQBMjWkKy+Ppz3WkUucx53DTpOa6siMn4xDGSOhlVyMrDaJTCTMLYPZVAIk1P0A==} + peerDependencies: + valibot: ^1.4.0 + '@vercel/nft@1.10.2': resolution: {integrity: sha512-w+WyX5Ulmj4dtTZrxaulqrjaLZHSbnPzx75SJsTNYmotKsqn1JlLnDJa+lz5hn90HJofhl/2MAtw0mCrgM3qYw==} engines: {node: '>=20'} @@ -2749,20 +2761,20 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 vue: ^3.2.25 - '@vitest/coverage-v8@4.1.7': - resolution: {integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==} + '@vitest/coverage-v8@4.1.8': + resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} peerDependencies: - '@vitest/browser': 4.1.7 - vitest: 4.1.7 + '@vitest/browser': 4.1.8 + vitest: 4.1.8 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.7': - resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} - '@vitest/mocker@4.1.7': - resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2772,25 +2784,25 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.7': - resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} + '@vitest/pretty-format@4.1.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} - '@vitest/runner@4.1.7': - resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} - '@vitest/snapshot@4.1.7': - resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} - '@vitest/spy@4.1.7': - resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} - '@vitest/ui@4.1.7': - resolution: {integrity: sha512-TP6utB2yX6rsJNVRo2qAlsi48i1YwFTrLV2tnTtWqJaYX7m4lRCCLirZBjU6xC5m0RsPHr+L2+N+eIPhgEzFfw==} + '@vitest/ui@4.1.8': + resolution: {integrity: sha512-RUS2ZU2TsduVrI+9c12uTNaKrNUTsm6yFt3fueEUB9iKvyC2UP83F+sqIz00HQIah4UOL1TMoDAki8K0NjGvsA==} peerDependencies: - vitest: 4.1.7 + vitest: 4.1.8 - '@vitest/utils@4.1.7': - resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} '@volar/language-core@2.4.28': resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} @@ -2826,17 +2838,17 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@vue/compiler-core@3.5.35': - resolution: {integrity: sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==} + '@vue/compiler-core@3.5.38': + resolution: {integrity: sha512-s99aGxWYig9ErHbct27KXEGhrBYlRI6c4MwAgXErOAbX9xiW37/uMa+XUDO69zLz83dng8UUZ70CTOJrLrYrEQ==} - '@vue/compiler-dom@3.5.35': - resolution: {integrity: sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==} + '@vue/compiler-dom@3.5.38': + resolution: {integrity: sha512-JTqp25l8aFfJYF7/KmsXZjAxJz7T+SjmTJLoXVjHtc2BrSgSiW2n9Aem/cWq1OPe68A8JL06B3eVdhlP0H4TVw==} - '@vue/compiler-sfc@3.5.35': - resolution: {integrity: sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==} + '@vue/compiler-sfc@3.5.38': + resolution: {integrity: sha512-DuA2GiZawSEW442iw/9+Fkol8hTgb4Ke5KkhmSry65QA7YuyMbIdy8p0XZRMvNwJdgRz307W8g1CSzdvS4nuNg==} - '@vue/compiler-ssr@3.5.35': - resolution: {integrity: sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==} + '@vue/compiler-ssr@3.5.38': + resolution: {integrity: sha512-7s+W5Gc42FGxZMcuwl8H5B29T8BJPMdBT7KHFE+BbAuZ/iTEdTtv7z2XiMjiaUUw4w3ZcCEdHs36RuYJ2VA7bA==} '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} @@ -2864,25 +2876,25 @@ packages: '@vue/devtools-shared@8.1.2': resolution: {integrity: sha512-X9RyVFYAdkBe4IUf5v48TxBF/6QPmF8CmWrDAjXzfUHrgQ/HGfTC1A6TqgXqZ03ye66l3AD51BAGD69IvKM9sw==} - '@vue/language-core@3.3.3': - resolution: {integrity: sha512-X6p+7nfY7vVT6dQwUJ+v0Jfq/lwIfhL2jMi91dQ3ln4hnlGXlxsDu/FNkeyHYgvYtyQy18ZX76IZy7X4diDbiQ==} + '@vue/language-core@3.3.4': + resolution: {integrity: sha512-IuHqQ5zGGOE7CXP72VX6A42IVeIzYv4WAhO6arej11TRNqtdZfGyH8Yr2FOCaDX0dSQG+JwULLoFHGY1igYVjQ==} - '@vue/reactivity@3.5.35': - resolution: {integrity: sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==} + '@vue/reactivity@3.5.38': + resolution: {integrity: sha512-pG6LV/NDNRbKizcUjFFLAfjaL8mcv4DmR9avNcUw2gDHBzZneuS2TWCmp633ynzxz9YYKNeEPK2I8Wraqy2HUQ==} - '@vue/runtime-core@3.5.35': - resolution: {integrity: sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==} + '@vue/runtime-core@3.5.38': + resolution: {integrity: sha512-iyW8WVfF1CpCXxncZY5Ei6rSd6oZr5DgEom//fUjRBRl56AXPD+s9ATvukRt77ZFTuYlnVA1bxY+dJB94tWVYw==} - '@vue/runtime-dom@3.5.35': - resolution: {integrity: sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==} + '@vue/runtime-dom@3.5.38': + resolution: {integrity: sha512-apX2wt9sdfDshS+a2xueFZLVpt0GkRJZSoPmrW/SA4yzXTznhfcMVW59gr7h4YQeY0vJhdJkk2rsIDwgfFgC5A==} - '@vue/server-renderer@3.5.35': - resolution: {integrity: sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==} + '@vue/server-renderer@3.5.38': + resolution: {integrity: sha512-vue8vbf2QlV4quHqzwmJy6dWfmRhP1J8l4wtZg60CL6VoKqcPY2oe7may3+1d9qfpedjK5PRLFqd5k3Isj9mUw==} peerDependencies: - vue: 3.5.35 + vue: 3.5.38 - '@vue/shared@3.5.35': - resolution: {integrity: sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==} + '@vue/shared@3.5.38': + resolution: {integrity: sha512-FTW0AFZNaK5/mOqvGBwVfUlNLU38TiQn4+DQgIFUnrBBJQ1crMJ82yeGQLV5jyKFsO8yRukpbuP7x+nRbH6aug==} '@vueuse/core@10.11.1': resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} @@ -2965,8 +2977,8 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - ansis@4.3.0: - resolution: {integrity: sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg==} + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} engines: {node: '>=14'} any-promise@1.3.0: @@ -2976,8 +2988,8 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - apexcharts@5.13.0: - resolution: {integrity: sha512-PJuXT6zdiCbv0IkX5cqkKFVIIh+9v3kqP9zsOHEGpIWi7DfTgzvfOKc8icw6G3/ulR3V1alDDUtOVH0zWCWGEQ==} + apexcharts@5.15.0: + resolution: {integrity: sha512-ATswoiZi8wynKcwqf0eyE0Is5mBQoDpxZN3PlSVy41OrD+9GMBp2kZQRjyGK+5/j0GFjHkuAd7GKOrt5VMoPrw==} archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} @@ -3013,8 +3025,8 @@ packages: resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} engines: {node: '>=20.19.0'} - ast-v8-to-istanbul@1.0.2: - resolution: {integrity: sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ==} + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} ast-walker-scope@0.8.3: resolution: {integrity: sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==} @@ -3056,16 +3068,16 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - bare-events@2.8.3: - resolution: {integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==} + bare-events@2.9.1: + resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: bare-abort-controller: optional: true - bare-fs@4.7.1: - resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==} + bare-fs@4.7.2: + resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -3077,11 +3089,11 @@ packages: resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} engines: {bare: '>=1.14.0'} - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + bare-path@3.0.1: + resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} - bare-stream@2.13.1: - resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} + bare-stream@2.13.2: + resolution: {integrity: sha512-2V5j0dOfxv3iIngIWMnW1O6UPXpeoU70HJzUJGVth/+RURhDyq7SEWTD70Y2SkUB0MQonYYWpIX3f85P/I22+Q==} peerDependencies: bare-abort-controller: '*' bare-buffer: '*' @@ -3094,14 +3106,14 @@ packages: bare-events: optional: true - bare-url@2.4.3: - resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==} + bare-url@2.4.5: + resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.33: - resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} + baseline-browser-mapping@2.10.35: + resolution: {integrity: sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg==} engines: {node: '>=6.0.0'} hasBin: true @@ -3158,12 +3170,6 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} - bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.18' - c12@3.3.4: resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} peerDependencies: @@ -3203,8 +3209,8 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001799: + resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} @@ -3241,8 +3247,8 @@ packages: resolution: {integrity: sha512-zEbNjf8/Un85X0XYUR9e99CYxZrq6ko4F6Xd6wnrxpgVi9F0Y7096+H2T+RDxYGSYHP6DUptmQE4j6RdRe+f7w==} engines: {node: '>=22'} - cidr-tools@12.0.2: - resolution: {integrity: sha512-J5cUh8tmX51xlodw0dbHpljFHqrOVUa5oFHq/KoVvyQqgrvxWqTmUfAb7//VRrZn8Zo+fdKOowfe6TXruXqBeg==} + cidr-tools@12.0.3: + resolution: {integrity: sha512-p5Hpuav9qgBFOcYWw7oehik4cSJSiJwo7f12CVeFvVoj9owyRG/yd7ILqE/ktEbEBprkqJladY8FXX/a4lONHQ==} engines: {node: '>=22'} citty@0.1.6: @@ -3251,10 +3257,6 @@ packages: citty@0.2.2: resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} - clean-regexp@1.0.0: - resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} - engines: {node: '>=4'} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -3297,10 +3299,6 @@ packages: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} - comment-parser@1.4.6: - resolution: {integrity: sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==} - engines: {node: '>= 12.0.0'} - comment-parser@1.4.7: resolution: {integrity: sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==} engines: {node: '>= 12.0.0'} @@ -3391,8 +3389,8 @@ packages: crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - crossws@0.4.5: - resolution: {integrity: sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==} + crossws@0.4.6: + resolution: {integrity: sha512-/Wxe9Z007EbJ496j88nToZEvyPZ8PY/wjZJ18Agh/GCA9cYHyLbxtrpdFlFzAw3TV20F0SUYGl0g6PzChbwUrg==} peerDependencies: srvx: '>=0.11.5' peerDependenciesMeta: @@ -3537,6 +3535,10 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} @@ -3548,6 +3550,14 @@ packages: devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + devframe@0.5.4: + resolution: {integrity: sha512-dbHU/LuptR1aMXcizjHUeY3gu7qVaRQoFYqbbyyGuO6Y+avFA4uQtwinHtG1qa7lRel/7b8JrBDm0nbnxU3vqg==} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -3688,8 +3698,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.364: - resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==} + electron-to-chromium@1.5.371: + resolution: {integrity: sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -3708,8 +3718,8 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - enhanced-resolve@5.22.1: - resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} + enhanced-resolve@5.23.0: + resolution: {integrity: sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -3768,10 +3778,6 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -3813,11 +3819,11 @@ packages: peerDependencies: eslint: '*' - eslint-plugin-import-lite@0.5.2: - resolution: {integrity: sha512-XvfdWOC5dSLEI9krIPRlNmKSI2ViIE9pVylzfV9fCq0ZpDaNeUk6o0wZv0OzN83QdadgXp1NsY0qjLINxwYCsw==} + eslint-plugin-import-lite@0.6.0: + resolution: {integrity: sha512-80vevx2A7i3H7n1/6pqDO8cc5wRz6OwLDvIyVl9UflBV1N1f46e9Ihzi65IOLYoSxM6YykK2fTw1xm0Ixx6aTQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: '>=9.0.0' + eslint: ^9.0.0 || ^10.0.0 eslint-plugin-import-x@4.16.2: resolution: {integrity: sha512-rM9K8UBHcWKpzQzStn1YRN2T5NvdeIfSVoKu/lKF41znQXHAUcBbYXe5wd6GNjZjTrP7viQ49n1D83x/2gYgIw==} @@ -3832,9 +3838,9 @@ packages: eslint-import-resolver-node: optional: true - eslint-plugin-jsdoc@62.9.0: - resolution: {integrity: sha512-PY7/X4jrVgoIDncUmITlUqK546Ltmx/Pd4Hdsu4CvSjryQZJI2mEV4vrdMufyTetMiZ5taNSqvK//BTgVUlNkA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + eslint-plugin-jsdoc@63.0.2: + resolution: {integrity: sha512-0TchoK1uS4VxHSo3P4CyWQ31Lm+6zsT+xkHMC5KbFKwgOf8YrXPf1Bl8EP7kpgw1wfe/Ui5jz5mSX7ou8WAVuw==} + engines: {node: ^22.13.0 || >=24} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 @@ -3844,14 +3850,14 @@ packages: peerDependencies: eslint: '>=9.38.0' - eslint-plugin-unicorn@63.0.0: - resolution: {integrity: sha512-Iqecl9118uQEXYh7adylgEmGfkn5es3/mlQTLLkd4pXkIk9CTGrAbeUux+YljSa2ohXCBmQQ0+Ej1kZaFgcfkA==} + eslint-plugin-unicorn@65.0.1: + resolution: {integrity: sha512-daCrQrgxOoOz2uMPWB3Y3vvv/5q+ncwICI8IjoebiwtW87CaY4tAN5EEiRXTYVnf7qi1v1BGBdHOSnZLV0rx6A==} engines: {node: ^20.10.0 || >=21.0.0} peerDependencies: eslint: '>=9.38.0' - eslint-plugin-vue@10.9.1: - resolution: {integrity: sha512-cHB0Tf4Duvzwecwd/AqWzZvF/QszE13BhjVUpVXWCy9AeMR5GjkAjP3i85vqgLgOuTmkHR1OJ5oMeqLHtuw8zg==} + eslint-plugin-vue@10.9.2: + resolution: {integrity: sha512-4g7ZP3pYcuqd7Zp0pzUKcos0W+RkjBz4EGdhJ92FcYk6v03Ti/GK5NwjgsjxHK+98eXDbHeK7VtX1az7/8doZA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 @@ -4094,8 +4100,8 @@ packages: resolution: {integrity: sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==} engines: {node: '>=14.16'} - fuse.js@7.4.0: - resolution: {integrity: sha512-3UqmoSFwzX1sNB1YSk+Co0EdH29XCW2p9g48OAiy93cjKqzuABsqw2VIgSN3CmsT/wo6pIJ3F0Jxeiiby8rhIQ==} + fuse.js@7.4.2: + resolution: {integrity: sha512-LVbzjD4WA6UP5B1UnP8wuaXJiLnqMdM/E4fiJXTJ5haJ5b/MBNsK29h2fm6swEoQaVQjvYFWKLE2RanyZIoRVQ==} engines: {node: '>=10'} fzf@0.5.2: @@ -4135,8 +4141,8 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} - giget@3.2.0: - resolution: {integrity: sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==} + giget@3.3.0: + resolution: {integrity: sha512-gzi2D96p+AMfDcmJHGDj3KJ9NRiwvlFAU5yfa3ROwWZmFUjX4P43x3BcyRaOMMLto1vUo7C+86+MFhYTl6Ryiw==} hasBin: true glob-parent@5.1.2: @@ -4168,10 +4174,6 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@16.5.0: - resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} - engines: {node: '>=18'} - globals@17.6.0: resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} engines: {node: '>=18'} @@ -4204,6 +4206,16 @@ packages: crossws: optional: true + h3@2.0.1-rc.22: + resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} + engines: {node: '>=20.11.1'} + hasBin: true + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -4306,12 +4318,12 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ioredis@5.11.0: - resolution: {integrity: sha512-EZBErytyVovD8f6pDfG3Kb37N6Y3lmDA9NNj+4+IP13CzzHGeX+OyeRM2Um13khRzoBSzzL+5lVnCX8V2RLeMg==} + ioredis@5.11.1: + resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==} engines: {node: '>=12.22.0'} - ip-bigint@9.0.5: - resolution: {integrity: sha512-C+wkW87nNsb6lmOG6mIuZFwosx+vRN7AMypCG3q0zDoqwQqQkhOff5/CWzwaV4o+4VsFae8S2GEf021cNIbYpQ==} + ip-bigint@9.0.6: + resolution: {integrity: sha512-dpEy7cSzYM9JsL6Ai9KGO0eCKALRtbYCb57Nfc8/kflSyBakf1Orb6/8u+NDlhS+7THbjrOfY52z9PnJXh/mWA==} engines: {node: '>=22'} ip-regex@5.0.0: @@ -4473,8 +4485,8 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true jsdoc-type-pratt-parser@7.2.0: @@ -4547,8 +4559,8 @@ packages: resolution: {integrity: sha512-3An0GCLDSR34tsCO4H8Tef8Pp2ngtaZDAZnsWJYelqXUK5wyiHvGItgK/xcSkmHLSTn1Jcho1mRQs2ehRzvKKw==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} - launch-editor@2.14.0: - resolution: {integrity: sha512-Pj3ZOx9dD1BClS7YcSQx0An1PCF9wz4JpvbEmKvDxQtm0jxlkk5NhW8x0SBAKA/acHBKZaqdd5FFOWlXo500JA==} + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} lazystream@1.0.1: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} @@ -4574,10 +4586,6 @@ packages: resolution: {integrity: sha512-kfz4C0OrC6IpaVMtYDJtf6PFjurxe9NBBoDAh/o2p587INryFOO4DQ9OetbCdDrWFt1m1CJKvYrzkGsuPHw8nQ==} hasBin: true - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - local-pkg@1.2.1: resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} engines: {node: '>=14'} @@ -4800,8 +4808,8 @@ packages: node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} - node-releases@2.0.46: - resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + node-releases@2.0.47: + resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} nopt@8.1.0: @@ -4813,6 +4821,9 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + nostics@0.2.0: + resolution: {integrity: sha512-/WQpI46UMbqvy1okYb+V+9wW3J8/m6GJ33wm691n/tyi6YtJiZ6ssJjENAU7y4evfYrrgYN9HllKDzPvffil1w==} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4827,8 +4838,8 @@ packages: nuxt-define@1.0.0: resolution: {integrity: sha512-CYZ2WjU+KCyCDVzjYUM4eEpMF0rkPmkpiFrybTqqQCRpUbPt2h3snswWIpFPXTi+osRCY6Og0W/XLAQgDL4FfQ==} - nuxt@3.21.6: - resolution: {integrity: sha512-jIs488icdWIzzwTQYa4J2WmbhDlBcVDPGc7LBTxezaHwf8C5LKnWZvBkFqREQ8UjMQe5KBnA98pFRUqT6ZDPYA==} + nuxt@3.21.8: + resolution: {integrity: sha512-RRB/MpZhdEhb/A21qaUaSI1UYDOy9bgK0vZvRRjDsA8HGY+eFBr2EvUkdeYQHOT8WKuByxWlg5ckz3H4A+QQ1w==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -4840,8 +4851,8 @@ packages: '@types/node': optional: true - nypm@0.6.6: - resolution: {integrity: sha512-vRyr0r4cbBapw07Xw8xrj9Teq3o7MUD35rSaTcanDbW+aK2XHDgJFiU6ZTj2GBw7Q12ysdsyFss+Vdz4hQ0Y6Q==} + nypm@0.6.7: + resolution: {integrity: sha512-s3ds97SD5pd1dULE+tHUk1DrV0cSHOnsfpcdGATJ8JpBo21DoKqN9exTH4/2nhPQNOLomBdTFMicN94S4DrZrQ==} engines: {node: '>=18'} hasBin: true @@ -4859,8 +4870,9 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.2: + resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==} + engines: {node: '>=12.20.0'} ofetch@1.5.1: resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} @@ -4907,24 +4919,24 @@ packages: otpauth@9.5.1: resolution: {integrity: sha512-fJmDAHc8wImfqqqOXIlBvT1dEKrZK0Cmb2VEgScpNTolCz0PHh6ExUZGv4sLtOsWNaHCQlD+rRqaPgnoxFoZjQ==} - oxc-minify@0.131.0: - resolution: {integrity: sha512-Ch0sBbrqZpeNZUMhVDbU2yrTWTVrUT/MkXb9E2DAc+hbhxbbO8D/XklUtfPP86/iqrkvl178+YQvh5u8Of1mUg==} + oxc-minify@0.132.0: + resolution: {integrity: sha512-7h3fOlgDwkIYxxKfGwCNejaLhH90Pvx+fttdPN7nRbWHxm6QSYcxW3IKjfxQVUeg+z1X2HZdOSY3rHkVqgxH1g==} engines: {node: ^20.19.0 || >=22.12.0} oxc-parser@0.128.0: resolution: {integrity: sha512-XkOw3eiIxAgQ19WRew/Bq9wc5Ga/guaWIzDBzq80z1PyuDNGvWBpPby9k6YGwV8A8uMw+Nlq3xqlzuDYmUFYUw==} engines: {node: ^20.19.0 || >=22.12.0} - oxc-parser@0.131.0: - resolution: {integrity: sha512-SJ3/7ZPbgie8dr5Z9BI/M51zZbpXba+hRSG0MDzVwMW5CRQg2fjYE0jHGlLX4eeiibGgC/mzoDFKSDHwVZEHRQ==} + oxc-parser@0.132.0: + resolution: {integrity: sha512-+0LAPHaqtfQlvWdpaAa09SmOaZZgP8C552xosEkGJ4+ruEwP1Vgx+sqBgcBCNfR6KDCmagGOZTde8wmAvcI/Hg==} engines: {node: ^20.19.0 || >=22.12.0} oxc-transform@0.128.0: resolution: {integrity: sha512-8DfEHlmUiLOHlCK9DGX+d5tORc1xwPPvoRSHSJCYgLHyGjKp4PvfBrvgi59DkEW0SMOWfO8GL9t+R7vdKtupbg==} engines: {node: ^20.19.0 || >=22.12.0} - oxc-transform@0.131.0: - resolution: {integrity: sha512-ml0/elXPNnDnuHo3VHmEMN2fnybmKx7YL+0E+gMQ0fuHRZHXYJzF6YJ01KsCWg6FXY6pbZcjm7DC3xwGHnB/BA==} + oxc-transform@0.132.0: + resolution: {integrity: sha512-DmP0+4kzpXoMvv08qPCD4aI6mAIzrEq15Yt9e6wXCNtOz6jEDHPpueusDa2/pvjRAqtNV37YxUUeX7cfCI4dpA==} engines: {node: ^20.19.0 || >=22.12.0} oxc-walker@0.7.0: @@ -5258,12 +5270,12 @@ packages: peerDependencies: postcss: ^8.5.13 - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + postcss-selector-parser@6.1.4: + resolution: {integrity: sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==} engines: {node: '>=4'} - postcss-selector-parser@7.1.1: - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + postcss-selector-parser@7.1.4: + resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} engines: {node: '>=4'} postcss-svgo@7.1.3: @@ -5348,8 +5360,8 @@ packages: prettier-plugin-svelte: optional: true - prettier@3.8.3: - resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} + prettier@3.8.4: + resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==} engines: {node: '>=14'} hasBin: true @@ -5505,8 +5517,8 @@ packages: rollup: optional: true - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} + rollup@4.61.1: + resolution: {integrity: sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -5545,8 +5557,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true @@ -5669,8 +5681,8 @@ packages: std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - streamx@2.26.0: - resolution: {integrity: sha512-VvNG1K72Po/xwJzxZFnZ++Tbrv4lwSptsbkFuzXCJAYZvCK5nnxsvXU6ajqkv7chyiI1Y0YXq2Jh8Iy8Y7NF/A==} + streamx@2.27.0: + resolution: {integrity: sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -5775,8 +5787,8 @@ packages: tar-stream@3.2.0: resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} - tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} + tar@7.5.16: + resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} teex@1.0.1: @@ -5810,12 +5822,12 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyclip@0.1.13: - resolution: {integrity: sha512-8OqlXQ35euK9+e7L68u8UwcODxkHoIkjbGsgXuARKNyQ5G6xt8nw1YPeMbxMLgCPFkToU+UEK5j05t2t8edKpQ==} + tinyclip@0.1.14: + resolution: {integrity: sha512-F1oWdz8tjT17qe1d5JgDK6z03WGOhYYAN0lK3/D/fzNiy93xswLLEw7pk+3g05onhAy6Bsc6PLNUGhdgVjemMQ==} engines: {node: ^16.14.0 || >= 17.3.0} - tinyexec@1.2.3: - resolution: {integrity: sha512-g62dB+w1/OEFnPvmX0yd/HnetYITOL+1nJW7kitOycOeAvmbWC/nu0fwmmQ/kupNojqExzyC/T++pST/jRJ2mQ==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} tinyglobby@0.2.17: @@ -5865,8 +5877,8 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - tsx@4.22.3: - resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} + tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} engines: {node: '>=18.0.0'} hasBin: true @@ -5874,8 +5886,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@5.6.0: - resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} + type-fest@5.7.0: + resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} engines: {node: '>=20'} type-is@1.6.18: @@ -5919,10 +5931,6 @@ packages: resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} engines: {node: '>=20'} - unimport@5.7.0: - resolution: {integrity: sha512-njnL6sp8lEA8QQbZrt+52p/g4X0rw3bnGGmUcJnt1jeG8+iiqO779aGz0PirCtydAIVcuTBRlJ52F0u46z309Q==} - engines: {node: '>=18.12.0'} - unimport@6.3.0: resolution: {integrity: sha512-M+Dxk5W9WRd+8j56W9tp8lGW/dmMc7g5zj7BWQnEjKQhryBstqsi1V0izb0zHwSkEN8cSYV7K75/bykairV2tA==} engines: {node: '>=18.12.0'} @@ -6055,6 +6063,14 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + valibot@1.4.1: + resolution: {integrity: sha512-klCmFTz2jeDluy9RwX+F884TCiogtdBJ/YaxSx1EOBYXa3NXNWj8kR1jjN8rzluwojJVWWaHJ4r1U5LfICnM3g==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -6127,8 +6143,8 @@ packages: vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 vue: ^3.5.0 - vite@7.3.3: - resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==} + vite@7.3.5: + resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -6170,20 +6186,20 @@ packages: vitest-environment-nuxt@2.0.0: resolution: {integrity: sha512-zEGFRiCAaRR3fHnqISHKMNTRvCzkQEI1XyFeqNgR2IBD0oYkfZ1rUHwi7C+h3Cns3KPykfB0av1B3MtLEbChDw==} - vitest@4.1.7: - resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} + vitest@4.1.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.7 - '@vitest/browser-preview': 4.1.7 - '@vitest/browser-webdriverio': 4.1.7 - '@vitest/coverage-istanbul': 4.1.7 - '@vitest/coverage-v8': 4.1.7 - '@vitest/ui': 4.1.7 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -6231,14 +6247,14 @@ packages: vue-devtools-stub@0.1.0: resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} - vue-eslint-parser@10.4.0: - resolution: {integrity: sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==} + vue-eslint-parser@10.4.1: + resolution: {integrity: sha512-Gk6gRDj0n/fkRa3C3l0bBheoBckUq/Rs0F/TvMWIS6nzzx67amAViMe9CkNgsP2tXyQONvGiHQESHwFtZ3aYDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - vue-i18n@11.4.4: - resolution: {integrity: sha512-gIbXVSFQV4jcSJxfwdZ5zSZmZ+12CnX0K3vBkRSd6Zn+HSzCp+QwUgPwpD/uN0oKNKI9RzlUXPKVedEuMgNG0A==} + vue-i18n@11.4.5: + resolution: {integrity: sha512-rm8YJ6RpjOrkcgS2GLrZwLvs/VbhxbTSuEspbyXDo233+fPK0OMFNLOj3fdQYVKdOgcpSfLW91JhbqgpkkcBWA==} engines: {node: '>= 22'} peerDependencies: vue: ^3.0.0 @@ -6266,8 +6282,8 @@ packages: vite: optional: true - vue-tsc@3.3.3: - resolution: {integrity: sha512-SWUEG7YRUeDJHT7Xsuhf02elYX2gxPzzAII7OxDAh4KNOr4QHQ0Lls0YfnaO5GNd560CwVa2HTfdqmA5MqvRqQ==} + vue-tsc@3.3.4: + resolution: {integrity: sha512-XA/JqmQwS2GZmfgpjOEGdrKwaTSEuPwxpHa7/t6f4yiGrJb3gVHTPb9wBfByMNZwQ+xDXs41b8gaS2DKsOozUw==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -6278,8 +6294,8 @@ packages: apexcharts: '>=5.10.0' vue: '>=3.0.0' - vue@3.5.35: - resolution: {integrity: sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==} + vue@3.5.38: + resolution: {integrity: sha512-vAMKHfImQlYSy0C+PBue4s3ERZ2xGKfgZg5GXAsLInq1dyh2H78ILVP5sK0KPFPVW4kv+OGCIvBEondcjpZp7A==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -6417,12 +6433,12 @@ snapshots: '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.6.0 - tinyexec: 1.2.3 + tinyexec: 1.2.4 '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': dependencies: '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 + js-yaml: 4.2.0 '@babel/code-frame@7.29.7': dependencies: @@ -6625,7 +6641,7 @@ snapshots: fast-wrap-ansi: 0.1.6 sisteransi: 1.0.5 - '@clack/core@1.4.0': + '@clack/core@1.4.1': dependencies: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 @@ -6637,9 +6653,9 @@ snapshots: fast-wrap-ansi: 0.1.6 sisteransi: 1.0.5 - '@clack/prompts@1.5.0': + '@clack/prompts@1.5.1': dependencies: - '@clack/core': 1.4.0 + '@clack/core': 1.4.1 fast-string-width: 3.0.2 fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 @@ -6648,20 +6664,20 @@ snapshots: '@colordx/core@5.4.3': {} - '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.1)': + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.4)': dependencies: - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 - '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)': + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.4)': dependencies: - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 '@drizzle-team/brocli@0.10.2': {} '@dxup/nuxt@0.4.1(magicast@0.5.3)(typescript@6.0.3)': dependencies: '@dxup/unimport': 0.1.2 - '@nuxt/kit': 4.4.6(magicast@0.5.3) + '@nuxt/kit': 4.4.8(magicast@0.5.3) chokidar: 5.0.0 pathe: 2.0.3 tinyglobby: 0.2.17 @@ -6690,11 +6706,11 @@ snapshots: '@epic-web/invariant@1.0.0': {} - '@es-joy/jsdoccomment@0.86.0': + '@es-joy/jsdoccomment@0.87.0': dependencies: '@types/estree': 1.0.9 - '@typescript-eslint/types': 8.60.0 - comment-parser: 1.4.6 + '@typescript-eslint/types': 8.61.0 + comment-parser: 1.4.7 esquery: 1.7.0 jsdoc-type-pratt-parser: 7.2.0 @@ -7012,7 +7028,7 @@ snapshots: '@eschricht/nuxt-color-mode@1.2.0(magicast@0.5.3)': dependencies: - '@nuxt/kit': 4.4.6(magicast@0.5.3) + '@nuxt/kit': 4.4.8(magicast@0.5.3) transitivePeerDependencies: - magicast @@ -7045,19 +7061,20 @@ snapshots: dependencies: '@eslint/core': 1.2.1 - '@eslint/config-inspector@1.5.0(eslint@9.39.4(jiti@1.21.7))': + '@eslint/config-inspector@3.0.4(crossws@0.4.6(srvx@0.11.16))(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: - ansis: 4.3.0 - bundle-require: 5.1.0(esbuild@0.27.7) + ansis: 4.3.1 cac: 7.0.0 chokidar: 5.0.0 - esbuild: 0.27.7 + devframe: 0.5.4(crossws@0.4.6(srvx@0.11.16))(typescript@6.0.3) eslint: 9.39.4(jiti@1.21.7) - h3: 1.15.11 + jiti: 2.7.0 tinyglobby: 0.2.17 - ws: 8.21.0 transitivePeerDependencies: + - '@modelcontextprotocol/sdk' - bufferutil + - crossws + - typescript - utf-8-validate '@eslint/core@0.17.0': @@ -7076,12 +7093,16 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color + '@eslint/js@10.0.1(eslint@9.39.4(jiti@1.21.7))': + optionalDependencies: + eslint: 9.39.4(jiti@1.21.7) + '@eslint/js@9.39.4': {} '@eslint/object-schema@2.1.7': {} @@ -7102,18 +7123,18 @@ snapshots: '@floating-ui/utils@0.2.11': {} - '@floating-ui/vue@1.1.11(vue@3.5.35(typescript@6.0.3))': + '@floating-ui/vue@1.1.11(vue@3.5.38(typescript@6.0.3))': dependencies: '@floating-ui/dom': 1.7.6 '@floating-ui/utils': 0.2.11 - vue-demi: 0.14.10(vue@3.5.35(typescript@6.0.3)) + vue-demi: 0.14.10(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@heroicons/vue@2.2.0(vue@3.5.35(typescript@6.0.3))': + '@heroicons/vue@2.2.0(vue@3.5.38(typescript@6.0.3))': dependencies: - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) '@humanfs/core@0.19.2': dependencies: @@ -7139,10 +7160,10 @@ snapshots: dependencies: '@swc/helpers': 0.5.23 - '@intlify/bundle-utils@11.2.3(vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3)))': + '@intlify/bundle-utils@11.2.3(vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3)))': dependencies: - '@intlify/message-compiler': 11.4.4 - '@intlify/shared': 11.4.4 + '@intlify/message-compiler': 11.4.5 + '@intlify/shared': 11.4.5 acorn: 8.16.0 esbuild: 0.25.12 escodegen: 2.1.0 @@ -7151,54 +7172,54 @@ snapshots: source-map-js: 1.2.1 yaml-eslint-parser: 1.3.2 optionalDependencies: - vue-i18n: 11.4.4(vue@3.5.35(typescript@6.0.3)) + vue-i18n: 11.4.5(vue@3.5.38(typescript@6.0.3)) - '@intlify/core-base@11.4.4': + '@intlify/core-base@11.4.5': dependencies: - '@intlify/devtools-types': 11.4.4 - '@intlify/message-compiler': 11.4.4 - '@intlify/shared': 11.4.4 + '@intlify/devtools-types': 11.4.5 + '@intlify/message-compiler': 11.4.5 + '@intlify/shared': 11.4.5 - '@intlify/core@11.4.4': + '@intlify/core@11.4.5': dependencies: - '@intlify/core-base': 11.4.4 - '@intlify/shared': 11.4.4 + '@intlify/core-base': 11.4.5 + '@intlify/shared': 11.4.5 - '@intlify/devtools-types@11.4.4': + '@intlify/devtools-types@11.4.5': dependencies: - '@intlify/core-base': 11.4.4 - '@intlify/shared': 11.4.4 + '@intlify/core-base': 11.4.5 + '@intlify/shared': 11.4.5 '@intlify/h3@0.7.4': dependencies: - '@intlify/core': 11.4.4 + '@intlify/core': 11.4.5 '@intlify/utils': 0.13.0 - '@intlify/message-compiler@11.4.4': + '@intlify/message-compiler@11.4.5': dependencies: - '@intlify/shared': 11.4.4 + '@intlify/shared': 11.4.5 source-map-js: 1.2.1 - '@intlify/shared@11.4.4': {} + '@intlify/shared@11.4.5': {} - '@intlify/unplugin-vue-i18n@11.2.3(@vue/compiler-dom@3.5.35)(eslint@9.39.4(jiti@1.21.7))(rollup@4.60.4)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3)))(vue@3.5.35(typescript@6.0.3))': + '@intlify/unplugin-vue-i18n@11.2.3(@vue/compiler-dom@3.5.38)(eslint@9.39.4(jiti@1.21.7))(rollup@4.61.1)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3)))(vue@3.5.38(typescript@6.0.3))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) - '@intlify/bundle-utils': 11.2.3(vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3))) - '@intlify/shared': 11.4.4 - '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.4.4)(@vue/compiler-dom@3.5.35)(vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3)))(vue@3.5.35(typescript@6.0.3)) - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) + '@intlify/bundle-utils': 11.2.3(vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3))) + '@intlify/shared': 11.4.5 + '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.4.5)(@vue/compiler-dom@3.5.38)(vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3)))(vue@3.5.38(typescript@6.0.3)) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) debug: 4.4.3 fast-glob: 3.3.3 pathe: 2.0.3 picocolors: 1.1.1 unplugin: 2.3.11 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) optionalDependencies: - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vue-i18n: 11.4.4(vue@3.5.35(typescript@6.0.3)) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vue-i18n: 11.4.5(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - '@vue/compiler-dom' - eslint @@ -7210,14 +7231,14 @@ snapshots: '@intlify/utils@0.14.1': {} - '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.4.4)(@vue/compiler-dom@3.5.35)(vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3)))(vue@3.5.35(typescript@6.0.3))': + '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.4.5)(@vue/compiler-dom@3.5.38)(vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3)))(vue@3.5.38(typescript@6.0.3))': dependencies: '@babel/parser': 7.29.7 optionalDependencies: - '@intlify/shared': 11.4.4 - '@vue/compiler-dom': 3.5.35 - vue: 3.5.35(typescript@6.0.3) - vue-i18n: 11.4.4(vue@3.5.35(typescript@6.0.3)) + '@intlify/shared': 11.4.5 + '@vue/compiler-dom': 3.5.38 + vue: 3.5.38(typescript@6.0.3) + vue-i18n: 11.4.5(vue@3.5.38(typescript@6.0.3)) '@ioredis/commands@1.10.0': {} @@ -7341,19 +7362,19 @@ snapshots: https-proxy-agent: 7.0.6 node-fetch: 2.7.0 nopt: 8.1.0 - semver: 7.8.1 - tar: 7.5.15 + semver: 7.8.4 + tar: 7.5.16 transitivePeerDependencies: - encoding - supports-color - '@miyaneee/rollup-plugin-json5@1.2.0(rollup@4.60.4)': + '@miyaneee/rollup-plugin-json5@1.2.0(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) json5: 2.2.3 - rollup: 4.60.4 + rollup: 4.61.1 - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 @@ -7376,10 +7397,10 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@nuxt/cli@3.35.2(@nuxt/schema@3.21.6)(cac@6.7.14)(magicast@0.5.3)': + '@nuxt/cli@3.35.2(@nuxt/schema@3.21.8)(cac@6.7.14)(magicast@0.5.3)': dependencies: '@bomb.sh/tab': 0.0.15(cac@6.7.14)(citty@0.2.2) - '@clack/prompts': 1.5.0 + '@clack/prompts': 1.5.1 c12: 3.3.4(magicast@0.5.3) citty: 0.2.2 confbox: 0.2.4 @@ -7387,27 +7408,27 @@ snapshots: debug: 4.4.3 defu: 6.1.7 exsolve: 1.0.8 - fuse.js: 7.4.0 + fuse.js: 7.4.2 fzf: 0.5.2 - giget: 3.2.0 + giget: 3.3.0 jiti: 2.7.0 listhen: 1.10.0(srvx@0.11.16) - nypm: 0.6.6 + nypm: 0.6.7 ofetch: 1.5.1 ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 2.1.0 pkg-types: 2.3.1 scule: 1.3.0 - semver: 7.8.1 + semver: 7.8.4 srvx: 0.11.16 std-env: 4.1.0 - tinyclip: 0.1.13 - tinyexec: 1.2.3 + tinyclip: 0.1.14 + tinyexec: 1.2.4 ufo: 1.6.4 youch: 4.1.1 optionalDependencies: - '@nuxt/schema': 3.21.6 + '@nuxt/schema': 3.21.8 transitivePeerDependencies: - cac - commander @@ -7416,39 +7437,39 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@2.7.0(magicast@0.5.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@nuxt/devtools-kit@2.7.0(magicast@0.5.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - '@nuxt/kit': 3.21.6(magicast@0.5.3) + '@nuxt/kit': 3.21.8(magicast@0.5.3) execa: 8.0.1 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) transitivePeerDependencies: - magicast - '@nuxt/devtools-kit@3.2.4(magicast@0.5.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@nuxt/devtools-kit@3.2.4(magicast@0.5.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - '@nuxt/kit': 4.4.6(magicast@0.5.3) + '@nuxt/kit': 4.4.8(magicast@0.5.3) execa: 8.0.1 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) transitivePeerDependencies: - magicast '@nuxt/devtools-wizard@3.2.4': dependencies: - '@clack/prompts': 1.5.0 + '@clack/prompts': 1.5.1 consola: 3.4.2 diff: 8.0.4 execa: 8.0.1 magicast: 0.5.3 pathe: 2.0.3 pkg-types: 2.3.1 - semver: 7.8.1 + semver: 7.8.4 - '@nuxt/devtools@3.2.4(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))': + '@nuxt/devtools@3.2.4(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3))': dependencies: - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) '@nuxt/devtools-wizard': 3.2.4 - '@nuxt/kit': 4.4.6(magicast@0.5.3) - '@vue/devtools-core': 8.1.2(vue@3.5.35(typescript@6.0.3)) + '@nuxt/kit': 4.4.8(magicast@0.5.3) + '@vue/devtools-core': 8.1.2(vue@3.5.38(typescript@6.0.3)) '@vue/devtools-kit': 8.1.2 birpc: 4.0.0 consola: 3.4.2 @@ -7460,22 +7481,22 @@ snapshots: hookable: 6.1.1 image-meta: 0.2.2 is-installed-globally: 1.0.0 - launch-editor: 2.14.0 + launch-editor: 2.14.1 local-pkg: 1.2.1 magicast: 0.5.3 - nypm: 0.6.6 + nypm: 0.6.7 ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 2.1.0 pkg-types: 2.3.1 - semver: 7.8.1 + semver: 7.8.4 simple-git: 3.36.0 sirv: 3.0.2 structured-clone-es: 2.0.0 tinyglobby: 0.2.17 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vite-plugin-inspect: 11.4.1(@nuxt/kit@4.4.6(magicast@0.5.3))(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) - vite-plugin-vue-tracer: 1.4.0(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite-plugin-inspect: 11.4.1(@nuxt/kit@4.4.8(magicast@0.5.3))(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + vite-plugin-vue-tracer: 1.4.0(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) which: 6.0.1 ws: 8.21.0 transitivePeerDependencies: @@ -7484,30 +7505,30 @@ snapshots: - utf-8-validate - vue - '@nuxt/eslint-config@1.15.2(@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.35)(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': + '@nuxt/eslint-config@1.16.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.38)(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: '@antfu/install-pkg': 1.1.0 - '@clack/prompts': 1.5.0 - '@eslint/js': 9.39.4 - '@nuxt/eslint-plugin': 1.15.2(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@clack/prompts': 1.5.1 + '@eslint/js': 10.0.1(eslint@9.39.4(jiti@1.21.7)) + '@nuxt/eslint-plugin': 1.16.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) '@stylistic/eslint-plugin': 5.10.0(eslint@9.39.4(jiti@1.21.7)) - '@typescript-eslint/eslint-plugin': 8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/parser': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) eslint: 9.39.4(jiti@1.21.7) eslint-config-flat-gitignore: 2.3.0(eslint@9.39.4(jiti@1.21.7)) eslint-flat-config-utils: 3.2.0 eslint-merge-processors: 2.0.0(eslint@9.39.4(jiti@1.21.7)) - eslint-plugin-import-lite: 0.5.2(eslint@9.39.4(jiti@1.21.7)) - eslint-plugin-import-x: 4.16.2(@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7)) - eslint-plugin-jsdoc: 62.9.0(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-import-lite: 0.6.0(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-import-x: 4.16.2(@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-jsdoc: 63.0.2(eslint@9.39.4(jiti@1.21.7)) eslint-plugin-regexp: 3.1.0(eslint@9.39.4(jiti@1.21.7)) - eslint-plugin-unicorn: 63.0.0(eslint@9.39.4(jiti@1.21.7)) - eslint-plugin-vue: 10.9.1(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@1.21.7)))(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@1.21.7))) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.35)(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-unicorn: 65.0.1(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-vue: 10.9.2(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@1.21.7)))(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(vue-eslint-parser@10.4.1(eslint@9.39.4(jiti@1.21.7))) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.38)(eslint@9.39.4(jiti@1.21.7)) globals: 17.6.0 local-pkg: 1.2.1 pathe: 2.0.3 - vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@1.21.7)) + vue-eslint-parser: 10.4.1(eslint@9.39.4(jiti@1.21.7)) transitivePeerDependencies: - '@typescript-eslint/utils' - '@vue/compiler-sfc' @@ -7515,22 +7536,22 @@ snapshots: - supports-color - typescript - '@nuxt/eslint-plugin@1.15.2(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': + '@nuxt/eslint-plugin@1.16.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) eslint: 9.39.4(jiti@1.21.7) transitivePeerDependencies: - supports-color - typescript - '@nuxt/eslint@1.15.2(@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.35)(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@nuxt/eslint@1.16.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.38)(crossws@0.4.6(srvx@0.11.16))(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(oxc-parser@0.132.0)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - '@eslint/config-inspector': 1.5.0(eslint@9.39.4(jiti@1.21.7)) - '@nuxt/devtools-kit': 3.2.4(magicast@0.5.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) - '@nuxt/eslint-config': 1.15.2(@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.35)(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - '@nuxt/eslint-plugin': 1.15.2(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - '@nuxt/kit': 4.4.6(magicast@0.5.3) + '@eslint/config-inspector': 3.0.4(crossws@0.4.6(srvx@0.11.16))(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@nuxt/devtools-kit': 3.2.4(magicast@0.5.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + '@nuxt/eslint-config': 1.16.0(@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(@vue/compiler-sfc@3.5.38)(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@nuxt/eslint-plugin': 1.16.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@nuxt/kit': 4.4.8(magicast@0.5.3) chokidar: 5.0.0 eslint: 9.39.4(jiti@1.21.7) eslint-flat-config-utils: 3.2.0 @@ -7539,20 +7560,24 @@ snapshots: get-port-please: 3.2.0 mlly: 1.8.2 pathe: 2.0.3 - unimport: 5.7.0 + unimport: 6.3.0(oxc-parser@0.132.0) transitivePeerDependencies: + - '@modelcontextprotocol/sdk' - '@typescript-eslint/utils' - '@vue/compiler-sfc' - bufferutil + - crossws - eslint-import-resolver-node - eslint-plugin-format - magicast + - oxc-parser + - rolldown - supports-color - typescript - utf-8-validate - vite - '@nuxt/kit@3.21.6(magicast@0.5.3)': + '@nuxt/kit@3.21.8(magicast@0.5.3)': dependencies: c12: 3.3.4(magicast@0.5.3) consola: 3.4.2 @@ -7570,7 +7595,7 @@ snapshots: pkg-types: 2.3.1 rc9: 3.0.1 scule: 1.3.0 - semver: 7.8.1 + semver: 7.8.4 tinyglobby: 0.2.17 ufo: 1.6.4 unctx: 2.5.0 @@ -7578,7 +7603,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/kit@4.4.6(magicast@0.5.3)': + '@nuxt/kit@4.4.8(magicast@0.5.3)': dependencies: c12: 3.3.4(magicast@0.5.3) consola: 3.4.2 @@ -7595,7 +7620,7 @@ snapshots: pkg-types: 2.3.1 rc9: 3.0.1 scule: 1.3.0 - semver: 7.8.1 + semver: 7.8.4 tinyglobby: 0.2.17 ufo: 1.6.4 unctx: 2.5.0 @@ -7603,12 +7628,12 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/nitro-server@3.21.6(@libsql/client@0.17.3)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(ioredis@5.11.0)(magicast@0.5.3)(nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0))(oxc-parser@0.131.0)(srvx@0.11.16)(typescript@6.0.3)': + '@nuxt/nitro-server@3.21.8(@libsql/client@0.17.3)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(ioredis@5.11.1)(magicast@0.5.3)(nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0))(oxc-parser@0.132.0)(srvx@0.11.16)(typescript@6.0.3)': dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/kit': 3.21.6(magicast@0.5.3) - '@unhead/vue': 2.1.15(vue@3.5.35(typescript@6.0.3)) - '@vue/shared': 3.5.35 + '@nuxt/kit': 3.21.8(magicast@0.5.3) + '@unhead/vue': 2.1.15(vue@3.5.38(typescript@6.0.3)) + '@vue/shared': 3.5.38 consola: 3.4.2 defu: 6.1.7 destr: 2.0.5 @@ -7620,8 +7645,8 @@ snapshots: impound: 1.1.5 klona: 2.0.6 mocked-exports: 0.1.1 - nitropack: 2.13.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3))(oxc-parser@0.131.0)(srvx@0.11.16) - nuxt: 3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0) + nitropack: 2.13.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3))(oxc-parser@0.132.0)(srvx@0.11.16) + nuxt: 3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0) ohash: 2.0.11 pathe: 2.0.3 pkg-types: 2.3.1 @@ -7629,8 +7654,8 @@ snapshots: std-env: 4.1.0 ufo: 1.6.4 unctx: 2.5.0 - unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.0) - vue: 3.5.35(typescript@6.0.3) + unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.1) + vue: 3.5.38(typescript@6.0.3) vue-bundle-renderer: 2.2.0 vue-devtools-stub: 0.1.0 transitivePeerDependencies: @@ -7671,28 +7696,28 @@ snapshots: - uploadthing - xml2js - '@nuxt/schema@3.21.6': + '@nuxt/schema@3.21.8': dependencies: - '@vue/shared': 3.5.35 + '@vue/shared': 3.5.38 defu: 6.1.7 pathe: 2.0.3 pkg-types: 2.3.1 std-env: 4.1.0 - '@nuxt/telemetry@2.8.0(@nuxt/kit@3.21.6(magicast@0.5.3))': + '@nuxt/telemetry@2.8.0(@nuxt/kit@3.21.8(magicast@0.5.3))': dependencies: - '@nuxt/kit': 3.21.6(magicast@0.5.3) + '@nuxt/kit': 3.21.8(magicast@0.5.3) citty: 0.2.2 consola: 3.4.2 ofetch: 2.0.0-alpha.3 rc9: 3.0.1 std-env: 4.1.0 - '@nuxt/test-utils@4.0.3(@vitest/ui@4.1.7)(crossws@0.4.5(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7)': + '@nuxt/test-utils@4.0.3(@vitest/ui@4.1.8)(crossws@0.4.6(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vitest@4.1.8)': dependencies: '@clack/prompts': 1.2.0 - '@nuxt/devtools-kit': 2.7.0(magicast@0.5.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) - '@nuxt/kit': 3.21.6(magicast@0.5.3) + '@nuxt/devtools-kit': 2.7.0(magicast@0.5.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + '@nuxt/kit': 3.21.8(magicast@0.5.3) c12: 3.3.4(magicast@0.5.3) consola: 3.4.2 defu: 6.1.7 @@ -7702,38 +7727,38 @@ snapshots: fake-indexeddb: 6.2.5 get-port-please: 3.2.0 h3: 1.15.11 - h3-next: h3@2.0.1-rc.20(crossws@0.4.5(srvx@0.11.16)) + h3-next: h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.16)) local-pkg: 1.2.1 magic-string: 0.30.21 node-fetch-native: 1.6.7 node-mock-http: 1.0.4 - nypm: 0.6.6 + nypm: 0.6.7 ofetch: 1.5.1 pathe: 2.0.3 perfect-debounce: 2.1.0 radix3: 1.1.2 scule: 1.3.0 std-env: 4.1.0 - tinyexec: 1.2.3 + tinyexec: 1.2.4 ufo: 1.6.4 unplugin: 3.0.0 - vitest-environment-nuxt: 2.0.0(@vitest/ui@4.1.7)(crossws@0.4.5(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7) - vue: 3.5.35(typescript@6.0.3) + vitest-environment-nuxt: 2.0.0(@vitest/ui@4.1.8)(crossws@0.4.6(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vitest@4.1.8) + vue: 3.5.38(typescript@6.0.3) optionalDependencies: - '@vitest/ui': 4.1.7(vitest@4.1.7) - vitest: 4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(@vitest/ui@4.1.7)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/ui': 4.1.8(vitest@4.1.8) + vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(@vitest/ui@4.1.8)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) transitivePeerDependencies: - crossws - magicast - typescript - vite - '@nuxt/vite-builder@3.21.6(@types/node@25.9.1)(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0))(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vue-tsc@3.3.3(typescript@6.0.3))(vue@3.5.35(typescript@6.0.3))(yaml@2.9.0)': + '@nuxt/vite-builder@3.21.8(@types/node@25.9.3)(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0))(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vue-tsc@3.3.4(typescript@6.0.3))(vue@3.5.38(typescript@6.0.3))(yaml@2.9.0)': dependencies: - '@nuxt/kit': 3.21.6(magicast@0.5.3) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) - '@vitejs/plugin-vue': 6.0.7(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) - '@vitejs/plugin-vue-jsx': 5.1.5(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) + '@nuxt/kit': 3.21.8(magicast@0.5.3) + '@rollup/plugin-replace': 6.0.3(rollup@4.61.1) + '@vitejs/plugin-vue': 6.0.7(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) + '@vitejs/plugin-vue-jsx': 5.1.5(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) autoprefixer: 10.5.0(postcss@8.5.15) consola: 3.4.2 cssnano: 7.1.9(postcss@8.5.15) @@ -7747,8 +7772,8 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0) - nypm: 0.6.6 + nuxt: 3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0) + nypm: 0.6.7 ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 2.1.0 @@ -7758,13 +7783,13 @@ snapshots: std-env: 4.1.0 ufo: 1.6.4 unenv: 2.0.0-rc.24 - vite: 7.3.3(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vite-node: 5.3.0(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vite-plugin-checker: 0.13.0(eslint@9.39.4(jiti@1.21.7))(optionator@0.9.4)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3)) - vue: 3.5.35(typescript@6.0.3) + vite: 7.3.5(@types/node@25.9.3)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite-node: 5.3.0(@types/node@25.9.3)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite-plugin-checker: 0.13.0(eslint@9.39.4(jiti@1.21.7))(optionator@0.9.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3)) + vue: 3.5.38(typescript@6.0.3) vue-bundle-renderer: 2.2.0 optionalDependencies: - rollup-plugin-visualizer: 7.0.1(rollup@4.60.4) + rollup-plugin-visualizer: 7.0.1(rollup@4.61.1) transitivePeerDependencies: - '@biomejs/biome' - '@types/node' @@ -7790,17 +7815,17 @@ snapshots: - vue-tsc - yaml - '@nuxtjs/i18n@10.4.0(@vue/compiler-dom@3.5.35)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(rollup@4.60.4)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))': + '@nuxtjs/i18n@10.4.0(@vue/compiler-dom@3.5.38)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)))(rollup@4.61.1)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3))': dependencies: - '@intlify/core': 11.4.4 + '@intlify/core': 11.4.5 '@intlify/h3': 0.7.4 - '@intlify/shared': 11.4.4 - '@intlify/unplugin-vue-i18n': 11.2.3(@vue/compiler-dom@3.5.35)(eslint@9.39.4(jiti@1.21.7))(rollup@4.60.4)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3)))(vue@3.5.35(typescript@6.0.3)) + '@intlify/shared': 11.4.5 + '@intlify/unplugin-vue-i18n': 11.2.3(@vue/compiler-dom@3.5.38)(eslint@9.39.4(jiti@1.21.7))(rollup@4.61.1)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3)))(vue@3.5.38(typescript@6.0.3)) '@intlify/utils': 0.14.1 - '@miyaneee/rollup-plugin-json5': 1.2.0(rollup@4.60.4) - '@nuxt/kit': 4.4.6(magicast@0.5.3) - '@rollup/plugin-yaml': 4.1.2(rollup@4.60.4) - '@vue/compiler-sfc': 3.5.35 + '@miyaneee/rollup-plugin-json5': 1.2.0(rollup@4.61.1) + '@nuxt/kit': 4.4.8(magicast@0.5.3) + '@rollup/plugin-yaml': 4.1.2(rollup@4.61.1) + '@vue/compiler-sfc': 3.5.38 defu: 6.1.7 devalue: 5.8.1 h3: 1.15.11 @@ -7815,9 +7840,9 @@ snapshots: ufo: 1.6.4 unplugin: 3.0.0 unrouting: 0.1.7 - unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.0) - vue-i18n: 11.4.4(vue@3.5.35(typescript@6.0.3)) - vue-router: 5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) + unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.1) + vue-i18n: 11.4.5(vue@3.5.38(typescript@6.0.3)) + vue-router: 5.1.0(@vue/compiler-sfc@3.5.38)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)))(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -7850,9 +7875,9 @@ snapshots: - vite - vue - '@nuxtjs/tailwindcss@6.14.0(magicast@0.5.3)(tsx@4.22.3)(yaml@2.9.0)': + '@nuxtjs/tailwindcss@6.14.0(magicast@0.5.3)(tsx@4.22.4)(yaml@2.9.0)': dependencies: - '@nuxt/kit': 3.21.6(magicast@0.5.3) + '@nuxt/kit': 3.21.8(magicast@0.5.3) autoprefixer: 10.5.0(postcss@8.5.15) c12: 3.3.4(magicast@0.5.3) consola: 3.4.2 @@ -7864,8 +7889,8 @@ snapshots: pkg-types: 2.3.1 postcss: 8.5.15 postcss-nesting: 13.0.2(postcss@8.5.15) - tailwind-config-viewer: 2.0.4(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)) - tailwindcss: 3.4.19(tsx@4.22.3)(yaml@2.9.0) + tailwind-config-viewer: 2.0.4(tailwindcss@3.4.19(tsx@4.22.4)(yaml@2.9.0)) + tailwindcss: 3.4.19(tsx@4.22.4)(yaml@2.9.0) ufo: 1.6.4 unctx: 2.5.0 transitivePeerDependencies: @@ -7874,328 +7899,328 @@ snapshots: - tsx - yaml - '@oxc-minify/binding-android-arm-eabi@0.131.0': + '@oxc-minify/binding-android-arm-eabi@0.132.0': optional: true - '@oxc-minify/binding-android-arm64@0.131.0': + '@oxc-minify/binding-android-arm64@0.132.0': optional: true - '@oxc-minify/binding-darwin-arm64@0.131.0': + '@oxc-minify/binding-darwin-arm64@0.132.0': optional: true - '@oxc-minify/binding-darwin-x64@0.131.0': + '@oxc-minify/binding-darwin-x64@0.132.0': optional: true - '@oxc-minify/binding-freebsd-x64@0.131.0': + '@oxc-minify/binding-freebsd-x64@0.132.0': optional: true - '@oxc-minify/binding-linux-arm-gnueabihf@0.131.0': + '@oxc-minify/binding-linux-arm-gnueabihf@0.132.0': optional: true - '@oxc-minify/binding-linux-arm-musleabihf@0.131.0': + '@oxc-minify/binding-linux-arm-musleabihf@0.132.0': optional: true - '@oxc-minify/binding-linux-arm64-gnu@0.131.0': + '@oxc-minify/binding-linux-arm64-gnu@0.132.0': optional: true - '@oxc-minify/binding-linux-arm64-musl@0.131.0': + '@oxc-minify/binding-linux-arm64-musl@0.132.0': optional: true - '@oxc-minify/binding-linux-ppc64-gnu@0.131.0': + '@oxc-minify/binding-linux-ppc64-gnu@0.132.0': optional: true - '@oxc-minify/binding-linux-riscv64-gnu@0.131.0': + '@oxc-minify/binding-linux-riscv64-gnu@0.132.0': optional: true - '@oxc-minify/binding-linux-riscv64-musl@0.131.0': + '@oxc-minify/binding-linux-riscv64-musl@0.132.0': optional: true - '@oxc-minify/binding-linux-s390x-gnu@0.131.0': + '@oxc-minify/binding-linux-s390x-gnu@0.132.0': optional: true - '@oxc-minify/binding-linux-x64-gnu@0.131.0': + '@oxc-minify/binding-linux-x64-gnu@0.132.0': optional: true - '@oxc-minify/binding-linux-x64-musl@0.131.0': + '@oxc-minify/binding-linux-x64-musl@0.132.0': optional: true - '@oxc-minify/binding-openharmony-arm64@0.131.0': + '@oxc-minify/binding-openharmony-arm64@0.132.0': optional: true - '@oxc-minify/binding-wasm32-wasi@0.131.0': + '@oxc-minify/binding-wasm32-wasi@0.132.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@oxc-minify/binding-win32-arm64-msvc@0.131.0': + '@oxc-minify/binding-win32-arm64-msvc@0.132.0': optional: true - '@oxc-minify/binding-win32-ia32-msvc@0.131.0': + '@oxc-minify/binding-win32-ia32-msvc@0.132.0': optional: true - '@oxc-minify/binding-win32-x64-msvc@0.131.0': + '@oxc-minify/binding-win32-x64-msvc@0.132.0': optional: true '@oxc-parser/binding-android-arm-eabi@0.128.0': optional: true - '@oxc-parser/binding-android-arm-eabi@0.131.0': + '@oxc-parser/binding-android-arm-eabi@0.132.0': optional: true '@oxc-parser/binding-android-arm64@0.128.0': optional: true - '@oxc-parser/binding-android-arm64@0.131.0': + '@oxc-parser/binding-android-arm64@0.132.0': optional: true '@oxc-parser/binding-darwin-arm64@0.128.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.131.0': + '@oxc-parser/binding-darwin-arm64@0.132.0': optional: true '@oxc-parser/binding-darwin-x64@0.128.0': optional: true - '@oxc-parser/binding-darwin-x64@0.131.0': + '@oxc-parser/binding-darwin-x64@0.132.0': optional: true '@oxc-parser/binding-freebsd-x64@0.128.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.131.0': + '@oxc-parser/binding-freebsd-x64@0.132.0': optional: true '@oxc-parser/binding-linux-arm-gnueabihf@0.128.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.131.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.132.0': optional: true '@oxc-parser/binding-linux-arm-musleabihf@0.128.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.131.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.132.0': optional: true '@oxc-parser/binding-linux-arm64-gnu@0.128.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.131.0': + '@oxc-parser/binding-linux-arm64-gnu@0.132.0': optional: true '@oxc-parser/binding-linux-arm64-musl@0.128.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.131.0': + '@oxc-parser/binding-linux-arm64-musl@0.132.0': optional: true '@oxc-parser/binding-linux-ppc64-gnu@0.128.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.131.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.132.0': optional: true '@oxc-parser/binding-linux-riscv64-gnu@0.128.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.131.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.132.0': optional: true '@oxc-parser/binding-linux-riscv64-musl@0.128.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.131.0': + '@oxc-parser/binding-linux-riscv64-musl@0.132.0': optional: true '@oxc-parser/binding-linux-s390x-gnu@0.128.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.131.0': + '@oxc-parser/binding-linux-s390x-gnu@0.132.0': optional: true '@oxc-parser/binding-linux-x64-gnu@0.128.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.131.0': + '@oxc-parser/binding-linux-x64-gnu@0.132.0': optional: true '@oxc-parser/binding-linux-x64-musl@0.128.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.131.0': + '@oxc-parser/binding-linux-x64-musl@0.132.0': optional: true '@oxc-parser/binding-openharmony-arm64@0.128.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.131.0': + '@oxc-parser/binding-openharmony-arm64@0.132.0': optional: true '@oxc-parser/binding-wasm32-wasi@0.128.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@oxc-parser/binding-wasm32-wasi@0.131.0': + '@oxc-parser/binding-wasm32-wasi@0.132.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@oxc-parser/binding-win32-arm64-msvc@0.128.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.131.0': + '@oxc-parser/binding-win32-arm64-msvc@0.132.0': optional: true '@oxc-parser/binding-win32-ia32-msvc@0.128.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.131.0': + '@oxc-parser/binding-win32-ia32-msvc@0.132.0': optional: true '@oxc-parser/binding-win32-x64-msvc@0.128.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.131.0': + '@oxc-parser/binding-win32-x64-msvc@0.132.0': optional: true '@oxc-project/types@0.128.0': {} - '@oxc-project/types@0.131.0': {} + '@oxc-project/types@0.132.0': {} '@oxc-transform/binding-android-arm-eabi@0.128.0': optional: true - '@oxc-transform/binding-android-arm-eabi@0.131.0': + '@oxc-transform/binding-android-arm-eabi@0.132.0': optional: true '@oxc-transform/binding-android-arm64@0.128.0': optional: true - '@oxc-transform/binding-android-arm64@0.131.0': + '@oxc-transform/binding-android-arm64@0.132.0': optional: true '@oxc-transform/binding-darwin-arm64@0.128.0': optional: true - '@oxc-transform/binding-darwin-arm64@0.131.0': + '@oxc-transform/binding-darwin-arm64@0.132.0': optional: true '@oxc-transform/binding-darwin-x64@0.128.0': optional: true - '@oxc-transform/binding-darwin-x64@0.131.0': + '@oxc-transform/binding-darwin-x64@0.132.0': optional: true '@oxc-transform/binding-freebsd-x64@0.128.0': optional: true - '@oxc-transform/binding-freebsd-x64@0.131.0': + '@oxc-transform/binding-freebsd-x64@0.132.0': optional: true '@oxc-transform/binding-linux-arm-gnueabihf@0.128.0': optional: true - '@oxc-transform/binding-linux-arm-gnueabihf@0.131.0': + '@oxc-transform/binding-linux-arm-gnueabihf@0.132.0': optional: true '@oxc-transform/binding-linux-arm-musleabihf@0.128.0': optional: true - '@oxc-transform/binding-linux-arm-musleabihf@0.131.0': + '@oxc-transform/binding-linux-arm-musleabihf@0.132.0': optional: true '@oxc-transform/binding-linux-arm64-gnu@0.128.0': optional: true - '@oxc-transform/binding-linux-arm64-gnu@0.131.0': + '@oxc-transform/binding-linux-arm64-gnu@0.132.0': optional: true '@oxc-transform/binding-linux-arm64-musl@0.128.0': optional: true - '@oxc-transform/binding-linux-arm64-musl@0.131.0': + '@oxc-transform/binding-linux-arm64-musl@0.132.0': optional: true '@oxc-transform/binding-linux-ppc64-gnu@0.128.0': optional: true - '@oxc-transform/binding-linux-ppc64-gnu@0.131.0': + '@oxc-transform/binding-linux-ppc64-gnu@0.132.0': optional: true '@oxc-transform/binding-linux-riscv64-gnu@0.128.0': optional: true - '@oxc-transform/binding-linux-riscv64-gnu@0.131.0': + '@oxc-transform/binding-linux-riscv64-gnu@0.132.0': optional: true '@oxc-transform/binding-linux-riscv64-musl@0.128.0': optional: true - '@oxc-transform/binding-linux-riscv64-musl@0.131.0': + '@oxc-transform/binding-linux-riscv64-musl@0.132.0': optional: true '@oxc-transform/binding-linux-s390x-gnu@0.128.0': optional: true - '@oxc-transform/binding-linux-s390x-gnu@0.131.0': + '@oxc-transform/binding-linux-s390x-gnu@0.132.0': optional: true '@oxc-transform/binding-linux-x64-gnu@0.128.0': optional: true - '@oxc-transform/binding-linux-x64-gnu@0.131.0': + '@oxc-transform/binding-linux-x64-gnu@0.132.0': optional: true '@oxc-transform/binding-linux-x64-musl@0.128.0': optional: true - '@oxc-transform/binding-linux-x64-musl@0.131.0': + '@oxc-transform/binding-linux-x64-musl@0.132.0': optional: true '@oxc-transform/binding-openharmony-arm64@0.128.0': optional: true - '@oxc-transform/binding-openharmony-arm64@0.131.0': + '@oxc-transform/binding-openharmony-arm64@0.132.0': optional: true '@oxc-transform/binding-wasm32-wasi@0.128.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@oxc-transform/binding-wasm32-wasi@0.131.0': + '@oxc-transform/binding-wasm32-wasi@0.132.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@oxc-transform/binding-win32-arm64-msvc@0.128.0': optional: true - '@oxc-transform/binding-win32-arm64-msvc@0.131.0': + '@oxc-transform/binding-win32-arm64-msvc@0.132.0': optional: true '@oxc-transform/binding-win32-ia32-msvc@0.128.0': optional: true - '@oxc-transform/binding-win32-ia32-msvc@0.131.0': + '@oxc-transform/binding-win32-ia32-msvc@0.132.0': optional: true '@oxc-transform/binding-win32-x64-msvc@0.128.0': optional: true - '@oxc-transform/binding-win32-x64-msvc@0.131.0': + '@oxc-transform/binding-win32-x64-msvc@0.132.0': optional: true '@package-json/types@0.0.12': {} @@ -8267,10 +8292,10 @@ snapshots: '@phc/format@1.0.0': {} - '@pinia/nuxt@0.11.3(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))': + '@pinia/nuxt@0.11.3(magicast@0.5.3)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)))': dependencies: - '@nuxt/kit': 4.4.6(magicast@0.5.3) - pinia: 3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)) + '@nuxt/kit': 4.4.8(magicast@0.5.3) + pinia: 3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - magicast @@ -8293,13 +8318,13 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-alias@6.0.0(rollup@4.60.4)': + '@rollup/plugin-alias@6.0.0(rollup@4.61.1)': optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-commonjs@29.0.3(rollup@4.60.4)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.4) @@ -8307,136 +8332,136 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-inject@5.0.5(rollup@4.60.4)': + '@rollup/plugin-inject@5.0.5(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) estree-walker: 2.0.2 magic-string: 0.30.21 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-json@6.1.0(rollup@4.60.4)': + '@rollup/plugin-json@6.1.0(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.4)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-replace@6.0.3(rollup@4.60.4)': + '@rollup/plugin-replace@6.0.3(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) magic-string: 0.30.21 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-terser@1.0.0(rollup@4.60.4)': + '@rollup/plugin-terser@1.0.0(rollup@4.61.1)': dependencies: serialize-javascript: 7.0.5 smob: 1.6.2 terser: 5.48.0 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/plugin-yaml@4.1.2(rollup@4.60.4)': + '@rollup/plugin-yaml@4.1.2(rollup@4.61.1)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) - js-yaml: 4.1.1 + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) + js-yaml: 4.2.0 tosource: 2.0.0-alpha.3 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/pluginutils@5.4.0(rollup@4.60.4)': + '@rollup/pluginutils@5.4.0(rollup@4.61.1)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - '@rollup/rollup-android-arm-eabi@4.60.4': + '@rollup/rollup-android-arm-eabi@4.61.1': optional: true - '@rollup/rollup-android-arm64@4.60.4': + '@rollup/rollup-android-arm64@4.61.1': optional: true - '@rollup/rollup-darwin-arm64@4.60.4': + '@rollup/rollup-darwin-arm64@4.61.1': optional: true - '@rollup/rollup-darwin-x64@4.60.4': + '@rollup/rollup-darwin-x64@4.61.1': optional: true - '@rollup/rollup-freebsd-arm64@4.60.4': + '@rollup/rollup-freebsd-arm64@4.61.1': optional: true - '@rollup/rollup-freebsd-x64@4.60.4': + '@rollup/rollup-freebsd-x64@4.61.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + '@rollup/rollup-linux-arm-gnueabihf@4.61.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.4': + '@rollup/rollup-linux-arm-musleabihf@4.61.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.4': + '@rollup/rollup-linux-arm64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.4': + '@rollup/rollup-linux-arm64-musl@4.61.1': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.4': + '@rollup/rollup-linux-loong64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.4': + '@rollup/rollup-linux-loong64-musl@4.61.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.4': + '@rollup/rollup-linux-ppc64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.4': + '@rollup/rollup-linux-ppc64-musl@4.61.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.4': + '@rollup/rollup-linux-riscv64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.4': + '@rollup/rollup-linux-riscv64-musl@4.61.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.4': + '@rollup/rollup-linux-s390x-gnu@4.61.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.4': + '@rollup/rollup-linux-x64-gnu@4.61.1': optional: true - '@rollup/rollup-linux-x64-musl@4.60.4': + '@rollup/rollup-linux-x64-musl@4.61.1': optional: true - '@rollup/rollup-openbsd-x64@4.60.4': + '@rollup/rollup-openbsd-x64@4.61.1': optional: true - '@rollup/rollup-openharmony-arm64@4.60.4': + '@rollup/rollup-openharmony-arm64@4.61.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.4': + '@rollup/rollup-win32-arm64-msvc@4.61.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.4': + '@rollup/rollup-win32-ia32-msvc@4.61.1': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.4': + '@rollup/rollup-win32-x64-gnu@4.61.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.4': + '@rollup/rollup-win32-x64-msvc@4.61.1': optional: true '@simple-git/args-pathspec@1.0.3': {} @@ -8451,14 +8476,14 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@speed-highlight/core@1.2.15': {} + '@speed-highlight/core@1.2.16': {} '@standard-schema/spec@1.1.0': {} '@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@1.21.7))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.61.0 eslint: 9.39.4(jiti@1.21.7) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -8469,17 +8494,17 @@ snapshots: dependencies: tslib: 2.8.1 - '@tailwindcss/forms@0.5.11(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0))': + '@tailwindcss/forms@0.5.11(tailwindcss@3.4.19(tsx@4.22.4)(yaml@2.9.0))': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.4.19(tsx@4.22.3)(yaml@2.9.0) + tailwindcss: 3.4.19(tsx@4.22.4)(yaml@2.9.0) - '@tanstack/virtual-core@3.16.0': {} + '@tanstack/virtual-core@3.17.0': {} - '@tanstack/vue-virtual@3.13.26(vue@3.5.35(typescript@6.0.3))': + '@tanstack/vue-virtual@3.13.28(vue@3.5.38(typescript@6.0.3))': dependencies: - '@tanstack/virtual-core': 3.16.0 - vue: 3.5.35(typescript@6.0.3) + '@tanstack/virtual-core': 3.17.0 + vue: 3.5.38(typescript@6.0.3) '@tybys/wasm-util@0.10.2': dependencies: @@ -8495,21 +8520,19 @@ snapshots: '@types/esrecurse@4.3.1': {} - '@types/estree@1.0.8': {} - '@types/estree@1.0.9': {} '@types/jsesc@2.5.1': {} '@types/json-schema@7.0.15': {} - '@types/node@25.9.1': + '@types/node@25.9.3': dependencies: undici-types: 7.24.6 '@types/phc__format@1.0.1': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 '@types/resolve@1.20.2': {} @@ -8521,16 +8544,16 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 - '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/type-utils': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 eslint: 9.39.4(jiti@1.21.7) ignore: 7.0.5 natural-compare: 1.4.0 @@ -8539,41 +8562,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 eslint: 9.39.4(jiti@1.21.7) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.60.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.60.0': + '@typescript-eslint/scope-manager@8.61.0': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 - '@typescript-eslint/tsconfig-utils@8.60.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) debug: 4.4.3 eslint: 9.39.4(jiti@1.21.7) ts-api-utils: 2.5.0(typescript@6.0.3) @@ -8581,44 +8604,44 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.60.0': {} + '@typescript-eslint/types@8.61.0': {} - '@typescript-eslint/typescript-estree@8.60.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.60.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.1 + semver: 7.8.4 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': + '@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) eslint: 9.39.4(jiti@1.21.7) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.60.0': + '@typescript-eslint/visitor-keys@8.61.0': dependencies: - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.61.0 eslint-visitor-keys: 5.0.1 - '@unhead/vue@2.1.15(vue@3.5.35(typescript@6.0.3))': + '@unhead/vue@2.1.15(vue@3.5.38(typescript@6.0.3))': dependencies: hookable: 6.1.1 unhead: 2.1.15 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) '@unrs/resolver-binding-android-arm-eabi@1.12.2': optional: true @@ -8678,7 +8701,7 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': @@ -8690,10 +8713,14 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true - '@vercel/nft@1.10.2(rollup@4.60.4)': + '@valibot/to-json-schema@1.7.1(valibot@1.4.1(typescript@6.0.3))': + dependencies: + valibot: 1.4.1(typescript@6.0.3) + + '@vercel/nft@1.10.2(rollup@4.61.1)': dependencies: '@mapbox/node-pre-gyp': 2.0.3 - '@rollup/pluginutils': 5.4.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.61.1) acorn: 8.16.0 acorn-import-attributes: 1.9.5(acorn@8.16.0) async-sema: 3.1.1 @@ -8709,87 +8736,87 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-vue-jsx@5.1.5(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))': + '@vitejs/plugin-vue-jsx@5.1.5(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7) '@rolldown/pluginutils': 1.0.1 '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.7) - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vue: 3.5.35(typescript@6.0.3) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vue: 3.5.38(typescript@6.0.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@6.0.7(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))': + '@vitejs/plugin-vue@6.0.7(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vue: 3.5.35(typescript@6.0.3) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vue: 3.5.38(typescript@6.0.3) - '@vitest/coverage-v8@4.1.7(vitest@4.1.7)': + '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.7 - ast-v8-to-istanbul: 1.0.2 + '@vitest/utils': 4.1.8 + ast-v8-to-istanbul: 1.0.4 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.3 - obug: 2.1.1 + obug: 2.1.2 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(@vitest/ui@4.1.7)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(@vitest/ui@4.1.8)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) - '@vitest/expect@4.1.7': + '@vitest/expect@4.1.8': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.7(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.7 + '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) - '@vitest/pretty-format@4.1.7': + '@vitest/pretty-format@4.1.8': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.7': + '@vitest/runner@4.1.8': dependencies: - '@vitest/utils': 4.1.7 + '@vitest/utils': 4.1.8 pathe: 2.0.3 - '@vitest/snapshot@4.1.7': + '@vitest/snapshot@4.1.8': dependencies: - '@vitest/pretty-format': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.7': {} + '@vitest/spy@4.1.8': {} - '@vitest/ui@4.1.7(vitest@4.1.7)': + '@vitest/ui@4.1.8(vitest@4.1.8)': dependencies: - '@vitest/utils': 4.1.7 + '@vitest/utils': 4.1.8 fflate: 0.8.3 flatted: 3.4.2 pathe: 2.0.3 sirv: 3.0.2 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vitest: 4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(@vitest/ui@4.1.7)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + vitest: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(@vitest/ui@4.1.8)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) - '@vitest/utils@4.1.7': + '@vitest/utils@4.1.8': dependencies: - '@vitest/pretty-format': 4.1.7 + '@vitest/pretty-format': 4.1.8 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -8805,15 +8832,15 @@ snapshots: path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@vue-macros/common@3.1.2(vue@3.5.35(typescript@6.0.3))': + '@vue-macros/common@3.1.2(vue@3.5.38(typescript@6.0.3))': dependencies: - '@vue/compiler-sfc': 3.5.35 + '@vue/compiler-sfc': 3.5.38 ast-kit: 2.2.0 local-pkg: 1.2.1 magic-string-ast: 1.0.3 unplugin-utils: 0.3.1 optionalDependencies: - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) '@vue/babel-helper-vue-transform-on@2.0.1': {} @@ -8827,7 +8854,7 @@ snapshots: '@babel/types': 7.29.7 '@vue/babel-helper-vue-transform-on': 2.0.1 '@vue/babel-plugin-resolve-type': 2.0.1(@babel/core@7.29.7) - '@vue/shared': 3.5.35 + '@vue/shared': 3.5.38 optionalDependencies: '@babel/core': 7.29.7 transitivePeerDependencies: @@ -8840,39 +8867,39 @@ snapshots: '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/parser': 7.29.7 - '@vue/compiler-sfc': 3.5.35 + '@vue/compiler-sfc': 3.5.38 transitivePeerDependencies: - supports-color - '@vue/compiler-core@3.5.35': + '@vue/compiler-core@3.5.38': dependencies: '@babel/parser': 7.29.7 - '@vue/shared': 3.5.35 + '@vue/shared': 3.5.38 entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.35': + '@vue/compiler-dom@3.5.38': dependencies: - '@vue/compiler-core': 3.5.35 - '@vue/shared': 3.5.35 + '@vue/compiler-core': 3.5.38 + '@vue/shared': 3.5.38 - '@vue/compiler-sfc@3.5.35': + '@vue/compiler-sfc@3.5.38': dependencies: '@babel/parser': 7.29.7 - '@vue/compiler-core': 3.5.35 - '@vue/compiler-dom': 3.5.35 - '@vue/compiler-ssr': 3.5.35 - '@vue/shared': 3.5.35 + '@vue/compiler-core': 3.5.38 + '@vue/compiler-dom': 3.5.38 + '@vue/compiler-ssr': 3.5.38 + '@vue/shared': 3.5.38 estree-walker: 2.0.2 magic-string: 0.30.21 postcss: 8.5.15 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.35': + '@vue/compiler-ssr@3.5.38': dependencies: - '@vue/compiler-dom': 3.5.35 - '@vue/shared': 3.5.35 + '@vue/compiler-dom': 3.5.38 + '@vue/shared': 3.5.38 '@vue/devtools-api@6.6.4': {} @@ -8884,11 +8911,11 @@ snapshots: dependencies: '@vue/devtools-kit': 8.1.2 - '@vue/devtools-core@8.1.2(vue@3.5.35(typescript@6.0.3))': + '@vue/devtools-core@8.1.2(vue@3.5.38(typescript@6.0.3))': dependencies: '@vue/devtools-kit': 8.1.2 '@vue/devtools-shared': 8.1.2 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) '@vue/devtools-kit@7.7.9': dependencies: @@ -8913,82 +8940,82 @@ snapshots: '@vue/devtools-shared@8.1.2': {} - '@vue/language-core@3.3.3': + '@vue/language-core@3.3.4': dependencies: '@volar/language-core': 2.4.28 - '@vue/compiler-dom': 3.5.35 - '@vue/shared': 3.5.35 + '@vue/compiler-dom': 3.5.38 + '@vue/shared': 3.5.38 alien-signals: 3.2.1 muggle-string: 0.4.1 path-browserify: 1.0.1 picomatch: 4.0.4 - '@vue/reactivity@3.5.35': + '@vue/reactivity@3.5.38': dependencies: - '@vue/shared': 3.5.35 + '@vue/shared': 3.5.38 - '@vue/runtime-core@3.5.35': + '@vue/runtime-core@3.5.38': dependencies: - '@vue/reactivity': 3.5.35 - '@vue/shared': 3.5.35 + '@vue/reactivity': 3.5.38 + '@vue/shared': 3.5.38 - '@vue/runtime-dom@3.5.35': + '@vue/runtime-dom@3.5.38': dependencies: - '@vue/reactivity': 3.5.35 - '@vue/runtime-core': 3.5.35 - '@vue/shared': 3.5.35 + '@vue/reactivity': 3.5.38 + '@vue/runtime-core': 3.5.38 + '@vue/shared': 3.5.38 csstype: 3.2.3 - '@vue/server-renderer@3.5.35(vue@3.5.35(typescript@6.0.3))': + '@vue/server-renderer@3.5.38(vue@3.5.38(typescript@6.0.3))': dependencies: - '@vue/compiler-ssr': 3.5.35 - '@vue/shared': 3.5.35 - vue: 3.5.35(typescript@6.0.3) + '@vue/compiler-ssr': 3.5.38 + '@vue/shared': 3.5.38 + vue: 3.5.38(typescript@6.0.3) - '@vue/shared@3.5.35': {} + '@vue/shared@3.5.38': {} - '@vueuse/core@10.11.1(vue@3.5.35(typescript@6.0.3))': + '@vueuse/core@10.11.1(vue@3.5.38(typescript@6.0.3))': dependencies: '@types/web-bluetooth': 0.0.20 '@vueuse/metadata': 10.11.1 - '@vueuse/shared': 10.11.1(vue@3.5.35(typescript@6.0.3)) - vue-demi: 0.14.10(vue@3.5.35(typescript@6.0.3)) + '@vueuse/shared': 10.11.1(vue@3.5.38(typescript@6.0.3)) + vue-demi: 0.14.10(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/core@14.3.0(vue@3.5.35(typescript@6.0.3))': + '@vueuse/core@14.3.0(vue@3.5.38(typescript@6.0.3))': dependencies: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 14.3.0 - '@vueuse/shared': 14.3.0(vue@3.5.35(typescript@6.0.3)) - vue: 3.5.35(typescript@6.0.3) + '@vueuse/shared': 14.3.0(vue@3.5.38(typescript@6.0.3)) + vue: 3.5.38(typescript@6.0.3) '@vueuse/metadata@10.11.1': {} '@vueuse/metadata@14.3.0': {} - '@vueuse/nuxt@14.3.0(magicast@0.5.3)(nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))': + '@vueuse/nuxt@14.3.0(magicast@0.5.3)(nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3))': dependencies: - '@nuxt/kit': 4.4.6(magicast@0.5.3) - '@vueuse/core': 14.3.0(vue@3.5.35(typescript@6.0.3)) + '@nuxt/kit': 4.4.8(magicast@0.5.3) + '@vueuse/core': 14.3.0(vue@3.5.38(typescript@6.0.3)) '@vueuse/metadata': 14.3.0 local-pkg: 1.2.1 - nuxt: 3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0) - vue: 3.5.35(typescript@6.0.3) + nuxt: 3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0) + vue: 3.5.38(typescript@6.0.3) transitivePeerDependencies: - magicast - '@vueuse/shared@10.11.1(vue@3.5.35(typescript@6.0.3))': + '@vueuse/shared@10.11.1(vue@3.5.38(typescript@6.0.3))': dependencies: - vue-demi: 0.14.10(vue@3.5.35(typescript@6.0.3)) + vue-demi: 0.14.10(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/shared@14.3.0(vue@3.5.35(typescript@6.0.3))': + '@vueuse/shared@14.3.0(vue@3.5.38(typescript@6.0.3))': dependencies: - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) abbrev@3.0.1: {} @@ -9032,7 +9059,7 @@ snapshots: ansi-styles@6.2.3: {} - ansis@4.3.0: {} + ansis@4.3.1: {} any-promise@1.3.0: {} @@ -9041,7 +9068,7 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.2 - apexcharts@5.13.0: {} + apexcharts@5.15.0: {} archiver-utils@5.0.2: dependencies: @@ -9091,7 +9118,7 @@ snapshots: '@babel/parser': 7.29.7 pathe: 2.0.3 - ast-v8-to-istanbul@1.0.2: + ast-v8-to-istanbul@1.0.4: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -9117,7 +9144,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001793 + caniuse-lite: 1.0.30001799 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.15 @@ -9129,14 +9156,14 @@ snapshots: balanced-match@4.0.4: {} - bare-events@2.8.3: {} + bare-events@2.9.1: {} - bare-fs@4.7.1: + bare-fs@4.7.2: dependencies: - bare-events: 2.8.3 - bare-path: 3.0.0 - bare-stream: 2.13.1(bare-events@2.8.3) - bare-url: 2.4.3 + bare-events: 2.9.1 + bare-path: 3.0.1 + bare-stream: 2.13.2(bare-events@2.9.1) + bare-url: 2.4.5 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -9144,26 +9171,26 @@ snapshots: bare-os@3.9.1: {} - bare-path@3.0.0: + bare-path@3.0.1: dependencies: bare-os: 3.9.1 - bare-stream@2.13.1(bare-events@2.8.3): + bare-stream@2.13.2(bare-events@2.9.1): dependencies: - streamx: 2.26.0 + streamx: 2.27.0 teex: 1.0.1 optionalDependencies: - bare-events: 2.8.3 + bare-events: 2.9.1 transitivePeerDependencies: - react-native-b4a - bare-url@2.4.3: + bare-url@2.4.5: dependencies: - bare-path: 3.0.0 + bare-path: 3.0.1 base64-js@1.5.1: {} - baseline-browser-mapping@2.10.33: {} + baseline-browser-mapping@2.10.35: {} binary-extensions@2.3.0: {} @@ -9196,10 +9223,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.33 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.364 - node-releases: 2.0.46 + baseline-browser-mapping: 2.10.35 + caniuse-lite: 1.0.30001799 + electron-to-chromium: 1.5.371 + node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-crc32@1.0.0: {} @@ -9217,11 +9244,6 @@ snapshots: dependencies: run-applescript: 7.1.0 - bundle-require@5.1.0(esbuild@0.27.7): - dependencies: - esbuild: 0.27.7 - load-tsconfig: 0.2.5 - c12@3.3.4(magicast@0.5.3): dependencies: chokidar: 5.0.0 @@ -9229,7 +9251,7 @@ snapshots: defu: 6.1.7 dotenv: 17.4.2 exsolve: 1.0.8 - giget: 3.2.0 + giget: 3.3.0 jiti: 2.7.0 ohash: 2.0.11 pathe: 2.0.3 @@ -9265,11 +9287,11 @@ snapshots: caniuse-api@3.0.0: dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001793 + caniuse-lite: 1.0.30001799 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001799: {} chai@6.2.2: {} @@ -9306,9 +9328,9 @@ snapshots: cidr-regex@6.0.0: {} - cidr-tools@12.0.2: + cidr-tools@12.0.3: dependencies: - ip-bigint: 9.0.5 + ip-bigint: 9.0.6 citty@0.1.6: dependencies: @@ -9316,10 +9338,6 @@ snapshots: citty@0.2.2: {} - clean-regexp@1.0.0: - dependencies: - escape-string-regexp: 1.0.5 - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -9354,8 +9372,6 @@ snapshots: commander@6.2.1: {} - comment-parser@1.4.6: {} - comment-parser@1.4.7: {} commondir@1.0.1: {} @@ -9433,7 +9449,7 @@ snapshots: dependencies: uncrypto: 0.1.3 - crossws@0.4.5(srvx@0.11.16): + crossws@0.4.6(srvx@0.11.16): optionalDependencies: srvx: 0.11.16 @@ -9555,12 +9571,31 @@ snapshots: destroy@1.2.0: {} + detect-indent@7.0.2: {} + detect-libc@2.0.2: {} detect-libc@2.1.2: {} devalue@5.8.1: {} + devframe@0.5.4(crossws@0.4.6(srvx@0.11.16))(typescript@6.0.3): + dependencies: + '@valibot/to-json-schema': 1.7.1(valibot@1.4.1(typescript@6.0.3)) + birpc: 4.0.0 + cac: 7.0.0 + h3: 2.0.1-rc.22(crossws@0.4.6(srvx@0.11.16)) + mrmime: 2.0.1 + nostics: 0.2.0 + pathe: 2.0.3 + valibot: 1.4.1(typescript@6.0.3) + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - crossws + - typescript + - utf-8-validate + didyoumean@1.2.2: {} diff@8.0.4: {} @@ -9587,7 +9622,7 @@ snapshots: dot-prop@10.1.0: dependencies: - type-fest: 5.6.0 + type-fest: 5.7.0 dotenv@17.4.2: {} @@ -9596,7 +9631,7 @@ snapshots: '@drizzle-team/brocli': 0.10.2 '@esbuild-kit/esm-loader': 2.6.5 esbuild: 0.25.12 - tsx: 4.22.3 + tsx: 4.22.4 drizzle-orm@0.45.2(@libsql/client@0.17.3): optionalDependencies: @@ -9614,7 +9649,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.364: {} + electron-to-chromium@1.5.371: {} emoji-regex@10.6.0: {} @@ -9626,7 +9661,7 @@ snapshots: encodeurl@2.0.0: {} - enhanced-resolve@5.22.1: + enhanced-resolve@5.23.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -9765,8 +9800,6 @@ snapshots: escape-html@1.0.3: {} - escape-string-regexp@1.0.5: {} - escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} @@ -9804,34 +9837,34 @@ snapshots: dependencies: eslint: 9.39.4(jiti@1.21.7) - eslint-plugin-import-lite@0.5.2(eslint@9.39.4(jiti@1.21.7)): + eslint-plugin-import-lite@0.6.0(eslint@9.39.4(jiti@1.21.7)): dependencies: eslint: 9.39.4(jiti@1.21.7) - eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7)): + eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7)): dependencies: '@package-json/types': 0.0.12 - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.61.0 comment-parser: 1.4.7 debug: 4.4.3 eslint: 9.39.4(jiti@1.21.7) eslint-import-context: 0.1.9(unrs-resolver@1.12.2) is-glob: 4.0.3 minimatch: 10.2.5 - semver: 7.8.1 + semver: 7.8.4 stable-hash-x: 0.2.0 unrs-resolver: 1.12.2 optionalDependencies: - '@typescript-eslint/utils': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) transitivePeerDependencies: - supports-color - eslint-plugin-jsdoc@62.9.0(eslint@9.39.4(jiti@1.21.7)): + eslint-plugin-jsdoc@63.0.2(eslint@9.39.4(jiti@1.21.7)): dependencies: - '@es-joy/jsdoccomment': 0.86.0 + '@es-joy/jsdoccomment': 0.87.0 '@es-joy/resolve.exports': 1.2.0 are-docs-informative: 0.0.2 - comment-parser: 1.4.6 + comment-parser: 1.4.7 debug: 4.4.3 escape-string-regexp: 4.0.0 eslint: 9.39.4(jiti@1.21.7) @@ -9840,7 +9873,7 @@ snapshots: html-entities: 2.6.0 object-deep-merge: 2.0.1 parse-imports-exports: 0.2.4 - semver: 7.8.1 + semver: 7.8.4 spdx-expression-parse: 4.0.0 to-valid-identifier: 1.0.0 transitivePeerDependencies: @@ -9857,43 +9890,42 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-unicorn@63.0.0(eslint@9.39.4(jiti@1.21.7)): + eslint-plugin-unicorn@65.0.1(eslint@9.39.4(jiti@1.21.7)): dependencies: '@babel/helper-validator-identifier': 7.29.7 '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) change-case: 5.4.4 ci-info: 4.4.0 - clean-regexp: 1.0.0 core-js-compat: 3.49.0 + detect-indent: 7.0.2 eslint: 9.39.4(jiti@1.21.7) find-up-simple: 1.0.1 - globals: 16.5.0 + globals: 17.6.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 pluralize: 8.0.0 - regexp-tree: 0.1.27 regjsparser: 0.13.1 - semver: 7.8.1 + semver: 7.8.4 strip-indent: 4.1.1 - eslint-plugin-vue@10.9.1(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@1.21.7)))(@typescript-eslint/parser@8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@1.21.7))): + eslint-plugin-vue@10.9.2(@stylistic/eslint-plugin@5.10.0(eslint@9.39.4(jiti@1.21.7)))(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3))(eslint@9.39.4(jiti@1.21.7))(vue-eslint-parser@10.4.1(eslint@9.39.4(jiti@1.21.7))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) eslint: 9.39.4(jiti@1.21.7) natural-compare: 1.4.0 nth-check: 2.1.1 - postcss-selector-parser: 7.1.1 - semver: 7.8.1 - vue-eslint-parser: 10.4.0(eslint@9.39.4(jiti@1.21.7)) + postcss-selector-parser: 7.1.4 + semver: 7.8.4 + vue-eslint-parser: 10.4.1(eslint@9.39.4(jiti@1.21.7)) xml-name-validator: 4.0.0 optionalDependencies: '@stylistic/eslint-plugin': 5.10.0(eslint@9.39.4(jiti@1.21.7)) - '@typescript-eslint/parser': 8.60.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@1.21.7))(typescript@6.0.3) - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.35)(eslint@9.39.4(jiti@1.21.7)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.38)(eslint@9.39.4(jiti@1.21.7)): dependencies: - '@vue/compiler-sfc': 3.5.35 + '@vue/compiler-sfc': 3.5.38 eslint: 9.39.4(jiti@1.21.7) eslint-scope@8.4.0: @@ -10005,7 +10037,7 @@ snapshots: events-universal@1.0.1: dependencies: - bare-events: 2.8.3 + bare-events: 2.9.1 transitivePeerDependencies: - bare-abort-controller @@ -10029,7 +10061,7 @@ snapshots: externality@1.0.2: dependencies: - enhanced-resolve: 5.22.1 + enhanced-resolve: 5.23.0 mlly: 1.8.2 pathe: 1.1.2 ufo: 1.6.4 @@ -10140,7 +10172,7 @@ snapshots: function-timeout@0.1.1: {} - fuse.js@7.4.0: {} + fuse.js@7.4.2: {} fzf@0.5.2: {} @@ -10178,7 +10210,7 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - giget@3.2.0: {} + giget@3.3.0: {} glob-parent@5.1.2: dependencies: @@ -10218,8 +10250,6 @@ snapshots: globals@14.0.0: {} - globals@16.5.0: {} - globals@17.6.0: {} globby@16.2.0: @@ -10251,12 +10281,19 @@ snapshots: ufo: 1.6.4 uncrypto: 0.1.3 - h3@2.0.1-rc.20(crossws@0.4.5(srvx@0.11.16)): + h3@2.0.1-rc.20(crossws@0.4.6(srvx@0.11.16)): dependencies: rou3: 0.8.1 srvx: 0.11.16 optionalDependencies: - crossws: 0.4.5(srvx@0.11.16) + crossws: 0.4.6(srvx@0.11.16) + + h3@2.0.1-rc.22(crossws@0.4.6(srvx@0.11.16)): + dependencies: + rou3: 0.8.1 + srvx: 0.11.16 + optionalDependencies: + crossws: 0.4.6(srvx@0.11.16) has-flag@4.0.0: {} @@ -10355,7 +10392,7 @@ snapshots: ini@4.1.1: {} - ioredis@5.11.0: + ioredis@5.11.1: dependencies: '@ioredis/commands': 1.10.0 cluster-key-slot: 1.1.1 @@ -10367,7 +10404,7 @@ snapshots: transitivePeerDependencies: - supports-color - ip-bigint@9.0.5: {} + ip-bigint@9.0.6: {} ip-regex@5.0.0: {} @@ -10499,7 +10536,7 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@4.1.1: + js-yaml@4.2.0: dependencies: argparse: 2.0.1 @@ -10525,7 +10562,7 @@ snapshots: acorn: 8.16.0 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - semver: 7.8.1 + semver: 7.8.4 jsonfile@6.2.1: dependencies: @@ -10597,7 +10634,7 @@ snapshots: transitivePeerDependencies: - supports-color - launch-editor@2.14.0: + launch-editor@2.14.1: dependencies: picocolors: 1.1.1 shell-quote: 1.8.4 @@ -10636,7 +10673,7 @@ snapshots: '@parcel/watcher-wasm': 2.5.6 citty: 0.2.2 consola: 3.4.2 - crossws: 0.4.5(srvx@0.11.16) + crossws: 0.4.6(srvx@0.11.16) defu: 6.1.7 get-port-please: 3.2.0 h3: 1.15.11 @@ -10646,15 +10683,13 @@ snapshots: node-forge: 1.4.0 pathe: 2.0.3 std-env: 4.1.0 - tinyclip: 0.1.13 + tinyclip: 0.1.14 ufo: 1.6.4 untun: 0.1.3 uqr: 0.1.3 transitivePeerDependencies: - srvx - load-tsconfig@0.2.5: {} - local-pkg@1.2.1: dependencies: mlly: 1.8.2 @@ -10718,7 +10753,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.8.1 + semver: 7.8.4 math-intrinsics@1.1.0: {} @@ -10814,17 +10849,17 @@ snapshots: negotiator@0.6.3: {} - nitropack@2.13.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3))(oxc-parser@0.131.0)(srvx@0.11.16): + nitropack@2.13.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3))(oxc-parser@0.132.0)(srvx@0.11.16): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 - '@rollup/plugin-alias': 6.0.0(rollup@4.60.4) - '@rollup/plugin-commonjs': 29.0.3(rollup@4.60.4) - '@rollup/plugin-inject': 5.0.5(rollup@4.60.4) - '@rollup/plugin-json': 6.1.0(rollup@4.60.4) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.4) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) - '@rollup/plugin-terser': 1.0.0(rollup@4.60.4) - '@vercel/nft': 1.10.2(rollup@4.60.4) + '@rollup/plugin-alias': 6.0.0(rollup@4.61.1) + '@rollup/plugin-commonjs': 29.0.3(rollup@4.61.1) + '@rollup/plugin-inject': 5.0.5(rollup@4.61.1) + '@rollup/plugin-json': 6.1.0(rollup@4.61.1) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.61.1) + '@rollup/plugin-replace': 6.0.3(rollup@4.61.1) + '@rollup/plugin-terser': 1.0.0(rollup@4.61.1) + '@vercel/nft': 1.10.2(rollup@4.61.1) archiver: 7.0.1 c12: 3.3.4(magicast@0.5.3) chokidar: 5.0.0 @@ -10848,7 +10883,7 @@ snapshots: h3: 1.15.11 hookable: 5.5.3 httpxy: 0.5.3 - ioredis: 5.11.0 + ioredis: 5.11.1 jiti: 2.7.0 klona: 2.0.6 knitwork: 1.3.0 @@ -10866,10 +10901,10 @@ snapshots: pkg-types: 2.3.1 pretty-bytes: 7.1.0 radix3: 1.1.2 - rollup: 4.60.4 - rollup-plugin-visualizer: 7.0.1(rollup@4.60.4) + rollup: 4.61.1 + rollup-plugin-visualizer: 7.0.1(rollup@4.61.1) scule: 1.3.0 - semver: 7.8.1 + semver: 7.8.4 serve-placeholder: 2.0.2 serve-static: 2.2.1 source-map: 0.7.6 @@ -10879,9 +10914,9 @@ snapshots: uncrypto: 0.1.3 unctx: 2.5.0 unenv: 2.0.0-rc.24 - unimport: 6.3.0(oxc-parser@0.131.0) + unimport: 6.3.0(oxc-parser@0.132.0) unplugin-utils: 0.3.1 - unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.0) + unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.1) untyped: 2.0.0 unwasm: 0.5.3 youch: 4.1.1 @@ -10935,7 +10970,7 @@ snapshots: node-mock-http@1.0.4: {} - node-releases@2.0.46: {} + node-releases@2.0.47: {} nopt@8.1.0: dependencies: @@ -10943,6 +10978,12 @@ snapshots: normalize-path@3.0.0: {} + nostics@0.2.0: + dependencies: + magic-string: 0.30.21 + oxc-parser: 0.132.0 + unplugin: 3.0.0 + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -10958,18 +10999,18 @@ snapshots: nuxt-define@1.0.0: {} - nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0): + nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0): dependencies: '@dxup/nuxt': 0.4.1(magicast@0.5.3)(typescript@6.0.3) - '@nuxt/cli': 3.35.2(@nuxt/schema@3.21.6)(cac@6.7.14)(magicast@0.5.3) - '@nuxt/devtools': 3.2.4(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)) - '@nuxt/kit': 3.21.6(magicast@0.5.3) - '@nuxt/nitro-server': 3.21.6(@libsql/client@0.17.3)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(ioredis@5.11.0)(magicast@0.5.3)(nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0))(oxc-parser@0.131.0)(srvx@0.11.16)(typescript@6.0.3) - '@nuxt/schema': 3.21.6 - '@nuxt/telemetry': 2.8.0(@nuxt/kit@3.21.6(magicast@0.5.3)) - '@nuxt/vite-builder': 3.21.6(@types/node@25.9.1)(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(nuxt@3.21.6(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.1)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.0)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3))(yaml@2.9.0))(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(terser@5.48.0)(tsx@4.22.3)(typescript@6.0.3)(vue-tsc@3.3.3(typescript@6.0.3))(vue@3.5.35(typescript@6.0.3))(yaml@2.9.0) - '@unhead/vue': 2.1.15(vue@3.5.35(typescript@6.0.3)) - '@vue/shared': 3.5.35 + '@nuxt/cli': 3.35.2(@nuxt/schema@3.21.8)(cac@6.7.14)(magicast@0.5.3) + '@nuxt/devtools': 3.2.4(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)) + '@nuxt/kit': 3.21.8(magicast@0.5.3) + '@nuxt/nitro-server': 3.21.8(@libsql/client@0.17.3)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(ioredis@5.11.1)(magicast@0.5.3)(nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0))(oxc-parser@0.132.0)(srvx@0.11.16)(typescript@6.0.3) + '@nuxt/schema': 3.21.8 + '@nuxt/telemetry': 2.8.0(@nuxt/kit@3.21.8(magicast@0.5.3)) + '@nuxt/vite-builder': 3.21.8(@types/node@25.9.3)(eslint@9.39.4(jiti@1.21.7))(magicast@0.5.3)(nuxt@3.21.8(@libsql/client@0.17.3)(@parcel/watcher@2.5.6)(@types/node@25.9.3)(@vue/compiler-sfc@3.5.38)(cac@6.7.14)(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(drizzle-orm@0.45.2(@libsql/client@0.17.3))(eslint@9.39.4(jiti@1.21.7))(ioredis@5.11.1)(magicast@0.5.3)(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(srvx@0.11.16)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3))(yaml@2.9.0))(optionator@0.9.4)(rollup-plugin-visualizer@7.0.1(rollup@4.61.1))(rollup@4.61.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.3)(vue-tsc@3.3.4(typescript@6.0.3))(vue@3.5.38(typescript@6.0.3))(yaml@2.9.0) + '@unhead/vue': 2.1.15(vue@3.5.38(typescript@6.0.3)) + '@vue/shared': 3.5.38 c12: 3.3.4(magicast@0.5.3) chokidar: 5.0.0 compatx: 0.2.0 @@ -10991,35 +11032,35 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 nanotar: 0.3.0 - nypm: 0.6.6 + nypm: 0.6.7 ofetch: 1.5.1 ohash: 2.0.11 on-change: 6.0.2 - oxc-minify: 0.131.0 - oxc-parser: 0.131.0 - oxc-transform: 0.131.0 - oxc-walker: 1.0.0(oxc-parser@0.131.0) + oxc-minify: 0.132.0 + oxc-parser: 0.132.0 + oxc-transform: 0.132.0 + oxc-walker: 1.0.0(oxc-parser@0.132.0) pathe: 2.0.3 perfect-debounce: 2.1.0 pkg-types: 2.3.1 rou3: 0.8.1 scule: 1.3.0 - semver: 7.8.1 + semver: 7.8.4 std-env: 4.1.0 tinyglobby: 0.2.17 ufo: 1.6.4 ultrahtml: 1.6.0 uncrypto: 0.1.3 unctx: 2.5.0 - unimport: 6.3.0(oxc-parser@0.131.0) + unimport: 6.3.0(oxc-parser@0.132.0) unplugin: 3.0.0 - unplugin-vue-router: 0.19.2(@vue/compiler-sfc@3.5.35)(vue-router@4.6.4(vue@3.5.35(typescript@6.0.3)))(vue@3.5.35(typescript@6.0.3)) + unplugin-vue-router: 0.19.2(@vue/compiler-sfc@3.5.38)(vue-router@4.6.4(vue@3.5.38(typescript@6.0.3)))(vue@3.5.38(typescript@6.0.3)) untyped: 2.0.0 - vue: 3.5.35(typescript@6.0.3) - vue-router: 4.6.4(vue@3.5.35(typescript@6.0.3)) + vue: 3.5.38(typescript@6.0.3) + vue-router: 4.6.4(vue@3.5.38(typescript@6.0.3)) optionalDependencies: '@parcel/watcher': 2.5.6 - '@types/node': 25.9.1 + '@types/node': 25.9.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -11084,11 +11125,11 @@ snapshots: - xml2js - yaml - nypm@0.6.6: + nypm@0.6.7: dependencies: citty: 0.2.2 pathe: 2.0.3 - tinyexec: 1.2.3 + tinyexec: 1.2.4 oauth4webapi@3.8.6: {} @@ -11098,7 +11139,7 @@ snapshots: object-hash@3.0.0: {} - obug@2.1.1: {} + obug@2.1.2: {} ofetch@1.5.1: dependencies: @@ -11158,28 +11199,28 @@ snapshots: dependencies: '@noble/hashes': 2.2.0 - oxc-minify@0.131.0: + oxc-minify@0.132.0: optionalDependencies: - '@oxc-minify/binding-android-arm-eabi': 0.131.0 - '@oxc-minify/binding-android-arm64': 0.131.0 - '@oxc-minify/binding-darwin-arm64': 0.131.0 - '@oxc-minify/binding-darwin-x64': 0.131.0 - '@oxc-minify/binding-freebsd-x64': 0.131.0 - '@oxc-minify/binding-linux-arm-gnueabihf': 0.131.0 - '@oxc-minify/binding-linux-arm-musleabihf': 0.131.0 - '@oxc-minify/binding-linux-arm64-gnu': 0.131.0 - '@oxc-minify/binding-linux-arm64-musl': 0.131.0 - '@oxc-minify/binding-linux-ppc64-gnu': 0.131.0 - '@oxc-minify/binding-linux-riscv64-gnu': 0.131.0 - '@oxc-minify/binding-linux-riscv64-musl': 0.131.0 - '@oxc-minify/binding-linux-s390x-gnu': 0.131.0 - '@oxc-minify/binding-linux-x64-gnu': 0.131.0 - '@oxc-minify/binding-linux-x64-musl': 0.131.0 - '@oxc-minify/binding-openharmony-arm64': 0.131.0 - '@oxc-minify/binding-wasm32-wasi': 0.131.0 - '@oxc-minify/binding-win32-arm64-msvc': 0.131.0 - '@oxc-minify/binding-win32-ia32-msvc': 0.131.0 - '@oxc-minify/binding-win32-x64-msvc': 0.131.0 + '@oxc-minify/binding-android-arm-eabi': 0.132.0 + '@oxc-minify/binding-android-arm64': 0.132.0 + '@oxc-minify/binding-darwin-arm64': 0.132.0 + '@oxc-minify/binding-darwin-x64': 0.132.0 + '@oxc-minify/binding-freebsd-x64': 0.132.0 + '@oxc-minify/binding-linux-arm-gnueabihf': 0.132.0 + '@oxc-minify/binding-linux-arm-musleabihf': 0.132.0 + '@oxc-minify/binding-linux-arm64-gnu': 0.132.0 + '@oxc-minify/binding-linux-arm64-musl': 0.132.0 + '@oxc-minify/binding-linux-ppc64-gnu': 0.132.0 + '@oxc-minify/binding-linux-riscv64-gnu': 0.132.0 + '@oxc-minify/binding-linux-riscv64-musl': 0.132.0 + '@oxc-minify/binding-linux-s390x-gnu': 0.132.0 + '@oxc-minify/binding-linux-x64-gnu': 0.132.0 + '@oxc-minify/binding-linux-x64-musl': 0.132.0 + '@oxc-minify/binding-openharmony-arm64': 0.132.0 + '@oxc-minify/binding-wasm32-wasi': 0.132.0 + '@oxc-minify/binding-win32-arm64-msvc': 0.132.0 + '@oxc-minify/binding-win32-ia32-msvc': 0.132.0 + '@oxc-minify/binding-win32-x64-msvc': 0.132.0 oxc-parser@0.128.0: dependencies: @@ -11206,30 +11247,30 @@ snapshots: '@oxc-parser/binding-win32-ia32-msvc': 0.128.0 '@oxc-parser/binding-win32-x64-msvc': 0.128.0 - oxc-parser@0.131.0: + oxc-parser@0.132.0: dependencies: - '@oxc-project/types': 0.131.0 + '@oxc-project/types': 0.132.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.131.0 - '@oxc-parser/binding-android-arm64': 0.131.0 - '@oxc-parser/binding-darwin-arm64': 0.131.0 - '@oxc-parser/binding-darwin-x64': 0.131.0 - '@oxc-parser/binding-freebsd-x64': 0.131.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.131.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.131.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.131.0 - '@oxc-parser/binding-linux-arm64-musl': 0.131.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.131.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.131.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.131.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.131.0 - '@oxc-parser/binding-linux-x64-gnu': 0.131.0 - '@oxc-parser/binding-linux-x64-musl': 0.131.0 - '@oxc-parser/binding-openharmony-arm64': 0.131.0 - '@oxc-parser/binding-wasm32-wasi': 0.131.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.131.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.131.0 - '@oxc-parser/binding-win32-x64-msvc': 0.131.0 + '@oxc-parser/binding-android-arm-eabi': 0.132.0 + '@oxc-parser/binding-android-arm64': 0.132.0 + '@oxc-parser/binding-darwin-arm64': 0.132.0 + '@oxc-parser/binding-darwin-x64': 0.132.0 + '@oxc-parser/binding-freebsd-x64': 0.132.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.132.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.132.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.132.0 + '@oxc-parser/binding-linux-arm64-musl': 0.132.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.132.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.132.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.132.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.132.0 + '@oxc-parser/binding-linux-x64-gnu': 0.132.0 + '@oxc-parser/binding-linux-x64-musl': 0.132.0 + '@oxc-parser/binding-openharmony-arm64': 0.132.0 + '@oxc-parser/binding-wasm32-wasi': 0.132.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.132.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.132.0 + '@oxc-parser/binding-win32-x64-msvc': 0.132.0 oxc-transform@0.128.0: optionalDependencies: @@ -11254,39 +11295,39 @@ snapshots: '@oxc-transform/binding-win32-ia32-msvc': 0.128.0 '@oxc-transform/binding-win32-x64-msvc': 0.128.0 - oxc-transform@0.131.0: + oxc-transform@0.132.0: optionalDependencies: - '@oxc-transform/binding-android-arm-eabi': 0.131.0 - '@oxc-transform/binding-android-arm64': 0.131.0 - '@oxc-transform/binding-darwin-arm64': 0.131.0 - '@oxc-transform/binding-darwin-x64': 0.131.0 - '@oxc-transform/binding-freebsd-x64': 0.131.0 - '@oxc-transform/binding-linux-arm-gnueabihf': 0.131.0 - '@oxc-transform/binding-linux-arm-musleabihf': 0.131.0 - '@oxc-transform/binding-linux-arm64-gnu': 0.131.0 - '@oxc-transform/binding-linux-arm64-musl': 0.131.0 - '@oxc-transform/binding-linux-ppc64-gnu': 0.131.0 - '@oxc-transform/binding-linux-riscv64-gnu': 0.131.0 - '@oxc-transform/binding-linux-riscv64-musl': 0.131.0 - '@oxc-transform/binding-linux-s390x-gnu': 0.131.0 - '@oxc-transform/binding-linux-x64-gnu': 0.131.0 - '@oxc-transform/binding-linux-x64-musl': 0.131.0 - '@oxc-transform/binding-openharmony-arm64': 0.131.0 - '@oxc-transform/binding-wasm32-wasi': 0.131.0 - '@oxc-transform/binding-win32-arm64-msvc': 0.131.0 - '@oxc-transform/binding-win32-ia32-msvc': 0.131.0 - '@oxc-transform/binding-win32-x64-msvc': 0.131.0 + '@oxc-transform/binding-android-arm-eabi': 0.132.0 + '@oxc-transform/binding-android-arm64': 0.132.0 + '@oxc-transform/binding-darwin-arm64': 0.132.0 + '@oxc-transform/binding-darwin-x64': 0.132.0 + '@oxc-transform/binding-freebsd-x64': 0.132.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.132.0 + '@oxc-transform/binding-linux-arm-musleabihf': 0.132.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.132.0 + '@oxc-transform/binding-linux-arm64-musl': 0.132.0 + '@oxc-transform/binding-linux-ppc64-gnu': 0.132.0 + '@oxc-transform/binding-linux-riscv64-gnu': 0.132.0 + '@oxc-transform/binding-linux-riscv64-musl': 0.132.0 + '@oxc-transform/binding-linux-s390x-gnu': 0.132.0 + '@oxc-transform/binding-linux-x64-gnu': 0.132.0 + '@oxc-transform/binding-linux-x64-musl': 0.132.0 + '@oxc-transform/binding-openharmony-arm64': 0.132.0 + '@oxc-transform/binding-wasm32-wasi': 0.132.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.132.0 + '@oxc-transform/binding-win32-ia32-msvc': 0.132.0 + '@oxc-transform/binding-win32-x64-msvc': 0.132.0 oxc-walker@0.7.0(oxc-parser@0.128.0): dependencies: magic-regexp: 0.10.0 oxc-parser: 0.128.0 - oxc-walker@1.0.0(oxc-parser@0.131.0): + oxc-walker@1.0.0(oxc-parser@0.132.0): dependencies: magic-regexp: 0.11.0 optionalDependencies: - oxc-parser: 0.131.0 + oxc-parser: 0.132.0 p-limit@3.1.0: dependencies: @@ -11360,10 +11401,10 @@ snapshots: pify@2.3.0: {} - pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)): + pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)): dependencies: '@vue/devtools-api': 7.7.9 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) optionalDependencies: typescript: 6.0.3 @@ -11393,7 +11434,7 @@ snapshots: postcss-calc@10.1.1(postcss@8.5.15): dependencies: postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 postcss-value-parser: 4.2.0 postcss-colormin@7.0.10(postcss@8.5.15): @@ -11413,7 +11454,7 @@ snapshots: postcss-discard-comments@7.0.8(postcss@8.5.15): dependencies: postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 postcss-discard-duplicates@7.0.4(postcss@8.5.15): dependencies: @@ -11439,13 +11480,13 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.5.15 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.15)(tsx@4.22.3)(yaml@2.9.0): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.15)(tsx@4.22.4)(yaml@2.9.0): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.15 - tsx: 4.22.3 + tsx: 4.22.4 yaml: 2.9.0 postcss-merge-longhand@7.0.7(postcss@8.5.15): @@ -11460,7 +11501,7 @@ snapshots: caniuse-api: 3.0.0 cssnano-utils: 5.0.3(postcss@8.5.15) postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 postcss-minify-font-values@7.0.3(postcss@8.5.15): dependencies: @@ -11487,19 +11528,19 @@ snapshots: caniuse-api: 3.0.0 cssesc: 3.0.0 postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 postcss-nested@6.2.0(postcss@8.5.15): dependencies: postcss: 8.5.15 - postcss-selector-parser: 6.1.2 + postcss-selector-parser: 6.1.4 postcss-nesting@13.0.2(postcss@8.5.15): dependencies: - '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.1) - '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1) + '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.4) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.4) postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 postcss-normalize-charset@7.0.3(postcss@8.5.15): dependencies: @@ -11563,12 +11604,12 @@ snapshots: postcss: 8.5.15 postcss-value-parser: 4.2.0 - postcss-selector-parser@6.1.2: + postcss-selector-parser@6.1.4: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.1.1: + postcss-selector-parser@7.1.4: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -11582,7 +11623,7 @@ snapshots: postcss-unique-selectors@7.0.7(postcss@8.5.15): dependencies: postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 postcss-value-parser@4.2.0: {} @@ -11596,11 +11637,11 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-tailwindcss@0.8.0(prettier@3.8.3): + prettier-plugin-tailwindcss@0.8.0(prettier@3.8.4): dependencies: - prettier: 3.8.3 + prettier: 3.8.4 - prettier@3.8.3: {} + prettier@3.8.4: {} pretty-bytes@7.1.0: {} @@ -11624,20 +11665,20 @@ snapshots: queue-microtask@1.2.3: {} - radix-vue@1.9.17(vue@3.5.35(typescript@6.0.3)): + radix-vue@1.9.17(vue@3.5.38(typescript@6.0.3)): dependencies: '@floating-ui/dom': 1.7.6 - '@floating-ui/vue': 1.1.11(vue@3.5.35(typescript@6.0.3)) + '@floating-ui/vue': 1.1.11(vue@3.5.38(typescript@6.0.3)) '@internationalized/date': 3.12.2 '@internationalized/number': 3.6.7 - '@tanstack/vue-virtual': 3.13.26(vue@3.5.35(typescript@6.0.3)) - '@vueuse/core': 10.11.1(vue@3.5.35(typescript@6.0.3)) - '@vueuse/shared': 10.11.1(vue@3.5.35(typescript@6.0.3)) + '@tanstack/vue-virtual': 3.13.28(vue@3.5.38(typescript@6.0.3)) + '@vueuse/core': 10.11.1(vue@3.5.38(typescript@6.0.3)) + '@vueuse/shared': 10.11.1(vue@3.5.38(typescript@6.0.3)) aria-hidden: 1.2.6 defu: 6.1.7 fast-deep-equal: 3.1.3 nanoid: 5.1.11 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) transitivePeerDependencies: - '@vue/composition-api' @@ -11739,44 +11780,44 @@ snapshots: rfdc@1.4.1: {} - rollup-plugin-visualizer@7.0.1(rollup@4.60.4): + rollup-plugin-visualizer@7.0.1(rollup@4.61.1): dependencies: open: 11.0.0 picomatch: 4.0.4 source-map: 0.7.6 yargs: 18.0.0 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.1 - rollup@4.60.4: + rollup@4.61.1: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 + '@rollup/rollup-android-arm-eabi': 4.61.1 + '@rollup/rollup-android-arm64': 4.61.1 + '@rollup/rollup-darwin-arm64': 4.61.1 + '@rollup/rollup-darwin-x64': 4.61.1 + '@rollup/rollup-freebsd-arm64': 4.61.1 + '@rollup/rollup-freebsd-x64': 4.61.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.61.1 + '@rollup/rollup-linux-arm-musleabihf': 4.61.1 + '@rollup/rollup-linux-arm64-gnu': 4.61.1 + '@rollup/rollup-linux-arm64-musl': 4.61.1 + '@rollup/rollup-linux-loong64-gnu': 4.61.1 + '@rollup/rollup-linux-loong64-musl': 4.61.1 + '@rollup/rollup-linux-ppc64-gnu': 4.61.1 + '@rollup/rollup-linux-ppc64-musl': 4.61.1 + '@rollup/rollup-linux-riscv64-gnu': 4.61.1 + '@rollup/rollup-linux-riscv64-musl': 4.61.1 + '@rollup/rollup-linux-s390x-gnu': 4.61.1 + '@rollup/rollup-linux-x64-gnu': 4.61.1 + '@rollup/rollup-linux-x64-musl': 4.61.1 + '@rollup/rollup-openbsd-x64': 4.61.1 + '@rollup/rollup-openharmony-arm64': 4.61.1 + '@rollup/rollup-win32-arm64-msvc': 4.61.1 + '@rollup/rollup-win32-ia32-msvc': 4.61.1 + '@rollup/rollup-win32-x64-gnu': 4.61.1 + '@rollup/rollup-win32-x64-msvc': 4.61.1 fsevents: 2.3.3 rou3@0.8.1: {} @@ -11809,7 +11850,7 @@ snapshots: semver@6.3.1: {} - semver@7.8.1: {} + semver@7.8.4: {} send@1.2.1: dependencies: @@ -11920,7 +11961,7 @@ snapshots: std-env@4.1.0: {} - streamx@2.26.0: + streamx@2.27.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -11979,7 +12020,7 @@ snapshots: dependencies: browserslist: 4.28.2 postcss: 8.5.15 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.4 sucrase@3.35.1: dependencies: @@ -12021,7 +12062,7 @@ snapshots: tagged-tag@1.0.0: {} - tailwind-config-viewer@2.0.4(tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0)): + tailwind-config-viewer@2.0.4(tailwindcss@3.4.19(tsx@4.22.4)(yaml@2.9.0)): dependencies: '@koa/router': 12.0.2 commander: 6.2.1 @@ -12031,11 +12072,11 @@ snapshots: open: 7.4.2 portfinder: 1.0.38 replace-in-file: 6.3.5 - tailwindcss: 3.4.19(tsx@4.22.3)(yaml@2.9.0) + tailwindcss: 3.4.19(tsx@4.22.4)(yaml@2.9.0) transitivePeerDependencies: - supports-color - tailwindcss@3.4.19(tsx@4.22.3)(yaml@2.9.0): + tailwindcss@3.4.19(tsx@4.22.4)(yaml@2.9.0): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -12054,9 +12095,9 @@ snapshots: postcss: 8.5.15 postcss-import: 15.1.0(postcss@8.5.15) postcss-js: 4.1.0(postcss@8.5.15) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.15)(tsx@4.22.3)(yaml@2.9.0) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.15)(tsx@4.22.4)(yaml@2.9.0) postcss-nested: 6.2.0(postcss@8.5.15) - postcss-selector-parser: 6.1.2 + postcss-selector-parser: 6.1.4 resolve: 1.22.12 sucrase: 3.35.1 transitivePeerDependencies: @@ -12068,15 +12109,15 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.8.1 - bare-fs: 4.7.1 + bare-fs: 4.7.2 fast-fifo: 1.3.2 - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer - react-native-b4a - tar@7.5.15: + tar@7.5.16: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -12086,7 +12127,7 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -12122,9 +12163,9 @@ snapshots: tinybench@2.9.0: {} - tinyclip@0.1.13: {} + tinyclip@0.1.14: {} - tinyexec@1.2.3: {} + tinyexec@1.2.4: {} tinyglobby@0.2.17: dependencies: @@ -12160,7 +12201,7 @@ snapshots: tsscmp@1.0.6: {} - tsx@4.22.3: + tsx@4.22.4: dependencies: esbuild: 0.28.0 optionalDependencies: @@ -12170,7 +12211,7 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@5.6.0: + type-fest@5.7.0: dependencies: tagged-tag: 1.0.0 @@ -12210,24 +12251,7 @@ snapshots: unicorn-magic@0.4.0: {} - unimport@5.7.0: - dependencies: - acorn: 8.16.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - local-pkg: 1.2.1 - magic-string: 0.30.21 - mlly: 1.8.2 - pathe: 2.0.3 - picomatch: 4.0.4 - pkg-types: 2.3.1 - scule: 1.3.0 - strip-literal: 3.1.0 - tinyglobby: 0.2.17 - unplugin: 2.3.11 - unplugin-utils: 0.3.1 - - unimport@6.3.0(oxc-parser@0.131.0): + unimport@6.3.0(oxc-parser@0.132.0): dependencies: acorn: 8.16.0 escape-string-regexp: 5.0.0 @@ -12244,7 +12268,7 @@ snapshots: unplugin: 3.0.0 unplugin-utils: 0.3.1 optionalDependencies: - oxc-parser: 0.131.0 + oxc-parser: 0.132.0 universalify@2.0.1: {} @@ -12253,12 +12277,12 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.4 - unplugin-vue-router@0.19.2(@vue/compiler-sfc@3.5.35)(vue-router@4.6.4(vue@3.5.35(typescript@6.0.3)))(vue@3.5.35(typescript@6.0.3)): + unplugin-vue-router@0.19.2(@vue/compiler-sfc@3.5.38)(vue-router@4.6.4(vue@3.5.38(typescript@6.0.3)))(vue@3.5.38(typescript@6.0.3)): dependencies: '@babel/generator': 7.29.7 - '@vue-macros/common': 3.1.2(vue@3.5.35(typescript@6.0.3)) - '@vue/compiler-sfc': 3.5.35 - '@vue/language-core': 3.3.3 + '@vue-macros/common': 3.1.2(vue@3.5.38(typescript@6.0.3)) + '@vue/compiler-sfc': 3.5.38 + '@vue/language-core': 3.3.4 ast-walker-scope: 0.8.3 chokidar: 5.0.0 json5: 2.2.3 @@ -12274,7 +12298,7 @@ snapshots: unplugin-utils: 0.3.1 yaml: 2.9.0 optionalDependencies: - vue-router: 4.6.4(vue@3.5.35(typescript@6.0.3)) + vue-router: 4.6.4(vue@3.5.38(typescript@6.0.3)) transitivePeerDependencies: - vue @@ -12323,7 +12347,7 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 - unstorage@1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.0): + unstorage@1.17.5(db0@0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)))(ioredis@5.11.1): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -12335,7 +12359,7 @@ snapshots: ufo: 1.6.4 optionalDependencies: db0: 0.3.4(@libsql/client@0.17.3)(drizzle-orm@0.45.2(@libsql/client@0.17.3)) - ioredis: 5.11.0 + ioredis: 5.11.1 untun@0.1.3: dependencies: @@ -12374,25 +12398,29 @@ snapshots: util-deprecate@1.0.2: {} + valibot@1.4.1(typescript@6.0.3): + optionalDependencies: + typescript: 6.0.3 + vary@1.1.2: {} - vite-dev-rpc@2.0.0(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)): + vite-dev-rpc@2.0.0(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)): dependencies: birpc: 4.0.0 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vite-hot-client: 2.2.0(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite-hot-client: 2.2.0(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) - vite-hot-client@2.2.0(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)): + vite-hot-client@2.2.0(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)): dependencies: - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) - vite-node@5.3.0(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + vite-node@5.3.0(@types/node@25.9.3)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: cac: 6.7.14 es-module-lexer: 2.1.0 - obug: 2.1.1 + obug: 2.1.2 pathe: 2.0.3 - vite: 7.3.3(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) transitivePeerDependencies: - '@types/node' - jiti @@ -12406,7 +12434,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.13.0(eslint@9.39.4(jiti@1.21.7))(optionator@0.9.4)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue-tsc@3.3.3(typescript@6.0.3)): + vite-plugin-checker@0.13.0(eslint@9.39.4(jiti@1.21.7))(optionator@0.9.4)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue-tsc@3.3.4(typescript@6.0.3)): dependencies: '@babel/code-frame': 7.29.7 chokidar: 4.0.3 @@ -12416,74 +12444,74 @@ snapshots: proper-lockfile: 4.1.2 tiny-invariant: 1.3.3 tinyglobby: 0.2.17 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) vscode-uri: 3.1.0 optionalDependencies: eslint: 9.39.4(jiti@1.21.7) optionator: 0.9.4 typescript: 6.0.3 - vue-tsc: 3.3.3(typescript@6.0.3) + vue-tsc: 3.3.4(typescript@6.0.3) - vite-plugin-inspect@11.4.1(@nuxt/kit@4.4.6(magicast@0.5.3))(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)): + vite-plugin-inspect@11.4.1(@nuxt/kit@4.4.8(magicast@0.5.3))(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)): dependencies: - ansis: 4.3.0 + ansis: 4.3.1 error-stack-parser-es: 1.0.5 - obug: 2.1.1 + obug: 2.1.2 ohash: 2.0.11 open: 11.0.0 perfect-debounce: 2.1.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vite-dev-rpc: 2.0.0(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite-dev-rpc: 2.0.0(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) optionalDependencies: - '@nuxt/kit': 4.4.6(magicast@0.5.3) + '@nuxt/kit': 4.4.8(magicast@0.5.3) - vite-plugin-vue-tracer@1.4.0(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)): + vite-plugin-vue-tracer@1.4.0(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)): dependencies: estree-walker: 3.0.3 exsolve: 1.0.8 magic-string: 0.30.21 pathe: 2.0.3 source-map-js: 1.2.1 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - vue: 3.5.35(typescript@6.0.3) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vue: 3.5.38(typescript@6.0.3) - vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.15 - rollup: 4.60.4 + rollup: 4.61.1 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 fsevents: 2.3.3 jiti: 1.21.7 terser: 5.48.0 - tsx: 4.22.3 + tsx: 4.22.4 yaml: 2.9.0 - vite@7.3.3(@types/node@25.9.1)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + vite@7.3.5(@types/node@25.9.3)(jiti@2.7.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.15 - rollup: 4.60.4 + rollup: 4.61.1 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.3 fsevents: 2.3.3 jiti: 2.7.0 terser: 5.48.0 - tsx: 4.22.3 + tsx: 4.22.4 yaml: 2.9.0 - vitest-environment-nuxt@2.0.0(@vitest/ui@4.1.7)(crossws@0.4.5(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7): + vitest-environment-nuxt@2.0.0(@vitest/ui@4.1.8)(crossws@0.4.6(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vitest@4.1.8): dependencies: - '@nuxt/test-utils': 4.0.3(@vitest/ui@4.1.7)(crossws@0.4.5(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vitest@4.1.7) + '@nuxt/test-utils': 4.0.3(@vitest/ui@4.1.8)(crossws@0.4.6(srvx@0.11.16))(magicast@0.5.3)(typescript@6.0.3)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vitest@4.1.8) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -12500,32 +12528,32 @@ snapshots: - vite - vitest - vitest@4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(@vitest/ui@4.1.7)(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)): + vitest@4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(@vitest/ui@4.1.8)(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)): dependencies: - '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.7 - '@vitest/runner': 4.1.7 - '@vitest/snapshot': 4.1.7 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.2 pathe: 2.0.3 picomatch: 4.0.4 std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.2.3 + tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.9.1 - '@vitest/coverage-v8': 4.1.7(vitest@4.1.7) - '@vitest/ui': 4.1.7(vitest@4.1.7) + '@types/node': 25.9.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) + '@vitest/ui': 4.1.8(vitest@4.1.8) transitivePeerDependencies: - msw @@ -12535,13 +12563,13 @@ snapshots: dependencies: ufo: 1.6.4 - vue-demi@0.14.10(vue@3.5.35(typescript@6.0.3)): + vue-demi@0.14.10(vue@3.5.38(typescript@6.0.3)): dependencies: - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) vue-devtools-stub@0.1.0: {} - vue-eslint-parser@10.4.0(eslint@9.39.4(jiti@1.21.7)): + vue-eslint-parser@10.4.1(eslint@9.39.4(jiti@1.21.7)): dependencies: debug: 4.4.3 eslint: 9.39.4(jiti@1.21.7) @@ -12549,27 +12577,27 @@ snapshots: eslint-visitor-keys: 5.0.1 espree: 11.2.0 esquery: 1.7.0 - semver: 7.8.1 + semver: 7.8.4 transitivePeerDependencies: - supports-color - vue-i18n@11.4.4(vue@3.5.35(typescript@6.0.3)): + vue-i18n@11.4.5(vue@3.5.38(typescript@6.0.3)): dependencies: - '@intlify/core-base': 11.4.4 - '@intlify/devtools-types': 11.4.4 - '@intlify/shared': 11.4.4 + '@intlify/core-base': 11.4.5 + '@intlify/devtools-types': 11.4.5 + '@intlify/shared': 11.4.5 '@vue/devtools-api': 6.6.4 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) - vue-router@4.6.4(vue@3.5.35(typescript@6.0.3)): + vue-router@4.6.4(vue@3.5.38(typescript@6.0.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) - vue-router@5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3)): + vue-router@5.1.0(@vue/compiler-sfc@3.5.38)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)))(vite@7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.38(typescript@6.0.3)): dependencies: '@babel/generator': 8.0.0-rc.6 - '@vue-macros/common': 3.1.2(vue@3.5.35(typescript@6.0.3)) + '@vue-macros/common': 3.1.2(vue@3.5.38(typescript@6.0.3)) '@vue/devtools-api': 8.1.2 ast-walker-scope: 0.9.0 chokidar: 5.0.0 @@ -12584,31 +12612,31 @@ snapshots: tinyglobby: 0.2.17 unplugin: 3.0.0 unplugin-utils: 0.3.1 - vue: 3.5.35(typescript@6.0.3) + vue: 3.5.38(typescript@6.0.3) yaml: 2.9.0 optionalDependencies: - '@vue/compiler-sfc': 3.5.35 - pinia: 3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)) - vite: 7.3.3(@types/node@25.9.1)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + '@vue/compiler-sfc': 3.5.38 + pinia: 3.0.4(typescript@6.0.3)(vue@3.5.38(typescript@6.0.3)) + vite: 7.3.5(@types/node@25.9.3)(jiti@1.21.7)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) - vue-tsc@3.3.3(typescript@6.0.3): + vue-tsc@3.3.4(typescript@6.0.3): dependencies: '@volar/typescript': 2.4.28 - '@vue/language-core': 3.3.3 + '@vue/language-core': 3.3.4 typescript: 6.0.3 - vue3-apexcharts@1.11.1(apexcharts@5.13.0)(vue@3.5.35(typescript@6.0.3)): + vue3-apexcharts@1.11.1(apexcharts@5.15.0)(vue@3.5.38(typescript@6.0.3)): dependencies: - apexcharts: 5.13.0 - vue: 3.5.35(typescript@6.0.3) + apexcharts: 5.15.0 + vue: 3.5.38(typescript@6.0.3) - vue@3.5.35(typescript@6.0.3): + vue@3.5.38(typescript@6.0.3): dependencies: - '@vue/compiler-dom': 3.5.35 - '@vue/compiler-sfc': 3.5.35 - '@vue/runtime-dom': 3.5.35 - '@vue/server-renderer': 3.5.35(vue@3.5.35(typescript@6.0.3)) - '@vue/shared': 3.5.35 + '@vue/compiler-dom': 3.5.38 + '@vue/compiler-sfc': 3.5.38 + '@vue/runtime-dom': 3.5.38 + '@vue/server-renderer': 3.5.38(vue@3.5.38(typescript@6.0.3)) + '@vue/shared': 3.5.38 optionalDependencies: typescript: 6.0.3 @@ -12716,7 +12744,7 @@ snapshots: dependencies: '@poppinss/colors': 4.1.6 '@poppinss/dumper': 0.7.0 - '@speed-highlight/core': 1.2.15 + '@speed-highlight/core': 1.2.16 cookie-es: 3.1.1 youch-core: 0.3.3 From bb5aff19198008c529f285bc8878946f6323aa3b Mon Sep 17 00:00:00 2001 From: Bernd Storath Date: Fri, 12 Jun 2026 15:27:38 +0200 Subject: [PATCH 03/34] fix lint --- src/server/utils/session.ts | 2 +- src/server/utils/types.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/utils/session.ts b/src/server/utils/session.ts index 5c697e85..ef48a326 100644 --- a/src/server/utils/session.ts +++ b/src/server/utils/session.ts @@ -49,7 +49,7 @@ export async function getCurrentUser(event: H3Event) { const authorization = getHeader(event, 'Authorization'); - let user: UserType | undefined = undefined; + let user: UserType | undefined; if (session.data.userId) { // Handle if authenticating using Session user = await Database.users.get(session.data.userId); diff --git a/src/server/utils/types.ts b/src/server/utils/types.ts index a0e9694e..526b69b9 100644 --- a/src/server/utils/types.ts +++ b/src/server/utils/types.ts @@ -247,6 +247,7 @@ export function validateZod( }) .join('; '); } + // eslint-disable-next-line preserve-caught-error throw new Error(message); } }; From 66b292b11bde3664f05ffb016c8082665d261ded Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Fri, 12 Jun 2026 15:55:22 +0200 Subject: [PATCH 04/34] improve security (#2661) * disable basic auth when password auth disabled * clarify otl security --- src/server/database/repositories/oneTimeLink/service.ts | 9 +++++++++ src/server/routes/cnf/[oneTimeLink].ts | 7 +++++++ src/server/utils/session.ts | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/src/server/database/repositories/oneTimeLink/service.ts b/src/server/database/repositories/oneTimeLink/service.ts index 49162ac0..68328d13 100644 --- a/src/server/database/repositories/oneTimeLink/service.ts +++ b/src/server/database/repositories/oneTimeLink/service.ts @@ -52,6 +52,10 @@ export class OneTimeLinkService { } generate(id: ID) { + // SECURITY + // This is known to be vulnerable to brute force attacks + // Mitigations: Small Window, One Time Use + // Making it longer defeats the whole purpose const key = `${id}-${Math.floor(Math.random() * 1000)}`; const oneTimeLink = Math.abs(CRC32.str(key)).toString(16); const expiresAt = new Date(Date.now() + 5 * 60 * 1000).toISOString(); @@ -60,6 +64,11 @@ export class OneTimeLinkService { } erase(id: ID) { + // SECURITY + // This is known the extend the Window for brute force attacks + // Reason: Set the expiresAt to 10 seconds in the future to allow a second request to get the otl + // some browser apparently make two requests when downloading a file + // cant find the bug report anymore, maybe this can be removed? const expiresAt = new Date(Date.now() + 10 * 1000).toISOString(); return this.#statements.erase.execute({ id, expiresAt }); } diff --git a/src/server/routes/cnf/[oneTimeLink].ts b/src/server/routes/cnf/[oneTimeLink].ts index bc38d9ea..ecc4273a 100644 --- a/src/server/routes/cnf/[oneTimeLink].ts +++ b/src/server/routes/cnf/[oneTimeLink].ts @@ -14,6 +14,13 @@ export default defineEventHandler(async (event) => { }); } + if (new Date() > new Date(otl.expiresAt)) { + throw createError({ + statusCode: 410, + statusMessage: 'One Time Link has expired', + }); + } + const client = await Database.clients.get(otl.id); if (!client) { throw createError({ diff --git a/src/server/utils/session.ts b/src/server/utils/session.ts index ef48a326..8fd7646f 100644 --- a/src/server/utils/session.ts +++ b/src/server/utils/session.ts @@ -54,6 +54,13 @@ export async function getCurrentUser(event: H3Event) { // Handle if authenticating using Session user = await Database.users.get(session.data.userId); } else if (authorization) { + if (WG_ENV.DISABLE_PASSWORD_AUTH) { + throw createError({ + statusCode: 403, + statusMessage: 'Password authentication is disabled', + }); + } + // Handle if authenticating using Header const [method, value] = authorization.split(' '); // Support Basic Authentication From e9252be45c568bdd68a66e3b1df226035d92ad8f Mon Sep 17 00:00:00 2001 From: Daeho Ro <40587651+daeho-ro@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:34:09 +0900 Subject: [PATCH 05/34] i18n: add missing Korean (#2665) --- src/i18n/locales/ko.json | 77 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/src/i18n/locales/ko.json b/src/i18n/locales/ko.json index e712aa3c..c28d1fd5 100644 --- a/src/i18n/locales/ko.json +++ b/src/i18n/locales/ko.json @@ -20,7 +20,11 @@ "2faKey": "TOTP 키", "2faCodeDesc": "인증기 앱에서 코드를 입력하십시오.", "disable2fa": "2단계 인증 비활성화", - "disable2faDesc": "2단계 인증을 비활성화하려면 비밀번호를 입력하세요." + "disable2faDesc": "2단계 인증을 비활성화하려면 비밀번호를 입력하세요.", + "linkOauth": "외부 제공자와 계정 연결", + "unlinkOauth": "연결 해제", + "linkedWith": "{0}와(과) 연결됨", + "providerDisabled": "현재 연결된 제공자가 활성화되어 있지 않습니다" }, "general": { "name": "이름", @@ -28,6 +32,7 @@ "password": "비밀번호", "newPassword": "새 비밀번호", "updatePassword": "비밀번호 업데이트", + "addPassword": "비밀번호 추가", "mtu": "MTU", "allowedIps": "허용된 IP", "dns": "DNS", @@ -41,7 +46,8 @@ "confirmPassword": "비밀번호 확인", "loading": "로딩 중...", "2fa": "2단계 인증", - "2faCode": "TOTP 코드" + "2faCode": "TOTP 코드", + "externalAuth": "외부 인증" }, "setup": { "welcome": "wg-easy의 첫 번째 설정에 오신 것을 환영합니다.", @@ -72,6 +78,8 @@ }, "login": { "signIn": "로그인", + "signInWith": "{0}(으)로 로그인", + "or": "또는", "rememberMe": "로그인 상태 유지", "rememberMeDesc": "브라우저를 닫은 후에도 로그인 유지", "insecure": "안전하지 않은 연결로 로그인할 수 없습니다. HTTPS를 사용하세요.", @@ -88,6 +96,7 @@ "name": "이름", "expireDate": "만료 날짜", "expireDateDesc": "클라이언트가 비활성화될 날짜. 영구적으로 비워두기", + "delete": "삭제", "deleteClient": "클라이언트 삭제", "deleteDialog1": "정말로 삭제하시겠습니까", "deleteDialog2": "이 작업은 실행 취소할 수 없습니다.", @@ -116,7 +125,14 @@ "dnsDesc": "클라이언트가 사용할 DNS 서버(전역 구성 무시)", "notConnected": "클라이언트가 연결되지 않음", "endpoint": "엔드포인트", - "endpointDesc": "WireGuard에 연결된 클라이언트의 IP 주소" + "endpointDesc": "WireGuard에 연결된 클라이언트의 IP 주소", + "search": "클라이언트 검색...", + "config": "구성", + "viewConfig": "구성 보기", + "firewallIps": "방화벽 허용 IP", + "firewallIpsDesc": "이 클라이언트가 접근할 수 있는 목적지 IP/CIDR(서버 측 적용). 허용된 IP를 사용하려면 비워 두십시오. 선택적 포트 및 프로토콜 필터링을 지원합니다. 구문은 문서를 참조하십시오.", + "downloadPng": "PNG 다운로드", + "copyPng": "PNG 복사" }, "dialog": { "change": "변경", @@ -126,7 +142,8 @@ "toast": { "success": "성공", "saved": "저장됨", - "error": "오류" + "error": "오류", + "unknown": "알 수 없는 오류. 자세한 내용은 콘솔을 참조하십시오" }, "form": { "actions": "작업", @@ -171,7 +188,10 @@ "restart": "인터페이스 재시작", "restartDesc": "WireGuard 인터페이스를 재시작합니다.", "restartWarn": "인터페이스를 재시작하시겠습니까? 이 작업은 모든 클라이언트를 연결 해제합니다.", - "restartSuccess": "인터페이스가 재시작되었습니다" + "restartSuccess": "인터페이스가 재시작되었습니다", + "firewall": "트래픽 필터링", + "firewallEnabled": "클라이언트별 방화벽 활성화", + "firewallEnabledDesc": "iptables를 사용하여 클라이언트 트래픽을 특정 목적지 IP로 제한합니다. 활성화하면 각 클라이언트에 허용된 목적지를 구성할 수 있습니다." }, "introText": "관리 패널에 오신 것을 환영합니다.\n\n여기에서 일반 설정, 구성, 인터페이스 설정 및 후크를 관리할 수 있습니다.\n\n사이드바에서 섹션 중 하나를 선택하여 시작하세요." }, @@ -179,6 +199,7 @@ "generic": { "required": "{0}은(는) 필수입니다.", "validNumber": "{0}은(는) 유효한 숫자여야 합니다.", + "validNumberRange": "{0}은(는) 유효한 숫자 또는 숫자 범위여야 합니다", "validString": "{0}은 유효한 문자열이어야 합니다", "validBoolean": "{0}은(는) 유효한 불리언이어야 합니다.", "validArray": "{0}는 유효한 배열이어야 합니다", @@ -191,7 +212,9 @@ "expiresAt": "만료 시간", "address4": "IPv4 주소", "address6": "IPv6 주소", - "serverAllowedIps": "서버 허용된 IP" + "serverAllowedIps": "서버 허용된 IP", + "firewallIps": "방화벽 허용 IP", + "firewallIpsInvalid": "잘못된 방화벽 IP 항목입니다. 지원되는 구문은 문서를 참조하십시오." }, "user": { "username": "사용자 이름", @@ -236,5 +259,47 @@ "postUp": "PostUp", "preDown": "PreDown", "postDown": "PostDown" + }, + "copy": { + "notSupported": "복사가 지원되지 않습니다", + "copied": "복사됨!", + "failed": "복사 실패", + "copy": "복사" + }, + "awg": { + "jCLabel": "정크 패킷 수 (Jc)", + "jCDescription": "보낼 정크 패킷의 수 (1-128, 권장: 4-12)", + "jMinLabel": "정크 패킷 최소 크기 (Jmin)", + "jMinDescription": "정크 패킷의 최소 크기 (0-1279*, 권장: 8, Jmax보다 작아야 함)", + "jMaxLabel": "정크 패킷 최대 크기 (Jmax)", + "jMaxDescription": "정크 패킷의 최대 크기 (1-1280*, 권장: 80, Jmin보다 커야 함)", + "s1Label": "초기화 패킷 정크 크기 (S1)", + "s1Description": "초기화 패킷 정크 크기 (0-1132[1280* - 148 = 1132], 권장: 15-150, S1+56 ≠ S2)", + "s2Label": "응답 패킷 정크 크기 (S2)", + "s2Description": "응답 패킷 정크 크기 (0-1188[1280* - 92 = 1188], 권장: 15-150)", + "s3Label": "쿠키 응답 패킷 정크 크기 (S3)", + "s3Description": "쿠키 응답 패킷 정크 크기", + "s4Label": "전송 패킷 정크 크기 (S4)", + "s4Description": "전송 패킷 정크 크기", + "h1Label": "초기화 매직 헤더 (H1)", + "h1Description": "초기화 패킷 헤더 값 또는 범위 (X 또는 X-Y, X", + "i2Label": "특수 정크 패킷 2 (I2)", + "i2Description": "16진수 형식의 프로토콜 모방 패킷: ", + "i3Label": "특수 정크 패킷 3 (I3)", + "i3Description": "16진수 형식의 프로토콜 모방 패킷: ", + "i4Label": "특수 정크 패킷 4 (I4)", + "i4Description": "16진수 형식의 프로토콜 모방 패킷: ", + "i5Label": "특수 정크 패킷 5 (I5)", + "i5Description": "16진수 형식의 프로토콜 모방 패킷: ", + "mtuNote": "값은 MTU에 따라 달라집니다", + "obfuscationParameters": "AmneziaWG 난독화 매개변수" } } From 09cf2089330d350ab26b23d7ae28a9e45cfa4c41 Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:11:10 +0200 Subject: [PATCH 06/34] fix: improve buttons (#2666) improve buttons Co-authored-by: anhhna --- .../components/Form/PrimaryActionField.vue | 2 +- .../components/Form/SecondaryActionField.vue | 33 ++++++++++++++----- src/app/pages/admin/interface.vue | 8 ++--- src/app/pages/clients/[id].vue | 8 ++--- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/app/components/Form/PrimaryActionField.vue b/src/app/components/Form/PrimaryActionField.vue index 8e2d8c6e..2ea0d04b 100644 --- a/src/app/components/Form/PrimaryActionField.vue +++ b/src/app/components/Form/PrimaryActionField.vue @@ -2,7 +2,7 @@ diff --git a/src/app/components/Form/SecondaryActionField.vue b/src/app/components/Form/SecondaryActionField.vue index 94878c55..77c80fff 100644 --- a/src/app/components/Form/SecondaryActionField.vue +++ b/src/app/components/Form/SecondaryActionField.vue @@ -1,17 +1,32 @@ diff --git a/src/app/pages/admin/interface.vue b/src/app/pages/admin/interface.vue index e75f164a..8924d8ac 100644 --- a/src/app/pages/admin/interface.vue +++ b/src/app/pages/admin/interface.vue @@ -145,8 +145,8 @@ > diff --git a/src/app/pages/clients/[id].vue b/src/app/pages/clients/[id].vue index 0b875282..6694c284 100644 --- a/src/app/pages/clients/[id].vue +++ b/src/app/pages/clients/[id].vue @@ -188,9 +188,7 @@ > @@ -200,9 +198,7 @@ > From 47c6f476ac86eebb3d27ab7cfc9b3ba55f6a8703 Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:56:54 +0200 Subject: [PATCH 07/34] refactor: replace mkdocs with zensical (#2667) * move docs to zensical * fix requirements * fixes * remove manual font loading does not work properly with mike * switch back to pymdownx.blocks.admonition * revert back * remove css * add note about privacy plugin * pr review findings --- .gitignore | 5 +- .vscode/settings.json | 5 +- docs/content/advanced/api.md | 1 + docs/content/advanced/config/amnezia.md | 16 +-- .../config/external-authentication.md | 36 +++---- .../advanced/config/unattended-setup.md | 2 + docs/content/advanced/metrics/prometheus.md | 1 + .../contributing/issues-and-pull-requests.md | 3 + docs/content/examples/tutorials/adguard.md | 6 +- docs/content/examples/tutorials/caddy.md | 1 + .../examples/tutorials/reverse-proxyless.md | 1 + docs/content/examples/tutorials/routed.md | 1 + docs/content/examples/tutorials/traefik.md | 1 + docs/content/getting-started.md | 2 + docs/content/guides/admin.md | 2 + docs/content/guides/clients.md | 2 + docs/content/index.md | 1 + docs/mkdocs.yml | 87 ----------------- docs/requirements.txt | 6 +- docs/zensical.toml | 97 +++++++++++++++++++ package.json | 2 +- 21 files changed, 157 insertions(+), 121 deletions(-) delete mode 100644 docs/mkdocs.yml create mode 100644 docs/zensical.toml diff --git a/.gitignore b/.gitignore index c36465bd..2d1e2d0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .DS_Store *.swp -node_modules \ No newline at end of file +node_modules + +docs/site +docs/.cache \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index f62f2c98..691bcfba 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,5 +26,8 @@ "i18n-ally.sortKeys": false, "i18n-ally.keepFulfilled": false, "i18n-ally.keystyle": "nested", - "editor.gotoLocation.multipleDefinitions": "goto" + "editor.gotoLocation.multipleDefinitions": "goto", + "[toml]": { + "editor.defaultFormatter": "tamasfe.even-better-toml" + } } diff --git a/docs/content/advanced/api.md b/docs/content/advanced/api.md index 58d5df2d..e285d98a 100644 --- a/docs/content/advanced/api.md +++ b/docs/content/advanced/api.md @@ -5,6 +5,7 @@ title: API /// warning | Breaking Changes This API is not yet stable and may change in the future. The API is currently in development and is subject to change without notice. The API is not yet documented, but we will add documentation as the API stabilizes. + /// You can use the API to interact with the application programmatically. The API is available at `/api` and supports both GET and POST requests. The API is designed to be simple and easy to use, with a focus on providing a consistent interface for all endpoints. diff --git a/docs/content/advanced/config/amnezia.md b/docs/content/advanced/config/amnezia.md index 1d4f2b5b..3e8d4d0a 100644 --- a/docs/content/advanced/config/amnezia.md +++ b/docs/content/advanced/config/amnezia.md @@ -39,14 +39,14 @@ If a parameter is not set, it will not be added to the configuration. If all Amn ### Parameter Compatibility Table -| Parameter | Can differ between server and client | Configurable on server | Configurable on client | -| --------- | ------------------------------------ | ---------------------- | ----------------------- | -| Jc | ✅ Yes | ✅ | ✅ | -| Jmin | ✅ Yes | ✅ | ✅ | -| Jmax | ✅ Yes | ✅ | ✅ | -| S1-S4 | ❌ No, must match | ✅ | ❌ (copied from server) | -| H1-H4 | ❌ No, must match | ✅ | ❌ (copied from server) | -| I1-I5 | ✅ Yes | ✅ | ✅ | +| Parameter | Can differ between server and client | Configurable on server | Configurable on client | +| --------- | ------------------------------------ | ---------------------- | ------------------------ | +| Jc | :white_check_mark: Yes | :white_check_mark: | :white_check_mark: | +| Jmin | :white_check_mark: Yes | :white_check_mark: | :white_check_mark: | +| Jmax | :white_check_mark: Yes | :white_check_mark: | :white_check_mark: | +| S1-S4 | :x: No, must match | :white_check_mark: | :x: (copied from server) | +| H1-H4 | :x: No, must match | :white_check_mark: | :x: (copied from server) | +| I1-I5 | :white_check_mark: Yes | :white_check_mark: | :white_check_mark: | ## Client Applications diff --git a/docs/content/advanced/config/external-authentication.md b/docs/content/advanced/config/external-authentication.md index 420c3275..aeb33e4f 100644 --- a/docs/content/advanced/config/external-authentication.md +++ b/docs/content/advanced/config/external-authentication.md @@ -24,7 +24,7 @@ To automatically register users that log in with an OAuth provider, set the foll | Env | Required | Default | Description | | --------------------- | -------- | ------- | ------------------------ | -| `OAUTH_AUTO_REGISTER` | ✖️ | `false` | Enable auto-registration | +| `OAUTH_AUTO_REGISTER` | :x: | `false` | Enable auto-registration | When enabled: @@ -46,7 +46,7 @@ To only allow users with an email address from a specific domain to log in, set | Env | Required | Default | Description | | ----------------------- | -------- | ------- | --------------------- | -| `OAUTH_ALLOWED_DOMAINS` | ✖️ | - | Allowed email domains | +| `OAUTH_ALLOWED_DOMAINS` | :x: | - | Allowed email domains | You can allow multiple domains by separating them with a comma: @@ -58,7 +58,7 @@ To automatically launch the OAuth login flow when visiting the login page, set t | Env | Required | Default | Description | | ------------------- | -------- | ------- | ----------------------------- | -| `OAUTH_AUTO_LAUNCH` | ✖️ | - | Auto launch an OAuth provider | +| `OAUTH_AUTO_LAUNCH` | :x: | - | Auto launch an OAuth provider | When enabled: @@ -83,10 +83,10 @@ If your provider does not support multiple redirect URIs (e.g. GitHub) but allow #### Google -| Env | Required | Description | -| ---------------------------- | -------- | -------------------- | -| `OAUTH_GOOGLE_CLIENT_ID` | ✔️ | Google Client ID | -| `OAUTH_GOOGLE_CLIENT_SECRET` | ✔️ | Google Client Secret | +| Env | Required | Description | +| ---------------------------- | ------------------ | -------------------- | +| `OAUTH_GOOGLE_CLIENT_ID` | :white_check_mark: | Google Client ID | +| `OAUTH_GOOGLE_CLIENT_SECRET` | :white_check_mark: | Google Client Secret |
Setup
@@ -97,10 +97,10 @@ If your provider does not support multiple redirect URIs (e.g. GitHub) but allow #### GitHub -| Env | Required | Description | -| ---------------------------- | -------- | -------------------- | -| `OAUTH_GITHUB_CLIENT_ID` | ✔️ | GitHub Client ID | -| `OAUTH_GITHUB_CLIENT_SECRET` | ✔️ | GitHub Client Secret | +| Env | Required | Description | +| ---------------------------- | ------------------ | -------------------- | +| `OAUTH_GITHUB_CLIENT_ID` | :white_check_mark: | GitHub Client ID | +| `OAUTH_GITHUB_CLIENT_SECRET` | :white_check_mark: | GitHub Client Secret |
Setup
@@ -122,12 +122,12 @@ The provider needs to support: The provider needs to be available with HTTPS and have a valid certificate. -| Env | Required | Default | Example | Description | -| -------------------------- | -------- | ------- | -------------------------- | ------------------ | -| `OAUTH_OIDC_SERVER` | ✔️ | - | `https://auth.example.com` | OIDC Server | -| `OAUTH_OIDC_CLIENT_ID` | ✔️ | - | - | OIDC Client ID | -| `OAUTH_OIDC_CLIENT_SECRET` | ✔️ | - | - | OIDC Client Secret | -| `OAUTH_OIDC_NAME` | ✖️ | OIDC | `Authelia` | Provider Name | +| Env | Required | Default | Example | Description | +| -------------------------- | ------------------ | ------- | -------------------------- | ------------------ | +| `OAUTH_OIDC_SERVER` | :white_check_mark: | - | `https://auth.example.com` | OIDC Server | +| `OAUTH_OIDC_CLIENT_ID` | :white_check_mark: | - | - | OIDC Client ID | +| `OAUTH_OIDC_CLIENT_SECRET` | :white_check_mark: | - | - | OIDC Client Secret | +| `OAUTH_OIDC_NAME` | :x: | OIDC | `Authelia` | Provider Name | ##### Authelia Setup @@ -167,7 +167,7 @@ To disable password-based authentication and only allow login via OAuth provider | Env | Required | Default | Description | | ----------------------- | -------- | ------- | ------------------------------- | -| `DISABLE_PASSWORD_AUTH` | ✖️ | `false` | Disable password authentication | +| `DISABLE_PASSWORD_AUTH` | :x: | `false` | Disable password authentication | When enabled: diff --git a/docs/content/advanced/config/unattended-setup.md b/docs/content/advanced/config/unattended-setup.md index b0444d93..5572df99 100644 --- a/docs/content/advanced/config/unattended-setup.md +++ b/docs/content/advanced/config/unattended-setup.md @@ -23,6 +23,7 @@ These will only be used during the first start of the container. After that, the If variables are in the same group, you have to set all of them. For example, if you set `INIT_IPV4_CIDR`, you also have to set `INIT_IPV6_CIDR`. If you want to skip the setup process, you have to configure group `1` + /// /// note | Security @@ -30,4 +31,5 @@ If you want to skip the setup process, you have to configure group `1` The initial username and password is not checked for complexity. Make sure to set a long enough username and password. Otherwise, the user won't be able to log in. It's recommended to remove the variables after the setup is done to prevent the password from being exposed. + /// diff --git a/docs/content/advanced/metrics/prometheus.md b/docs/content/advanced/metrics/prometheus.md index 09ad087b..1af384d2 100644 --- a/docs/content/advanced/metrics/prometheus.md +++ b/docs/content/advanced/metrics/prometheus.md @@ -39,4 +39,5 @@ You can use the following Grafana dashboard to visualize the metrics: The Grafana dashboard is not official and is not maintained by the `wg-easy` team. If you have any issues with the dashboard, please contact the author of the dashboard. See [#1299](https://github.com/wg-easy/wg-easy/pull/1299) for more information. + /// diff --git a/docs/content/contributing/issues-and-pull-requests.md b/docs/content/contributing/issues-and-pull-requests.md index 92f36016..a58a4c31 100644 --- a/docs/content/contributing/issues-and-pull-requests.md +++ b/docs/content/contributing/issues-and-pull-requests.md @@ -9,6 +9,7 @@ This project is Open Source. That means that you can contribute on enhancements, /// note | Attention **Before opening an issue**, read the [`README`][github-file-readme] carefully, study the docs for your version (maybe [latest][docs-latest]) and your search engine you trust. The issue tracker is not meant to be used for unrelated questions! + /// When opening an issue, please provide details use case to let the community reproduce your problem. @@ -16,6 +17,7 @@ When opening an issue, please provide details use case to let the community repr /// note | Attention **Use the issue templates** to provide the necessary information. Issues which do not use these templates are not worked on and closed. + /// By raising issues, I agree to these terms and I understand, that the rules set for the issue tracker will help both maintainers as well as everyone to find a solution. @@ -39,6 +41,7 @@ When an option is marked with "not officially supported" / "unsupported", then s /// question | Motivation You want to add a feature? Feel free to start creating an issue explaining what you want to do and how you're thinking doing it. Other users may have the same need and collaboration may lead to better results. + /// ### Submit a Pull-Request diff --git a/docs/content/examples/tutorials/adguard.md b/docs/content/examples/tutorials/adguard.md index 8f357b1c..e65054ae 100644 --- a/docs/content/examples/tutorials/adguard.md +++ b/docs/content/examples/tutorials/adguard.md @@ -9,9 +9,11 @@ This tutorial is a follow-up to the official [Traefik tutorial](./traefik.md). I - A working [wg-easy](./basic-installation.md) and [Traefik](./traefik.md) setup from the previous guides. /// warning | Important: Following this guide will reset your WireGuard configuration. + The process involves re-creating the `wg-easy` container and its data, which means **all existing WireGuard clients and settings will be deleted.** You will need to create your clients again after completing this guide. + /// ## Add `adguard` configuration @@ -152,13 +154,15 @@ networks: 2. Navigate to `https://adguard.$example.com$` to begin the AdGuard Home setup. /// warning | Important: Configure AdGuard Home Admin Web Interface Port + During the initial AdGuard Home setup on the `Step 2/5` page, you **must** set the **Admin Web Interface Port** to **3000**. Do not use the default port 80, as it will not work with the Traefik configuration. After completing the setup, the AdGuard UI might appear unresponsive. This is expected. **Simply reload the page**, and the panel will display correctly. -/// > If you accidentally left it default (80), you will need to manually edit the `docker-compose.yml` file for AdGuard Home (`/etc/docker/containers/adguard/docker-compose.yml`) and change the line `traefik.http.services.adguard.loadbalancer.server.port=3000` to `traefik.http.services.adguard.loadbalancer.server.port=80`. After making this change, restart AdGuard Home by navigating to `/etc/docker/containers/adguard` and running `sudo docker compose up -d`. +/// + ## Final System Checks ### Firewall diff --git a/docs/content/examples/tutorials/caddy.md b/docs/content/examples/tutorials/caddy.md index b3bc2d95..c9373d92 100644 --- a/docs/content/examples/tutorials/caddy.md +++ b/docs/content/examples/tutorials/caddy.md @@ -5,6 +5,7 @@ title: Caddy /// note | Opinionated This guide is opinionated. If you use other conventions or folder layouts, feel free to change the commands and paths. + /// We're using [Caddy](https://caddyserver.com/) here as reverse proxy to serve `wg-easy` on [https://wg-easy.example.com](https://wg-easy.example.com) via TLS. diff --git a/docs/content/examples/tutorials/reverse-proxyless.md b/docs/content/examples/tutorials/reverse-proxyless.md index 2dfc1191..f7c968d8 100644 --- a/docs/content/examples/tutorials/reverse-proxyless.md +++ b/docs/content/examples/tutorials/reverse-proxyless.md @@ -7,6 +7,7 @@ title: No Reverse Proxy This is insecure. You should use a reverse proxy to secure the connection. Only use this method if you know what you are doing. + /// If you only allow access to the web UI from your local network, you can skip the reverse proxy setup. This is not recommended, but it is possible. diff --git a/docs/content/examples/tutorials/routed.md b/docs/content/examples/tutorials/routed.md index 3ed4070d..2afdd9c9 100644 --- a/docs/content/examples/tutorials/routed.md +++ b/docs/content/examples/tutorials/routed.md @@ -61,6 +61,7 @@ Pick an IPv4 and IPv6 subnet for your clients and add static routes on your rout /// note | 2001:db8::/32 The _documentation prefix_ `2001:db8::/32` (RFC 3849) used in this example is not meant for production use, replace it with your own ISP-assigned IPv6 prefix (GUA) or local prefix (ULA) + /// I want my WireGuard clients in `192.168.0.0/24` and `2001:db8:abc:0::/64`. diff --git a/docs/content/examples/tutorials/traefik.md b/docs/content/examples/tutorials/traefik.md index 51b9e134..1760f4f5 100644 --- a/docs/content/examples/tutorials/traefik.md +++ b/docs/content/examples/tutorials/traefik.md @@ -5,6 +5,7 @@ title: Traefik /// note | Opinionated This guide is opinionated. If you use other conventions or folder layouts, feel free to change the commands and paths. + /// ## Create docker compose project diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 406fbf90..a063cbb3 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -24,6 +24,7 @@ There are a few requirements for a suitable host system: On the host, you need to have a suitable container runtime (like _Docker_ or _Podman_) installed. We assume [_Docker Compose_][docker-compose] is [installed][docker-compose-installation]. We have aligned file names and configuration conventions with the latest [Docker Compose specification][docker-compose-specification]. If you're using podman, make sure to read the related [documentation][docs-podman]. + /// [docker-compose]: https://docs.docker.com/compose/ @@ -69,6 +70,7 @@ When publishing a tag we follow the [Semantic Versioning][semver] specification. /// danger | Use the Correct Commands For Stopping and Starting `wg-easy` **Use `sudo docker compose up / down`, not `sudo docker compose start / stop`**. Otherwise, the container is not properly destroyed and you may experience problems during startup because of inconsistent state. + /// **That's it! It really is that easy**. diff --git a/docs/content/guides/admin.md b/docs/content/guides/admin.md index 66c765b3..5f3d0572 100644 --- a/docs/content/guides/admin.md +++ b/docs/content/guides/admin.md @@ -23,7 +23,9 @@ This feature is currently experimental. While functional, it should be thoroughl - The feature cannot be enabled if these tools are not available /// note + Most Linux distributions include iptables by default. If you're running in a minimal container environment, you may need to install the `iptables` package on the host system. + /// **Enable this feature if you want to:** diff --git a/docs/content/guides/clients.md b/docs/content/guides/clients.md index 6314adac..edb514e1 100644 --- a/docs/content/guides/clients.md +++ b/docs/content/guides/clients.md @@ -62,7 +62,9 @@ Protocol specifiers (`/tcp` or `/udp`) require a port number. The following form - **Disable for specific client**: To disable firewall filtering for a single client while keeping it enabled for others, add `0.0.0.0/0, ::/0` to allow all traffic /// note + To allow clients to reach the VPN server itself (e.g. for DNS), include the server's VPN address in the firewall allowed IPs. + /// **Use Case Examples**: diff --git a/docs/content/index.md b/docs/content/index.md index e15fd9c0..6c6c8616 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -9,6 +9,7 @@ hide: /// info | This Documentation is Versioned **Make sure** to select the correct version of this documentation! It should match the version of the image you are using. The default version corresponds to [the most recent stable release][docs-tagging]. + /// This documentation provides you not only with the basic setup and configuration of `wg-easy` but also with advanced configuration, elaborate usage scenarios, detailed examples, hints and more. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml deleted file mode 100644 index 5247b1c8..00000000 --- a/docs/mkdocs.yml +++ /dev/null @@ -1,87 +0,0 @@ -site_name: 'wg-easy' -site_description: 'The easiest way to run WireGuard VPN + Web-based Admin UI.' -site_author: 'WireGuard Easy' -copyright: > -

- © Wireguard Easy
- This project is licensed under AGPL-3.0-only.
- This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Jason A. Donenfeld, ZX2C4 or Edge Security
- "WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld -

- -repo_url: https://github.com/wg-easy/wg-easy -repo_name: wg-easy - -edit_uri: 'edit/master/docs/content' - -docs_dir: 'content/' - -site_url: https://wg-easy.github.io/wg-easy - -theme: - name: material - favicon: assets/logo/favicon.png - logo: assets/logo/logo.png - icon: - repo: fontawesome/brands/github - features: - - navigation.tabs - - navigation.top - - navigation.expand - - navigation.instant - - content.action.edit - - content.action.view - - content.code.annotate - palette: - # Light mode - - media: '(prefers-color-scheme: light)' - scheme: default - primary: grey - accent: red - toggle: - icon: material/weather-night - name: Switch to dark mode - # Dark mode - - media: '(prefers-color-scheme: dark)' - scheme: slate - primary: grey - accent: red - toggle: - icon: material/weather-sunny - name: Switch to light mode - -extra: - version: - provider: mike - -markdown_extensions: - - toc: - anchorlink: true - - abbr - - attr_list - - pymdownx.blocks.admonition: - types: - - danger - - note - - info - - question - - warning - - pymdownx.details - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - - pymdownx.tabbed: - alternate_style: true - slugify: !!python/object/apply:pymdownx.slugs.slugify - kwds: - case: lower - - pymdownx.tasklist: - custom_checkbox: true - - pymdownx.magiclink - - pymdownx.inlinehilite - - pymdownx.tilde - - pymdownx.emoji: - emoji_index: !!python/name:material.extensions.emoji.twemoji - emoji_generator: !!python/name:material.extensions.emoji.to_svg diff --git a/docs/requirements.txt b/docs/requirements.txt index e0aaf166..5640c9b8 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,2 @@ -mkdocs-material -pillow -cairosvg -mike +zensical==0.0.45 +git+https://github.com/squidfunk/mike.git diff --git a/docs/zensical.toml b/docs/zensical.toml new file mode 100644 index 00000000..98a3a977 --- /dev/null +++ b/docs/zensical.toml @@ -0,0 +1,97 @@ +[project] +site_name = "wg-easy" +site_description = "The easiest way to run WireGuard VPN + Web-based Admin UI." +site_author = "WireGuard Easy" +copyright = """ +

Wireguard Easy
+This project is licensed under AGPL-3.0-only.
+This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Jason A. Donenfeld, ZX2C4 or Edge Security
+"WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld +

+""" + +repo_url = "https://github.com/wg-easy/wg-easy" +repo_name = "wg-easy" + +edit_uri = "edit/master/docs/content" + +docs_dir = "content/" + +site_url = "https://wg-easy.github.io/wg-easy" + +[project.theme] +variant = "modern" +favicon = "assets/logo/favicon.png" +logo = "assets/logo/logo.png" +features = [ + "navigation.instant", + "navigation.tabs", + "navigation.expand", + "navigation.path", + "navigation.top", + "content.action.edit", + "content.action.view", + "content.code.copy", + "content.code.annotate", +] + +[project.theme.icon] +repo = "fontawesome/brands/github" + +# Palette toggle for automatic mode +[[project.theme.palette]] +media = "(prefers-color-scheme)" +toggle.icon = "lucide/sun-moon" +toggle.name = "Switch to light mode" + +# Palette toggle for light mode +[[project.theme.palette]] +media = "(prefers-color-scheme: light)" +scheme = "default" +primary = "grey" +accent = "red" +toggle.icon = "lucide/sun" +toggle.name = "Switch to dark mode" + +# Palette toggle for dark mode +[[project.theme.palette]] +media = "(prefers-color-scheme: dark)" +scheme = "slate" +primary = "grey" +accent = "red" +toggle.icon = "lucide/moon" +toggle.name = "Switch to system preference" + +# [project.plugins.privacy] + +[project.extra.version] +provider = "mike" + +[project.markdown_extensions.pymdownx.blocks.admonition] +types = ["danger", "note", "info", "question", "warning"] + +[project.markdown_extensions.md_in_html] + +[project.markdown_extensions.toc] +permalink = true + +[project.markdown_extensions.pymdownx.details] + +[project.markdown_extensions.pymdownx.emoji] +emoji_generator = "zensical.extensions.emoji.to_svg" +emoji_index = "zensical.extensions.emoji.twemoji" + +[project.markdown_extensions.pymdownx.highlight] +anchor_linenums = true +line_spans = "__span" +pygments_lang_class = true + +[project.markdown_extensions.pymdownx.inlinehilite] + +[project.markdown_extensions.pymdownx.smartsymbols] + +[project.markdown_extensions.pymdownx.superfences] +custom_fences = [ + { name = "mermaid", class = "mermaid", format = "pymdownx.superfences.fence_code_format" }, +] diff --git a/package.json b/package.json index d95f8df9..a3690fda 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dev": "docker compose -f docker-compose.dev.yml up wg-easy --build", "cli:dev": "docker compose -f docker-compose.dev.yml run --build --rm -it wg-easy cli:dev", "build": "docker build -t wg-easy .", - "docs:preview": "docker run --rm -it -p 8080:8080 -v ./docs:/docs squidfunk/mkdocs-material serve -a 0.0.0.0:8080", + "docs:preview": "docker run --rm -it -p 8080:8080 -v ./docs:/docs zensical/zensical serve -a 0.0.0.0:8080", "scripts:version": "bash scripts/version.sh", "scripts:i18n": "bash scripts/i18n.sh", "format:check:docs": "prettier --check docs" From 30498520d2bee692879b6ca952e71fd62a03a050 Mon Sep 17 00:00:00 2001 From: Bernd Storath Date: Tue, 16 Jun 2026 13:12:40 +0200 Subject: [PATCH 08/34] retry docker push step --- .github/workflows/deploy-development.yml | 10 ++++++++-- .github/workflows/deploy-edge.yml | 10 ++++++++-- .github/workflows/deploy.yml | 10 ++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-development.yml b/.github/workflows/deploy-development.yml index 9d549148..988f8c8e 100644 --- a/.github/workflows/deploy-development.yml +++ b/.github/workflows/deploy-development.yml @@ -123,8 +123,14 @@ jobs: - name: Create manifest list and push working-directory: ${{ runner.temp }}/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf 'ghcr.io/wg-easy/wg-easy@sha256:%s ' *) + n=3 + for i in $(seq 1 $n); do + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'ghcr.io/wg-easy/wg-easy@sha256:%s ' *) && break + + [ "$i" = "$n" ] && exit 1 + sleep 10 + done - name: Inspect image run: | diff --git a/.github/workflows/deploy-edge.yml b/.github/workflows/deploy-edge.yml index 4e46b92a..75e402e1 100644 --- a/.github/workflows/deploy-edge.yml +++ b/.github/workflows/deploy-edge.yml @@ -132,8 +132,14 @@ jobs: - name: Create manifest list and push working-directory: ${{ runner.temp }}/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf 'ghcr.io/wg-easy/wg-easy@sha256:%s ' *) + n=3 + for i in $(seq 1 $n); do + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'ghcr.io/wg-easy/wg-easy@sha256:%s ' *) && break + + [ "$i" = "$n" ] && exit 1 + sleep 10 + done - name: Inspect image run: | diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f45b5589..4bf028ca 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -135,8 +135,14 @@ jobs: - name: Create manifest list and push working-directory: ${{ runner.temp }}/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf 'ghcr.io/wg-easy/wg-easy@sha256:%s ' *) + n=3 + for i in $(seq 1 $n); do + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf 'ghcr.io/wg-easy/wg-easy@sha256:%s ' *) && break + + [ "$i" = "$n" ] && exit 1 + sleep 10 + done - name: Inspect image run: | From 5f54fa3e580be736ea219d76603074e91c0d17cc Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Tue, 16 Jun 2026 14:12:00 +0200 Subject: [PATCH 09/34] improve totp security (#2668) improve security --- src/server/api/me/totp.post.ts | 14 ++++++++++++++ src/server/database/repositories/user/service.ts | 4 ++++ src/server/database/repositories/user/types.ts | 3 +++ 3 files changed, 21 insertions(+) diff --git a/src/server/api/me/totp.post.ts b/src/server/api/me/totp.post.ts index 53c87f8a..f3782828 100644 --- a/src/server/api/me/totp.post.ts +++ b/src/server/api/me/totp.post.ts @@ -23,6 +23,13 @@ export default definePermissionEventHandler( checkPermissions(user); if (body.type === 'setup') { + if (user.totpVerified) { + throw createError({ + statusCode: 409, + statusMessage: 'TOTP is already enabled', + }); + } + const key = new Secret({ size: 20 }); const totp = new TOTP({ @@ -50,6 +57,13 @@ export default definePermissionEventHandler( type: 'created', } as Response; } else if (body.type === 'delete') { + if (!user.totpVerified) { + throw createError({ + statusCode: 409, + statusMessage: 'TOTP is not enabled', + }); + } + await Database.users.deleteTotpKey(user.id, body.currentPassword); return { diff --git a/src/server/database/repositories/user/service.ts b/src/server/database/repositories/user/service.ts index e3526315..b84ed365 100644 --- a/src/server/database/repositories/user/service.ts +++ b/src/server/database/repositories/user/service.ts @@ -221,6 +221,10 @@ export class UserService { throw new Error('User not found'); } + if (txUser.totpVerified) { + throw new Error('TOTP is already verified'); + } + const totpKey = txUser.totpKey; if (!totpKey) { throw new Error('TOTP key is not set'); diff --git a/src/server/database/repositories/user/types.ts b/src/server/database/repositories/user/types.ts index bb5a7290..9a175a6a 100644 --- a/src/server/database/repositories/user/types.ts +++ b/src/server/database/repositories/user/types.ts @@ -18,7 +18,10 @@ const remember = z.boolean({ message: t('zod.user.remember') }); const totpCode = z .string({ message: t('zod.user.totpCode') }) + // min and max to improve error messages .min(6, t('zod.user.totpCode')) + .max(6, t('zod.user.totpCode')) + .regex(/^\d{6}$/, t('zod.user.totpCode')) .pipe(safeStringRefine); export const UserLoginSchema = z.object({ From 032347648d0a3167d08707da64098610b2143b59 Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:00:25 +0200 Subject: [PATCH 10/34] improve security against injection (#2669) * improve security against injection * fix shell injection through ipv4, ipv6 address Co-authored-by: 7megaumka7 <116706490+7megaumka7@users.noreply.github.com> --------- Co-authored-by: 7megaumka7 <116706490+7megaumka7@users.noreply.github.com> --- src/i18n/locales/en.json | 4 +- src/server/api/auth/verify-2fa.post.ts | 6 +-- .../database/repositories/client/types.ts | 14 +++++-- .../database/repositories/general/types.ts | 1 + .../database/repositories/user/types.ts | 7 +++- src/server/utils/types.ts | 38 +++++++++++++++++-- 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 6a863f7d..a8f3da02 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -204,7 +204,9 @@ "validBoolean": "{0} must be a valid boolean", "validArray": "{0} must be a valid array", "stringMin": "{0} must be at least {1} Character", - "numberMin": "{0} must be at least {1}" + "stringMax": "{0} must be at most {1} Character", + "numberMin": "{0} must be at least {1}", + "numberMax": "{0} must be at most {1}" }, "client": { "id": "Client ID", diff --git a/src/server/api/auth/verify-2fa.post.ts b/src/server/api/auth/verify-2fa.post.ts index 2fa19d86..51bbc718 100644 --- a/src/server/api/auth/verify-2fa.post.ts +++ b/src/server/api/auth/verify-2fa.post.ts @@ -1,8 +1,4 @@ -import { z } from 'zod'; - -const Verify2faSchema = z.object({ - totpCode: z.string().min(6).max(6), -}); +import { Verify2faSchema } from '#db/repositories/user/types'; export default defineEventHandler(async (event) => { const { totpCode } = await readValidatedBody( diff --git a/src/server/database/repositories/client/types.ts b/src/server/database/repositories/client/types.ts index b0aa7fa3..cffd694d 100644 --- a/src/server/database/repositories/client/types.ts +++ b/src/server/database/repositories/client/types.ts @@ -1,6 +1,7 @@ import type { InferSelectModel } from 'drizzle-orm'; import z from 'zod'; +import { isIPv4, isIPv6 } from 'is-ip'; import type { client } from './schema'; export type ClientType = InferSelectModel; @@ -20,7 +21,8 @@ export type UpdateClientType = Omit< const name = z .string({ message: t('zod.client.name') }) .min(1, t('zod.client.name')) - .pipe(safeStringRefine); + .pipe(safeStringRefine) + .pipe(controlStringRefine); // TODO?: validate iso string const expiresAt = z @@ -32,14 +34,18 @@ const expiresAt = z const address4 = z .string({ message: t('zod.client.address4') }) .min(1, { message: t('zod.client.address4') }) - .pipe(safeStringRefine); + .pipe(safeStringRefine) + .pipe(controlStringRefine) + .refine((v) => isIPv4(v)); const address6 = z .string({ message: t('zod.client.address6') }) .min(1, { message: t('zod.client.address6') }) - .pipe(safeStringRefine); + .pipe(safeStringRefine) + .pipe(controlStringRefine) + .refine((v) => isIPv6(v)); -const filter = z.string().optional(); +const filter = z.string().pipe(safeStringRefine).optional(); const serverAllowedIps = z.array(AddressSchema, { message: t('zod.client.serverAllowedIps'), diff --git a/src/server/database/repositories/general/types.ts b/src/server/database/repositories/general/types.ts index e16bc4c6..3097f645 100644 --- a/src/server/database/repositories/general/types.ts +++ b/src/server/database/repositories/general/types.ts @@ -11,6 +11,7 @@ const metricsEnabled = z.boolean({ message: t('zod.general.metricsEnabled') }); const metricsPassword = z .string({ message: t('zod.general.metricsPassword') }) .min(1, { message: t('zod.general.metricsPassword') }) + .pipe(safeStringRefine) .nullable(); export const GeneralUpdateSchema = z.object({ diff --git a/src/server/database/repositories/user/types.ts b/src/server/database/repositories/user/types.ts index 9a175a6a..043d560b 100644 --- a/src/server/database/repositories/user/types.ts +++ b/src/server/database/repositories/user/types.ts @@ -46,9 +46,8 @@ const name = z .pipe(safeStringRefine); const email = z - .string({ message: t('zod.user.email') }) - .min(5, t('zod.user.email')) .email({ message: t('zod.user.emailInvalid') }) + .min(5, t('zod.user.email')) .pipe(safeStringRefine) .nullable(); @@ -80,3 +79,7 @@ export const UserUpdateTotpSchema = z.union([ currentPassword: password, }), ]); + +export const Verify2faSchema = z.object({ + totpCode: totpCode, +}); diff --git a/src/server/utils/types.ts b/src/server/utils/types.ts index 526b69b9..b18bf2f0 100644 --- a/src/server/utils/types.ts +++ b/src/server/utils/types.ts @@ -1,4 +1,4 @@ -import type { ZodSchema } from 'zod'; +import type { ZodType } from 'zod'; import z from 'zod'; import type { H3Event, EventHandlerRequest } from 'h3'; import { isIP } from 'is-ip'; @@ -20,6 +20,15 @@ export const safeStringRefine = z { message: t('zod.stringMalformed') } ); +function hasControlChars(str: string) { + // eslint-disable-next-line no-control-regex + return /[\x00-\x1F\x7F]/.test(str); +} + +export const controlStringRefine = z + .string() + .refine((v) => !hasControlChars(v), { message: t('zod.stringMalformed') }); + export const EnabledSchema = z.boolean({ message: t('zod.enabled') }); export const MtuSchema = z @@ -70,7 +79,11 @@ export const HSchema = z }) .nullable(); -export const ISchema = z.string().nullable(); +export const ISchema = z + .string() + .pipe(safeStringRefine) + .pipe(controlStringRefine) + .nullable(); export const PortSchema = z .number({ message: t('zod.port') }) @@ -85,7 +98,8 @@ export const PersistentKeepaliveSchema = z export const AddressSchema = z .string({ message: t('zod.address') }) .min(1, { message: t('zod.address') }) - .pipe(safeStringRefine); + .pipe(safeStringRefine) + .pipe(controlStringRefine); export const DnsSchema = z.array(AddressSchema, { message: t('zod.dns') }); @@ -168,7 +182,7 @@ export const schemaForType = }; export function validateZod( - schema: ZodSchema, + schema: ZodType, event: H3Event ) { return async (data: unknown) => { @@ -203,6 +217,22 @@ export function validateZod( break; } break; + case 'too_big': + switch (v.origin) { + case 'string': + newMessage = t('zod.generic.stringMax', [ + t(v.message), + v.maximum, + ]); + break; + case 'number': + newMessage = t('zod.generic.numberMax', [ + t(v.message), + v.maximum, + ]); + break; + } + break; case 'invalid_type': { if (v.input === null || v.input === undefined) { newMessage = t('zod.generic.required', [ From e7ea65a898781b2bb29c36e5832cbd39ae2a3ebc Mon Sep 17 00:00:00 2001 From: Bernd Storath <32197462+kaaax0815@users.noreply.github.com> Date: Thu, 18 Jun 2026 11:14:20 +0200 Subject: [PATCH 11/34] various improvements (#2671) * improve oauth config logic * expire pending login * move sort to backend --- src/app/components/Clients/Sort.vue | 4 +- src/app/pages/login/2fa.vue | 8 + src/app/stores/clients.ts | 24 ++- src/app/stores/global.ts | 2 +- src/i18n/locales/en.json | 3 +- .../api/auth/[provider]/callback.get.ts | 2 + src/server/api/auth/cancel.post.ts | 4 +- src/server/api/auth/password.post.ts | 2 + src/server/api/auth/pending.get.ts | 10 ++ src/server/api/auth/verify-2fa.post.ts | 7 + src/server/api/client/index.get.ts | 6 +- .../database/repositories/client/service.ts | 151 ++++++++---------- .../database/repositories/client/types.ts | 10 +- src/server/utils/WireGuard.ts | 19 +-- src/server/utils/config.ts | 2 +- src/server/utils/oauth.ts | 34 ++-- src/server/utils/session.ts | 3 +- 17 files changed, 144 insertions(+), 147 deletions(-) diff --git a/src/app/components/Clients/Sort.vue b/src/app/components/Clients/Sort.vue index e6db6db4..bbc8e057 100644 --- a/src/app/components/Clients/Sort.vue +++ b/src/app/components/Clients/Sort.vue @@ -1,6 +1,6 @@