From 1fd58e0a5a86c178ff0c2fe2537f9f96858e8684 Mon Sep 17 00:00:00 2001 From: Truman Gao <106889354+tdgao@users.noreply.github.com> Date: Sat, 2 May 2026 20:28:42 -0600 Subject: [PATCH 01/89] docs: update contribution pages (#5608) * docs: update contribution pages * adjust pull request titles * update pull request description * remove codenames for modrinth website and app --- README.md | 6 +- .../src/content/docs/contributing/daedalus.md | 11 +++ .../src/content/docs/contributing/docs.md | 2 +- .../docs/contributing/getting-started.md | 69 ++++++++++++++----- .../src/content/docs/contributing/knossos.md | 33 ++++----- .../src/content/docs/contributing/labrinth.md | 4 +- .../src/content/docs/contributing/minotaur.md | 2 + .../src/content/docs/contributing/theseus.md | 36 ++++++---- 8 files changed, 108 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 74def556e..f7c3730a7 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,10 @@ If you're not a developer and you've stumbled upon this repository, you can acce ## Development -This repository contains two primary packages. For detailed development information, please refer to their respective READMEs: +This repository contains two primary packages. For detailed development information, please refer to their respective guides: -- [Web Interface](apps/frontend/README.md) -- [Desktop App](apps/app/README.md) +- [Website frontend](https://docs.modrinth.com/contributing/knossos/) +- [Desktop app](https://docs.modrinth.com/contributing/theseus/) ## Contributing diff --git a/apps/docs/src/content/docs/contributing/daedalus.md b/apps/docs/src/content/docs/contributing/daedalus.md index 87aa4179d..ea68831ac 100644 --- a/apps/docs/src/content/docs/contributing/daedalus.md +++ b/apps/docs/src/content/docs/contributing/daedalus.md @@ -1,4 +1,15 @@ --- title: Daedalus (Metadata service) description: Guide for contributing to Modrinth's frontend +sidebar: + order: 5 --- + +Daedalus is a powerful tool which queries and generates metadata for the Minecraft (and other games in the future!) game +and mod loaders for: + +- Performance (Serving static files can be easily cached and is extremely quick) +- Ease for Launcher Devs (Metadata is served in an easy to query and use format) +- Reliability (Provides a versioning system which ensures no breakage with updates) + +Daedalus supports the original Minecraft data and reposting for the Forge, Fabric, Quilt, and NeoForge loaders. diff --git a/apps/docs/src/content/docs/contributing/docs.md b/apps/docs/src/content/docs/contributing/docs.md index fd0500ef9..09f238be0 100644 --- a/apps/docs/src/content/docs/contributing/docs.md +++ b/apps/docs/src/content/docs/contributing/docs.md @@ -17,7 +17,7 @@ pnpm run docs:dev When ready, you will have a hot-reloading environment of the docs site running on port 4321. -#### Ready to open a PR? +## Ready to open a PR? While there is no linting requirement on Docs, we do ask that you quickly check your writing before contributing. diff --git a/apps/docs/src/content/docs/contributing/getting-started.md b/apps/docs/src/content/docs/contributing/getting-started.md index 28bec6a4f..f8dea7881 100644 --- a/apps/docs/src/content/docs/contributing/getting-started.md +++ b/apps/docs/src/content/docs/contributing/getting-started.md @@ -9,23 +9,7 @@ sidebar: Every public-facing aspect of Modrinth, including everything from our [API/backend][labrinth] and [frontend][knossos] to our [Gradle plugin][minotaur] and [launcher][theseus], is released under free and open source licenses on [GitHub]. As such, we love contributions from community members! Before proceeding to do so, though, there are a number of things you'll want to keep in mind throughout the process, as well as some details specific to certain projects. -## Things to keep in mind - -### Consult people on Discord - -There are a number of reasons to want to consult with people on our [Discord] before making a pull request. For example, if you're not sure whether something is a good idea or not, if you're not sure how to implement something, or if you can't get something working, these would all be good opportunities to create a thread in the `#development` forum channel. - -If you intend to work on new features, to make significant codebase changes, or to make UI/design changes, please open a discussion thread first to ensure your work is put to its best use. - -### Don't get discouraged - -At times, pull requests may be rejected or left unmerged for a variation of reasons. Don't take it personally, and don't get discouraged! Sometimes a contribution just isn't the right fit for the time, or it might have just been lost in the mess of other things to do. Remember, the core Modrinth team are often busy, whether it be on a specific project/task or on external factors such as offline responsibilities. It all falls back to the same thing: don't get discouraged! - -### Code isn't the only way to contribute - -You don't need to know how to program to contribute to Modrinth. Quality assurance, supporting the community, coming up with feature ideas, and making sure your voice is heard in public decisions are all great ways to contribute to Modrinth. If you find bugs, reporting them on the appropriate issue tracker is your responsibility; however, remember that potential security breaches and exploits must instead be reported in accordance with our [security policy](https://modrinth.com/legal/security). - -## Project-specific details +## Development If you wish to contribute code to a specific project, here's the place to start. Most of Modrinth is written in the [Rust language](https://www.rust-lang.org), but some things are written in other languages/frameworks like [Nuxt.js](https://nuxtjs.org) or Java. @@ -33,8 +17,8 @@ Most of Modrinth's code is in our monorepo, which you can find [here](https://gi Follow the project-specific instructions below to get started: -- [Knossos (frontend)](/contributing/knossos) -- [Theseus (Modrinth App)](/contributing/theseus) +- [Modrinth Website](/contributing/knossos) +- [Modrinth App](/contributing/theseus) - [Minotaur (Gradle plugin)](/contributing/minotaur) - [Labrinth (API/backend)](/contributing/labrinth) - [Daedalus (Metadata service)](/contributing/daedalus) @@ -49,3 +33,50 @@ Follow the project-specific instructions below to get started: [docs]: https://github.com/modrinth/code/tree/main/apps/docs [Rust]: https://www.rust-lang.org/tools/install [pnpm]: https://pnpm.io + +## Contribution guidelines + +These guidelines apply to all Modrinth projects. Following them will help your contributions get reviewed and merged smoothly. + +### Keep pull requests small and focused + +We strongly encourage small, focused pull requests over large, sweeping changes. Bug fixes, QOL improvements, and other incremental contributions are much easier to review and more likely to be merged quickly. If you're looking for something to work on, check out the [GitHub issues](https://github.com/modrinth/code/issues) tab for open tasks and known bugs. + +### Pull request descriptions + +Every PR should include a clear description of what it does. Briefly explain what was added, updated, or fixed, and provide any relevant context for reviewers. If your PR fixes or relates to an existing issue, reference the issue number in the description (e.g., `Fixes #1234`) as this helps maintain traceability and automatically closes issues when the PR is merged. + +### Pull request titles + +Make sure the title starts with a semantic prefix: + +- **feat**: A new feature +- **fix**: A bug fix +- **devex**: Improves developer experience +- **refactor**: A code change that neither fixes a bug nor adds a feature +- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +- **docs**: Documentation only changes +- **chore**: Other changes that don't modify src or test files +- **revert**: Reverts a previous commit +- **perf**: A code change that improves performance +- **test**: Adding missing tests or correcting existing tests +- **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) +- **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) + +## Things to keep in mind + +Here are some tips and reminders to help you in your contribution. + +### Consult people on Discord + +There are a number of reasons to want to consult with people on our [Discord] before making a pull request. For example, if you're not sure whether something is a good idea or not, if you're not sure how to implement something, or if you can't get something working, these would all be good opportunities to create a thread in the `#development` forum channel. + +If you intend to work on new features, to make significant codebase changes, or to make UI/design changes, please open a discussion thread first to ensure your work is put to its best use. + +### Don't get discouraged + +At times, pull requests may be rejected or left unmerged for a variation of reasons. Don't take it personally, and don't get discouraged! Sometimes a contribution just isn't the right fit for the time, or it might have just been lost in the mess of other things to do. Remember, the core Modrinth team are often busy, whether it be on a specific project/task or on external factors such as offline responsibilities. It all falls back to the same thing: don't get discouraged! + +### Code isn't the only way to contribute + +You don't need to know how to program to contribute to Modrinth. Quality assurance, supporting the community, coming up with feature ideas, and making sure your voice is heard in public decisions are all great ways to contribute to Modrinth. If you find bugs, reporting them on the appropriate issue tracker is your responsibility; however, remember that potential security breaches and exploits must instead be reported in accordance with our [security policy](https://modrinth.com/legal/security). diff --git a/apps/docs/src/content/docs/contributing/knossos.md b/apps/docs/src/content/docs/contributing/knossos.md index ed166164b..efe79b9f5 100644 --- a/apps/docs/src/content/docs/contributing/knossos.md +++ b/apps/docs/src/content/docs/contributing/knossos.md @@ -1,35 +1,32 @@ --- -title: Knossos (Frontend) +title: Modrinth Website description: Guide for contributing to Modrinth's frontend +sidebar: + order: 2 --- -This project is part of our [monorepo](https://github.com/modrinth/code). You can find it in the `apps/frontend` directory. +The [Modrinth Website], codename Knossos, is a Nuxt.js frontend. You will need to install [pnpm] and run the standard commands: -[knossos] is the Nuxt.js frontend. You will need to install [pnpm] and run the standard commands: +## Setup -```bash -pnpm install -pnpm run web:dev -``` +### 1. Install prerequisites -Once that's done, you'll be serving knossos on `localhost:3000` with hot reloading. You can replace the `dev` in `pnpm run dev` with `build` to build for a production server and `start` to start the server. You can also use `pnpm run lint` to find any eslint problems, and `pnpm run fix` to try automatically fixing those problems. +- Install the package manager [pnpm](https://pnpm.io/) -
-.env variables & command line options +### 2. Install dependencies & set up .env -#### Basic configuration +- Clone [`https://github.com/modrinth/code`](https://github.com/modrinth/code) and run `pnpm install` in the workspace root folder. +- In `apps/frontend` you should be able to see `.env.prod`, `.env.staging` — for basic work, it's recommended to use `.env.prod`. Copy the relevant file into a new `.env` file within the `apps/frontend` folder. -`SITE_URL`: The URL of the site (used for auth redirects). Default: `http://localhost:3000` -`BASE_URL`: The base URL for the API. Default: `https://staging-api.modrinth.com/v2/` -`BROWSER_BASE_URL`: The base URL for the API used in the browser. Default: `https://staging-api.modrinth.com/v2/` +### 3. Run the frontend -
+- Run `pnpm web:dev` in the workspace root folder. Once that's done, you'll be serving the website on `localhost:3000` with hot reloading. -#### Ready to open a PR? +## Ready to open a PR? If you're prepared to contribute by submitting a pull request, ensure you have met the following criteria: -- `pnpm run fix` has been run. +- `pnpm prepr:frontend` has been run. -[knossos]: https://github.com/modrinth/code/tree/main/apps/frontend +[Modrinth website]: https://github.com/modrinth/code/tree/main/apps/frontend [pnpm]: https://pnpm.io diff --git a/apps/docs/src/content/docs/contributing/labrinth.md b/apps/docs/src/content/docs/contributing/labrinth.md index 9fd1626ce..9d48a89fa 100644 --- a/apps/docs/src/content/docs/contributing/labrinth.md +++ b/apps/docs/src/content/docs/contributing/labrinth.md @@ -1,6 +1,8 @@ --- title: Labrinth (API) description: Guide for contributing to Modrinth's backend +sidebar: + order: 4 --- This project is part of our [monorepo](https://github.com/modrinth/code). You can find it in the `apps/labrinth` directory. The instructions below assume that you have switched your working directory to the `apps/labrinth` subdirectory. @@ -89,7 +91,7 @@ The OAuth configuration options are fairly self-explanatory. For help setting up -#### Ready to open a PR? +## Ready to open a PR? If you're prepared to contribute by submitting a pull request, ensure you have met the following criteria: diff --git a/apps/docs/src/content/docs/contributing/minotaur.md b/apps/docs/src/content/docs/contributing/minotaur.md index 130ca6879..f2c87eee9 100644 --- a/apps/docs/src/content/docs/contributing/minotaur.md +++ b/apps/docs/src/content/docs/contributing/minotaur.md @@ -1,6 +1,8 @@ --- title: Minotaur (Gradle plugin) description: Guide for contributing to Modrinth's gradle plugin +sidebar: + order: 5 --- [Minotaur][minotaur] is the Gradle plugin used to automatically publish artifacts to Modrinth. To run your copy of the plugin in a project, publish it to your local Maven with `./gradlew publishToMavenLocal` and add `mavenLocal()` to your buildscript. diff --git a/apps/docs/src/content/docs/contributing/theseus.md b/apps/docs/src/content/docs/contributing/theseus.md index 1138f04a4..090f58aaa 100644 --- a/apps/docs/src/content/docs/contributing/theseus.md +++ b/apps/docs/src/content/docs/contributing/theseus.md @@ -1,22 +1,32 @@ --- -title: Theseus (Modrinth App) +title: Modrinth App description: Guide for contributing to Modrinth's desktop app +sidebar: + order: 3 --- -This project is part of our [monorepo](https://github.com/modrinth/code). You can find it in the `apps/app` directory. +The [Modrinth App], codename Theseus, is the Tauri-based launcher that lets users conveniently play any mod or modpack on Modrinth. It uses the Rust-based Tauri as the backend and Vue.js as the frontend. -[theseus] is the Tauri-based launcher that lets users conveniently play any mod or modpack on Modrinth. It uses the Rust-based Tauri as the backend and Vue.js as the frontend. To get started, install [pnpm], [Rust], and the [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) for your system. Then, run the following commands: +## Setup -```bash -pnpm install -pnpm run app:dev -``` +### 1. Install prerequisites -Once the commands finish, you'll be viewing a Tauri window with Nuxt.js hot reloading. +- [pnpm](https://pnpm.io/) +- [Rust](https://www.rust-lang.org/tools/install) +- [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) -You can use `pnpm run lint` to find any eslint problems, and `pnpm run fix` to try automatically fixing those problems. +### 2. Install dependencies & set up .env -### Theseus Architecture +- Clone [`https://github.com/modrinth/code`](https://github.com/modrinth/code) and run `pnpm install` in the workspace root folder. +- In `packages/app-lib` you should be able to see `.env.prod`, `.env.staging` — for basic app work, it's recommended to use `.env.prod`. Copy the relevant file into a new `.env` file within the `packages/app-lib` folder. + +### 3. Run the app + +- Run `pnpm app:dev` in the workspace root folder. +- If you encounter an "Unable to initialise GTK" error on Linux, try running `pnpm run dev` within the `apps/app` folder rather than the workspace root command. If this doesn't work, use a VM with Windows and repeat these steps. +- If you get issues with being unable to find a display, and you're running the dev env inside a container (e.g. an Arch dev container on a non-Arch host), run `xhost +local:` to allow it to bind to an X11/Xwayland socket. + +## Theseus Architecture Theseus is split up into three parts: @@ -30,15 +40,15 @@ When running SQLX commands, be sure to set the `DATABASE_URL` environment variab You can edit the app's data directory using the `THESEUS_CONFIG_DIR` environment variable. -#### Ready to open a PR? +## Ready to open a PR? If you're prepared to contribute by submitting a pull request, ensure you have met the following criteria: -- Run `pnpm run fix` to address any fixable issues automatically. +- Run `pnpm prepr:frontend` to address any fixable issues automatically. - Run `cargo fmt` to format Rust-related code. - Run `cargo clippy` to validate Rust-related code. - Run `cargo sqlx prepare --package theseus` if you've changed any SQL code to validate statements. -[theseus]: https://github.com/modrinth/code/tree/main/apps/app +[Modrinth App]: https://github.com/modrinth/code/tree/main/apps/app [Rust]: https://www.rust-lang.org/tools/install [pnpm]: https://pnpm.io From 9015ff09711482afab942697572a8b98f57ab10d Mon Sep 17 00:00:00 2001 From: Green Date: Sun, 3 May 2026 10:46:31 +0200 Subject: [PATCH 02/89] Add git.gay as a common source domain (#5968) * Add git.gay as a common source domain Signed-off-by: Green * prepr --------- Signed-off-by: Green Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com> --- packages/moderation/src/data/nags/links.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/moderation/src/data/nags/links.ts b/packages/moderation/src/data/nags/links.ts index cf57b9a78..abdc95fa2 100644 --- a/packages/moderation/src/data/nags/links.ts +++ b/packages/moderation/src/data/nags/links.ts @@ -3,7 +3,15 @@ import { defineMessage, useVIntl } from '@modrinth/ui' import type { Nag, NagContext } from '../../types/nags' export const commonLinkDomains = { - source: ['github.com', 'gitlab.com', 'bitbucket.org', 'codeberg.org', 'git.sr.ht', 'tangled.org'], + source: [ + 'github.com', + 'gitlab.com', + 'bitbucket.org', + 'codeberg.org', + 'git.sr.ht', + 'tangled.org', + 'git.gay', + ], issues: [ 'github.com', 'gitlab.com', @@ -11,6 +19,7 @@ export const commonLinkDomains = { 'codeberg.org', 'docs.google.com', 'tangled.org', + 'git.gay', ], discord: ['discord.gg', 'discord.com', 'dsc.gg'], licenseBlocklist: [ From 5b59e39a8af3a0da4dcc6da9f247d7f9a4cc7d97 Mon Sep 17 00:00:00 2001 From: "Michael H." Date: Sun, 3 May 2026 14:18:31 +0200 Subject: [PATCH 03/89] chore: improve actions performance and security practices (#5970) * chore: bump actions and pin versions * build: switch to blacksmith * fix: use rust-toolchain stable * build: improve pnpm store caching * chore: remove emoji from workflows * fix: run prepare job on blacksmith * chore: kebab case id * build: add concurrency groups to limit duplicate jobs * build: switch around node setup and pnpm setup task * chore: bump to nodejs 24, fix pnpm caching * fix: enable corepack * fix: concurrency deadlock in frontend preview * fix: approve build scripts * fix: just don't cancel concurrent previews * build: remove pnpm setup action everywhere * build: cache apt packages * build: yet another attempt at fixing concurrency * build: lower runner type for frontend deploy * fix: eslint not existing * build: add sccache to turbo-ci * fix: correct nextest pkg * fix: turbo ignoring sccache * revert me: test labrinth tests * Revert "revert me: test labrinth tests" This reverts commit def5cc19183d5c0fe3b6f3c03635d73bb59bd312. * build: compile app before docker build * build: lower runner types * build: remove docker inline caching * build: try mold on labrinth * build: tweak labrinth prod build profile * fix: app windows builds and caching * fix: tombi format cargo.toml * fix: swap ping test to cubecraft to avoid CI flakiness * typos fix --------- Co-authored-by: aecsocket --- .github/workflows/changelog-comment.yml | 4 +- .github/workflows/check-generic.yml | 8 +- .github/workflows/check-rust.yml | 6 +- .github/workflows/daedalus-docker.yml | 84 ++- .github/workflows/daedalus-run.yml | 4 +- .github/workflows/frontend-deploy.yml | 35 +- .github/workflows/frontend-preview.yml | 39 +- .github/workflows/i18n-pull.yml | 8 +- .github/workflows/i18n-push.yml | 4 +- .github/workflows/labrinth-docker.yml | 89 ++- .github/workflows/prepare-pnpm-cache.yml | 40 ++ .github/workflows/theseus-build.yml | 71 +- .github/workflows/theseus-release.yml | 25 +- .github/workflows/turbo-ci.yml | 106 ++- .npmrc | 9 + .nvmrc | 2 +- Cargo.toml | 3 +- .../src/components/ui/ErrorModal.vue | 2 +- apps/daedalus_client/Dockerfile | 16 +- apps/frontend/package.json | 2 +- apps/labrinth/Dockerfile | 21 +- apps/labrinth/src/queue/server_ping.rs | 6 +- package.json | 128 ++-- packages/app-lib/src/state/dirs.rs | 6 +- packages/assets/package.json | 2 +- packages/tooling-config/package.json | 13 +- pnpm-lock.yaml | 606 ++++++++++++++---- pnpm-workspace.yaml | 1 + turbo.jsonc | 18 + 29 files changed, 976 insertions(+), 382 deletions(-) create mode 100644 .github/workflows/prepare-pnpm-cache.yml diff --git a/.github/workflows/changelog-comment.yml b/.github/workflows/changelog-comment.yml index b68e72c86..79937c7a3 100644 --- a/.github/workflows/changelog-comment.yml +++ b/.github/workflows/changelog-comment.yml @@ -16,8 +16,8 @@ jobs: runs-on: ubuntu-latest steps: - - name: 💬 Post or update changelog comment - uses: actions/github-script@v7 + - name: Post or update changelog comment + uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0 with: github-token: ${{ secrets.CROWDIN_GH_TOKEN }} script: | diff --git a/.github/workflows/check-generic.yml b/.github/workflows/check-generic.yml index 03e3dc649..60d389e94 100644 --- a/.github/workflows/check-generic.yml +++ b/.github/workflows/check-generic.yml @@ -12,15 +12,15 @@ jobs: typos: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.43.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: crate-ci/typos@6ac2ebd1b93eade61faf7e12688ad87a073fea59 # v1.46.0 # see tombi: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: taiki-e/install-action@v2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: taiki-e/install-action@b5fddbb5361bce8a06fb168c9d403a6cc552b084 # v2.75.29 with: tool: tombi - run: tombi lint diff --git a/.github/workflows/check-rust.yml b/.github/workflows/check-rust.yml index 97b08c255..59e678fa2 100644 --- a/.github/workflows/check-rust.yml +++ b/.github/workflows/check-rust.yml @@ -12,8 +12,8 @@ jobs: shear: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: cargo-bins/cargo-binstall@main + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable + - uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1 - run: cargo binstall --no-confirm cargo-shear - run: cargo shear diff --git a/.github/workflows/daedalus-docker.yml b/.github/workflows/daedalus-docker.yml index ad6661134..a7d131016 100644 --- a/.github/workflows/daedalus-docker.yml +++ b/.github/workflows/daedalus-docker.yml @@ -8,28 +8,79 @@ on: - .github/workflows/daedalus-docker.yml - 'apps/daedalus_client/**' - 'packages/daedalus/**' + - Cargo.toml + - Cargo.lock pull_request: types: [opened, synchronize] paths: - .github/workflows/daedalus-docker.yml - 'apps/daedalus_client/**' - 'packages/daedalus/**' + - Cargo.toml + - Cargo.lock merge_group: types: [checks_requested] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + jobs: docker: - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 + env: + SCCACHE_DIR: '/mnt/sccache' + SCCACHE_CACHE_SIZE: '10G' + SCCACHE_MULTILEVEL_CHAIN: 'disk,s3' + SCCACHE_S3_KEY_PREFIX: '${{ github.repository }}/' + SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }} + SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }} + SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }} + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} + RUSTC_WRAPPER: 'sccache' steps: - - name: 📥 Check out code - uses: actions/checkout@v4 + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: 🧰 Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0 + with: + rustflags: '' + cache: false - - name: ⚙️ Generate Docker image metadata - id: docker_meta - uses: docker/metadata-action@v5 + - name: Cache Cargo registry and index + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ~/.cargo/bin + key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Mount sccache disk cache + uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0 + with: + key: ${{ github.repository }}-daedalus-sccache + path: /mnt/sccache + + - name: Setup sccache + uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 + + - name: Build daedalus_client + run: cargo build --release --package daedalus_client + + - name: Stage Docker context + run: | + mkdir -p apps/daedalus_client/docker-stage + cp target/release/daedalus_client apps/daedalus_client/docker-stage/daedalus_client + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Generate Docker image metadata + id: docker-meta + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 env: DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index with: @@ -43,20 +94,19 @@ jobs: org.opencontainers.image.description=Modrinth game metadata query client org.opencontainers.image.licenses=MIT - - name: 🔑 Login to GitHub Packages - uses: docker/login-action@v3 + - name: Login to GitHub Packages + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: 🔨 Build and push - uses: docker/build-push-action@v6 + - name: Build and push + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: + context: ./apps/daedalus_client/docker-stage file: ./apps/daedalus_client/Dockerfile push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.docker_meta.outputs.tags }} - labels: ${{ steps.docker_meta.outputs.labels }} - annotations: ${{ steps.docker_meta.outputs.annotations }} - cache-from: type=registry,ref=ghcr.io/modrinth/daedalus:main - cache-to: type=inline + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + annotations: ${{ steps.docker-meta.outputs.annotations }} diff --git a/.github/workflows/daedalus-run.yml b/.github/workflows/daedalus-run.yml index 56fbd9f82..5060693e6 100644 --- a/.github/workflows/daedalus-run.yml +++ b/.github/workflows/daedalus-run.yml @@ -12,10 +12,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/frontend-deploy.yml b/.github/workflows/frontend-deploy.yml index cf6f8eff6..df9b93d2a 100644 --- a/.github/workflows/frontend-deploy.yml +++ b/.github/workflows/frontend-deploy.yml @@ -21,16 +21,20 @@ on: type: string description: 'The environment to deploy to (staging-preview or production-preview)' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.environment || 'push' }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + jobs: deploy: - runs-on: ubuntu-latest + runs-on: blacksmith-2vcpu-ubuntu-2404 permissions: contents: read deployments: write pull-requests: write steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -63,14 +67,25 @@ jobs: echo "url=https://modrinth.com" >> $GITHUB_OUTPUT fi - - name: Setup pnpm - uses: pnpm/action-setup@v4 - - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: .nvmrc - cache: pnpm + + - name: Enable Corepack + run: corepack enable + + - name: Get pnpm store path + id: pnpm-store + run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - name: Restore pnpm cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ${{ steps.pnpm-store.outputs.store-path }} + key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + pnpm-cache- - name: Inject build variables working-directory: ./apps/frontend @@ -99,7 +114,7 @@ jobs: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - name: Create Sentry release and upload sourcemaps - uses: getsentry/action-release@v3 + uses: getsentry/action-release@5657c9e888b4e2cc85f4d29143ea4131fde4a73a # v3.6.0 env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: modrinth @@ -111,7 +126,7 @@ jobs: - name: Deploy Cloudflare Worker id: wrangler - uses: cloudflare/wrangler-action@v3 + uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0 with: apiToken: ${{ secrets.CF_API_TOKEN }} accountId: ${{ secrets.CF_ACCOUNT_ID }} @@ -137,7 +152,7 @@ jobs: - name: Upload deployment URL if: ${{ inputs.environment != '' }} - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: deployment-url-${{ inputs.environment }} path: deployment-url-${{ inputs.environment }}.txt diff --git a/.github/workflows/frontend-preview.yml b/.github/workflows/frontend-preview.yml index d7ba1ad4b..16b3e98ed 100644 --- a/.github/workflows/frontend-preview.yml +++ b/.github/workflows/frontend-preview.yml @@ -16,6 +16,9 @@ jobs: if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository uses: ./.github/workflows/frontend-deploy.yml secrets: inherit + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.environment }} + cancel-in-progress: true strategy: matrix: environment: [staging-preview, production-preview] @@ -24,22 +27,36 @@ jobs: deploy-storybook: if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository - runs-on: ubuntu-latest + runs-on: blacksmith-2vcpu-ubuntu-2404 + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-storybook + cancel-in-progress: true permissions: contents: read deployments: write steps: - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: .nvmrc - cache: pnpm + + - name: Enable Corepack + run: corepack enable + + - name: Get pnpm store path + id: pnpm-store + run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - name: Restore pnpm cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ${{ steps.pnpm-store.outputs.store-path }} + key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + pnpm-cache- - name: Install dependencies working-directory: ./packages/ui @@ -54,7 +71,7 @@ jobs: run: echo "sha_short=${GITHUB_SHA::8}" >> $GITHUB_OUTPUT - name: Deploy Storybook preview - uses: cloudflare/wrangler-action@v3 + uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0 with: apiToken: ${{ secrets.CF_API_TOKEN }} accountId: ${{ secrets.CF_ACCOUNT_ID }} @@ -69,7 +86,7 @@ jobs: needs: [deploy, deploy-storybook] steps: - name: Download deployment URLs - uses: actions/download-artifact@v7 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: deployment-url-* merge-multiple: true @@ -89,7 +106,7 @@ jobs: - name: Find comment if: github.event_name == 'pull_request' - uses: peter-evans/find-comment@v3 + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 id: fc with: token: ${{ secrets.CROWDIN_GH_TOKEN }} @@ -98,7 +115,7 @@ jobs: - name: Comment deploy URL on PR if: github.event_name == 'pull_request' - uses: peter-evans/create-or-update-comment@v5 + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 with: token: ${{ secrets.CROWDIN_GH_TOKEN }} issue-number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/i18n-pull.yml b/.github/workflows/i18n-pull.yml index 530dec45b..4ea0e1952 100644 --- a/.github/workflows/i18n-pull.yml +++ b/.github/workflows/i18n-pull.yml @@ -51,14 +51,14 @@ jobs: CROWDIN_GH_TOKEN_DEFINED: ${{ secrets.CROWDIN_GH_TOKEN != '' }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.ref }} token: ${{ secrets.CROWDIN_GH_TOKEN }} - name: Configure Git author id: git-author - uses: MarcoIeni/git-config@v0.1 + uses: MarcoIeni/git-config@59144859caf016f8b817a2ac9b051578729173c4 # v0.1.2 env: GITHUB_TOKEN: ${{ secrets.CROWDIN_GH_TOKEN }} @@ -79,7 +79,7 @@ jobs: echo "safe_branch_name=$SAFE_BRANCH_NAME" >> "$GITHUB_OUTPUT" - name: Download translations from Crowdin - uses: crowdin/github-action@v2 + uses: crowdin/github-action@8868a33591d21088edfc398968173a3b98d51706 # v2.16.2 with: upload_sources: false upload_translations: false @@ -96,7 +96,7 @@ jobs: run: sudo chown -R $USER:$USER . - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: title: 'New translations from Crowdin (${{ steps.branch-name.outputs.branch_name }})' body-path: .github/templates/crowdin-pr.md diff --git a/.github/workflows/i18n-push.yml b/.github/workflows/i18n-push.yml index 0e34d9cfe..9a0de81d4 100644 --- a/.github/workflows/i18n-push.yml +++ b/.github/workflows/i18n-push.yml @@ -53,7 +53,7 @@ jobs: CROWDIN_PERSONAL_TOKEN_DEFINED: ${{ secrets.CROWDIN_PERSONAL_TOKEN != '' }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.ref }} @@ -68,7 +68,7 @@ jobs: echo "safe_branch_name=$SAFE_BRANCH_NAME" >> "$GITHUB_OUTPUT" - name: Upload translations to Crowdin - uses: crowdin/github-action@v1 + uses: crowdin/github-action@8868a33591d21088edfc398968173a3b98d51706 # v2.16.2 with: upload_sources: true upload_translations: false diff --git a/.github/workflows/labrinth-docker.yml b/.github/workflows/labrinth-docker.yml index 99a57f7a8..a63ee74d1 100644 --- a/.github/workflows/labrinth-docker.yml +++ b/.github/workflows/labrinth-docker.yml @@ -19,19 +19,73 @@ on: merge_group: types: [checks_requested] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + jobs: docker: - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 + env: + SQLX_OFFLINE: 'true' + GIT_HASH: ${{ github.sha }} + SCCACHE_DIR: '/mnt/sccache' + SCCACHE_CACHE_SIZE: '10G' + SCCACHE_MULTILEVEL_CHAIN: 'disk,s3' + SCCACHE_S3_KEY_PREFIX: '${{ github.repository }}/' + SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }} + SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }} + SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }} + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} + RUSTC_WRAPPER: 'sccache' steps: - - name: 📥 Check out code - uses: actions/checkout@v4 + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: 🧰 Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0 + with: + rustflags: '' + cache: false - - name: ⚙️ Generate Docker image metadata - id: docker_meta - uses: docker/metadata-action@v5 + - name: Setup mold + uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1 / Mold 2.41.0 + + - name: Cache Cargo registry and index + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ~/.cargo/bin + key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Mount sccache disk cache + uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0 + with: + key: ${{ github.repository }}-labrinth-sccache + path: /mnt/sccache + + - name: Setup sccache + uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 + + - name: Build labrinth + run: cargo build --profile release-labrinth --package labrinth + + - name: Stage Docker context + run: | + mkdir -p apps/labrinth/docker-stage + cp target/release-labrinth/labrinth apps/labrinth/docker-stage/labrinth + cp -r apps/labrinth/migrations apps/labrinth/docker-stage/migrations + cp -r apps/labrinth/assets apps/labrinth/docker-stage/assets + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Generate Docker image metadata + id: docker-meta + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 env: # GitHub Packages requires annotations metadata in at least the index descriptor to show them # up properly in its UI it seems, but it's not clear about it, because the docs refer to the @@ -49,22 +103,19 @@ jobs: org.opencontainers.image.description=Modrinth API org.opencontainers.image.licenses=AGPL-3.0-only - - name: 🔑 Login to GitHub Packages - uses: docker/login-action@v3 + - name: Login to GitHub Packages + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: 🔨 Build and push - uses: docker/build-push-action@v6 + - name: Build and push + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: + context: ./apps/labrinth/docker-stage file: ./apps/labrinth/Dockerfile push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.docker_meta.outputs.tags }} - labels: ${{ steps.docker_meta.outputs.labels }} - annotations: ${{ steps.docker_meta.outputs.annotations }} - build-args: | - GIT_HASH=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.revision'] }} - cache-from: type=registry,ref=ghcr.io/modrinth/labrinth:main - cache-to: type=inline + tags: ${{ steps.docker-meta.outputs.tags }} + labels: ${{ steps.docker-meta.outputs.labels }} + annotations: ${{ steps.docker-meta.outputs.annotations }} diff --git a/.github/workflows/prepare-pnpm-cache.yml b/.github/workflows/prepare-pnpm-cache.yml new file mode 100644 index 000000000..a7e479878 --- /dev/null +++ b/.github/workflows/prepare-pnpm-cache.yml @@ -0,0 +1,40 @@ +name: Prepare pnpm cache + +on: + push: + paths: + - .github/workflows/prepare-pnpm-cache.yml + - package.json + - pnpm-lock.yaml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + +jobs: + prepare: + runs-on: blacksmith-2vcpu-ubuntu-2404 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version-file: .nvmrc + + - name: Enable Corepack + run: corepack enable + + - name: Get pnpm store path + id: pnpm-store + run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - name: Cache pnpm + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ${{ steps.pnpm-store.outputs.store-path }} + key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }} + + - name: Install dependencies + run: pnpm recursive install --frozen-lockfile diff --git a/.github/workflows/theseus-build.yml b/.github/workflows/theseus-build.yml index 36547186e..175ce7579 100644 --- a/.github/workflows/theseus-build.yml +++ b/.github/workflows/theseus-build.yml @@ -31,45 +31,67 @@ on: default: prod required: false +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + jobs: build: name: Build env: VITE_STRIPE_PUBLISHABLE_KEY: pk_live_51JbFxJJygY5LJFfKLVVldb10HlLt24p421OWRsTOWc5sXYFOnFUXWieSc6HD3PHo25ktx8db1WcHr36XGFvZFVUz00V9ixrCs5 + # SCCACHE_DIR: '/mnt/sccache' + # SCCACHE_CACHE_SIZE: '10G' + # SCCACHE_MULTILEVEL_CHAIN: 'disk,s3' + SCCACHE_S3_KEY_PREFIX: '${{ github.repository }}/' + SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }} + SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }} + SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }} + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} + RUSTC_WRAPPER: 'sccache' strategy: fail-fast: false matrix: - platform: [macos-latest, windows-latest, ubuntu-latest] + platform: + [ + blacksmith-6vcpu-macos-26, + blacksmith-8vcpu-windows-2025, + blacksmith-8vcpu-ubuntu-2404, + ] include: - - platform: macos-latest + - platform: blacksmith-6vcpu-macos-26 artifact-target-name: universal-apple-darwin - - platform: windows-latest + - platform: blacksmith-8vcpu-windows-2025 artifact-target-name: x86_64-pc-windows-msvc - - platform: ubuntu-latest + - platform: blacksmith-8vcpu-ubuntu-2404 artifact-target-name: x86_64-unknown-linux-gnu runs-on: ${{ matrix.platform }} steps: - name: Check out code - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Setup Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0 with: rustflags: '' - target: ${{ startsWith(matrix.platform, 'macos') && 'x86_64-apple-darwin' || '' }} + target: ${{ contains(matrix.platform, 'macos') && 'x86_64-apple-darwin' || '' }} - - name: Install pnpm - uses: pnpm/action-setup@v4 + - name: Setup sccache + uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 - - name: Setup Node.js - uses: actions/setup-node@v4 + - name: Enable Corepack + run: corepack enable + + - name: Setup Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: .nvmrc - cache: pnpm + cache: 'pnpm' - name: Generate tauri-dev.conf.json shell: bash @@ -87,18 +109,19 @@ jobs: EOF - name: Install Linux build dependencies - if: startsWith(matrix.platform, 'ubuntu') - run: | - sudo apt-get update - sudo apt-get install -yq libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev + if: contains(matrix.platform, 'ubuntu') + uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 + with: + packages: libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev + version: v1 # cache key - name: Setup Dasel - uses: jaxxstorm/action-install-gh-release@v2.1.0 + uses: jaxxstorm/action-install-gh-release@25e24d2d23ae098373794ef1d6faecb48ee52da8 # v3.0.0 with: repo: TomWright/dasel tag: v2.8.1 extension-matching: disable - rename-to: ${{ startsWith(matrix.platform, 'windows') && 'dasel.exe' || 'dasel' }} + rename-to: ${{ contains(matrix.platform, 'windows') && 'dasel.exe' || 'dasel' }} chmod: 0755 - name: Set application version and environment @@ -115,13 +138,13 @@ jobs: cp "packages/app-lib/.env.${BUILD_ENVIRONMENT}" packages/app-lib/.env - name: Setup Turbo cache - uses: rharkor/caching-for-turbo@v1.8 + uses: rharkor/caching-for-turbo@56219402aacc0d06b650d898c222996dbc1191ec # v2.3.14 - name: Install dependencies run: pnpm install - name: Set up Windows code signing - if: startsWith(matrix.platform, 'windows') + if: contains(matrix.platform, 'windows') shell: bash run: | if [ '${{ startsWith(github.ref, 'refs/tags/v') || inputs.sign-windows-binaries }}' = 'true' ]; then @@ -132,7 +155,7 @@ jobs: - name: Build macOS app run: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && 'pnpm --filter=@modrinth/app run tauri build --target universal-apple-darwin --config tauri-release.conf.json' || 'pnpm --filter=@modrinth/app run tauri build --target universal-apple-darwin --config tauri-dev.conf.json' }} - if: startsWith(matrix.platform, 'macos') + if: contains(matrix.platform, 'macos') env: ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} @@ -146,7 +169,7 @@ jobs: - name: Build Linux app run: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && 'pnpm --filter=@modrinth/app run tauri build --config tauri-release.conf.json' || 'pnpm --filter=@modrinth/app run tauri build --config tauri-dev.conf.json' }} - if: startsWith(matrix.platform, 'ubuntu') + if: contains(matrix.platform, 'ubuntu') env: TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} @@ -158,7 +181,7 @@ jobs: $env:JAVA_HOME = "$env:JAVA_HOME_17_X64" ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && 'pnpm --filter=@modrinth/app run tauri build --config tauri-release.conf.json --verbose --bundles "nsis,updater"' || 'pnpm --filter=@modrinth/app run tauri build --config tauri-dev.conf.json --verbose --bundles "nsis,updater"' }} Remove-Item -Path signer-client-cert.p12 -ErrorAction SilentlyContinue - if: startsWith(matrix.platform, 'windows') + if: contains(matrix.platform, 'windows') env: TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} @@ -167,7 +190,7 @@ jobs: DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD: ${{ secrets.DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD }} - name: Upload app bundles - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: App bundle (${{ matrix.artifact-target-name }}) path: | diff --git a/.github/workflows/theseus-release.yml b/.github/workflows/theseus-release.yml index 20d6fa331..030bf7349 100644 --- a/.github/workflows/theseus-release.yml +++ b/.github/workflows/theseus-release.yml @@ -4,6 +4,10 @@ on: workflows: ['Modrinth App build'] types: [completed] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + jobs: release: name: Release Modrinth App @@ -11,8 +15,7 @@ jobs: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && startsWith(github.event.workflow_run.head_branch, 'v') - runs-on: ubuntu-latest - + runs-on: blacksmith-8vcpu-ubuntu-2404 env: VERSION_TAG: ${{ github.event.workflow_run.head_branch }} LINUX_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-unknown-linux-gnu) @@ -21,10 +24,10 @@ jobs: LAUNCHER_FILES_BUCKET_BASE_URL: https://launcher-files.modrinth.com steps: - - name: 📥 Check out code - uses: actions/checkout@v4 + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: 🔒 Verify ref is a tag + - name: Verify ref is a tag env: GH_TOKEN: ${{ github.token }} HEAD_SHA: ${{ github.event.workflow_run.head_sha }} @@ -43,8 +46,8 @@ jobs: fi echo "Verified ${VERSION_TAG} is a tag pointing at ${HEAD_SHA}" - - name: 📥 Download Modrinth App artifacts - uses: dawidd6/action-download-artifact@v11 + - name: Download Modrinth App artifacts + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 with: workflow: theseus-build.yml workflow_conclusion: success @@ -52,12 +55,12 @@ jobs: branch: ${{ env.VERSION_TAG }} use_unzip: true - - name: 📝 Extract app changelog + - name: Extract app changelog env: VERSION: ${{ env.VERSION_TAG }} run: npx --yes tsx scripts/build-theseus-release-notes.ts - - name: 🛠️ Generate version manifest + - name: Generate version manifest run: | # Reference: https://tauri.app/plugin/updater/#server-support jq -nc \ @@ -102,7 +105,7 @@ jobs: echo "Generated manifest for version ${VERSION_TAG}:" cat updates.json - - name: 📤 Upload release artifacts + - name: Upload release artifacts env: AWS_ACCESS_KEY_ID: ${{ secrets.LAUNCHER_FILES_BUCKET_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.LAUNCHER_FILES_BUCKET_SECRET_ACCESS_KEY }} @@ -137,7 +140,7 @@ jobs: aws s3 cp updates.json "s3://${AWS_BUCKET}" - - name: 🏷️ Create GitHub release + - name: Create GitHub release env: GH_TOKEN: ${{ github.token }} run: | diff --git a/.github/workflows/turbo-ci.yml b/.github/workflows/turbo-ci.yml index f416e6c09..65d0dcd2d 100644 --- a/.github/workflows/turbo-ci.yml +++ b/.github/workflows/turbo-ci.yml @@ -8,10 +8,14 @@ on: merge_group: types: [checks_requested] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }} + jobs: build: name: Lint and Test - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 env: # Ensure pnpm output is colored in GitHub Actions logs @@ -23,59 +27,103 @@ jobs: # since we don't want warnings to become errors # while developing) RUSTFLAGS: -Dwarnings + # sccache config + SCCACHE_DIR: '/mnt/sccache' + SCCACHE_CACHE_SIZE: '10G' + SCCACHE_MULTILEVEL_CHAIN: 'disk,s3' + SCCACHE_S3_KEY_PREFIX: '${{ github.repository }}/' + SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }} + SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }} + SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }} + AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} + RUSTC_WRAPPER: 'sccache' steps: - - name: 📥 Check out code - uses: actions/checkout@v4 + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 - - name: 🧰 Install build dependencies - run: | - sudo apt-get update - sudo apt-get install -yq libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev + - name: Install build dependencies + uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0 + with: + packages: libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev + version: v1 # cache key - - name: 🧰 Install pnpm - uses: pnpm/action-setup@v4 - - - name: 🧰 Setup Node.js - uses: actions/setup-node@v4 + - name: Setup Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: .nvmrc - cache: pnpm - - name: 🧰 Setup Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Enable Corepack + run: corepack enable + + - name: Get pnpm store path + id: pnpm-store + run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT + + - name: Restore pnpm cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ${{ steps.pnpm-store.outputs.store-path }} + key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + pnpm-cache- + + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0 with: rustflags: '' components: clippy, rustfmt cache: false - - name: 🧰 Setup nextest - uses: taiki-e/install-action@nextest + - name: Cache Cargo registry and index + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae #v5.0.5 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ~/.cargo/bin + key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Mount sccache disk cache + uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0 + with: + key: ${{ github.repository }}-turbo-sccache + path: /mnt/sccache + + - name: Setup sccache + uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 + + - name: Setup binstall + uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1 + + - name: Setup nextest + run: cargo binstall --no-confirm --secure cargo-nextest@0.9.133 # cargo-binstall does not have pre-built binaries for sqlx-cli, so we fall # back to a cached cargo install - - name: 🧰 Setup cargo-sqlx - uses: taiki-e/cache-cargo-install-action@v2 + - name: Setup cargo-sqlx + uses: taiki-e/cache-cargo-install-action@f9eed3e4680f27610dc6d8c67be1b88593f7dade # v3.0.6 with: - tool: sqlx-cli + tool: sqlx-cli@0.8.6 locked: false no-default-features: true features: rustls,postgres - - name: 💨 Setup Turbo cache - uses: rharkor/caching-for-turbo@v1.8 + - name: Setup Turbo cache + uses: rharkor/caching-for-turbo@56219402aacc0d06b650d898c222996dbc1191ec # v2.3.14 - - name: 🧰 Install dependencies + - name: Install dependencies run: pnpm install - - name: ⚙️ Set app environment + - name: Set app environment working-directory: packages/app-lib run: cp .env.staging .env # check if labrinth tests will actually run (cache miss) - - name: 🔍 Check if labrinth tests need to run + - name: Check if labrinth tests need to run id: check-labrinth run: | LABRINTH_TEST_STATUS=$(pnpm turbo run test --filter=@modrinth/labrinth --dry-run=json | jq -r '.tasks[] | select(.task == "test") | .cache.status') @@ -86,21 +134,21 @@ jobs: echo "needs_services=true" >> $GITHUB_OUTPUT fi - - name: ⚙️ Start services + - name: Start services if: steps.check-labrinth.outputs.needs_services == 'true' run: docker compose up --wait - - name: ⚙️ Setup labrinth environment and database + - name: Setup labrinth environment and database if: steps.check-labrinth.outputs.needs_services == 'true' working-directory: apps/labrinth run: | cp .env.local .env sqlx database setup - - name: 🔍 Lint and test + - name: Lint and test run: pnpm run ci - - name: 🔍 Verify intl:extract has been run + - name: Verify intl:extract has been run run: | pnpm turbo run intl:extract --force git diff --exit-code --color */*/src/locales/en-US/index.json diff --git a/.npmrc b/.npmrc index 19be10eb3..babcb1fd5 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,11 @@ strict-peer-dependencies=false auto-install-peers=true +public-hoist-pattern[]=prettier-plugin-* +public-hoist-pattern[]=@prettier/plugin-* +public-hoist-pattern[]=eslint +public-hoist-pattern[]=@eslint/* +public-hoist-pattern[]=eslint-plugin-* +public-hoist-pattern[]=@nuxt/eslint-config +public-hoist-pattern[]=typescript-eslint +public-hoist-pattern[]=vue-eslint-parser +public-hoist-pattern[]=globals diff --git a/.nvmrc b/.nvmrc index ba331903d..5bf4400f2 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.19.2 +24.15.0 diff --git a/Cargo.toml b/Cargo.toml index 57e076b19..af805f52e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -279,10 +279,11 @@ opt-level = "s" # Optimize for binary size strip = true # Remove debug symbols lto = true # Enables link to optimizations panic = "abort" # Strip expensive panic clean-up logic -codegen-units = 1 # Compile crates one after another so the compiler can optimize better # Specific profile for labrinth production builds [profile.release-labrinth] inherits = "release" +opt-level = 2 strip = false # Keep debug symbols for Sentry +lto = "thin" # Enable LTO but keep compile times reasonable panic = "unwind" # Don't exit the whole app on panic in production diff --git a/apps/app-frontend/src/components/ui/ErrorModal.vue b/apps/app-frontend/src/components/ui/ErrorModal.vue index 1eade7702..6ae482c77 100644 --- a/apps/app-frontend/src/components/ui/ErrorModal.vue +++ b/apps/app-frontend/src/components/ui/ErrorModal.vue @@ -61,7 +61,7 @@ defineExpose({ errorType.value = 'directory_move' supportLink.value = 'https://support.modrinth.com' - if (errorVal.message.includes('directory is not writeable')) { + if (errorVal.message.includes('directory is not writable')) { metadata.value.readOnly = true } diff --git a/apps/daedalus_client/Dockerfile b/apps/daedalus_client/Dockerfile index 4b7e98c15..64a86e051 100644 --- a/apps/daedalus_client/Dockerfile +++ b/apps/daedalus_client/Dockerfile @@ -1,19 +1,5 @@ # syntax=docker/dockerfile:1 -FROM rust:1.90.0 AS build - -WORKDIR /usr/src/daedalus -COPY . . -RUN --mount=type=cache,target=/usr/src/daedalus/target \ - --mount=type=cache,target=/usr/local/cargo,from=rust:1.89.0,source=/usr/local/cargo \ - cargo build --release --package daedalus_client - -FROM build AS artifacts - -RUN --mount=type=cache,target=/usr/src/daedalus/target \ - mkdir /daedalus \ - && cp /usr/src/daedalus/target/release/daedalus_client /daedalus/daedalus_client - FROM debian:trixie-slim LABEL org.opencontainers.image.source=https://github.com/modrinth/code @@ -25,7 +11,7 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates openssl \ && rm -rf /var/lib/apt/lists/* -COPY --from=artifacts /daedalus /daedalus +COPY daedalus_client /daedalus/daedalus_client WORKDIR /daedalus_client CMD ["/daedalus/daedalus_client"] diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 737cdc3ec..624c6c943 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -21,7 +21,7 @@ "@types/dompurify": "^3.0.5", "@types/iso-3166-2": "^1.0.4", "@types/js-yaml": "^4.0.9", - "@types/node": "^20.1.0", + "@types/node": "^24", "@types/semver": "^7.7.1", "autoprefixer": "^10.4.19", "glob": "^10.2.7", diff --git a/apps/labrinth/Dockerfile b/apps/labrinth/Dockerfile index 42e485dfc..328c4137d 100644 --- a/apps/labrinth/Dockerfile +++ b/apps/labrinth/Dockerfile @@ -1,22 +1,5 @@ # syntax=docker/dockerfile:1 -FROM rust:1.90.0 AS build - -WORKDIR /usr/src/labrinth -COPY . . -ARG GIT_HASH -RUN --mount=type=cache,target=/usr/src/labrinth/target \ - --mount=type=cache,target=/usr/local/cargo,from=rust:1.89.0,source=/usr/local/cargo \ - SQLX_OFFLINE=true cargo build --profile release-labrinth --package labrinth - -FROM build AS artifacts - -RUN --mount=type=cache,target=/usr/src/labrinth/target \ - mkdir /labrinth \ - && cp /usr/src/labrinth/target/release-labrinth/labrinth /labrinth/labrinth \ - && cp -r /usr/src/labrinth/apps/labrinth/migrations /labrinth \ - && cp -r /usr/src/labrinth/apps/labrinth/assets /labrinth - FROM debian:trixie-slim LABEL org.opencontainers.image.source=https://github.com/modrinth/code @@ -28,7 +11,9 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates dumb-init curl \ && rm -rf /var/lib/apt/lists/* -COPY --from=artifacts /labrinth /labrinth +COPY labrinth /labrinth/labrinth +COPY migrations /labrinth/migrations +COPY assets /labrinth/assets WORKDIR /labrinth ENTRYPOINT ["dumb-init", "--"] diff --git a/apps/labrinth/src/queue/server_ping.rs b/apps/labrinth/src/queue/server_ping.rs index b53708290..2698aad5e 100644 --- a/apps/labrinth/src/queue/server_ping.rs +++ b/apps/labrinth/src/queue/server_ping.rs @@ -355,12 +355,12 @@ mod tests { #[actix_rt::test] async fn test_ping_server_success() { - let _status = ping_server("mc.hypixel.net", None).await.unwrap(); + let _status = ping_server("play.cubecraft.net", None).await.unwrap(); } #[actix_rt::test] async fn test_follow_srv_record() { - _ = ping_server("hypixel.net", None).await.unwrap(); + _ = ping_server("cubecraft.net", None).await.unwrap(); } #[actix_rt::test] @@ -370,7 +370,7 @@ mod tests { #[actix_rt::test] async fn test_ping_zero_timeout() { - _ = ping_server("mc.hypixel.net", Some(Duration::ZERO)) + _ = ping_server("play.cubecraft.net", Some(Duration::ZERO)) .await .unwrap_err(); } diff --git a/package.json b/package.json index 79c1175f1..253987844 100644 --- a/package.json +++ b/package.json @@ -1,59 +1,73 @@ { - "name": "@modrinth/monorepo", - "version": "0.0.0", - "private": true, - "scripts": { - "web:dev": "turbo run dev --filter=@modrinth/frontend", - "web:build": "turbo run build --filter=@modrinth/frontend", - "app:dev": "turbo run dev --filter=@modrinth/app", - "app:build": "turbo run build --filter=@modrinth/app", - "docs:dev": "turbo run dev --filter=@modrinth/docs", - "pages:build": "NITRO_PRESET=cloudflare-pages pnpm --filter frontend run build", - "build": "turbo run build --continue", - "lint": "turbo run lint lint:ancillary --continue", - "lint:ancillary": "prettier --check .github *.*", - "test": "turbo run test --continue", - "fix": "turbo run fix fix:ancillary --continue", - "fix:ancillary": "prettier --write .github *.*", - "ci": "turbo run lint test --continue", - "prepr": "turbo run prepr --continue", - "prepr:frontend": "turbo run prepr --filter=@modrinth/frontend --filter=@modrinth/app-frontend", - "prepr:frontend:lib": "turbo run prepr --filter=@modrinth/ui --filter=@modrinth/moderation --filter=@modrinth/assets --filter=@modrinth/blog --filter=@modrinth/api-client --filter=@modrinth/utils --filter=@modrinth/tooling-config", - "prepr:frontend:web": "turbo run prepr --filter=@modrinth/frontend", - "prepr:frontend:app": "turbo run prepr --filter=@modrinth/app-frontend", - "storybook": "pnpm --filter @modrinth/ui storybook", - "build-storybook": "pnpm --filter @modrinth/ui build-storybook", - "icons:add": "pnpm --filter @modrinth/assets icons:add", - "changelog:collect": "node scripts/run.mjs collect-changelog", - "changelog:combine-for-app": "node scripts/run.mjs build-theseus-release-notes", - "scripts": "node scripts/run.mjs" - }, - "devDependencies": { - "@clack/prompts": "^1.0.0", - "@modrinth/tooling-config": "workspace:*", - "@tailwindcss/container-queries": "^0.1.1", - "@types/node": "^20.1.0", - "@vue/compiler-dom": "^3.5.26", - "@vue/compiler-sfc": "^3.5.26", - "chalk": "^5.6.2", - "if-ci": "^3.0.0", - "keep-a-changelog": "^3.0.2", - "prettier": "^3.3.2", - "turbo": "^2.5.4", - "vue": "^3.5.13", - "yaml": "^2.8.2" - }, - "packageManager": "pnpm@9.15.0", - "pnpm": { - "patchedDependencies": { - "readable-stream@2.3.8": "patches/readable-stream@2.3.8.patch" - }, - "peerDependencyRules": { - "allowedVersions": { - "vite": "8", - "esbuild": "0" - } - } - }, - "prettier": "@modrinth/tooling-config/prettier.config.cjs" + "name": "@modrinth/monorepo", + "version": "0.0.0", + "private": true, + "scripts": { + "web:dev": "turbo run dev --filter=@modrinth/frontend", + "web:build": "turbo run build --filter=@modrinth/frontend", + "app:dev": "turbo run dev --filter=@modrinth/app", + "app:build": "turbo run build --filter=@modrinth/app", + "docs:dev": "turbo run dev --filter=@modrinth/docs", + "pages:build": "NITRO_PRESET=cloudflare-pages pnpm --filter frontend run build", + "build": "turbo run build --continue", + "lint": "turbo run lint lint:ancillary --continue", + "lint:ancillary": "prettier --check .github *.*", + "test": "turbo run test --continue", + "fix": "turbo run fix fix:ancillary --continue", + "fix:ancillary": "prettier --write .github *.*", + "ci": "turbo run lint test --continue", + "prepr": "turbo run prepr --continue", + "prepr:frontend": "turbo run prepr --filter=@modrinth/frontend --filter=@modrinth/app-frontend", + "prepr:frontend:lib": "turbo run prepr --filter=@modrinth/ui --filter=@modrinth/moderation --filter=@modrinth/assets --filter=@modrinth/blog --filter=@modrinth/api-client --filter=@modrinth/utils --filter=@modrinth/tooling-config", + "prepr:frontend:web": "turbo run prepr --filter=@modrinth/frontend", + "prepr:frontend:app": "turbo run prepr --filter=@modrinth/app-frontend", + "storybook": "pnpm --filter @modrinth/ui storybook", + "build-storybook": "pnpm --filter @modrinth/ui build-storybook", + "icons:add": "pnpm --filter @modrinth/assets icons:add", + "changelog:collect": "node scripts/run.mjs collect-changelog", + "changelog:combine-for-app": "node scripts/run.mjs build-theseus-release-notes", + "scripts": "node scripts/run.mjs" + }, + "devDependencies": { + "@clack/prompts": "^1.0.0", + "@modrinth/tooling-config": "workspace:*", + "@tailwindcss/container-queries": "^0.1.1", + "@types/node": "^24", + "@vue/compiler-dom": "^3.5.26", + "@vue/compiler-sfc": "^3.5.26", + "chalk": "^5.6.2", + "if-ci": "^3.0.0", + "keep-a-changelog": "^3.0.2", + "prettier": "^3.3.2", + "turbo": "^2.5.4", + "vue": "^3.5.13", + "yaml": "^2.8.2" + }, + "packageManager": "pnpm@10.33.2", + "engines": { + "node": ">=24.15.0" + }, + "pnpm": { + "patchedDependencies": { + "readable-stream@2.3.8": "patches/readable-stream@2.3.8.patch" + }, + "peerDependencyRules": { + "allowedVersions": { + "vite": "8", + "esbuild": "0" + } + }, + "onlyBuiltDependencies": [ + "@parcel/watcher", + "@sentry/cli", + "core-js", + "esbuild", + "protobufjs", + "sharp", + "unrs-resolver", + "vue-demi", + "workerd" + ] + }, + "prettier": "@modrinth/tooling-config/prettier.config.cjs" } diff --git a/packages/app-lib/src/state/dirs.rs b/packages/app-lib/src/state/dirs.rs index 3a23da862..50f22c2db 100644 --- a/packages/app-lib/src/state/dirs.rs +++ b/packages/app-lib/src/state/dirs.rs @@ -213,7 +213,7 @@ impl DirectoryInfo { .as_ref() .map_or_else(|| app_dir.clone(), PathBuf::from); - async fn is_dir_writeable( + async fn is_dir_writable( new_config_dir: &Path, ) -> crate::Result { let temp_path = new_config_dir.join(".tmp"); @@ -259,8 +259,8 @@ impl DirectoryInfo { ) .await?; - if !is_dir_writeable(&move_dir).await? { - return Err(crate::ErrorKind::DirectoryMoveError(format!("Cannot move directory to {}: directory is not writeable", move_dir.display())).into()); + if !is_dir_writable(&move_dir).await? { + return Err(crate::ErrorKind::DirectoryMoveError(format!("Cannot move directory to {}: directory is not writable", move_dir.display())).into()); } const MOVE_DIRS: &[&str] = &[ diff --git a/packages/assets/package.json b/packages/assets/package.json index 8c5f12173..7dff68a47 100644 --- a/packages/assets/package.json +++ b/packages/assets/package.json @@ -14,7 +14,7 @@ }, "devDependencies": { "@modrinth/tooling-config": "workspace:*", - "@types/node": "^20.1.0", + "@types/node": "^24", "jiti": "^2.4.2", "lucide-static": "^0.562.0", "vue": "^3.5.13" diff --git a/packages/tooling-config/package.json b/packages/tooling-config/package.json index ddfeaf52e..81fc725cd 100644 --- a/packages/tooling-config/package.json +++ b/packages/tooling-config/package.json @@ -31,19 +31,24 @@ "prettier": "^3.6.2", "typescript": ">=5.0.0" }, - "devDependencies": { - "@eslint/js": "^9.32.0", + "dependencies": { "@prettier/plugin-xml": "^3.4.2", + "prettier-plugin-sql-cst": "^0.13.0", + "prettier-plugin-toml": "^2.0.6" + }, + "devDependencies": { + "@eslint/compat": "^1.4.1", + "@eslint/js": "^9.32.0", + "@nuxt/eslint-config": "^0.5.7", "@vue/tsconfig": "^0.7.0", "eslint": "^9.32.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.3", "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-turbo": "^2.5.4", "eslint-plugin-vue": "^10.4.0", "vue-eslint-parser": "^10.1.3", "globals": "^16.3.0", - "prettier-plugin-sql-cst": "^0.13.0", - "prettier-plugin-toml": "^2.0.6", "typescript-eslint": "^8.38.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 39c0a11b9..d314e9663 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: patchedDependencies: readable-stream@2.3.8: - hash: h52dazg37p4h3yox67pw36akse + hash: 3045f7adf989b4e668a4a13819b7285b0de186b79bbf22408acaf2a41c6eaa86 path: patches/readable-stream@2.3.8.patch importers: @@ -23,8 +23,8 @@ importers: specifier: ^0.1.1 version: 0.1.1(tailwindcss@4.1.18) '@types/node': - specifier: ^20.1.0 - version: 20.19.31 + specifier: ^24 + version: 24.12.2 '@vue/compiler-dom': specifier: ^3.5.26 version: 3.5.27 @@ -170,7 +170,7 @@ importers: devDependencies: '@eslint/compat': specifier: ^1.1.1 - version: 1.4.1(eslint@9.39.2(jiti@2.6.1)) + version: 1.4.1(eslint@9.39.2(jiti@1.21.7)) '@formatjs/cli': specifier: ^6.2.12 version: 6.12.2(@vue/compiler-core@3.5.27)(vue@3.5.27(typescript@5.9.3)) @@ -179,22 +179,22 @@ importers: version: link:../../packages/tooling-config '@nuxt/eslint-config': specifier: ^0.5.6 - version: 0.5.7(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 0.5.7(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) '@taijased/vue-render-tracker': specifier: ^1.0.7 version: 1.0.7(vue@3.5.27(typescript@5.9.3)) '@vitejs/plugin-vue': specifier: ^6.0.3 - version: 6.0.4(vite@8.0.3(@types/node@20.19.31)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + version: 6.0.4(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@1.21.7)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) autoprefixer: specifier: ^10.4.19 version: 10.4.24(postcss@8.5.6) eslint: specifier: ^9.9.1 - version: 9.39.2(jiti@2.6.1) + version: 9.39.2(jiti@1.21.7) eslint-plugin-turbo: specifier: ^2.5.4 - version: 2.8.2(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.2) + version: 2.8.2(eslint@9.39.2(jiti@1.21.7))(turbo@2.8.2) postcss: specifier: ^8.4.39 version: 8.5.6 @@ -212,7 +212,7 @@ importers: version: 5.9.3 vite: specifier: ^8.0.0 - version: 8.0.3(@types/node@20.19.31)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + version: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@1.21.7)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) vue-component-type-helpers: specifier: ^3.1.8 version: 3.2.4 @@ -235,19 +235,19 @@ importers: version: 0.9.6(prettier@3.8.1)(typescript@5.9.3) '@astrojs/starlight': specifier: ^0.32.2 - version: 0.32.6(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) + version: 0.32.6(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) '@modrinth/assets': specifier: workspace:* version: link:../../packages/assets astro: specifier: ^5.4.1 - version: 5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) + version: 5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) sharp: specifier: ^0.33.5 version: 0.33.5 starlight-openapi: specifier: ^0.14.0 - version: 0.14.4(@astrojs/markdown-remark@6.3.10)(@astrojs/starlight@0.32.6(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)))(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(openapi-types@12.1.3) + version: 0.14.4(@astrojs/markdown-remark@6.3.10)(@astrojs/starlight@0.32.6(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)))(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(openapi-types@12.1.3) typescript: specifier: ^5.8.2 version: 5.9.3 @@ -283,7 +283,7 @@ importers: version: link:../../packages/utils '@sentry/nuxt': specifier: ^10.33.0 - version: 10.38.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(pinia@3.0.4(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)))(rollup@4.57.1)(vue@3.5.27(typescript@5.9.3)) + version: 10.38.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(pinia@3.0.4(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)))(rollup@4.57.1)(vue@3.5.27(typescript@5.9.3)) '@tanstack/vue-query': specifier: ^5.90.7 version: 5.92.9(vue@3.5.27(typescript@5.9.3)) @@ -292,7 +292,7 @@ importers: version: 0.172.0 '@vitejs/plugin-vue': specifier: ^6.0.3 - version: 6.0.4(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + version: 6.0.4(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) '@vue-email/components': specifier: ^0.0.21 version: 0.0.21(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)) @@ -394,8 +394,8 @@ importers: specifier: ^4.0.9 version: 4.0.9 '@types/node': - specifier: ^20.1.0 - version: 20.19.31 + specifier: ^24 + version: 24.12.2 '@types/semver': specifier: ^7.7.1 version: 7.7.1 @@ -407,7 +407,7 @@ importers: version: 10.5.0 nuxt: specifier: ^3.20.2 - version: 3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) + version: 3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) postcss: specifier: ^8.4.39 version: 8.5.6 @@ -462,8 +462,8 @@ importers: specifier: workspace:* version: link:../tooling-config '@types/node': - specifier: ^20.1.0 - version: 20.19.31 + specifier: ^24 + version: 24.12.2 jiti: specifier: ^2.4.2 version: 2.6.1 @@ -546,19 +546,31 @@ importers: packages/tooling-config: dependencies: + '@prettier/plugin-xml': + specifier: ^3.4.2 + version: 3.4.2(prettier@3.8.1) prettier: specifier: ^3.6.2 version: 3.8.1 + prettier-plugin-sql-cst: + specifier: ^0.13.0 + version: 0.13.0 + prettier-plugin-toml: + specifier: ^2.0.6 + version: 2.0.6(prettier@3.8.1) typescript: specifier: '>=5.0.0' version: 5.9.3 devDependencies: + '@eslint/compat': + specifier: ^1.4.1 + version: 1.4.1(eslint@9.39.2(jiti@2.6.1)) '@eslint/js': specifier: ^9.32.0 version: 9.39.2 - '@prettier/plugin-xml': - specifier: ^3.4.2 - version: 3.4.2(prettier@3.8.1) + '@nuxt/eslint-config': + specifier: ^0.5.7 + version: 0.5.7(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vue/tsconfig': specifier: ^0.7.0 version: 0.7.0(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)) @@ -574,18 +586,15 @@ importers: eslint-plugin-simple-import-sort: specifier: ^12.1.1 version: 12.1.1(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-turbo: + specifier: ^2.5.4 + version: 2.8.2(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.2) eslint-plugin-vue: specifier: ^10.4.0 version: 10.7.0(@stylistic/eslint-plugin@2.13.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.2(jiti@2.6.1))) globals: specifier: ^16.3.0 version: 16.5.0 - prettier-plugin-sql-cst: - specifier: ^0.13.0 - version: 0.13.0 - prettier-plugin-toml: - specifier: ^2.0.6 - version: 2.0.6(prettier@3.8.1) typescript-eslint: specifier: ^8.38.0 version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) @@ -742,28 +751,28 @@ importers: version: 10.2.4(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/builder-vite': specifier: ^10.1.10 - version: 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) + version: 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) '@storybook/vue3-vite': specifier: ^10.1.10 - version: 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3)) + version: 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3)) '@stripe/stripe-js': specifier: ^7.3.1 version: 7.9.0 '@tailwindcss/vite': specifier: ^4.1.18 - version: 4.1.18(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) + version: 4.1.18(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) '@vitejs/plugin-vue': specifier: ^5.2.1 - version: 5.2.4(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3)) + version: 5.2.4(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3)) eslint-plugin-storybook: specifier: ^10.1.10 - version: 10.2.4(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + version: 10.2.4(eslint@9.39.2(jiti@2.6.1))(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) storybook: specifier: ^10.1.10 version: 10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) stripe: specifier: ^18.1.1 - version: 18.5.0(@types/node@20.19.31) + version: 18.5.0(@types/node@24.12.2) tailwindcss: specifier: ^3.4.4 version: 3.4.19(yaml@2.8.2) @@ -772,7 +781,7 @@ importers: version: 5.9.3 vite: specifier: ^5.4.6 - version: 5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) + version: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) vite-svg-loader: specifier: ^5.1.0 version: 5.1.0(vue@3.5.27(typescript@5.9.3)) @@ -2203,155 +2212,183 @@ packages: resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm64@1.2.4': resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.0.4': resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.0.4': resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.33.5': resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.33.5': resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.33.5': resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} @@ -2881,48 +2918,56 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@oxc-minify/binding-linux-arm64-musl@0.110.0': resolution: {integrity: sha512-53GjCVY8kvymk9P6qNDh6zyblcehF5QHstq9QgCjv13ONGRnSHjeds0PxIwiihD7h295bxsWs84DN39syLPH4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@oxc-minify/binding-linux-ppc64-gnu@0.110.0': resolution: {integrity: sha512-li8XcN81dxbJDMBESnTgGhoiAQ+CNIdM0QGscZ4duVPjCry1RpX+5FJySFbGqG3pk4s9ZzlL/vtQtbRzZIZOzg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@oxc-minify/binding-linux-riscv64-gnu@0.110.0': resolution: {integrity: sha512-SweKfsnLKShu6UFV8mwuj1d1wmlNoL/FlAxPUzwjEBgwiT2HQkY24KnjBH+TIA+//1O83kzmWKvvs4OuEhdIEQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@oxc-minify/binding-linux-riscv64-musl@0.110.0': resolution: {integrity: sha512-oH8G4aFMP8XyTsEpdANC5PQyHgSeGlopHZuW1rpyYcaErg5YaK0vXjQ4EM5HVvPm+feBV24JjxgakTnZoF3aOQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [musl] '@oxc-minify/binding-linux-s390x-gnu@0.110.0': resolution: {integrity: sha512-W9na+Vza7XVUlpf8wMt4QBfH35KeTENEmnpPUq3NSlbQHz8lSlSvhAafvo43NcKvHAXV3ckD/mUf2VkqSdbklg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@oxc-minify/binding-linux-x64-gnu@0.110.0': resolution: {integrity: sha512-XJdA4mmmXOjJxSRgNJXsDP7Xe8h3gQhmb56hUcCrvq5d+h5UcEi2pR8rxsdIrS8QmkLuBA3eHkGK8E27D7DTgQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@oxc-minify/binding-linux-x64-musl@0.110.0': resolution: {integrity: sha512-QqzvALuOTtSckI8x467R4GNArzYDb/yEh6aNzLoeaY1O7vfT7SPDwlOEcchaTznutpeS9Dy8gUS/AfqtUHaufw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@oxc-minify/binding-openharmony-arm64@0.110.0': resolution: {integrity: sha512-gAMssLs2Q3+uhLZxanh1DF+27Kaug3cf4PXb9AB7XK81DR+LVcKySXaoGYoOs20Co0fFSphd6rRzKge2qDK3dA==} @@ -3000,48 +3045,56 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@oxc-parser/binding-linux-arm64-musl@0.110.0': resolution: {integrity: sha512-5xwm1hPrGGvjCVtTWNGJ39MmQGnyipoIDShneGBgSrnDh0XX+COAO7AZKajgNipqgNq5rGEItpzFkMtSDyx0bQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@oxc-parser/binding-linux-ppc64-gnu@0.110.0': resolution: {integrity: sha512-I8Xop7z+enuvW1xe0AcRQ9XqFNkUYgeXusyGjCyW6TstRb62P90h+nL1AoGaUMy0E0518DJam5vRYVRgXaAzYg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@oxc-parser/binding-linux-riscv64-gnu@0.110.0': resolution: {integrity: sha512-XPM0jpght/AuHnweNaIo0twpId6rWFs8NrTkMijxcsRQMzNBeSQQgYm9ErrutmKQS6gb8XNAEIkYXHgPmhdDPg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@oxc-parser/binding-linux-riscv64-musl@0.110.0': resolution: {integrity: sha512-ylJIuJyMzAqR191QeCwZLEkyo4Sx817TNILjNhT0W1EDQusGicOYKSsGXM/2DHCNYGcidV+MQ8pUVzNeVmuM6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [musl] '@oxc-parser/binding-linux-s390x-gnu@0.110.0': resolution: {integrity: sha512-DL6oR0PfYor9tBX9xlAxMUVwfm6+sKTL4H+KiQ6JKP3xkJTwBIdDCgeN2AjMht1D3N40uUwVq3v8/2fqnZRgLQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@oxc-parser/binding-linux-x64-gnu@0.110.0': resolution: {integrity: sha512-+e6ws5JLpFehdK+wh6q8icx1iM3Ao+9dtItVWFcRiXxSvGcIlS9viWcMvXKrmcsyVDUf81dnvuMSBigNslxhIQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@oxc-parser/binding-linux-x64-musl@0.110.0': resolution: {integrity: sha512-6DiYhVdXKOzB01+j/tyrB6/d2o6b4XYFQvcbBRNbVHIimS6nl992y3V3mGG3NaA+uCZAzhT3M3btTdKAxE4A3A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@oxc-parser/binding-openharmony-arm64@0.110.0': resolution: {integrity: sha512-U9KEK7tXdHrXl2eZpoHYGWj31ZSvdGiaXwjkJzeRN0elt89PXi+VcryRh6BAFbEz1EQpTteyMDwDXMgJVWM85A==} @@ -3125,48 +3178,56 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@oxc-transform/binding-linux-arm64-musl@0.110.0': resolution: {integrity: sha512-e5JN94/oy+wevk76q+LMr+2klTTcO60uXa+Wkq558Ms7mdF2TvkKFI++d/JeiuIwJLTi/BxQ4qdT5FWcsHM/ug==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@oxc-transform/binding-linux-ppc64-gnu@0.110.0': resolution: {integrity: sha512-Y3/Tnnz1GvDpmv8FXBIKtdZPsdZklOEPdrL6NHrN5i2u54BOkybFaDSptgWF53wOrJlTrcmAVSE6fRKK9XCM2Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@oxc-transform/binding-linux-riscv64-gnu@0.110.0': resolution: {integrity: sha512-Y0E35iA9/v9jlkNcP6tMJ+ZFOS0rLsWDqG6rU9z+X2R3fBFJBO9UARIK6ngx8upxk81y1TFR2CmBFhupfYdH6Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@oxc-transform/binding-linux-riscv64-musl@0.110.0': resolution: {integrity: sha512-JOUSYFfHjBUs7xp2FHmZHb8eTYD/oEu0NklS6JgUauqnoXZHiTLPLVW2o2uVCqldnabYHcomuwI2iqVFYJNhTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] + libc: [musl] '@oxc-transform/binding-linux-s390x-gnu@0.110.0': resolution: {integrity: sha512-7blgoXF9D3Ngzb7eun23pNrHJpoV/TtE6LObwlZ3Nmb4oZ6Z+yMvBVaoW68NarbmvNGfZ95zrOjgm6cVETLYBA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@oxc-transform/binding-linux-x64-gnu@0.110.0': resolution: {integrity: sha512-YQ2joGWCVDZVEU2cD/r/w49hVjDm/Qu1BvC/7zs8LvprzdLS/HyMXGF2oA0puw0b+AqgYaz3bhwKB2xexHyITQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@oxc-transform/binding-linux-x64-musl@0.110.0': resolution: {integrity: sha512-fkjr5qE632ULmNgvFXWDR/8668WxERz3tU7TQFp6JebPBneColitjSkdx6VKNVXEoMmQnOvBIGeP5tUNT384oA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@oxc-transform/binding-openharmony-arm64@0.110.0': resolution: {integrity: sha512-HWH9Zj+lMrdSTqFRCZsvDWMz7OnMjbdGsm3xURXWfRZpuaz0bVvyuZNDQXc4FyyhRDsemICaJbU1bgeIpUJDGw==} @@ -3259,36 +3320,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.6': resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.6': resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.6': resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.6': resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.6': resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-wasm@2.5.6': resolution: {integrity: sha512-byAiBZ1t3tXQvc8dMD/eoyE7lTXYorhn+6uVW5AC+JGI1KtJC/LvDche5cfUE+qiefH+Ybq0bUCJU0aB1cSHUA==} @@ -3439,36 +3506,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==} @@ -3605,66 +3678,79 @@ packages: resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.57.1': resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.57.1': resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.57.1': resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.57.1': resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.57.1': resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.57.1': resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.57.1': resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.57.1': resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.57.1': resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.57.1': resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.57.1': resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.57.1': resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.57.1': resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} @@ -4072,24 +4158,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.18': resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.18': resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.18': resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.18': resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} @@ -4172,30 +4262,35 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tauri-apps/cli-linux-arm64-musl@2.5.0': resolution: {integrity: sha512-rQO1HhRUQqyEaal5dUVOQruTRda/TD36s9kv1hTxZiFuSq3558lsTjAcUEnMAtBcBkps20sbyTJNMT0AwYIk8Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tauri-apps/cli-linux-riscv64-gnu@2.5.0': resolution: {integrity: sha512-7oS18FN46yDxyw1zX/AxhLAd7T3GrLj3Ai6s8hZKd9qFVzrAn36ESL7d3G05s8wEtsJf26qjXnVF4qleS3dYsA==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] + libc: [glibc] '@tauri-apps/cli-linux-x64-gnu@2.5.0': resolution: {integrity: sha512-SG5sFNL7VMmDBdIg3nO3EzNRT306HsiEQ0N90ILe3ZABYAVoPDO/ttpCO37ApLInTzrq/DLN+gOlC/mgZvLw1w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tauri-apps/cli-linux-x64-musl@2.5.0': resolution: {integrity: sha512-QXDM8zp/6v05PNWju5ELsVwF0VH1n6b5pk2E6W/jFbbiwz80Vs1lACl9pv5kEHkrxBj+aWU/03JzGuIj2g3SkQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tauri-apps/cli-win32-arm64-msvc@2.5.0': resolution: {integrity: sha512-pFSHFK6b+o9y4Un8w0gGLwVyFTZaC3P0kQ7umRt/BLDkzD5RnQ4vBM7CF8BCU5nkwmEBUCZd7Wt3TWZxe41o6Q==} @@ -4359,8 +4454,8 @@ packages: '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - '@types/node@20.19.31': - resolution: {integrity: sha512-5jsi0wpncvTD33Sh1UCgacK37FFwDn+EG7wCmEvs62fCvBL+n8/76cAYDok21NF6+jaVWIqKwCZyX7Vbu8eB3A==} + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -4529,41 +4624,49 @@ packages: resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -6945,48 +7048,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.32.0: resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -9172,8 +9283,8 @@ packages: unctx@2.5.0: resolution: {integrity: sha512-p+Rz9x0R7X+CYDkT+Xg8/GhpcShTlU8n+cf9OtOEf7zEQsNcCZO1dPKNRDqvUTaq+P32PMMkxWHwfrxkqfqAYg==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} undici@7.18.2: resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==} @@ -10146,12 +10257,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.3.13(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))': + '@astrojs/mdx@4.3.13(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))': dependencies: '@astrojs/markdown-remark': 6.3.10 '@mdx-js/mdx': 3.1.1 acorn: 8.15.0 - astro: 5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) + astro: 5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) es-module-lexer: 1.7.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -10175,16 +10286,16 @@ snapshots: stream-replace-string: 2.0.0 zod: 3.25.76 - '@astrojs/starlight@0.32.6(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))': + '@astrojs/starlight@0.32.6(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))': dependencies: - '@astrojs/mdx': 4.3.13(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) + '@astrojs/mdx': 4.3.13(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) '@astrojs/sitemap': 3.7.0 '@pagefind/default-ui': 1.4.0 '@types/hast': 3.0.4 '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 - astro: 5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) - astro-expressive-code: 0.40.2(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) + astro: 5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) + astro-expressive-code: 0.40.2(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) bcp-47: 2.1.0 hast-util-from-html: 2.0.3 hast-util-select: 6.0.4 @@ -11002,6 +11113,12 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} + '@eslint/compat@1.4.1(eslint@9.39.2(jiti@1.21.7))': + dependencies: + '@eslint/core': 0.17.0 + optionalDependencies: + eslint: 9.39.2(jiti@1.21.7) + '@eslint/compat@1.4.1(eslint@9.39.2(jiti@2.6.1))': dependencies: '@eslint/core': 0.17.0 @@ -11567,11 +11684,11 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@3.1.1(magicast@0.5.1)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))': + '@nuxt/devtools-kit@3.1.1(magicast@0.5.1)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))': dependencies: '@nuxt/kit': 4.3.0(magicast@0.5.1) execa: 8.0.1 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) transitivePeerDependencies: - magicast @@ -11586,12 +11703,12 @@ snapshots: prompts: 2.4.2 semver: 7.7.3 - '@nuxt/devtools@3.1.1(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': + '@nuxt/devtools@3.1.1(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@nuxt/devtools-kit': 3.1.1(magicast@0.5.1)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + '@nuxt/devtools-kit': 3.1.1(magicast@0.5.1)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) '@nuxt/devtools-wizard': 3.1.1 '@nuxt/kit': 4.3.0(magicast@0.5.1) - '@vue/devtools-core': 8.0.5(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + '@vue/devtools-core': 8.0.5(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) '@vue/devtools-kit': 8.0.5 birpc: 2.9.0 consola: 3.4.2 @@ -11616,9 +11733,9 @@ snapshots: sirv: 3.0.2 structured-clone-es: 1.0.0 tinyglobby: 0.2.15 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vite-plugin-inspect: 11.3.3(@nuxt/kit@4.3.0(magicast@0.5.1))(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) - vite-plugin-vue-tracer: 1.2.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite-plugin-inspect: 11.3.3(@nuxt/kit@4.3.0(magicast@0.5.1))(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + vite-plugin-vue-tracer: 1.2.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) which: 5.0.0 ws: 8.19.0 transitivePeerDependencies: @@ -11627,6 +11744,31 @@ snapshots: - utf-8-validate - vue + '@nuxt/eslint-config@0.5.7(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint/js': 9.39.2 + '@nuxt/eslint-plugin': 0.5.7(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@stylistic/eslint-plugin': 2.13.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + eslint-config-flat-gitignore: 0.3.0(eslint@9.39.2(jiti@1.21.7)) + eslint-flat-config-utils: 0.4.0 + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-jsdoc: 50.8.0(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-regexp: 2.10.0(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-unicorn: 55.0.0(eslint@9.39.2(jiti@1.21.7)) + eslint-plugin-vue: 9.33.0(eslint@9.39.2(jiti@1.21.7)) + globals: 15.15.0 + local-pkg: 0.5.1 + pathe: 1.1.2 + vue-eslint-parser: 9.4.3(eslint@9.39.2(jiti@1.21.7)) + transitivePeerDependencies: + - '@typescript-eslint/utils' + - eslint-import-resolver-node + - supports-color + - typescript + '@nuxt/eslint-config@0.5.7(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint/js': 9.39.2 @@ -11652,6 +11794,15 @@ snapshots: - supports-color - typescript + '@nuxt/eslint-plugin@0.5.7(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + transitivePeerDependencies: + - supports-color + - typescript + '@nuxt/eslint-plugin@0.5.7(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.54.0 @@ -11712,7 +11863,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/nitro-server@3.21.0(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(rolldown@1.0.0-rc.12)(typescript@5.9.3)(xml2js@0.6.2)': + '@nuxt/nitro-server@3.21.0(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(rolldown@1.0.0-rc.12)(typescript@5.9.3)(xml2js@0.6.2)': dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/kit': 3.21.0(magicast@0.5.1) @@ -11730,7 +11881,7 @@ snapshots: klona: 2.0.6 mocked-exports: 0.1.1 nitropack: 2.13.1(rolldown@1.0.0-rc.12)(xml2js@0.6.2) - nuxt: 3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) + nuxt: 3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) ohash: 2.0.11 pathe: 2.0.3 pkg-types: 2.3.0 @@ -11802,12 +11953,12 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/vite-builder@3.21.0(@types/node@20.19.31)(eslint@9.39.2(jiti@2.6.1))(lightningcss@1.32.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.27(typescript@5.9.3))(yaml@2.8.2)': + '@nuxt/vite-builder@3.21.0(@types/node@24.12.2)(eslint@9.39.2(jiti@2.6.1))(lightningcss@1.32.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.27(typescript@5.9.3))(yaml@2.8.2)': dependencies: '@nuxt/kit': 3.21.0(magicast@0.5.1) '@rollup/plugin-replace': 6.0.3(rollup@4.57.1) - '@vitejs/plugin-vue': 6.0.4(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) - '@vitejs/plugin-vue-jsx': 5.1.4(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + '@vitejs/plugin-vue': 6.0.4(vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + '@vitejs/plugin-vue-jsx': 5.1.4(vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) autoprefixer: 10.4.24(postcss@8.5.6) consola: 3.4.2 cssnano: 7.1.2(postcss@8.5.6) @@ -11822,7 +11973,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.0 mocked-exports: 0.1.1 - nuxt: 3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) + nuxt: 3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) ohash: 2.0.11 pathe: 2.0.3 perfect-debounce: 2.1.0 @@ -11833,9 +11984,9 @@ snapshots: std-env: 3.10.0 ufo: 1.6.3 unenv: 2.0.0-rc.24 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vite-node: 5.3.0(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vite-plugin-checker: 0.12.0(eslint@9.39.2(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3)) + vite: 7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite-node: 5.3.0(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite-plugin-checker: 0.12.0(eslint@9.39.2(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3)) vue: 3.5.27(typescript@5.9.3) vue-bundle-renderer: 2.2.0 optionalDependencies: @@ -12917,7 +13068,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@sentry/nuxt@10.38.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(pinia@3.0.4(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)))(rollup@4.57.1)(vue@3.5.27(typescript@5.9.3))': + '@sentry/nuxt@10.38.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.211.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.5.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.39.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(pinia@3.0.4(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)))(rollup@4.57.1)(vue@3.5.27(typescript@5.9.3))': dependencies: '@nuxt/kit': 3.21.0(magicast@0.5.1) '@sentry/browser': 10.38.0 @@ -12928,7 +13079,7 @@ snapshots: '@sentry/rollup-plugin': 4.9.0(rollup@4.57.1) '@sentry/vite-plugin': 4.9.0 '@sentry/vue': 10.38.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3)) - nuxt: 3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) + nuxt: 3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2) transitivePeerDependencies: - '@cloudflare/workers-types' - '@opentelemetry/api' @@ -13073,25 +13224,25 @@ snapshots: storybook: 10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - '@storybook/builder-vite@10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))': + '@storybook/builder-vite@10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))': dependencies: - '@storybook/csf-plugin': 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) + '@storybook/csf-plugin': 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) storybook: 10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - vite: 5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) transitivePeerDependencies: - esbuild - rollup - webpack - '@storybook/csf-plugin@10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))': + '@storybook/csf-plugin@10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))': dependencies: storybook: 10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.3 rollup: 4.57.1 - vite: 5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) '@storybook/global@5.0.0': {} @@ -13100,14 +13251,14 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/vue3-vite@10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3))': + '@storybook/vue3-vite@10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3))': dependencies: - '@storybook/builder-vite': 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) + '@storybook/builder-vite': 10.2.4(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)) '@storybook/vue3': 10.2.4(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vue@3.5.27(typescript@5.9.3)) magic-string: 0.30.21 storybook: 10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) typescript: 5.9.3 - vite: 5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) vue-component-meta: 2.2.12(typescript@5.9.3) vue-docgen-api: 4.79.2(vue@3.5.27(typescript@5.9.3)) transitivePeerDependencies: @@ -13126,6 +13277,18 @@ snapshots: '@stripe/stripe-js@7.9.0': {} + '@stylistic/eslint-plugin@2.13.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + estraverse: 5.3.0 + picomatch: 4.0.3 + transitivePeerDependencies: + - supports-color + - typescript + '@stylistic/eslint-plugin@2.13.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) @@ -13226,12 +13389,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - '@tailwindcss/vite@4.1.18(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))': + '@tailwindcss/vite@4.1.18(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) '@tanstack/match-sorter-utils@8.19.4': dependencies: @@ -13409,7 +13572,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 '@types/debug@4.1.12': dependencies: @@ -13464,7 +13627,7 @@ snapshots: '@types/mysql@2.15.27': dependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 '@types/nlcst@2.0.3': dependencies: @@ -13472,9 +13635,9 @@ snapshots: '@types/node@17.0.45': {} - '@types/node@20.19.31': + '@types/node@24.12.2': dependencies: - undici-types: 6.21.0 + undici-types: 7.16.0 '@types/normalize-package-data@2.4.4': {} @@ -13490,7 +13653,7 @@ snapshots: '@types/pg@8.15.6': dependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 pg-protocol: 1.11.0 pg-types: 2.2.0 @@ -13500,7 +13663,7 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 '@types/semver@7.7.1': {} @@ -13508,7 +13671,7 @@ snapshots: '@types/tedious@4.0.14': dependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 '@types/three@0.172.0': dependencies: @@ -13536,7 +13699,23 @@ snapshots: '@types/xml2js@0.4.14': dependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 + + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 + eslint: 9.39.2(jiti@1.21.7) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: @@ -13554,6 +13733,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.54.0 @@ -13584,6 +13775,18 @@ snapshots: dependencies: typescript: 5.9.3 + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.54.0 @@ -13731,33 +13934,39 @@ snapshots: '@formatjs/intl': 2.10.15(typescript@5.9.3) intl-messageformat: 10.7.18 - '@vitejs/plugin-vue-jsx@5.1.4(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue-jsx@5.1.4(vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@rolldown/pluginutils': 1.0.0-rc.2 '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0) - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) vue: 3.5.27(typescript@5.9.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0))(vue@3.5.27(typescript@5.9.3))': dependencies: - vite: 5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0) vue: 3.5.27(typescript@5.9.3) - '@vitejs/plugin-vue@6.0.4(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.4(vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.2 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) vue: 3.5.27(typescript@5.9.3) - '@vitejs/plugin-vue@6.0.4(vite@8.0.3(@types/node@20.19.31)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.4(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@1.21.7)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.2 - vite: 8.0.3(@types/node@20.19.31)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@1.21.7)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vue: 3.5.27(typescript@5.9.3) + + '@vitejs/plugin-vue@6.0.4(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.2 + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) vue: 3.5.27(typescript@5.9.3) '@vitest/expect@3.2.4': @@ -14047,14 +14256,14 @@ snapshots: dependencies: '@vue/devtools-kit': 7.7.9 - '@vue/devtools-core@8.0.5(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': + '@vue/devtools-core@8.0.5(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3))': dependencies: '@vue/devtools-kit': 8.0.5 '@vue/devtools-shared': 8.0.5 mitt: 3.0.1 nanoid: 5.1.6 pathe: 2.0.3 - vite-hot-client: 2.1.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + vite-hot-client: 2.1.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) vue: 3.5.27(typescript@5.9.3) transitivePeerDependencies: - vite @@ -14361,12 +14570,12 @@ snapshots: astring@1.9.0: {} - astro-expressive-code@0.40.2(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)): + astro-expressive-code@0.40.2(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)): dependencies: - astro: 5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) + astro: 5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) rehype-expressive-code: 0.40.2 - astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2): + astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: '@astrojs/compiler': 2.13.0 '@astrojs/internal-helpers': 0.7.5 @@ -14423,8 +14632,8 @@ snapshots: unist-util-visit: 5.1.0 unstorage: 1.17.4(db0@0.3.4)(ioredis@5.9.2) vfile: 6.0.3 - vite: 6.4.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vitefu: 1.1.1(vite@6.4.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + vite: 6.4.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vitefu: 1.1.1(vite@6.4.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.3 @@ -15283,6 +15492,12 @@ snapshots: escape-string-regexp@5.0.0: {} + eslint-config-flat-gitignore@0.3.0(eslint@9.39.2(jiti@1.21.7)): + dependencies: + '@eslint/compat': 1.4.1(eslint@9.39.2(jiti@1.21.7)) + eslint: 9.39.2(jiti@1.21.7) + find-up-simple: 1.0.1 + eslint-config-flat-gitignore@0.3.0(eslint@9.39.2(jiti@2.6.1)): dependencies: '@eslint/compat': 1.4.1(eslint@9.39.2(jiti@2.6.1)) @@ -15304,6 +15519,23 @@ snapshots: optionalDependencies: unrs-resolver: 1.11.1 + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7)): + dependencies: + '@typescript-eslint/types': 8.54.0 + comment-parser: 1.4.5 + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + is-glob: 4.0.3 + minimatch: 10.1.2 + semver: 7.7.3 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 + optionalDependencies: + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): dependencies: '@typescript-eslint/types': 8.54.0 @@ -15321,6 +15553,22 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-jsdoc@50.8.0(eslint@9.39.2(jiti@1.21.7)): + dependencies: + '@es-joy/jsdoccomment': 0.50.2 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint: 9.39.2(jiti@1.21.7) + espree: 10.4.0 + esquery: 1.7.0 + parse-imports-exports: 0.2.4 + semver: 7.7.3 + spdx-expression-parse: 4.0.0 + transitivePeerDependencies: + - supports-color + eslint-plugin-jsdoc@50.8.0(eslint@9.39.2(jiti@2.6.1)): dependencies: '@es-joy/jsdoccomment': 0.50.2 @@ -15346,6 +15594,17 @@ snapshots: optionalDependencies: eslint-config-prettier: 10.1.8(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-regexp@2.10.0(eslint@9.39.2(jiti@1.21.7)): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7)) + '@eslint-community/regexpp': 4.12.2 + comment-parser: 1.4.5 + eslint: 9.39.2(jiti@1.21.7) + jsdoc-type-pratt-parser: 4.8.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 + eslint-plugin-regexp@2.10.0(eslint@9.39.2(jiti@2.6.1)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) @@ -15361,21 +15620,47 @@ snapshots: dependencies: eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-storybook@10.2.4(eslint@9.39.2(jiti@1.21.7))(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): + eslint-plugin-storybook@10.2.4(eslint@9.39.2(jiti@2.6.1))(storybook@10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) - eslint: 9.39.2(jiti@1.21.7) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) storybook: 10.2.4(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) transitivePeerDependencies: - supports-color - typescript + eslint-plugin-turbo@2.8.2(eslint@9.39.2(jiti@1.21.7))(turbo@2.8.2): + dependencies: + dotenv: 16.0.3 + eslint: 9.39.2(jiti@1.21.7) + turbo: 2.8.2 + eslint-plugin-turbo@2.8.2(eslint@9.39.2(jiti@2.6.1))(turbo@2.8.2): dependencies: dotenv: 16.0.3 eslint: 9.39.2(jiti@2.6.1) turbo: 2.8.2 + eslint-plugin-unicorn@55.0.0(eslint@9.39.2(jiti@1.21.7)): + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7)) + ci-info: 4.4.0 + clean-regexp: 1.0.0 + core-js-compat: 3.48.0 + eslint: 9.39.2(jiti@1.21.7) + esquery: 1.7.0 + globals: 15.15.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.1.0 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.7.3 + strip-indent: 3.0.0 + eslint-plugin-unicorn@55.0.0(eslint@9.39.2(jiti@2.6.1)): dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -15410,6 +15695,20 @@ snapshots: '@stylistic/eslint-plugin': 2.13.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint-plugin-vue@9.33.0(eslint@9.39.2(jiti@1.21.7)): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@1.21.7)) + eslint: 9.39.2(jiti@1.21.7) + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.7.3 + vue-eslint-parser: 9.4.3(eslint@9.39.2(jiti@1.21.7)) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + eslint-plugin-vue@9.33.0(eslint@9.39.2(jiti@2.6.1)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) @@ -16449,7 +16748,7 @@ snapshots: dependencies: lie: 3.3.0 pako: 1.0.11 - readable-stream: 2.3.8(patch_hash=h52dazg37p4h3yox67pw36akse) + readable-stream: 2.3.8(patch_hash=3045f7adf989b4e668a4a13819b7285b0de186b79bbf22408acaf2a41c6eaa86) setimmediate: 1.0.5 keep-a-changelog@3.0.2: @@ -16478,7 +16777,7 @@ snapshots: lazystream@1.0.1: dependencies: - readable-stream: 2.3.8(patch_hash=h52dazg37p4h3yox67pw36akse) + readable-stream: 2.3.8(patch_hash=3045f7adf989b4e668a4a13819b7285b0de186b79bbf22408acaf2a41c6eaa86) leac@0.6.0: {} @@ -17503,16 +17802,16 @@ snapshots: dependencies: boolbase: 1.0.0 - nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2): + nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2): dependencies: '@dxup/nuxt': 0.3.2(magicast@0.5.1) '@nuxt/cli': 3.32.0(cac@6.7.14)(magicast@0.5.1) - '@nuxt/devtools': 3.1.1(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) + '@nuxt/devtools': 3.1.1(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)) '@nuxt/kit': 3.21.0(magicast@0.5.1) - '@nuxt/nitro-server': 3.21.0(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(rolldown@1.0.0-rc.12)(typescript@5.9.3)(xml2js@0.6.2) + '@nuxt/nitro-server': 3.21.0(db0@0.3.4)(ioredis@5.9.2)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(rolldown@1.0.0-rc.12)(typescript@5.9.3)(xml2js@0.6.2) '@nuxt/schema': 3.21.0 '@nuxt/telemetry': 2.6.6(magicast@0.5.1) - '@nuxt/vite-builder': 3.21.0(@types/node@20.19.31)(eslint@9.39.2(jiti@2.6.1))(lightningcss@1.32.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@20.19.31)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.27(typescript@5.9.3))(yaml@2.8.2) + '@nuxt/vite-builder': 3.21.0(@types/node@24.12.2)(eslint@9.39.2(jiti@2.6.1))(lightningcss@1.32.0)(magicast@0.5.1)(nuxt@3.21.0(@parcel/watcher@2.5.6)(@types/node@24.12.2)(@vue/compiler-sfc@3.5.27)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(lightningcss@1.32.0)(magicast@0.5.1)(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3))(xml2js@0.6.2)(yaml@2.8.2))(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.27(typescript@5.9.3))(yaml@2.8.2) '@unhead/vue': 2.1.2(vue@3.5.27(typescript@5.9.3)) '@vue/shared': 3.5.27 c12: 3.3.3(magicast@0.5.1) @@ -17564,7 +17863,7 @@ snapshots: vue-router: 4.6.4(vue@3.5.27(typescript@5.9.3)) optionalDependencies: '@parcel/watcher': 2.5.6 - '@types/node': 20.19.31 + '@types/node': 24.12.2 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -18268,7 +18567,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.19.31 + '@types/node': 24.12.2 long: 5.3.2 protocols@2.0.2: {} @@ -18411,7 +18710,7 @@ snapshots: isarray: 0.0.1 string_decoder: 0.10.31 - readable-stream@2.3.8(patch_hash=h52dazg37p4h3yox67pw36akse): + readable-stream@2.3.8(patch_hash=3045f7adf989b4e668a4a13819b7285b0de186b79bbf22408acaf2a41c6eaa86): dependencies: core-util-is: 1.0.3 inherits: 2.0.4 @@ -19045,12 +19344,12 @@ snapshots: standard-as-callback@2.1.0: {} - starlight-openapi@0.14.4(@astrojs/markdown-remark@6.3.10)(@astrojs/starlight@0.32.6(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)))(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(openapi-types@12.1.3): + starlight-openapi@0.14.4(@astrojs/markdown-remark@6.3.10)(@astrojs/starlight@0.32.6(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)))(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2))(openapi-types@12.1.3): dependencies: '@astrojs/markdown-remark': 6.3.10 - '@astrojs/starlight': 0.32.6(astro@5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) + '@astrojs/starlight': 0.32.6(astro@5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2)) '@readme/openapi-parser': 2.7.0(openapi-types@12.1.3) - astro: 5.17.1(@types/node@20.19.31)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) + astro: 5.17.1(@types/node@24.12.2)(db0@0.3.4)(ioredis@5.9.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(typescript@5.9.3)(yaml@2.8.2) github-slugger: 2.0.0 url-template: 3.1.1 transitivePeerDependencies: @@ -19158,11 +19457,11 @@ snapshots: dependencies: js-tokens: 9.0.1 - stripe@18.5.0(@types/node@20.19.31): + stripe@18.5.0(@types/node@24.12.2): dependencies: qs: 6.14.1 optionalDependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 structured-clone-es@1.0.0: {} @@ -19459,7 +19758,7 @@ snapshots: magic-string: 0.30.21 unplugin: 2.3.11 - undici-types@6.21.0: {} + undici-types@7.16.0: {} undici@7.18.2: {} @@ -19704,23 +20003,23 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-dev-rpc@1.1.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): + vite-dev-rpc@1.1.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): dependencies: birpc: 2.9.0 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vite-hot-client: 2.1.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite-hot-client: 2.1.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) - vite-hot-client@2.1.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): + vite-hot-client@2.1.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): dependencies: - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vite-node@5.3.0(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + vite-node@5.3.0(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): dependencies: cac: 6.7.14 es-module-lexer: 2.0.0 obug: 2.1.1 pathe: 2.0.3 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti @@ -19734,7 +20033,7 @@ snapshots: - tsx - yaml - vite-plugin-checker@0.12.0(eslint@9.39.2(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3)): + vite-plugin-checker@0.12.0(eslint@9.39.2(jiti@2.6.1))(optionator@0.9.4)(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue-tsc@2.2.12(typescript@5.9.3)): dependencies: '@babel/code-frame': 7.29.0 chokidar: 4.0.3 @@ -19743,7 +20042,7 @@ snapshots: picomatch: 4.0.3 tiny-invariant: 1.3.3 tinyglobby: 0.2.15 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) vscode-uri: 3.1.0 optionalDependencies: eslint: 9.39.2(jiti@2.6.1) @@ -19751,7 +20050,7 @@ snapshots: typescript: 5.9.3 vue-tsc: 2.2.12(typescript@5.9.3) - vite-plugin-inspect@11.3.3(@nuxt/kit@4.3.0(magicast@0.5.1))(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): + vite-plugin-inspect@11.3.3(@nuxt/kit@4.3.0(magicast@0.5.1))(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): dependencies: ansis: 4.2.0 debug: 4.4.3 @@ -19761,21 +20060,21 @@ snapshots: perfect-debounce: 2.1.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: 7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) - vite-dev-rpc: 1.1.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite-dev-rpc: 1.1.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)) optionalDependencies: '@nuxt/kit': 4.3.0(magicast@0.5.1) transitivePeerDependencies: - supports-color - vite-plugin-vue-tracer@1.2.0(vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.3)): + vite-plugin-vue-tracer@1.2.0(vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.27(typescript@5.9.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.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) vue: 3.5.27(typescript@5.9.3) vite-svg-loader@5.1.0(vue@3.5.27(typescript@5.9.3)): @@ -19783,19 +20082,19 @@ snapshots: svgo: 3.3.2 vue: 3.5.27(typescript@5.9.3) - vite@5.4.21(@types/node@20.19.31)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0): + vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0): dependencies: esbuild: 0.21.5 postcss: 8.5.6 rollup: 4.57.1 optionalDependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 fsevents: 2.3.3 lightningcss: 1.32.0 sass: 1.97.3 terser: 5.46.0 - vite@6.4.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + vite@6.4.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -19804,7 +20103,7 @@ snapshots: rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.32.0 @@ -19812,7 +20111,7 @@ snapshots: terser: 5.46.0 yaml: 2.8.2 - vite@7.3.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + vite@7.3.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) @@ -19821,7 +20120,7 @@ snapshots: rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.32.0 @@ -19829,7 +20128,7 @@ snapshots: terser: 5.46.0 yaml: 2.8.2 - vite@8.0.3(@types/node@20.19.31)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@1.21.7)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -19837,7 +20136,23 @@ snapshots: rolldown: 1.0.0-rc.12 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.31 + '@types/node': 24.12.2 + esbuild: 0.27.3 + fsevents: 2.3.3 + jiti: 1.21.7 + sass: 1.97.3 + terser: 5.46.0 + yaml: 2.8.2 + + vite@8.0.3(@types/node@24.12.2)(esbuild@0.27.3)(jiti@2.6.1)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.8 + rolldown: 1.0.0-rc.12 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.12.2 esbuild: 0.27.3 fsevents: 2.3.3 jiti: 2.6.1 @@ -19845,9 +20160,9 @@ snapshots: terser: 5.46.0 yaml: 2.8.2 - vitefu@1.1.1(vite@6.4.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): + vitefu@1.1.1(vite@6.4.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2)): optionalDependencies: - vite: 6.4.1(@types/node@20.19.31)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.97.3)(terser@5.46.0)(yaml@2.8.2) void-elements@3.1.0: {} @@ -20005,6 +20320,19 @@ snapshots: transitivePeerDependencies: - supports-color + vue-eslint-parser@9.4.3(eslint@9.39.2(jiti@1.21.7)): + dependencies: + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + lodash: 4.17.23 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + vue-eslint-parser@9.4.3(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 4.4.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e9b0dad63..6dae7f6bb 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - 'apps/*' - 'packages/*' +minimumReleaseAge: 4320 # 3 days diff --git a/turbo.jsonc b/turbo.jsonc index 1a2365a04..9f91ff2fa 100644 --- a/turbo.jsonc +++ b/turbo.jsonc @@ -46,6 +46,12 @@ "NEXTEST_*", "BUILD_ENV", "PREVIEW" + ], + "passThroughEnv": [ + "SCCACHE_*", + "RUSTC_WRAPPER", + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY" ] }, "lint": { @@ -57,6 +63,12 @@ "RUSTFLAGS", "FORCE_COLOR", "NEXTEST_*" + ], + "passThroughEnv": [ + "SCCACHE_*", + "RUSTC_WRAPPER", + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY" ] }, "lint:ancillary": {}, @@ -76,6 +88,12 @@ "RUSTFLAGS", "FORCE_COLOR", "NEXTEST_*" + ], + "passThroughEnv": [ + "SCCACHE_*", + "RUSTC_WRAPPER", + "AWS_ACCESS_KEY_ID", + "AWS_SECRET_ACCESS_KEY" ] }, "fix": {}, From f857d19aeea6b30fb05979b9a5a6dc7162ffff2d Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 3 May 2026 14:50:23 +0200 Subject: [PATCH 04/89] feat(backend): remove server play analytics fallback (#5884) Remove server play analytics fallback --- apps/labrinth/src/routes/analytics.rs | 65 ++++++++++++--------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/apps/labrinth/src/routes/analytics.rs b/apps/labrinth/src/routes/analytics.rs index 4bd524b56..ed25ef45a 100644 --- a/apps/labrinth/src/routes/analytics.rs +++ b/apps/labrinth/src/routes/analytics.rs @@ -252,9 +252,8 @@ struct MinecraftProfile { #[derive(Deserialize)] pub struct MinecraftJavaServerPlayInput { project_id: ProjectId, - username: Option, - server_id: Option, - minecraft_uuid: Option, + username: String, + server_id: String, } pub const MINECRAFT_SERVER_PLAYS: &str = "minecraft_server_plays"; @@ -292,44 +291,36 @@ async fn minecraft_server_play_ingest( ))); } - let minecraft_uuid = if let (Some(username), Some(server_id)) = - (&play_input.username, &play_input.server_id) + let has_joined = http + .get("https://sessionserver.mojang.com/session/minecraft/hasJoined") + .query(&[ + ("username", play_input.username.as_str()), + ("serverId", play_input.server_id.as_str()), + ]) + .send() + .await + .wrap_internal_err("failed to contact Mojang session server")?; + + if has_joined.status() == reqwest::StatusCode::NO_CONTENT + || !has_joined.status().is_success() { - let has_joined = http - .get("https://sessionserver.mojang.com/session/minecraft/hasJoined") - .query(&[ - ("username", username.as_str()), - ("serverId", server_id.as_str()), - ]) - .send() - .await - .wrap_internal_err("failed to contact Mojang session server")?; + return Err(ApiError::Request(eyre!( + "Minecraft session verification failed" + ))); + } - if has_joined.status() == reqwest::StatusCode::NO_CONTENT - || !has_joined.status().is_success() - { - return Err(ApiError::Request(eyre!( - "Minecraft session verification failed" - ))); - } + let profile = has_joined + .json::() + .await + .wrap_internal_err("invalid Mojang session response")?; - let profile = has_joined - .json::() - .await - .wrap_internal_err("invalid Mojang session response")?; + if profile.name != play_input.username { + return Err(ApiError::Request(eyre!( + "returned Mojang profile name does not match username" + ))); + } - if profile.name != *username { - return Err(ApiError::Request(eyre!( - "returned Mojang profile name does not match username" - ))); - } - - profile.id - } else { - play_input - .minecraft_uuid - .wrap_request_err("missing `minecraft_uuid`")? - }; + let minecraft_uuid = profile.id; let conn_info = req.connection_info().peer_addr().map(|x| x.to_string()); let headers = req From eb9c3477ff16c9c9f3d560c78daba514325a0330 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 3 May 2026 19:27:48 +0200 Subject: [PATCH 05/89] feat(app): make app update notification not close when opening the changelog (#5978) Make app update notification not close when opening the changelog --- apps/app-frontend/src/App.vue | 2 ++ packages/ui/src/components/nav/PopupNotificationPanel.vue | 4 +++- packages/ui/src/providers/popup-notifications.ts | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index aed1666ac..dbdce711c 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -920,6 +920,7 @@ async function checkUpdates() { { label: formatMessage(updatePopupMessages.changelog), action: () => openUrl('https://modrinth.com/news/changelog?filter=app'), + keepOpen: true, }, ], }) @@ -1002,6 +1003,7 @@ async function downloadUpdate(versionToDownload) { { label: formatMessage(updatePopupMessages.changelog), action: () => openUrl('https://modrinth.com/news/changelog?filter=app'), + keepOpen: true, }, ], }) diff --git a/packages/ui/src/components/nav/PopupNotificationPanel.vue b/packages/ui/src/components/nav/PopupNotificationPanel.vue index 7f8edac90..d443f752b 100644 --- a/packages/ui/src/components/nav/PopupNotificationPanel.vue +++ b/packages/ui/src/components/nav/PopupNotificationPanel.vue @@ -130,7 +130,9 @@ const dismiss = (id: string | number) => popupNotificationManager.removeNotifica function handleButtonClick(id: string | number, btn: PopupNotificationButton) { btn.action() - popupNotificationManager.removeNotification(id) + if (!btn.keepOpen) { + popupNotificationManager.removeNotification(id) + } } function progressColorForType(type: PopupNotification['type']) { diff --git a/packages/ui/src/providers/popup-notifications.ts b/packages/ui/src/providers/popup-notifications.ts index f5f7a56c9..5cd049c1e 100644 --- a/packages/ui/src/providers/popup-notifications.ts +++ b/packages/ui/src/providers/popup-notifications.ts @@ -4,6 +4,7 @@ export interface PopupNotificationButton { label: string action: () => void color?: 'brand' | 'red' | 'orange' | 'green' | 'blue' | 'standard' + keepOpen?: boolean } export interface PopupNotificationProgressItem { From 678f8049e3f2791b10d123ffa987e40573c8e169 Mon Sep 17 00:00:00 2001 From: "Michael H." Date: Sun, 3 May 2026 20:01:56 +0200 Subject: [PATCH 06/89] fix: labrinth memory leaks (#5980) --- apps/labrinth/src/database/redis/mod.rs | 98 ++++++++++++++----------- apps/labrinth/src/util/sentry.rs | 17 +++-- 2 files changed, 63 insertions(+), 52 deletions(-) diff --git a/apps/labrinth/src/database/redis/mod.rs b/apps/labrinth/src/database/redis/mod.rs index 51e94cfb1..022da0083 100644 --- a/apps/labrinth/src/database/redis/mod.rs +++ b/apps/labrinth/src/database/redis/mod.rs @@ -26,6 +26,19 @@ pub mod util; const DEFAULT_EXPIRY: i64 = 60 * 60 * 12; // 12 hours const ACTUAL_EXPIRY: i64 = 60 * 30; // 30 minutes +// Bound how many commands we send in a single Redis pipeline. The multiplexed +// connection's BytesMut write buffer keeps its peak capacity for the life of +// the connection, so larger pipelines cause higher steady-state RSS. +const PIPELINE_CHUNK_SIZE: usize = 25; +// Bound how many keys we send in a single MGET. Each MGET response must fit +// into the connection's read buffer, which also retains its peak capacity. At +// ~1 MB per cached value, 32 keys caps any single response at ~32 MB. +const MGET_CHUNK_SIZE: usize = 32; +// How long a pooled Redis connection lives before being recycled, regardless +// of activity. Forced recycling is the only way to release the per-connection +// BytesMut peak capacity that builds up under steady load. +const REDIS_MAX_CONN_AGE: Duration = Duration::from_secs(120); + #[derive(Clone)] pub struct RedisPool { pub url: String, @@ -85,14 +98,19 @@ impl RedisPool { }); let interval = Duration::from_secs(30); - let max_age = Duration::from_secs(5 * 60); // 5 minutes + let max_idle = Duration::from_secs(5 * 60); // 5 minutes let pool_ref = pool.clone(); tokio::spawn(async move { loop { tokio::time::sleep(interval).await; - pool_ref - .pool - .retain(|_, metrics| metrics.last_used() < max_age); + pool_ref.pool.retain(|_, metrics| { + // Drop connections that have been idle too long, OR that + // are older than REDIS_MAX_CONN_AGE regardless of use. + // The age-based recycle is what releases the per-connection + // BytesMut peak capacity under steady traffic. + metrics.last_used() < max_idle + && metrics.created.elapsed() < REDIS_MAX_CONN_AGE + }); } }); @@ -303,13 +321,16 @@ impl RedisPool { }) .collect::>(); - let v = cmd("MGET") - .arg(&args) - .query_async::>>(&mut connection) - .await? - .into_iter() - .flatten() - .collect::>(); + let mut v = Vec::new(); + for chunk in args.chunks(MGET_CHUNK_SIZE) { + let part = cmd("MGET") + .arg(chunk) + .query_async::>>( + &mut connection, + ) + .await?; + v.extend(part.into_iter().flatten()); + } Ok::<_, DatabaseError>(v) } .instrument(info_span!("get slug ids")) @@ -331,19 +352,20 @@ impl RedisPool { .map(|x| format!("{}_{namespace}:{x}", self.meta_namespace)) .collect::>(); - let cached_values = cmd("MGET") - .arg(&args) - .query_async::>>(&mut connection) - .await? - .into_iter() - .filter_map(|x| { + let mut cached_values = HashMap::new(); + for chunk in args.chunks(MGET_CHUNK_SIZE) { + let part = cmd("MGET") + .arg(chunk) + .query_async::>>(&mut connection) + .await?; + cached_values.extend(part.into_iter().filter_map(|x| { x.and_then(|val| { serde_json::from_str::>(&val) .ok() }) .map(|val| (val.key.clone(), val)) - }) - .collect::>(); + })); + } Ok::<_, DatabaseError>((cached_values, ids)) } @@ -440,6 +462,8 @@ impl RedisPool { let mut return_values = HashMap::new(); let mut pipe = redis_pipe(); + let mut pipe_cmds: usize = 0; + let mut connection = self.pool.get().await?; // Doesn't need to be atomic if !vals.is_empty() { @@ -459,6 +483,7 @@ impl RedisPool { serde_json::to_string(&value)?, DEFAULT_EXPIRY as u64, ); + pipe_cmds += 1; if let Some(slug) = slug { ids.remove(&slug.to_string()); @@ -478,46 +503,31 @@ impl RedisPool { key.to_string(), DEFAULT_EXPIRY as u64, ); - - /* - if let Some(_sentinel) = - cache_writers.remove(&actual_slug) - { - // drop it - } - */ + pipe_cmds += 1; } } let key_str = key.to_string(); ids.remove(&key_str); - /* - if let Some(_sentinel) = cache_writers.remove(&key_str) - { - // drop it - } - */ - if let Ok(value) = key_str.parse::() { let base62 = to_base62(value); ids.remove(&base62); - - /* - if let Some(_sentinel) = - cache_writers.remove(&base62) - { - // drop it - } - */ } return_values.insert(key, value); + + if pipe_cmds >= PIPELINE_CHUNK_SIZE { + pipe.query_async::<()>(&mut connection).await?; + pipe = redis_pipe(); + pipe_cmds = 0; + } } } - let mut connection = self.pool.get().await?; - pipe.query_async::<()>(&mut connection).await?; + if pipe_cmds > 0 { + pipe.query_async::<()>(&mut connection).await?; + } drop(cache_writers); diff --git a/apps/labrinth/src/util/sentry.rs b/apps/labrinth/src/util/sentry.rs index dfd233bd5..e0e89a0cf 100644 --- a/apps/labrinth/src/util/sentry.rs +++ b/apps/labrinth/src/util/sentry.rs @@ -3,7 +3,7 @@ // // TODO: PR something into sentry_actix to let us customize this -use std::{borrow::Cow, pin::Pin, rc::Rc}; +use std::{borrow::Cow, pin::Pin, rc::Rc, sync::Arc}; use actix_http::{ StatusCode, @@ -83,7 +83,11 @@ where } fn call(&self, req: ServiceRequest) -> Self::Future { - let hub = Hub::current(); + // Fork a Hub per request so the scope mutations below (event processor + // capturing the request, span attachment) live only for this request + // and are dropped when the future completes. Mutating the shared + // thread-local hub instead would leak one event processor per request. + let hub = Arc::new(Hub::new_from_top(Hub::main())); let client = hub.client(); let max_request_body_size = client @@ -110,7 +114,6 @@ where ); let transaction = hub.start_transaction(ctx); - transaction.set_request(sentry_req.clone()); transaction.set_origin("auto.http.actix"); transaction }; @@ -127,13 +130,13 @@ where sentry_req.data = Some(capture_request_body(&mut req).await); } - let parent_span = hub.configure_scope(|scope| { - let parent_span = scope.get_span(); + transaction.set_request(sentry_req.clone()); + + hub.configure_scope(|scope| { scope.set_span(Some(transaction.clone().into())); scope.add_event_processor(move |event| { Some(process_event(event, &sentry_req)) }); - parent_span }); let fut = @@ -150,7 +153,6 @@ where transaction.set_status(status); } transaction.finish(); - hub.configure_scope(|scope| scope.set_span(parent_span)); return Err(actix_err); } }; @@ -167,7 +169,6 @@ where transaction.set_status(status); } transaction.finish(); - hub.configure_scope(|scope| scope.set_span(parent_span)); Ok(res) } From 4c59a5e51dc0f0b0d91c1cfaaf7acd5a5695cd4a Mon Sep 17 00:00:00 2001 From: Prospector <6166773+Prospector@users.noreply.github.com> Date: Sun, 3 May 2026 11:03:29 -0700 Subject: [PATCH 07/89] fix: useTheme not defined errror (#5981) --- apps/frontend/src/components/ui/charts/ChartDisplay.vue | 1 + apps/frontend/src/utils/analytics.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/apps/frontend/src/components/ui/charts/ChartDisplay.vue b/apps/frontend/src/components/ui/charts/ChartDisplay.vue index 5dbb2dbdf..ba1855c96 100644 --- a/apps/frontend/src/components/ui/charts/ChartDisplay.vue +++ b/apps/frontend/src/components/ui/charts/ChartDisplay.vue @@ -324,6 +324,7 @@ import dayjs from 'dayjs' import { computed } from 'vue' import { UiChartsChart as Chart, UiChartsCompactChart as CompactChart } from '#components' +import { useTheme } from '~/composables/nuxt-accessors.ts' import { analyticsSetToCSVString, countryCodeToFlag, diff --git a/apps/frontend/src/utils/analytics.js b/apps/frontend/src/utils/analytics.js index c516de128..bb409886a 100644 --- a/apps/frontend/src/utils/analytics.js +++ b/apps/frontend/src/utils/analytics.js @@ -2,6 +2,8 @@ import { injectI18n, useDebugLogger } from '@modrinth/ui' import dayjs from 'dayjs' import { computed, ref, watch } from 'vue' +import { useTheme } from '~/composables/nuxt-accessors.ts' + // note: build step can miss unix import for some reason, so // we have to import it like this From 2da2035a6fe34bb4d8e7d652fe0b12e7b8e0452c Mon Sep 17 00:00:00 2001 From: Prospector <6166773+Prospector@users.noreply.github.com> Date: Sun, 3 May 2026 11:10:49 -0700 Subject: [PATCH 08/89] changelog --- packages/blog/changelog.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/blog/changelog.ts b/packages/blog/changelog.ts index e9cdefa54..128938472 100644 --- a/packages/blog/changelog.ts +++ b/packages/blog/changelog.ts @@ -10,6 +10,24 @@ export type VersionEntry = { } const VERSIONS: VersionEntry[] = [ + { + date: `2026-05-03T18:07:44+00:00`, + product: 'web', + body: `## Changed +- Added git.gay as a recognized sources link domain. + +## Fixed +- Fixed useTheme not defined error on project pages. +- Fixed latest snapshot sometimes appearing a second time outside of a version range.`, + }, + { + date: `2026-05-03T18:07:44+00:00`, + product: 'app', + version: '0.13.9', + body: `## Fixed +- Fixed update notification closing when pressing the Changelog button. +- Fixed latest snapshot sometimes appearing a second time outside of a version range.`, + }, { date: `2026-05-02T22:09:01+00:00`, product: 'app', From 8a72ee99687f957adc785f56c3ab64d315f3d664 Mon Sep 17 00:00:00 2001 From: "Calum H." Date: Sun, 3 May 2026 19:29:05 +0100 Subject: [PATCH 09/89] fix(backend): moderation locking logic fix (#5979) * fix(backend): moderation locking logic fix * fix: clippy --- apps/labrinth/src/routes/v3/projects.rs | 28 ++++++++++-------------- apps/labrinth/src/test/api_v2/project.rs | 2 +- apps/labrinth/src/test/api_v3/project.rs | 3 +-- apps/labrinth/tests/moderation_lock.rs | 24 +++++++++++++------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/apps/labrinth/src/routes/v3/projects.rs b/apps/labrinth/src/routes/v3/projects.rs index 3c9d978d5..a40f93305 100644 --- a/apps/labrinth/src/routes/v3/projects.rs +++ b/apps/labrinth/src/routes/v3/projects.rs @@ -424,28 +424,22 @@ pub async fn project_edit_internal( )); } - // If a moderator (non-admin) is completing a review (changing from Processing to another - // status), they must hold an active non-expired lock on this project. + // If a moderator (non-admin) is completing a review while another moderator holds an + // active checklist lock, block them from changing the project status. if user.role.is_mod() && !user.role.is_admin() && project_item.inner.status == ProjectStatus::Processing && status != &ProjectStatus::Processing - { - let lock = + && let Some(lock) = DBModerationLock::get_with_user(project_item.inner.id, &pool) - .await?; - let owns = lock.as_ref().is_some_and(|l| { - l.moderator_id == db_ids::DBUserId::from(user.id) && !l.expired - }); - if !owns { - return Err(ApiError::CustomAuthentication(match lock { - Some(l) => format!( - "This project is currently being moderated by @{}. Please wait for them to finish or for the lock to expire.", - l.moderator_username - ), - None => "You must hold an active moderation lock to complete this review. Open the project in the moderation checklist to acquire one.".to_string(), - })); - } + .await? + && lock.moderator_id != db_ids::DBUserId::from(user.id) + && !lock.expired + { + return Err(ApiError::CustomAuthentication(format!( + "This project is currently being moderated by @{}. Please wait for them to finish or for the lock to expire.", + lock.moderator_username + ))); } if status == &ProjectStatus::Processing { diff --git a/apps/labrinth/src/test/api_v2/project.rs b/apps/labrinth/src/test/api_v2/project.rs index fade15bee..665d5b109 100644 --- a/apps/labrinth/src/test/api_v2/project.rs +++ b/apps/labrinth/src/test/api_v2/project.rs @@ -95,7 +95,7 @@ impl ApiProject for ApiV2 { let resp = self.create_project(creation_data, pat).await; assert_status!(&resp, StatusCode::OK); - // Approve as admin so fixture setup is not blocked by the moderation-lock guard. + // Approve as admin so fixture setup is not affected by moderation-lock contention. let req = TestRequest::patch() .uri(&format!("/v2/project/{slug}")) .append_pat(ADMIN_USER_PAT) diff --git a/apps/labrinth/src/test/api_v3/project.rs b/apps/labrinth/src/test/api_v3/project.rs index fc26cdd60..2899bd095 100644 --- a/apps/labrinth/src/test/api_v3/project.rs +++ b/apps/labrinth/src/test/api_v3/project.rs @@ -49,8 +49,7 @@ impl ApiProject for ApiV3 { let resp = self.create_project(creation_data, pat).await; assert_status!(&resp, StatusCode::OK); - // Approve as admin so fixture setup is not blocked by the moderation-lock guard - // (non-admin moderators must hold a lock to move a project out of processing). + // Approve as admin so fixture setup is not affected by moderation-lock contention. let req = TestRequest::patch() .uri(&format!("/v3/project/{slug}")) .append_pat(ADMIN_USER_PAT) diff --git a/apps/labrinth/tests/moderation_lock.rs b/apps/labrinth/tests/moderation_lock.rs index 57cfe26f8..04e3ee8ec 100644 --- a/apps/labrinth/tests/moderation_lock.rs +++ b/apps/labrinth/tests/moderation_lock.rs @@ -769,9 +769,9 @@ async fn test_http_delete_all_locks_admin() { .await; } -/// Moderator without a lock cannot move a project out of processing (401 + lock message). +/// Moderator without a lock can move a project out of processing when nobody else has a lock. #[actix_rt::test] -async fn test_complete_review_requires_lock() { +async fn test_complete_review_without_lock_succeeds() { with_test_environment(None, |test_env: TestEnvironment| async move { let api = &test_env.api; let alpha_id = &test_env.dummy.project_alpha.project_id; @@ -793,8 +793,8 @@ async fn test_complete_review_requires_lock() { let resp = api.call(req).await; assert_eq!( resp.status(), - StatusCode::UNAUTHORIZED, - "moderator without lock should not be able to complete review: {}", + StatusCode::NO_CONTENT, + "moderator without lock should be able to complete review when no active lock exists: {}", String::from_utf8_lossy(test::read_body(resp).await.as_ref()) ); }) @@ -849,7 +849,7 @@ async fn test_complete_review_blocked_when_other_holds_lock() { } #[actix_rt::test] -async fn test_complete_review_fails_when_lock_expired() { +async fn test_complete_review_succeeds_when_other_lock_expired() { with_test_environment( None, |test_env: TestEnvironment| async move { @@ -858,7 +858,6 @@ async fn test_complete_review_fails_when_lock_expired() { let project_id = DBProjectId( test_env.dummy.project_alpha.project_id_parsed.0 as i64, ); - let mod_id = DBUserId(MOD_USER_ID_PARSED); let pool = &test_env.db.pool; set_project_processing( @@ -868,7 +867,11 @@ async fn test_complete_review_fails_when_lock_expired() { &test_env.db.redis_pool, ) .await; - DBModerationLock::acquire(project_id, mod_id, pool) + DBModerationLock::acquire( + project_id, + DBUserId(ADMIN_USER_ID_PARSED), + pool, + ) .await .unwrap() .unwrap(); @@ -881,7 +884,12 @@ async fn test_complete_review_fails_when_lock_expired() { .to_request(); let resp = api.call(req).await; - assert_eq!(resp.status(), StatusCode::UNAUTHORIZED); + assert_eq!( + resp.status(), + StatusCode::NO_CONTENT, + "moderator should be able to complete review when another moderator's lock expired: {}", + String::from_utf8_lossy(test::read_body(resp).await.as_ref()) + ); }, ) .await; From 7dbbbe590f367f36d2925e8affe7ec51c9c75e43 Mon Sep 17 00:00:00 2001 From: Prospector <6166773+Prospector@users.noreply.github.com> Date: Sun, 3 May 2026 11:53:06 -0700 Subject: [PATCH 10/89] chore: clean up a bunch of legacy styles (#5973) * remove unused experimental-styles-within * remove unused styles * more cleanup + prepr * Refactor nearly all legacy buttons to use ButtonStyled * prepr * Update MC account selector to modern version * prepr --------- Co-authored-by: Calum H. --- apps/app-frontend/src/App.vue | 6 +- .../src/components/ui/AccountsCard.vue | 506 +++++------------ .../src/components/ui/ExportModal.vue | 36 +- .../src/components/ui/JavaDetectionModal.vue | 22 +- .../src/components/ui/JavaSelector.vue | 74 +-- .../src/components/ui/ModpackVersionModal.vue | 21 +- .../src/components/ui/URLConfirmModal.vue | 7 +- .../IncompatibilityWarningModal.vue | 20 +- .../ui/install_flow/ModInstallModal.vue | 418 -------------- .../ui/modal/ConfirmDeleteInstanceModal.vue | 2 +- .../ui/modal/ModpackAlreadyInstalledModal.vue | 2 +- .../settings/ResourceManagementSettings.vue | 10 +- .../src/components/ui/skin/EditSkinModal.vue | 11 +- .../ui/world/modal/AddServerModal.vue | 2 +- .../ui/world/modal/EditServerModal.vue | 2 +- .../app-frontend/src/locales/en-US/index.json | 18 + apps/app-frontend/src/pages/Skins.vue | 39 +- .../src/pages/instance/Worlds.vue | 4 +- apps/app-frontend/src/pages/library/Index.vue | 12 +- .../src/pages/project/Gallery.vue | 65 ++- .../src/pages/project/Version.vue | 87 +-- .../src/pages/project/Versions.vue | 4 - .../api/oauth_utils/auth_code_reply/page.html | 2 +- .../src/assets/styles/components.scss | 519 ++---------------- apps/frontend/src/components/ui/Modal.vue | 10 +- .../src/components/ui/ModrinthFooter.vue | 4 +- .../src/components/ui/NotificationItem.vue | 160 +++--- .../src/components/ui/OptionGroup.vue | 2 +- .../ui/OrganizationProjectTransferModal.vue | 65 ++- .../SubscriptionPaymentFailedBanner.vue | 12 +- .../ui/banner/VerifyEmailBanner.vue | 26 +- .../src/components/ui/charts/ChartDisplay.vue | 34 +- .../ui/create/CollectionCreateModal.vue | 4 +- .../ui/create/OrganizationCreateModal.vue | 4 +- .../ui/create/ProjectCreateModal.vue | 4 +- .../ui/dashboard/CreatorWithdrawModal.vue | 14 +- .../ui/moderation/ModerationProjectNags.vue | 12 +- .../ui/moderation/ModerationReportCard.vue | 4 +- .../ui/moderation/ModerationTechRevCard.vue | 3 - .../ui/project-settings/CompatibilityCard.vue | 6 +- .../servers/marketing/MedalPlanPromotion.vue | 4 +- .../ui/thread/ConversationThread.vue | 360 ++++++------ .../components/ui/thread/ThreadMessage.vue | 31 +- apps/frontend/src/error.vue | 2 +- apps/frontend/src/layouts/default.vue | 5 +- apps/frontend/src/pages/[type]/[id].vue | 70 +-- .../src/pages/[type]/[id]/changelog.vue | 19 +- .../src/pages/[type]/[id]/gallery.vue | 316 +++++------ .../src/pages/[type]/[id]/settings.vue | 2 +- .../[type]/[id]/settings/environment.vue | 2 +- .../pages/[type]/[id]/settings/gallery.vue | 314 +++++------ .../src/pages/[type]/[id]/settings/index.vue | 100 ++-- .../pages/[type]/[id]/settings/license.vue | 2 +- .../src/pages/[type]/[id]/settings/links.vue | 31 +- .../pages/[type]/[id]/settings/members.vue | 181 +++--- .../src/pages/[type]/[id]/versions.vue | 2 +- .../frontend/src/pages/admin/billing/[id].vue | 2 +- apps/frontend/src/pages/admin/docs.vue | 4 +- apps/frontend/src/pages/admin/emails.vue | 126 +++-- .../src/pages/admin/servers/notices.vue | 2 +- .../src/pages/admin/servers/transfers.vue | 2 +- apps/frontend/src/pages/app.vue | 137 +++-- apps/frontend/src/pages/auth.vue | 14 +- apps/frontend/src/pages/auth/authorize.vue | 22 +- .../src/pages/auth/reset-password.vue | 25 +- apps/frontend/src/pages/auth/sign-in.vue | 85 +-- apps/frontend/src/pages/auth/sign-up.vue | 77 +-- apps/frontend/src/pages/auth/verify-email.vue | 8 +- apps/frontend/src/pages/auth/welcome.vue | 11 +- apps/frontend/src/pages/collection/[id].vue | 41 +- .../src/pages/dashboard/collections.vue | 16 +- apps/frontend/src/pages/dashboard/index.vue | 96 +--- .../src/pages/dashboard/notifications.vue | 22 +- .../src/pages/dashboard/organizations.vue | 12 +- .../frontend/src/pages/dashboard/projects.vue | 155 +++--- apps/frontend/src/pages/hosting/index.vue | 4 +- apps/frontend/src/pages/index.vue | 2 +- apps/frontend/src/pages/moderation.vue | 4 +- apps/frontend/src/pages/moderation/index.vue | 2 +- .../src/pages/news/article/[slug].vue | 4 +- apps/frontend/src/pages/news/changelog.vue | 2 +- apps/frontend/src/pages/news/index.vue | 4 +- apps/frontend/src/pages/organization/[id].vue | 22 +- .../organization/[id]/settings/index.vue | 54 +- .../organization/[id]/settings/members.vue | 146 ++--- .../organization/[id]/settings/projects.vue | 141 ++--- apps/frontend/src/pages/plus.vue | 39 +- apps/frontend/src/pages/report.vue | 2 +- apps/frontend/src/pages/settings/account.vue | 324 +++++------ .../src/pages/settings/applications.vue | 182 +++--- .../src/pages/settings/authorizations.vue | 28 +- .../src/pages/settings/billing/index.vue | 90 +-- apps/frontend/src/pages/settings/index.vue | 14 +- apps/frontend/src/pages/settings/pats.vue | 126 +++-- apps/frontend/src/pages/settings/profile.vue | 69 +-- apps/frontend/src/pages/settings/sessions.vue | 9 +- apps/frontend/src/pages/user/[id].vue | 2 +- packages/assets/styles/classes.scss | 146 ----- packages/ui/src/components/base/Avatar.vue | 4 +- packages/ui/src/components/base/Card.vue | 10 +- .../ui/src/components/base/JoinedButtons.vue | 19 +- .../ui/src/components/base/MarkdownEditor.vue | 115 ++-- .../src/components/base/MultiStageModal.vue | 1 - .../ui/src/components/base/OptionGroup.vue | 2 +- .../components/base/TeleportOverflowMenu.vue | 2 +- .../components/billing/ResubscribeModal.vue | 2 +- .../billing/ServersGuestPlanModal.vue | 4 +- .../billing/ServersPurchase0Plan.vue | 2 +- .../components/CustomSetupStage.vue | 4 +- .../components/ImportInstanceStage.vue | 9 +- .../components/ModpackStage.vue | 2 +- .../components/modal/ConfirmLeaveModal.vue | 2 +- packages/ui/src/components/modal/NewModal.vue | 2 +- .../src/components/modal/OpenInAppModal.vue | 13 +- .../ui/src/components/modal/ShareModal.vue | 143 ++--- .../src/components/nav/NotificationPanel.vue | 2 +- .../components/nav/PopupNotificationPanel.vue | 2 +- .../components/search/SearchFilterControl.vue | 2 +- .../src/components/servers/ServerListing.vue | 2 - .../servers/backups/BackupCreateModal.vue | 2 +- .../servers/backups/BackupDeleteModal.vue | 2 +- .../servers/backups/BackupRenameModal.vue | 2 +- .../servers/backups/BackupRestoreModal.vue | 2 +- .../servers/content/ContentVersionFilter.vue | 2 +- .../components/servers/icons/ServerIcon.vue | 2 +- .../components/servers/labels/Separator.vue | 2 +- .../version/VersionFilterControl.vue | 2 +- .../ui/src/layouts/shared/console/layout.vue | 2 +- .../components/ContentModpackCard.vue | 6 +- .../modals/ConfirmBulkUpdateModal.vue | 2 +- .../modals/ConfirmDeletionModal.vue | 2 +- .../modals/ConfirmModpackUpdateModal.vue | 2 +- .../modals/ConfirmReinstallModal.vue | 2 +- .../components/modals/ConfirmRepairModal.vue | 2 +- .../components/modals/ConfirmUnlinkModal.vue | 2 +- .../components/modals/ContentInstallModal.vue | 13 +- .../components/modals/ContentUpdaterModal.vue | 2 +- .../src/layouts/shared/content-tab/layout.vue | 4 +- .../files-tab/components/FileContextMenu.vue | 2 +- .../files-tab/components/FileNavbar.vue | 4 +- .../components/editor/EditorFindReplace.vue | 4 +- .../components/modals/FileCreateItemModal.vue | 2 +- .../components/modals/FileDeleteItemModal.vue | 2 +- .../components/modals/FileMoveItemModal.vue | 2 +- .../components/modals/FileRenameItemModal.vue | 2 +- .../modals/FileUnsavedChangesModal.vue | 2 +- .../modals/FileUploadConflictModal.vue | 2 +- .../modals/FileUploadZipUrlModal.vue | 2 +- .../shared/installation-settings/layout.vue | 5 +- .../shared/server-settings/pages/network.vue | 6 +- .../wrapped/hosting/manage/backups.vue | 2 +- .../layouts/wrapped/hosting/manage/index.vue | 2 +- .../layouts/wrapped/hosting/manage/root.vue | 8 +- 153 files changed, 2596 insertions(+), 3817 deletions(-) delete mode 100644 apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index dbdce711c..9e12ac691 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -1177,7 +1177,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
@@ -1378,7 +1378,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)

Playing as

- +
diff --git a/apps/app-frontend/src/components/ui/AccountsCard.vue b/apps/app-frontend/src/components/ui/AccountsCard.vue index 493ce451e..7d01d2e67 100644 --- a/apps/app-frontend/src/components/ui/AccountsCard.vue +++ b/apps/app-frontend/src/components/ui/AccountsCard.vue @@ -1,81 +1,107 @@ - - - diff --git a/apps/app-frontend/src/components/ui/ExportModal.vue b/apps/app-frontend/src/components/ui/ExportModal.vue index fa605f320..c6879ada3 100644 --- a/apps/app-frontend/src/components/ui/ExportModal.vue +++ b/apps/app-frontend/src/components/ui/ExportModal.vue @@ -1,7 +1,7 @@ - - - - diff --git a/apps/app-frontend/src/components/ui/modal/ConfirmDeleteInstanceModal.vue b/apps/app-frontend/src/components/ui/modal/ConfirmDeleteInstanceModal.vue index a2ee2a05c..d6c869ba1 100644 --- a/apps/app-frontend/src/components/ui/modal/ConfirmDeleteInstanceModal.vue +++ b/apps/app-frontend/src/components/ui/modal/ConfirmDeleteInstanceModal.vue @@ -7,7 +7,7 @@