diff --git a/.github/workflows/smoke-mastodon.yml b/.github/workflows/smoke-mastodon.yml new file mode 100644 index 00000000..6a01fdf9 --- /dev/null +++ b/.github/workflows/smoke-mastodon.yml @@ -0,0 +1,93 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json +# +# Interoperability smoke tests. +# Spins up a Mastodon instance via Docker Compose and verifies that Fedify +# can correctly exchange ActivityPub messages with it. +# See: https://github.com/fedify-dev/fedify/issues/481 +name: smoke-mastodon + +on: + push: + branches: + - main + - next + - "*.*-maintenance" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + smoke: + runs-on: ubuntu-latest + timeout-minutes: 25 + + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-mise + + - name: Generate Mastodon secrets + run: | + IMAGE=ghcr.io/mastodon/mastodon:v4.3.9 + docker pull "$IMAGE" + + SECRET1=$(docker run --rm "$IMAGE" bundle exec rails secret) + SECRET2=$(docker run --rm "$IMAGE" bundle exec rails secret) + + { + echo "SECRET_KEY_BASE=$SECRET1" + echo "OTP_SECRET=$SECRET2" + docker run --rm "$IMAGE" bundle exec rails mastodon:webpush:generate_vapid_key \ + | grep -E '^[A-Z_]+=.+' + docker run --rm "$IMAGE" bundle exec rails db:encryption:init \ + | grep -E '^[A-Z_]+=.+' + } >> test/smoke/mastodon/mastodon.env + + - name: Start database and redis + run: | + docker compose -f test/smoke/mastodon/docker-compose.yml up -d db redis + docker compose -f test/smoke/mastodon/docker-compose.yml exec -T db \ + sh -c 'until pg_isready -U mastodon; do sleep 1; done' + + - name: Run DB setup and migrations + run: | + docker compose -f test/smoke/mastodon/docker-compose.yml run --rm -T \ + mastodon-web bundle exec rails db:setup + timeout-minutes: 5 + + - name: Start Mastodon stack + run: docker compose -f test/smoke/mastodon/docker-compose.yml up --wait + timeout-minutes: 12 + + - name: Provision Mastodon + run: bash test/smoke/mastodon/provision.sh + + - name: Verify connectivity + run: | + echo "=== Harness health (from mastodon-web) ===" + docker compose -f test/smoke/mastodon/docker-compose.yml exec -T mastodon-web \ + curl -sf http://fedify-harness:3001/_test/health + echo " OK" + + echo "=== Harness health (from mastodon-sidekiq) ===" + docker compose -f test/smoke/mastodon/docker-compose.yml exec -T mastodon-sidekiq \ + curl -sf http://fedify-harness:3001/_test/health + echo " OK" + + - name: Run smoke tests + run: | + set -a && source test/smoke/.env.test && set +a + deno run --allow-net --allow-env --unstable-temporal \ + test/smoke/orchestrator.ts + + - name: Collect logs on failure + if: failure() + run: | + echo "=== Docker Compose logs ===" + docker compose -f test/smoke/mastodon/docker-compose.yml logs --tail=500 + + - name: Teardown + if: always() + run: docker compose -f test/smoke/mastodon/docker-compose.yml down -v diff --git a/.gitignore b/.gitignore index 3c36dafd..e2b18b38 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ dist/ node_modules/ package-lock.json repomix-output.xml +test/smoke/.env.test +test/smoke/mastodon/mastodon.env +smoke.log t.ts t2.ts plan.md diff --git a/deno.json b/deno.json index f51641b0..a893e5d5 100644 --- a/deno.json +++ b/deno.json @@ -29,7 +29,8 @@ "./packages/webfinger", "./examples/astro", "./examples/fresh", - "./examples/hono-sample" + "./examples/hono-sample", + "./test/smoke/harness" ], "imports": { "@cloudflare/workers-types": "npm:@cloudflare/workers-types@^4.20250529.0", diff --git a/deno.lock b/deno.lock index 1b93a1cc..d2ef21b7 100644 --- a/deno.lock +++ b/deno.lock @@ -6,47 +6,47 @@ "jsr:@david/dax@~0.43.2": "0.43.2", "jsr:@david/path@0.2": "0.2.0", "jsr:@david/which@~0.4.1": "0.4.1", - "jsr:@deno/esbuild-plugin@^1.2.0": "1.2.1", - "jsr:@deno/loader@~0.3.10": "0.3.12", - "jsr:@deno/loader@~0.3.2": "0.3.12", + "jsr:@deno/esbuild-plugin@^1.2.0": "1.2.0", + "jsr:@deno/loader@~0.3.2": "0.3.9", + "jsr:@deno/loader@~0.3.3": "0.3.9", "jsr:@fresh/build-id@1": "1.0.1", "jsr:@fresh/core@2": "2.2.0", "jsr:@fresh/core@^2.1.4": "2.2.0", - "jsr:@fresh/core@^2.2.0": "2.2.0", - "jsr:@fresh/plugin-vite@^1.0.7": "1.0.8", + "jsr:@fresh/plugin-vite@^1.0.7": "1.0.7", "jsr:@hongminhee/localtunnel@0.3": "0.3.0", - "jsr:@hono/hono@^4.7.1": "4.12.0", - "jsr:@hono/hono@^4.8.3": "4.12.0", - "jsr:@logtape/file@2": "2.0.2", - "jsr:@logtape/logtape@2": "2.0.2", - "jsr:@logtape/logtape@^1.0.4": "1.3.7", - "jsr:@logtape/logtape@^2.0.2": "2.0.2", - "jsr:@optique/config@~0.10.6": "0.10.6", - "jsr:@optique/core@~0.10.6": "0.10.6", - "jsr:@optique/run@~0.10.6": "0.10.6", + "jsr:@hono/hono@^4.7.1": "4.11.4", + "jsr:@hono/hono@^4.8.3": "4.11.4", + "jsr:@logtape/file@2": "2.0.0", + "jsr:@logtape/logtape@2": "2.0.0", + "jsr:@logtape/logtape@^1.0.4": "1.3.6", + "jsr:@optique/config@~0.10.6": "0.10.7", + "jsr:@optique/core@~0.10.6": "0.10.7", + "jsr:@optique/core@~0.10.7": "0.10.7", + "jsr:@optique/run@~0.10.6": "0.10.7", "jsr:@std/assert@0.224": "0.224.0", "jsr:@std/assert@0.226": "0.226.0", - "jsr:@std/assert@^1.0.13": "1.0.18", + "jsr:@std/assert@^1.0.13": "1.0.16", "jsr:@std/async@0.224": "0.224.2", "jsr:@std/async@^1.0.13": "1.0.16", + "jsr:@std/bytes@^1.0.5": "1.0.6", "jsr:@std/bytes@^1.0.6": "1.0.6", "jsr:@std/data-structures@0.224": "0.224.1", "jsr:@std/dotenv@~0.225.5": "0.225.6", "jsr:@std/encoding@^1.0.10": "1.0.10", "jsr:@std/fmt@0.224": "0.224.0", - "jsr:@std/fmt@1": "1.0.9", - "jsr:@std/fmt@^1.0.7": "1.0.9", - "jsr:@std/fmt@^1.0.8": "1.0.9", + "jsr:@std/fmt@1": "1.0.8", + "jsr:@std/fmt@^1.0.7": "1.0.8", + "jsr:@std/fmt@^1.0.8": "1.0.8", "jsr:@std/fs@0.224": "0.224.0", - "jsr:@std/fs@1": "1.0.22", - "jsr:@std/fs@^1.0.19": "1.0.22", - "jsr:@std/fs@^1.0.3": "1.0.22", + "jsr:@std/fs@1": "1.0.21", + "jsr:@std/fs@^1.0.19": "1.0.21", + "jsr:@std/fs@^1.0.3": "1.0.21", "jsr:@std/html@^1.0.5": "1.0.5", - "jsr:@std/http@^1.0.21": "1.0.24", + "jsr:@std/http@^1.0.21": "1.0.23", "jsr:@std/internal@0.224": "0.224.0", "jsr:@std/internal@1": "1.0.12", "jsr:@std/internal@^1.0.12": "1.0.12", - "jsr:@std/io@0.225": "0.225.3", + "jsr:@std/io@0.225": "0.225.2", "jsr:@std/json@^1.0.2": "1.0.2", "jsr:@std/jsonc@^1.0.2": "1.0.2", "jsr:@std/media-types@^1.1.0": "1.1.0", @@ -58,65 +58,64 @@ "jsr:@std/path@^1.1.1": "1.1.4", "jsr:@std/path@^1.1.2": "1.1.4", "jsr:@std/path@^1.1.4": "1.1.4", - "jsr:@std/semver@^1.0.6": "1.0.8", + "jsr:@std/semver@^1.0.6": "1.0.7", "jsr:@std/testing@0.224": "0.224.0", "jsr:@std/url@~0.225.1": "0.225.1", "jsr:@std/uuid@^1.0.9": "1.1.0", "jsr:@std/yaml@^1.0.8": "1.0.10", "jsr:@valibot/valibot@^1.2.0": "1.2.0", "npm:@alinea/suite@~0.6.3": "0.6.3", - "npm:@astrojs/node@^9.5.4": "9.5.4_astro@5.17.3__rollup@4.57.1__ioredis@5.9.2__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2", - "npm:@babel/core@^7.28.0": "7.29.0", - "npm:@babel/preset-react@^7.27.1": "7.28.5_@babel+core@7.29.0", + "npm:@astrojs/node@^9.5.4": "9.5.4_astro@5.18.0__rollup@4.55.1__ioredis@5.9.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.55.1_ioredis@5.9.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2", + "npm:@babel/core@^7.28.0": "7.28.6", + "npm:@babel/preset-react@^7.27.1": "7.28.5_@babel+core@7.28.6", "npm:@cfworker/json-schema@^4.1.1": "4.1.1", - "npm:@cloudflare/vitest-pool-workers@~0.8.31": "0.8.71_@vitest+runner@3.2.4_@vitest+snapshot@3.2.4_vitest@3.2.4__@types+node@22.19.10__vite@7.3.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__tsx@4.21.0__yaml@2.8.2_@types+node@22.19.10_@cloudflare+workers-types@4.20260210.0_tsx@4.21.0_yaml@2.8.2", - "npm:@cloudflare/workers-types@^4.20250529.0": "4.20260210.0", - "npm:@cloudflare/workers-types@^4.20250906.0": "4.20260210.0", - "npm:@deno/astro-adapter@~0.3.2": "0.3.2_@opentelemetry+api@1.9.0_astro@5.17.3__rollup@4.57.1__ioredis@5.9.2__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2", - "npm:@fxts/core@^1.21.1": "1.25.0", + "npm:@cloudflare/vitest-pool-workers@~0.8.31": "0.8.71_@vitest+runner@3.2.4_@vitest+snapshot@3.2.4_vitest@3.2.4__@types+node@22.19.3__vite@7.3.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__tsx@4.21.0__yaml@2.8.2_@types+node@22.19.3_@cloudflare+workers-types@4.20260109.0_tsx@4.21.0_yaml@2.8.2", + "npm:@cloudflare/workers-types@^4.20250529.0": "4.20260109.0", + "npm:@cloudflare/workers-types@^4.20250906.0": "4.20260109.0", + "npm:@deno/astro-adapter@~0.3.2": "0.3.2_@opentelemetry+api@1.9.0_astro@5.18.0__rollup@4.55.1__ioredis@5.9.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.55.1_ioredis@5.9.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2", + "npm:@fxts/core@^1.21.1": "1.23.0", "npm:@hongminhee/localtunnel@0.3": "0.3.0", - "npm:@inquirer/prompts@^7.8.4": "7.10.1_@types+node@22.19.10", + "npm:@inquirer/prompts@^7.8.4": "7.10.1_@types+node@22.19.3", "npm:@jimp/core@^1.6.0": "1.6.0", "npm:@jimp/wasm-webp@^1.6.0": "1.6.0", "npm:@js-temporal/polyfill@~0.5.1": "0.5.1", "npm:@jsr/std__assert@0.226": "0.226.0", "npm:@mjackson/node-fetch-server@0.7": "0.7.0", "npm:@multiformats/base-x@^4.0.1": "4.0.1", - "npm:@nestjs/common@^11.0.1": "11.1.13_reflect-metadata@0.2.2_rxjs@7.8.2", + "npm:@nestjs/common@^11.0.1": "11.1.11_reflect-metadata@0.2.2_rxjs@7.8.2", "npm:@opentelemetry/api@^1.9.0": "1.9.0", - "npm:@opentelemetry/context-async-hooks@^2.5.0": "2.5.0_@opentelemetry+api@1.9.0", - "npm:@opentelemetry/core@^2.5.0": "2.5.0_@opentelemetry+api@1.9.0", - "npm:@opentelemetry/sdk-trace-base@^2.5.0": "2.5.0_@opentelemetry+api@1.9.0", - "npm:@opentelemetry/semantic-conventions@^1.39.0": "1.39.0", + "npm:@opentelemetry/context-async-hooks@^2.5.0": "2.6.0_@opentelemetry+api@1.9.0", + "npm:@opentelemetry/core@^2.5.0": "2.6.0_@opentelemetry+api@1.9.0", + "npm:@opentelemetry/sdk-trace-base@^2.5.0": "2.6.0_@opentelemetry+api@1.9.0", + "npm:@opentelemetry/semantic-conventions@^1.39.0": "1.40.0", "npm:@poppanator/http-constants@^1.1.1": "1.1.1", - "npm:@preact/signals@^2.2.1": "2.7.1_preact@10.19.6", - "npm:@preact/signals@^2.3.2": "2.7.1_preact@10.19.6", - "npm:@prefresh/vite@^2.4.8": "2.4.11_preact@10.19.6_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2", + "npm:@preact/signals@^2.2.1": "2.5.1_preact@10.19.6", + "npm:@preact/signals@^2.3.2": "2.5.1_preact@10.19.6", + "npm:@prefresh/vite@^2.4.8": "2.4.11_preact@10.19.6_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2", "npm:@standard-schema/spec@^1.1.0": "1.1.0", - "npm:@sveltejs/kit@2": "2.50.2_@opentelemetry+api@1.9.0_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.50.1___acorn@8.15.0__vite@7.3.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2_svelte@5.50.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2", + "npm:@sveltejs/kit@2": "2.49.4_@opentelemetry+api@1.9.0_@sveltejs+vite-plugin-svelte@6.2.3__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2", "npm:@types/amqplib@*": "0.10.8", "npm:@types/amqplib@~0.10.7": "0.10.8", "npm:@types/eslint@9": "9.6.1", "npm:@types/estree@^1.0.8": "1.0.8", - "npm:@types/node@^22.16.0": "22.19.10", - "npm:@types/node@^24.2.1": "24.10.12", - "npm:@typescript-eslint/parser@^8.49.0": "8.55.0_eslint@9.39.2_typescript@5.9.3", - "npm:@typescript-eslint/utils@8": "8.55.0_eslint@9.39.2_typescript@5.9.3", + "npm:@types/node@^22.16.0": "22.19.3", + "npm:@types/node@^24.2.1": "24.10.4", + "npm:@typescript-eslint/parser@^8.49.0": "8.52.0_eslint@9.39.2_typescript@5.9.3", + "npm:@typescript-eslint/utils@8": "8.52.0_eslint@9.39.2_typescript@5.9.3", "npm:amqplib@~0.10.9": "0.10.9", "npm:asn1js@^3.0.6": "3.0.7", "npm:asn1js@^3.0.7": "3.0.7", - "npm:astro@*": "5.17.3_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_vite@6.4.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_zod@3.25.76", - "npm:astro@^5.17.3": "5.17.3_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_vite@6.4.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_zod@3.25.76", + "npm:astro@^5.17.3": "5.18.0_rollup@4.55.1_ioredis@5.9.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_vite@6.4.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_zod@3.25.76", "npm:byte-encodings@^1.0.11": "1.0.11", "npm:chalk@^5.6.2": "5.6.2", "npm:cli-highlight@^2.1.11": "2.1.11", "npm:cli-table3@~0.6.5": "0.6.5", "npm:enquirer@^2.4.1": "2.4.1", - "npm:es-toolkit@^1.30.0": "1.44.0", - "npm:es-toolkit@^1.31.0": "1.44.0", - "npm:es-toolkit@^1.39.10": "1.44.0", - "npm:es-toolkit@^1.42.0": "1.44.0", - "npm:es-toolkit@^1.43.0": "1.44.0", + "npm:es-toolkit@^1.30.0": "1.43.0", + "npm:es-toolkit@^1.31.0": "1.43.0", + "npm:es-toolkit@^1.39.10": "1.43.0", + "npm:es-toolkit@^1.42.0": "1.43.0", + "npm:es-toolkit@^1.43.0": "1.43.0", "npm:esbuild-wasm@~0.25.11": "0.25.12", "npm:esbuild@0.25.7": "0.25.7", "npm:esbuild@~0.25.5": "0.25.12", @@ -124,16 +123,15 @@ "npm:express@4": "4.22.1", "npm:fast-check@^3.22.0": "3.23.2", "npm:fastify-plugin@^5.0.1": "5.1.0", - "npm:fastify@^5.2.0": "5.7.4", + "npm:fastify@^5.2.0": "5.6.2", "npm:fetch-mock@^12.5.2": "12.6.0", "npm:fetch-mock@^12.5.4": "12.6.0", "npm:h3@^1.15.0": "1.15.5", "npm:hono@^4.8.3": "4.11.3", - "npm:html-to-text@^9.0.5": "9.0.5", "npm:icojs@~0.19.5": "0.19.5", "npm:inquirer-toggle@^1.0.1": "1.0.1", - "npm:inquirer@^12.9.4": "12.11.1_@types+node@22.19.10", - "npm:ioredis@^5.8.2": "5.9.2", + "npm:inquirer@^12.9.4": "12.11.1_@types+node@22.19.3", + "npm:ioredis@^5.8.2": "5.9.1", "npm:jimp@^1.6.0": "1.6.0", "npm:json-canon@^1.0.1": "1.0.1", "npm:json-preserve-indent@^1.1.3": "1.1.3", @@ -141,16 +139,16 @@ "npm:koa@2": "2.16.3", "npm:miniflare@^4.20250523.0": "4.20250906.0", "npm:multicodec@^3.2.1": "3.2.1", - "npm:mysql2@^3.18.0": "3.18.2_@types+node@22.19.10", + "npm:mysql2@^3.18.0": "3.18.2_@types+node@22.19.3", "npm:ora@^8.2.0": "8.2.0", "npm:pkijs@^3.2.5": "3.3.3", "npm:pkijs@^3.3.3": "3.3.3", "npm:postgres@^3.4.7": "3.4.8", "npm:preact-render-to-string@^6.6.3": "6.6.5_preact@10.19.6", "npm:preact@10.19.6": "10.19.6", - "npm:preact@^10.27.0": "10.28.3", - "npm:preact@^10.27.2": "10.28.3", - "npm:rollup@^4.50.0": "4.57.1", + "npm:preact@^10.27.0": "10.28.2", + "npm:preact@^10.27.2": "10.28.2", + "npm:rollup@^4.50.0": "4.55.1", "npm:shiki@^1.6.4": "1.29.2", "npm:smol-toml@^1.6.0": "1.6.0", "npm:srvx@~0.8.7": "0.8.16", @@ -160,11 +158,11 @@ "npm:uri-template-router@1": "1.0.0", "npm:url-template@^3.1.1": "3.1.1", "npm:valibot@^1.2.0": "1.2.0", - "npm:vite@^7.1.3": "7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", - "npm:vite@^7.1.4": "7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", - "npm:vitest@3.2": "3.2.4_@types+node@22.19.10_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_tsx@4.21.0_yaml@2.8.2", - "npm:wrangler@^4.17.0": "4.35.0_@cloudflare+workers-types@4.20260210.0_unenv@2.0.0-rc.21_workerd@1.20250906.0", - "npm:wrangler@^4.21.1": "4.35.0_@cloudflare+workers-types@4.20260210.0_unenv@2.0.0-rc.21_workerd@1.20250906.0", + "npm:vite@^7.1.3": "7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", + "npm:vite@^7.1.4": "7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", + "npm:vitest@3.2": "3.2.4_@types+node@22.19.3_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_tsx@4.21.0_yaml@2.8.2", + "npm:wrangler@^4.17.0": "4.35.0_@cloudflare+workers-types@4.20260109.0_unenv@2.0.0-rc.21_workerd@1.20250906.0", + "npm:wrangler@^4.21.1": "4.35.0_@cloudflare+workers-types@4.20260109.0_unenv@2.0.0-rc.21_workerd@1.20250906.0", "npm:yaml@^2.8.1": "2.8.2" }, "jsr": { @@ -196,16 +194,16 @@ "@david/which@0.4.1": { "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" }, - "@deno/esbuild-plugin@1.2.1": { - "integrity": "df629467913adc1f960149fdfa3a3430ba8c20381c310fba096db244e6c3c9f6", + "@deno/esbuild-plugin@1.2.0": { + "integrity": "04ddd0fca9416d8a2866263928a53b9d5ed08dfca064d64504a0aaf9800c709e", "dependencies": [ - "jsr:@deno/loader@~0.3.10", + "jsr:@deno/loader@~0.3.3", "jsr:@std/path@^1.1.1", "npm:esbuild@~0.25.5" ] }, - "@deno/loader@0.3.12": { - "integrity": "52d3b3be0a32192efe07b0a4f1b3047077d2f2bba0f693e32f47421507f9fdb6" + "@deno/loader@0.3.9": { + "integrity": "703d44656f7da0fa4a4a7f8a5105b5b41320821286508c2967b4252a00a2506f" }, "@fresh/build-id@1.0.1": { "integrity": "12a2ec25fd52ae9ec68c26848a5696cd1c9b537f7c983c7e56e4fb1e7e816c20", @@ -237,12 +235,12 @@ "npm:preact@^10.27.2" ] }, - "@fresh/plugin-vite@1.0.8": { - "integrity": "5780d842ed82e4cbccd93dd8ba2d54bf59dff5aee65921134aab15a4cd457c56", + "@fresh/plugin-vite@1.0.7": { + "integrity": "0dd7048f7c5d5cf7f62b29b4653a18cfa4dc81e074c4c0ab9e8166cce639cbeb", "dependencies": [ "jsr:@deno/loader@~0.3.2", "jsr:@fresh/core@2", - "jsr:@fresh/core@^2.2.0", + "jsr:@fresh/core@^2.1.4", "jsr:@std/dotenv", "jsr:@std/fmt@^1.0.7", "jsr:@std/path@1", @@ -266,19 +264,10 @@ "@hono/hono@4.11.4": { "integrity": "aaf7b9d5a6b2422b0778c091b712ee1f018bc7e82138067d21eb27d7c2e1f5be" }, - "@hono/hono@4.11.9": { - "integrity": "c82c6b846abc3c1879d921d8365287d77cdef8073019f509ff80bf53033bdcba" - }, - "@hono/hono@4.11.10": { - "integrity": "a5a6dac87ab5a8bcf3f92aeaca22417128d584c2732860c20bbf6fdb3cafbcc5" - }, - "@hono/hono@4.12.0": { - "integrity": "a09c74c4a15539f159ea386b5804fd88d984805aa74e4d847a136ba42487412b" - }, - "@logtape/file@2.0.2": { - "integrity": "a912459fe0d27213e05c95e6fadf716000f27eafa27e67c2737820ba24097fdc", + "@logtape/file@2.0.0": { + "integrity": "beb77f53a5792f4a3e22a8cbdb0f78d2c92c62700ccbff42eac7cf42cb3dac42", "dependencies": [ - "jsr:@logtape/logtape@^2.0.2", + "jsr:@logtape/logtape@2", "jsr:@std/path@^1.1.0" ] }, @@ -288,29 +277,23 @@ "@logtape/logtape@1.3.6": { "integrity": "d9a038ed8f85981d7c1cd43d931402ef52bc036cfd14bc9be5bdfc7ec8136b6f" }, - "@logtape/logtape@1.3.7": { - "integrity": "d9dc1f8c7e2e1e4e3998006ea84eaf4054e40ad39325b056b3f517c013286bed" - }, - "@logtape/logtape@2.0.2": { - "integrity": "546fcd514e66f2b841c6f261fa3a3d905b52d876dc1bba8ffe1a087d9275c4c9" + "@logtape/logtape@2.0.0": { + "integrity": "c4f2d7684a8239ad9b3fc2fd4ade6eec9f04cdb3a1741bae83f370b4b34253b2" }, - "@optique/config@0.10.6": { - "integrity": "ac216f6fc6ebe124fc17baa7a0a7cde13a6565942e6a2ec0c34d947299c7577d", + "@optique/config@0.10.7": { + "integrity": "2b5faae72106c2158e07e2b9b3c34ef595708a004798914059657b91851a3680", "dependencies": [ - "jsr:@optique/core", + "jsr:@optique/core@~0.10.7", "npm:@standard-schema/spec" ] }, - "@optique/core@0.10.0-dev.333+076fceae": { - "integrity": "1ebe1782740f08d568ae0c5258786933a8502d1e137feb49b2d8ab06d204b11a" + "@optique/core@0.10.7": { + "integrity": "7669bbf1840c356526634d205c8803fa286147d2b112c67aa1057a9e60f1da3d" }, - "@optique/core@0.10.6": { - "integrity": "a3ba44f15f9512856f4716362ef3731b711285ed2327c372ce6cc575be9d3072" - }, - "@optique/run@0.10.6": { - "integrity": "6c045917057b9657baae320c2e80bcc46f05572a8698d80e233da1e34915db1a", + "@optique/run@0.10.7": { + "integrity": "1529119beac780f219608dd59367c523f9e6c9ab711b15b6c6cb76e91b36851c", "dependencies": [ - "jsr:@optique/core" + "jsr:@optique/core@~0.10.7" ] }, "@std/assert@0.224.0": { @@ -326,8 +309,8 @@ "jsr:@std/internal@1" ] }, - "@std/assert@1.0.18": { - "integrity": "270245e9c2c13b446286de475131dc688ca9abcd94fc5db41d43a219b34d1c78", + "@std/assert@1.0.16": { + "integrity": "6a7272ed1eaa77defe76e5ff63ca705d9c495077e2d5fd0126d2b53fc5bd6532", "dependencies": [ "jsr:@std/internal@^1.0.12" ] @@ -338,9 +321,6 @@ "@std/async@1.0.16": { "integrity": "6c9e43035313b67b5de43e2b3ee3eadb39a488a0a0a3143097f112e025d3ee9a" }, - "@std/async@1.1.1": { - "integrity": "8a79beb3378cc229ce65ba2c746cfd03e4855ddd891d1eb6b9e32128e0d5339c" - }, "@std/bytes@1.0.6": { "integrity": "f6ac6adbd8ccd99314045f5703e23af0a68d7f7e58364b47d2c7f408aeb5820a" }, @@ -356,8 +336,8 @@ "@std/fmt@0.224.0": { "integrity": "e20e9a2312a8b5393272c26191c0a68eda8d2c4b08b046bad1673148f1d69851" }, - "@std/fmt@1.0.9": { - "integrity": "2487343e8899fb2be5d0e3d35013e54477ada198854e52dd05ed0422eddcabe0" + "@std/fmt@1.0.8": { + "integrity": "71e1fc498787e4434d213647a6e43e794af4fd393ef8f52062246e06f7e372b7" }, "@std/fs@0.224.0": { "integrity": "52a5ec89731ac0ca8f971079339286f88c571a4d61686acf75833f03a89d8e69", @@ -365,8 +345,8 @@ "jsr:@std/path@0.224" ] }, - "@std/fs@1.0.22": { - "integrity": "de0f277a58a867147a8a01bc1b181d0dfa80bfddba8c9cf2bacd6747bcec9308", + "@std/fs@1.0.21": { + "integrity": "d720fe1056d78d43065a4d6e0eeb2b19f34adb8a0bc7caf3a4dbf1d4178252cd", "dependencies": [ "jsr:@std/internal@^1.0.12", "jsr:@std/path@^1.1.4" @@ -375,8 +355,8 @@ "@std/html@1.0.5": { "integrity": "4e2d693f474cae8c16a920fa5e15a3b72267b94b84667f11a50c6dd1cb18d35e" }, - "@std/http@1.0.24": { - "integrity": "4dd59afd7cfd6e2e96e175b67a5a829b449ae55f08575721ec691e5d85d886d4", + "@std/http@1.0.23": { + "integrity": "6634e9e034c589bf35101c1b5ee5bbf052a5987abca20f903e58bdba85c80dee", "dependencies": [ "jsr:@std/encoding" ] @@ -390,10 +370,10 @@ "@std/internal@1.0.12": { "integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027" }, - "@std/io@0.225.3": { - "integrity": "27b07b591384d12d7b568f39e61dff966b8230559122df1e9fd11cc068f7ddd1", + "@std/io@0.225.2": { + "integrity": "3c740cd4ee4c082e6cfc86458f47e2ab7cb353dc6234d5e9b1f91a2de5f4d6c7", "dependencies": [ - "jsr:@std/bytes" + "jsr:@std/bytes@^1.0.5" ] }, "@std/json@1.0.2": { @@ -417,8 +397,8 @@ "jsr:@std/internal@^1.0.12" ] }, - "@std/semver@1.0.8": { - "integrity": "dc830e8b8b6a380c895d53fbfd1258dc253704ca57bbe1629ac65fd7830179b7" + "@std/semver@1.0.7": { + "integrity": "7d5f65391762dc4358abde80fc3354086ddb40101f140295e60f290c138887d0" }, "@std/testing@0.224.0": { "integrity": "371b8a929aa7132240d5dd766a439be8f780ef5c176ab194e0bcab72370c761e", @@ -440,7 +420,7 @@ "@std/uuid@1.1.0": { "integrity": "6268db2ccf172849c9be80763354ca305d49ef4af41fe995623d44fcc3f7457c", "dependencies": [ - "jsr:@std/bytes" + "jsr:@std/bytes@^1.0.6" ] }, "@std/yaml@1.0.10": { @@ -477,7 +457,7 @@ "remark-parse", "remark-rehype", "remark-smartypants", - "shiki@3.22.0", + "shiki@3.23.0", "smol-toml", "unified", "unist-util-remove-position", @@ -486,7 +466,7 @@ "vfile" ] }, - "@astrojs/node@9.5.4_astro@5.17.3__rollup@4.57.1__ioredis@5.9.2__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "@astrojs/node@9.5.4_astro@5.18.0__rollup@4.55.1__ioredis@5.9.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.55.1_ioredis@5.9.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-AbPSZsMGu8hXPR2XxV79RaKy8h6wijhtoqZGeUf4OXg2w1mxXlx4VnIc1D+QvtsgauSz7P5PLhmvf6w/J41GJg==", "dependencies": [ "@astrojs/internal-helpers", @@ -513,19 +493,19 @@ "which-pm-runs" ] }, - "@babel/code-frame@7.29.0": { - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "@babel/code-frame@7.28.6": { + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", "dependencies": [ "@babel/helper-validator-identifier", "js-tokens@4.0.0", "picocolors" ] }, - "@babel/compat-data@7.29.0": { - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==" + "@babel/compat-data@7.28.6": { + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==" }, - "@babel/core@7.29.0": { - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "@babel/core@7.28.6": { + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dependencies": [ "@babel/code-frame", "@babel/generator", @@ -544,8 +524,8 @@ "semver@6.3.1" ] }, - "@babel/generator@7.29.1": { - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "@babel/generator@7.28.6": { + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", "dependencies": [ "@babel/parser", "@babel/types", @@ -580,7 +560,7 @@ "@babel/types" ] }, - "@babel/helper-module-transforms@7.28.6_@babel+core@7.29.0": { + "@babel/helper-module-transforms@7.28.6_@babel+core@7.28.6": { "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dependencies": [ "@babel/core", @@ -615,28 +595,28 @@ ], "bin": true }, - "@babel/plugin-syntax-jsx@7.28.6_@babel+core@7.29.0": { + "@babel/plugin-syntax-jsx@7.28.6_@babel+core@7.28.6": { "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-react-display-name@7.28.0_@babel+core@7.29.0": { + "@babel/plugin-transform-react-display-name@7.28.0_@babel+core@7.28.6": { "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", "dependencies": [ "@babel/core", "@babel/helper-plugin-utils" ] }, - "@babel/plugin-transform-react-jsx-development@7.27.1_@babel+core@7.29.0": { + "@babel/plugin-transform-react-jsx-development@7.27.1_@babel+core@7.28.6": { "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", "dependencies": [ "@babel/core", "@babel/plugin-transform-react-jsx" ] }, - "@babel/plugin-transform-react-jsx@7.28.6_@babel+core@7.29.0": { + "@babel/plugin-transform-react-jsx@7.28.6_@babel+core@7.28.6": { "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", "dependencies": [ "@babel/core", @@ -647,7 +627,7 @@ "@babel/types" ] }, - "@babel/plugin-transform-react-pure-annotations@7.27.1_@babel+core@7.29.0": { + "@babel/plugin-transform-react-pure-annotations@7.27.1_@babel+core@7.28.6": { "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", "dependencies": [ "@babel/core", @@ -655,7 +635,7 @@ "@babel/helper-plugin-utils" ] }, - "@babel/preset-react@7.28.5_@babel+core@7.29.0": { + "@babel/preset-react@7.28.5_@babel+core@7.28.6": { "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", "dependencies": [ "@babel/core", @@ -675,8 +655,8 @@ "@babel/types" ] }, - "@babel/traverse@7.29.0": { - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "@babel/traverse@7.28.6": { + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", "dependencies": [ "@babel/code-frame", "@babel/generator", @@ -725,7 +705,7 @@ "workerd" ] }, - "@cloudflare/vitest-pool-workers@0.8.71_@vitest+runner@3.2.4_@vitest+snapshot@3.2.4_vitest@3.2.4__@types+node@22.19.10__vite@7.3.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__tsx@4.21.0__yaml@2.8.2_@types+node@22.19.10_@cloudflare+workers-types@4.20260210.0_tsx@4.21.0_yaml@2.8.2": { + "@cloudflare/vitest-pool-workers@0.8.71_@vitest+runner@3.2.4_@vitest+snapshot@3.2.4_vitest@3.2.4__@types+node@22.19.3__vite@7.3.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__tsx@4.21.0__yaml@2.8.2_@types+node@22.19.3_@cloudflare+workers-types@4.20260109.0_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-keu2HCLQfRNwbmLBCDXJgCFpANTaYnQpE01fBOo4CNwiWHUT7SZGN7w64RKiSWRHyYppStXBuE5Ng7F42+flpg==", "dependencies": [ "@vitest/runner", @@ -734,7 +714,7 @@ "cjs-module-lexer", "devalue", "miniflare", - "semver@7.7.4", + "semver@7.7.3", "vitest", "wrangler", "zod@3.25.76" @@ -765,8 +745,8 @@ "os": ["win32"], "cpu": ["x64"] }, - "@cloudflare/workers-types@4.20260210.0": { - "integrity": "sha512-zHaF0RZVYUQwNCJCECnNAJdMur72Lk3FMiD6wU78Dx3Bv7DQRcuXNmPNuJmsGnosVZCcWintHlPTQ/4BEiDG5w==" + "@cloudflare/workers-types@4.20260109.0": { + "integrity": "sha512-90vx2lVm+fhQyE8FKqNhT8JBI8GuY0biAwxTzvzeRIdWVo2ArCpUfYMYq4kzaGTfA6NwCmXmBFSgnqfG6OFxLw==" }, "@colors/colors@1.5.0": { "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" @@ -777,7 +757,7 @@ "@jridgewell/trace-mapping@0.3.9" ] }, - "@deno/astro-adapter@0.3.2_@opentelemetry+api@1.9.0_astro@5.17.3__rollup@4.57.1__ioredis@5.9.2__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "@deno/astro-adapter@0.3.2_@opentelemetry+api@1.9.0_astro@5.18.0__rollup@4.55.1__ioredis@5.9.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__vite@6.4.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__zod@3.25.76_rollup@4.55.1_ioredis@5.9.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-nN0kQGobRs2XE3R+O/DWYQanEWpteJNsIf5TD65787qFEw2CrqkFNcNolZFJiKUF/2Y/TKyOLRjMS3F6auECVg==", "dependencies": [ "@opentelemetry/api", @@ -1418,8 +1398,8 @@ "ipaddr.js@2.3.0" ] }, - "@fxts/core@1.25.0": { - "integrity": "sha512-olXPKT/LuNCVwKfVmE4G0lDFMndv+jl7k3mQkBv8ZbXqQvdQJq3nCi2wiUaZHms4eeCimWeZ5uLemW0thlnVUw==", + "@fxts/core@1.23.0": { + "integrity": "sha512-URaV1oAhU64s4zfhzMIAB444aDB1fyLHcS7tEw3TrHll7YExbks/FimjrJN2MXrHVB0jXBtGeTTpW5k40R7NXg==", "dependencies": [ "tslib" ] @@ -1446,8 +1426,8 @@ "@humanwhocodes/retry@0.4.3": { "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==" }, - "@img/colour@1.0.0": { - "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==" + "@img/colour@1.1.0": { + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==" }, "@img/sharp-darwin-arm64@0.33.5": { "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", @@ -1725,38 +1705,38 @@ "@inquirer/ansi@1.0.2": { "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==" }, - "@inquirer/checkbox@4.3.2_@types+node@22.19.10": { + "@inquirer/checkbox@4.3.2_@types+node@22.19.3": { "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/confirm@5.1.21_@types+node@22.19.10": { + "@inquirer/confirm@5.1.21_@types+node@22.19.3": { "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10" + "@inquirer/core@10.3.2_@types+node@22.19.3", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/core@10.3.2_@types+node@22.19.10": { + "@inquirer/core@10.3.2_@types+node@22.19.3": { "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dependencies": [ "@inquirer/ansi", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "cli-width", "mute-stream@2.0.0", "signal-exit", @@ -1764,7 +1744,7 @@ "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, "@inquirer/core@8.2.4": { @@ -1773,7 +1753,7 @@ "@inquirer/figures", "@inquirer/type@1.5.5", "@types/mute-stream", - "@types/node@20.19.33", + "@types/node@20.19.27", "@types/wrap-ansi", "ansi-escapes", "cli-spinners", @@ -1785,79 +1765,79 @@ "wrap-ansi@6.2.0" ] }, - "@inquirer/editor@4.2.23_@types+node@22.19.10": { + "@inquirer/editor@4.2.23_@types+node@22.19.3": { "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", "@inquirer/external-editor", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10" + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/expand@4.0.23_@types+node@22.19.10": { + "@inquirer/expand@4.0.23_@types+node@22.19.3": { "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/external-editor@1.0.3_@types+node@22.19.10": { + "@inquirer/external-editor@1.0.3_@types+node@22.19.3": { "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dependencies": [ - "@types/node@22.19.10", + "@types/node@22.19.3", "chardet", "iconv-lite@0.7.2" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, "@inquirer/figures@1.0.15": { "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==" }, - "@inquirer/input@4.3.1_@types+node@22.19.10": { + "@inquirer/input@4.3.1_@types+node@22.19.3": { "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10" + "@inquirer/core@10.3.2_@types+node@22.19.3", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/number@3.0.23_@types+node@22.19.10": { + "@inquirer/number@3.0.23_@types+node@22.19.3": { "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10" + "@inquirer/core@10.3.2_@types+node@22.19.3", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/password@4.0.23_@types+node@22.19.10": { + "@inquirer/password@4.0.23_@types+node@22.19.3": { "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@22.19.10", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10" + "@inquirer/core@10.3.2_@types+node@22.19.3", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/prompts@7.10.1_@types+node@22.19.10": { + "@inquirer/prompts@7.10.1_@types+node@22.19.3": { "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dependencies": [ "@inquirer/checkbox", @@ -1870,49 +1850,49 @@ "@inquirer/rawlist", "@inquirer/search", "@inquirer/select", - "@types/node@22.19.10" + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/rawlist@4.1.11_@types+node@22.19.10": { + "@inquirer/rawlist@4.1.11_@types+node@22.19.3": { "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/search@3.2.2_@types+node@22.19.10": { + "@inquirer/search@3.2.2_@types+node@22.19.3": { "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "@inquirer/select@4.4.2_@types+node@22.19.10": { + "@inquirer/select@4.4.2_@types+node@22.19.3": { "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, "@inquirer/type@1.5.5": { @@ -1921,13 +1901,13 @@ "mute-stream@1.0.0" ] }, - "@inquirer/type@3.0.10_@types+node@22.19.10": { + "@inquirer/type@3.0.10_@types+node@22.19.3": { "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dependencies": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, "@ioredis/commands@1.5.0": { @@ -2294,10 +2274,10 @@ "@tybys/wasm-util" ] }, - "@nestjs/common@11.1.13_reflect-metadata@0.2.2_rxjs@7.8.2": { - "integrity": "sha512-ieqWtipT+VlyDWLz5Rvz0f3E5rXcVAnaAi+D53DEHLjc1kmFxCgZ62qVfTX2vwkywwqNkTNXvBgGR72hYqV//Q==", + "@nestjs/common@11.1.11_reflect-metadata@0.2.2_rxjs@7.8.2": { + "integrity": "sha512-R/+A8XFqLgN8zNs2twhrOaE7dJbRQhdPX3g46am4RT/x8xGLqDphrXkUIno4cGUZHxbczChBAaAPTdPv73wDZA==", "dependencies": [ - "file-type@21.3.0", + "file-type@21.2.0", "iterare", "load-esm", "reflect-metadata", @@ -2312,29 +2292,29 @@ "@opentelemetry/api@1.9.0": { "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" }, - "@opentelemetry/context-async-hooks@2.5.0_@opentelemetry+api@1.9.0": { - "integrity": "sha512-uOXpVX0ZjO7heSVjhheW2XEPrhQAWr2BScDPoZ9UDycl5iuHG+Usyc3AIfG6kZeC1GyLpMInpQ6X5+9n69yOFw==", + "@opentelemetry/context-async-hooks@2.6.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-L8UyDwqpTcbkIK5cgwDRDYDoEhQoj8wp8BwsO19w3LB1Z41yEQm2VJyNfAi9DrLP/YTqXqWpKHyZfR9/tFYo1Q==", "dependencies": [ "@opentelemetry/api" ] }, - "@opentelemetry/core@2.5.0_@opentelemetry+api@1.9.0": { - "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "@opentelemetry/core@2.6.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==", "dependencies": [ "@opentelemetry/api", "@opentelemetry/semantic-conventions" ] }, - "@opentelemetry/resources@2.5.0_@opentelemetry+api@1.9.0": { - "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", + "@opentelemetry/resources@2.6.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-D4y/+OGe3JSuYUCBxtH5T9DSAWNcvCb/nQWIga8HNtXTVPQn59j0nTBAgaAXxUVBDl40mG3Tc76b46wPlZaiJQ==", "dependencies": [ "@opentelemetry/api", "@opentelemetry/core", "@opentelemetry/semantic-conventions" ] }, - "@opentelemetry/sdk-trace-base@2.5.0_@opentelemetry+api@1.9.0": { - "integrity": "sha512-VzRf8LzotASEyNDUxTdaJ9IRJ1/h692WyArDBInf5puLCjxbICD6XkHgpuudis56EndyS7LYFmtTMny6UABNdQ==", + "@opentelemetry/sdk-trace-base@2.6.0_@opentelemetry+api@1.9.0": { + "integrity": "sha512-g/OZVkqlxllgFM7qMKqbPV9c1DUPhQ7d4n3pgZFcrnrNft9eJXZM2TNHTPYREJBrtNdRytYyvwjgL5geDKl3EQ==", "dependencies": [ "@opentelemetry/api", "@opentelemetry/core", @@ -2342,8 +2322,8 @@ "@opentelemetry/semantic-conventions" ] }, - "@opentelemetry/semantic-conventions@1.39.0": { - "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==" + "@opentelemetry/semantic-conventions@1.40.0": { + "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==" }, "@oslojs/encoding@1.1.0": { "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==" @@ -2351,8 +2331,8 @@ "@oxc-project/types@0.103.0": { "integrity": "sha512-bkiYX5kaXWwUessFRSoXFkGIQTmc6dLGdxuRTrC+h8PSnIdZyuXHHlLAeTmOue5Br/a0/a7dHH0Gca6eXn9MKg==" }, - "@oxc-project/types@0.112.0": { - "integrity": "sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==" + "@oxc-project/types@0.107.0": { + "integrity": "sha512-QFDRbYfV2LVx8tyqtyiah3jQPUj1mK2+RYwxyFWyGoys6XJnwTdlzO6rdNNHOPorHAu5Uo34oWRKcvNpbJarmQ==" }, "@pinojs/redact@0.4.0": { "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==" @@ -2380,11 +2360,11 @@ "@poppinss/exception@1.2.3": { "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==" }, - "@preact/signals-core@1.13.0": { - "integrity": "sha512-slT6XeTCAbdql61GVLlGU4x7XHI7kCZV5Um5uhE4zLX4ApgiiXc0UYFvVOKq06xcovzp7p+61l68oPi563ARKg==" + "@preact/signals-core@1.12.1": { + "integrity": "sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==" }, - "@preact/signals@2.7.1_preact@10.19.6": { - "integrity": "sha512-mP2+wMYHqDXVKFGzjqkL6CiHj3okB8eVTTJUZBrSVGozi/XfA+zZRCEALKKZYRoSoqLyT4J6qM4lhwT9155s1Q==", + "@preact/signals@2.5.1_preact@10.19.6": { + "integrity": "sha512-VPjk5YFt7i11Fi4UK0tzaEe5xLwfhUxXL3l89ocxQ5aPz7bRo8M5+N73LjBMPklyXKYKz6YsNo4Smp8n6nplng==", "dependencies": [ "@preact/signals-core", "preact@10.19.6" @@ -2402,7 +2382,7 @@ "@prefresh/utils@1.2.1": { "integrity": "sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==" }, - "@prefresh/vite@2.4.11_preact@10.19.6_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "@prefresh/vite@2.4.11_preact@10.19.6_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-/XjURQqdRiCG3NpMmWqE9kJwrg9IchIOWHzulCfqg2sRe/8oQ1g5De7xrk9lbqPIQLn7ntBkKdqWXIj4E9YXyg==", "dependencies": [ "@babel/core", @@ -2411,7 +2391,7 @@ "@prefresh/utils", "@rollup/pluginutils@4.2.1", "preact@10.19.6", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ] }, "@quansync/fs@1.0.0": { @@ -2425,8 +2405,8 @@ "os": ["android"], "cpu": ["arm64"] }, - "@rolldown/binding-android-arm64@1.0.0-rc.3": { - "integrity": "sha512-0T1k9FinuBZ/t7rZ8jN6OpUKPnUjNdYHoj/cESWrQ3ZraAJ4OMm6z7QjSfCxqj8mOp9kTKc1zHK3kGz5vMu+nQ==", + "@rolldown/binding-android-arm64@1.0.0-beta.59": { + "integrity": "sha512-6yLLgyswYwiCfls9+hoNFY9F8TQdwo15hpXDHzlAR0X/GojeKF+AuNcXjYNbOJ4zjl/5D6lliE8CbpB5t1OWIQ==", "os": ["android"], "cpu": ["arm64"] }, @@ -2435,8 +2415,8 @@ "os": ["darwin"], "cpu": ["arm64"] }, - "@rolldown/binding-darwin-arm64@1.0.0-rc.3": { - "integrity": "sha512-JWWLzvcmc/3pe7qdJqPpuPk91SoE/N+f3PcWx/6ZwuyDVyungAEJPvKm/eEldiDdwTmaEzWfIR+HORxYWrCi1A==", + "@rolldown/binding-darwin-arm64@1.0.0-beta.59": { + "integrity": "sha512-hqGXRc162qCCIOAcHN2Cw4eXiVTwYsMFLOhAy1IG2CxY+dwc/l4Ga+dLPkLor3Ikqy5WDn+7kxHbbh6EmshEpQ==", "os": ["darwin"], "cpu": ["arm64"] }, @@ -2445,8 +2425,8 @@ "os": ["darwin"], "cpu": ["x64"] }, - "@rolldown/binding-darwin-x64@1.0.0-rc.3": { - "integrity": "sha512-MTakBxfx3tde5WSmbHxuqlDsIW0EzQym+PJYGF4P6lG2NmKzi128OGynoFUqoD5ryCySEY85dug4v+LWGBElIw==", + "@rolldown/binding-darwin-x64@1.0.0-beta.59": { + "integrity": "sha512-ezvvGuhteE15JmMhJW0wS7BaXmhwLy1YHeEwievYaPC1PgGD86wgBKfOpHr9tSKllAXbCe0BeeMvasscWLhKdA==", "os": ["darwin"], "cpu": ["x64"] }, @@ -2455,8 +2435,8 @@ "os": ["freebsd"], "cpu": ["x64"] }, - "@rolldown/binding-freebsd-x64@1.0.0-rc.3": { - "integrity": "sha512-jje3oopyOLs7IwfvXoS6Lxnmie5JJO7vW29fdGFu5YGY1EDbVDhD+P9vDihqS5X6fFiqL3ZQZCMBg6jyHkSVww==", + "@rolldown/binding-freebsd-x64@1.0.0-beta.59": { + "integrity": "sha512-4fhKVJiEYVd5n6no/mrL3LZ9kByfCGwmONOrdtvx8DJGDQhehH/q3RfhG3V/4jGKhpXgbDjpIjkkFdybCTcgew==", "os": ["freebsd"], "cpu": ["x64"] }, @@ -2465,8 +2445,8 @@ "os": ["linux"], "cpu": ["arm"] }, - "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3": { - "integrity": "sha512-A0n8P3hdLAaqzSFrQoA42p23ZKBYQOw+8EH5r15Sa9X1kD9/JXe0YT2gph2QTWvdr0CVK2BOXiK6ENfy6DXOag==", + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59": { + "integrity": "sha512-T3Y52sW6JAhvIqArBw+wtjNU1Ieaz4g0NBxyjSJoW971nZJBZygNlSYx78G4cwkCmo1dYTciTPDOnQygLV23pA==", "os": ["linux"], "cpu": ["arm"] }, @@ -2475,8 +2455,8 @@ "os": ["linux"], "cpu": ["arm64"] }, - "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3": { - "integrity": "sha512-kWXkoxxarYISBJ4bLNf5vFkEbb4JvccOwxWDxuK9yee8lg5XA7OpvlTptfRuwEvYcOZf+7VS69Uenpmpyo5Bjw==", + "@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59": { + "integrity": "sha512-NIW40jQDSQap2KDdmm9z3B/4OzWJ6trf8dwx3FD74kcQb3v34ThsBFTtzE5KjDuxnxgUlV+DkAu+XgSMKrgufw==", "os": ["linux"], "cpu": ["arm64"] }, @@ -2485,8 +2465,8 @@ "os": ["linux"], "cpu": ["arm64"] }, - "@rolldown/binding-linux-arm64-musl@1.0.0-rc.3": { - "integrity": "sha512-Z03/wrqau9Bicfgb3Dbs6SYTHliELk2PM2LpG2nFd+cGupTMF5kanLEcj2vuuJLLhptNyS61rtk7SOZ+lPsTUA==", + "@rolldown/binding-linux-arm64-musl@1.0.0-beta.59": { + "integrity": "sha512-CCKEk+H+8c0WGe/8n1E20n85Tq4Pv+HNAbjP1KfUXW+01aCWSMjU56ChNrM2tvHnXicfm7QRNoZyfY8cWh7jLQ==", "os": ["linux"], "cpu": ["arm64"] }, @@ -2495,8 +2475,8 @@ "os": ["linux"], "cpu": ["x64"] }, - "@rolldown/binding-linux-x64-gnu@1.0.0-rc.3": { - "integrity": "sha512-iSXXZsQp08CSilff/DCTFZHSVEpEwdicV3W8idHyrByrcsRDVh9sGC3sev6d8BygSGj3vt8GvUKBPCoyMA4tgQ==", + "@rolldown/binding-linux-x64-gnu@1.0.0-beta.59": { + "integrity": "sha512-VlfwJ/HCskPmQi8R0JuAFndySKVFX7yPhE658o27cjSDWWbXVtGkSbwaxstii7Q+3Rz87ZXN+HLnb1kd4R9Img==", "os": ["linux"], "cpu": ["x64"] }, @@ -2505,8 +2485,8 @@ "os": ["linux"], "cpu": ["x64"] }, - "@rolldown/binding-linux-x64-musl@1.0.0-rc.3": { - "integrity": "sha512-qaj+MFudtdCv9xZo9znFvkgoajLdc+vwf0Kz5N44g+LU5XMe+IsACgn3UG7uTRlCCvhMAGXm1XlpEA5bZBrOcw==", + "@rolldown/binding-linux-x64-musl@1.0.0-beta.59": { + "integrity": "sha512-kuO92hTRyGy0Ts3Nsqll0rfO8eFsEJe9dGQGktkQnZ2hrJrDVN0y419dMgKy/gB2S2o7F2dpWhpfQOBehZPwVA==", "os": ["linux"], "cpu": ["x64"] }, @@ -2515,8 +2495,8 @@ "os": ["openharmony"], "cpu": ["arm64"] }, - "@rolldown/binding-openharmony-arm64@1.0.0-rc.3": { - "integrity": "sha512-U662UnMETyjT65gFmG9ma+XziENrs7BBnENi/27swZPYagubfHRirXHG2oMl+pEax2WvO7Kb9gHZmMakpYqBHQ==", + "@rolldown/binding-openharmony-arm64@1.0.0-beta.59": { + "integrity": "sha512-PXAebvNL4sYfCqi8LdY4qyFRacrRoiPZLo3NoUmiTxm7MPtYYR8CNtBGNokqDmMuZIQIecRaD/jbmFAIDz7DxQ==", "os": ["openharmony"], "cpu": ["arm64"] }, @@ -2527,8 +2507,8 @@ ], "cpu": ["wasm32"] }, - "@rolldown/binding-wasm32-wasi@1.0.0-rc.3": { - "integrity": "sha512-gekrQ3Q2HiC1T5njGyuUJoGpK/l6B/TNXKed3fZXNf9YRTJn3L5MOZsFBn4bN2+UX+8+7hgdlTcEsexX988G4g==", + "@rolldown/binding-wasm32-wasi@1.0.0-beta.59": { + "integrity": "sha512-yJoklQg7XIZq8nAg0bbkEXcDK6sfpjxQGxpg2Nd6ERNtvg+eOaEBRgPww0BVTrYFQzje1pB5qPwC2VnJHT3koQ==", "dependencies": [ "@napi-rs/wasm-runtime" ], @@ -2539,8 +2519,8 @@ "os": ["win32"], "cpu": ["arm64"] }, - "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3": { - "integrity": "sha512-85y5JifyMgs8m5K2XzR/VDsapKbiFiohl7s5lEj7nmNGO0pkTXE7q6TQScei96BNAsoK7JC3pA7ukA8WRHVJpg==", + "@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59": { + "integrity": "sha512-ljZ4+McmCbIuZwEBaoGtiG8Rq2nJjaXEnLEIx+usWetXn1ECjXY0LAhkELxOV6ytv4ensEmoJJ8nXg47hRMjlw==", "os": ["win32"], "cpu": ["arm64"] }, @@ -2549,16 +2529,16 @@ "os": ["win32"], "cpu": ["x64"] }, - "@rolldown/binding-win32-x64-msvc@1.0.0-rc.3": { - "integrity": "sha512-a4VUQZH7LxGbUJ3qJ/TzQG8HxdHvf+jOnqf7B7oFx1TEBm+j2KNL2zr5SQ7wHkNAcaPevF6gf9tQnVBnC4mD+A==", + "@rolldown/binding-win32-x64-msvc@1.0.0-beta.59": { + "integrity": "sha512-bMY4tTIwbdZljW+xe/ln1hvs0SRitahQSXfWtvgAtIzgSX9Ar7KqJzU7lRm33YTRFIHLULRi53yNjw9nJGd6uQ==", "os": ["win32"], "cpu": ["x64"] }, "@rolldown/pluginutils@1.0.0-beta.57": { "integrity": "sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==" }, - "@rolldown/pluginutils@1.0.0-rc.3": { - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==" + "@rolldown/pluginutils@1.0.0-beta.59": { + "integrity": "sha512-aoh6LAJRyhtazs98ydgpNOYstxUlsOV1KJXcpf/0c0vFcUA8uyd/hwKRhqE/AAPNqAho9RliGsvitCoOzREoVA==" }, "@rollup/pluginutils@4.2.1": { "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", @@ -2567,7 +2547,7 @@ "picomatch@2.3.1" ] }, - "@rollup/pluginutils@5.3.0_rollup@4.57.1": { + "@rollup/pluginutils@5.3.0_rollup@4.55.1": { "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", "dependencies": [ "@types/estree", @@ -2579,141 +2559,134 @@ "rollup" ] }, - "@rollup/rollup-android-arm-eabi@4.57.1": { - "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", + "@rollup/rollup-android-arm-eabi@4.55.1": { + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", "os": ["android"], "cpu": ["arm"] }, - "@rollup/rollup-android-arm64@4.57.1": { - "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", + "@rollup/rollup-android-arm64@4.55.1": { + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", "os": ["android"], "cpu": ["arm64"] }, - "@rollup/rollup-darwin-arm64@4.57.1": { - "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", + "@rollup/rollup-darwin-arm64@4.55.1": { + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", "os": ["darwin"], "cpu": ["arm64"] }, - "@rollup/rollup-darwin-x64@4.57.1": { - "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", + "@rollup/rollup-darwin-x64@4.55.1": { + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", "os": ["darwin"], "cpu": ["x64"] }, - "@rollup/rollup-freebsd-arm64@4.57.1": { - "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", + "@rollup/rollup-freebsd-arm64@4.55.1": { + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", "os": ["freebsd"], "cpu": ["arm64"] }, - "@rollup/rollup-freebsd-x64@4.57.1": { - "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", + "@rollup/rollup-freebsd-x64@4.55.1": { + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", "os": ["freebsd"], "cpu": ["x64"] }, - "@rollup/rollup-linux-arm-gnueabihf@4.57.1": { - "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", + "@rollup/rollup-linux-arm-gnueabihf@4.55.1": { + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", "os": ["linux"], "cpu": ["arm"] }, - "@rollup/rollup-linux-arm-musleabihf@4.57.1": { - "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", + "@rollup/rollup-linux-arm-musleabihf@4.55.1": { + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", "os": ["linux"], "cpu": ["arm"] }, - "@rollup/rollup-linux-arm64-gnu@4.57.1": { - "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", + "@rollup/rollup-linux-arm64-gnu@4.55.1": { + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", "os": ["linux"], "cpu": ["arm64"] }, - "@rollup/rollup-linux-arm64-musl@4.57.1": { - "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", + "@rollup/rollup-linux-arm64-musl@4.55.1": { + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", "os": ["linux"], "cpu": ["arm64"] }, - "@rollup/rollup-linux-loong64-gnu@4.57.1": { - "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "@rollup/rollup-linux-loong64-gnu@4.55.1": { + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", "os": ["linux"], "cpu": ["loong64"] }, - "@rollup/rollup-linux-loong64-musl@4.57.1": { - "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", + "@rollup/rollup-linux-loong64-musl@4.55.1": { + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", "os": ["linux"], "cpu": ["loong64"] }, - "@rollup/rollup-linux-ppc64-gnu@4.57.1": { - "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "@rollup/rollup-linux-ppc64-gnu@4.55.1": { + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", "os": ["linux"], "cpu": ["ppc64"] }, - "@rollup/rollup-linux-ppc64-musl@4.57.1": { - "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", + "@rollup/rollup-linux-ppc64-musl@4.55.1": { + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", "os": ["linux"], "cpu": ["ppc64"] }, - "@rollup/rollup-linux-riscv64-gnu@4.57.1": { - "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", + "@rollup/rollup-linux-riscv64-gnu@4.55.1": { + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", "os": ["linux"], "cpu": ["riscv64"] }, - "@rollup/rollup-linux-riscv64-musl@4.57.1": { - "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", + "@rollup/rollup-linux-riscv64-musl@4.55.1": { + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", "os": ["linux"], "cpu": ["riscv64"] }, - "@rollup/rollup-linux-s390x-gnu@4.57.1": { - "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", + "@rollup/rollup-linux-s390x-gnu@4.55.1": { + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", "os": ["linux"], "cpu": ["s390x"] }, - "@rollup/rollup-linux-x64-gnu@4.57.1": { - "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", + "@rollup/rollup-linux-x64-gnu@4.55.1": { + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", "os": ["linux"], "cpu": ["x64"] }, - "@rollup/rollup-linux-x64-musl@4.57.1": { - "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", + "@rollup/rollup-linux-x64-musl@4.55.1": { + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", "os": ["linux"], "cpu": ["x64"] }, - "@rollup/rollup-openbsd-x64@4.57.1": { - "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "@rollup/rollup-openbsd-x64@4.55.1": { + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", "os": ["openbsd"], "cpu": ["x64"] }, - "@rollup/rollup-openharmony-arm64@4.57.1": { - "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", + "@rollup/rollup-openharmony-arm64@4.55.1": { + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", "os": ["openharmony"], "cpu": ["arm64"] }, - "@rollup/rollup-win32-arm64-msvc@4.57.1": { - "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", + "@rollup/rollup-win32-arm64-msvc@4.55.1": { + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", "os": ["win32"], "cpu": ["arm64"] }, - "@rollup/rollup-win32-ia32-msvc@4.57.1": { - "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", + "@rollup/rollup-win32-ia32-msvc@4.55.1": { + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", "os": ["win32"], "cpu": ["ia32"] }, - "@rollup/rollup-win32-x64-gnu@4.57.1": { - "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", + "@rollup/rollup-win32-x64-gnu@4.55.1": { + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", "os": ["win32"], "cpu": ["x64"] }, - "@rollup/rollup-win32-x64-msvc@4.57.1": { - "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", + "@rollup/rollup-win32-x64-msvc@4.55.1": { + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", "os": ["win32"], "cpu": ["x64"] }, "@sec-ant/readable-stream@0.4.1": { "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==" }, - "@selderee/plugin-htmlparser2@0.11.0": { - "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", - "dependencies": [ - "domhandler", - "selderee" - ] - }, "@shikijs/core@1.29.2": { "integrity": "sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==", "dependencies": [ @@ -2725,10 +2698,10 @@ "hast-util-to-html" ] }, - "@shikijs/core@3.22.0": { - "integrity": "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==", + "@shikijs/core@3.23.0": { + "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", "dependencies": [ - "@shikijs/types@3.22.0", + "@shikijs/types@3.23.0", "@shikijs/vscode-textmate", "@types/hast", "hast-util-to-html" @@ -2742,10 +2715,10 @@ "oniguruma-to-es@2.3.0" ] }, - "@shikijs/engine-javascript@3.22.0": { - "integrity": "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==", + "@shikijs/engine-javascript@3.23.0": { + "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", "dependencies": [ - "@shikijs/types@3.22.0", + "@shikijs/types@3.23.0", "@shikijs/vscode-textmate", "oniguruma-to-es@4.3.4" ] @@ -2757,10 +2730,10 @@ "@shikijs/vscode-textmate" ] }, - "@shikijs/engine-oniguruma@3.22.0": { - "integrity": "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==", + "@shikijs/engine-oniguruma@3.23.0": { + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", "dependencies": [ - "@shikijs/types@3.22.0", + "@shikijs/types@3.23.0", "@shikijs/vscode-textmate" ] }, @@ -2770,10 +2743,10 @@ "@shikijs/types@1.29.2" ] }, - "@shikijs/langs@3.22.0": { - "integrity": "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==", + "@shikijs/langs@3.23.0": { + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", "dependencies": [ - "@shikijs/types@3.22.0" + "@shikijs/types@3.23.0" ] }, "@shikijs/themes@1.29.2": { @@ -2782,10 +2755,10 @@ "@shikijs/types@1.29.2" ] }, - "@shikijs/themes@3.22.0": { - "integrity": "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==", + "@shikijs/themes@3.23.0": { + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", "dependencies": [ - "@shikijs/types@3.22.0" + "@shikijs/types@3.23.0" ] }, "@shikijs/types@1.29.2": { @@ -2795,8 +2768,8 @@ "@types/hast" ] }, - "@shikijs/types@3.22.0": { - "integrity": "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==", + "@shikijs/types@3.23.0": { + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", "dependencies": [ "@shikijs/vscode-textmate", "@types/hast" @@ -2820,8 +2793,8 @@ "acorn@8.15.0" ] }, - "@sveltejs/kit@2.50.2_@opentelemetry+api@1.9.0_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.50.1___acorn@8.15.0__vite@7.3.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2_svelte@5.50.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { - "integrity": "sha512-875hTUkEbz+MyJIxWbQjfMaekqdmEKUUfR7JyKcpfMRZqcGyrO9Gd+iS1D/Dx8LpE5FEtutWGOtlAh4ReSAiOA==", + "@sveltejs/kit@2.49.4_@opentelemetry+api@1.9.0_@sveltejs+vite-plugin-svelte@6.2.3__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { + "integrity": "sha512-JFtOqDoU0DI/+QSG8qnq5bKcehVb3tCHhOG4amsSYth5/KgO4EkJvi42xSAiyKmXAAULW1/Zdb6lkgGEgSxdZg==", "dependencies": [ "@opentelemetry/api", "@standard-schema/spec", @@ -2836,35 +2809,35 @@ "magic-string", "mrmime", "sade", - "set-cookie-parser@3.0.1", + "set-cookie-parser", "sirv", "svelte", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ], "optionalPeers": [ "@opentelemetry/api" ], "bin": true }, - "@sveltejs/vite-plugin-svelte-inspector@5.0.2_@sveltejs+vite-plugin-svelte@6.2.4__svelte@5.50.1___acorn@8.15.0__vite@7.3.1___@types+node@22.19.10___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2_svelte@5.50.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "@sveltejs/vite-plugin-svelte-inspector@5.0.2_@sveltejs+vite-plugin-svelte@6.2.3__svelte@5.46.1___acorn@8.15.0__vite@7.3.1___@types+node@22.19.3___tsx@4.21.0___yaml@2.8.2___picomatch@4.0.3__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==", "dependencies": [ "@sveltejs/vite-plugin-svelte", "obug", "svelte", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ] }, - "@sveltejs/vite-plugin-svelte@6.2.4_svelte@5.50.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { - "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", + "@sveltejs/vite-plugin-svelte@6.2.3_svelte@5.46.1__acorn@8.15.0_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { + "integrity": "sha512-a+uxqQ9j6Lxmq4plbGaNdM9hgDCZyxAv/yvuyF5iWoA2H5icZkqD3rdK155ZQgFLX2lc3NvahHG4OgKpYqYPiQ==", "dependencies": [ "@sveltejs/vite-plugin-svelte-inspector", "deepmerge", "magic-string", "obug", "svelte", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", - "vitefu@1.1.1_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", + "vitefu@1.1.1_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2" ] }, "@tokenizer/inflate@0.4.1": { @@ -2886,7 +2859,7 @@ "@types/amqplib@0.10.8": { "integrity": "sha512-vtDp8Pk1wsE/AuQ8/Rgtm6KUZYqcnTgNvEHwzCkX8rL7AGsC6zqAfKAAJhUZXFhM/Pp++tbnUHiam/8vVpPztA==", "dependencies": [ - "@types/node@24.10.12" + "@types/node@24.10.4" ] }, "@types/chai@5.2.3": { @@ -2942,7 +2915,7 @@ "@types/mute-stream@0.0.4": { "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", "dependencies": [ - "@types/node@24.10.12" + "@types/node@24.10.4" ] }, "@types/nlcst@2.0.3": { @@ -2954,20 +2927,20 @@ "@types/node@16.9.1": { "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" }, - "@types/node@20.19.33": { - "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", + "@types/node@20.19.27": { + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "dependencies": [ "undici-types@6.21.0" ] }, - "@types/node@22.19.10": { - "integrity": "sha512-tF5VOugLS/EuDlTBijk0MqABfP8UxgYazTLo3uIn3b4yJgg26QRbVYJYsDtHrjdDUIRfP70+VfhTTc+CE1yskw==", + "@types/node@22.19.3": { + "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", "dependencies": [ "undici-types@6.21.0" ] }, - "@types/node@24.10.12": { - "integrity": "sha512-68e+T28EbdmLSTkPgs3+UacC6rzmqrcWFPQs1C8mwJhI/r5Uxr0yEuQotczNRROd1gq30NGxee+fo0rSIxpyAw==", + "@types/node@24.10.4": { + "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", "dependencies": [ "undici-types@7.16.0" ] @@ -2978,8 +2951,8 @@ "@types/wrap-ansi@3.0.0": { "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==" }, - "@typescript-eslint/parser@8.55.0_eslint@9.39.2_typescript@5.9.3": { - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "@typescript-eslint/parser@8.52.0_eslint@9.39.2_typescript@5.9.3": { + "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==", "dependencies": [ "@typescript-eslint/scope-manager", "@typescript-eslint/types", @@ -2990,8 +2963,8 @@ "typescript" ] }, - "@typescript-eslint/project-service@8.55.0_typescript@5.9.3": { - "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "@typescript-eslint/project-service@8.52.0_typescript@5.9.3": { + "integrity": "sha512-xD0MfdSdEmeFa3OmVqonHi+Cciab96ls1UhIF/qX/O/gPu5KXD0bY9lu33jj04fjzrXHcuvjBcBC+D3SNSadaw==", "dependencies": [ "@typescript-eslint/tsconfig-utils", "@typescript-eslint/types", @@ -2999,24 +2972,24 @@ "typescript" ] }, - "@typescript-eslint/scope-manager@8.55.0": { - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "@typescript-eslint/scope-manager@8.52.0": { + "integrity": "sha512-ixxqmmCcc1Nf8S0mS0TkJ/3LKcC8mruYJPOU6Ia2F/zUUR4pApW7LzrpU3JmtePbRUTes9bEqRc1Gg4iyRnDzA==", "dependencies": [ "@typescript-eslint/types", "@typescript-eslint/visitor-keys" ] }, - "@typescript-eslint/tsconfig-utils@8.55.0_typescript@5.9.3": { - "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "@typescript-eslint/tsconfig-utils@8.52.0_typescript@5.9.3": { + "integrity": "sha512-jl+8fzr/SdzdxWJznq5nvoI7qn2tNYV/ZBAEcaFMVXf+K6jmXvAFrgo/+5rxgnL152f//pDEAYAhhBAZGrVfwg==", "dependencies": [ "typescript" ] }, - "@typescript-eslint/types@8.55.0": { - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==" + "@typescript-eslint/types@8.52.0": { + "integrity": "sha512-LWQV1V4q9V4cT4H5JCIx3481iIFxH1UkVk+ZkGGAV1ZGcjGI9IoFOfg3O6ywz8QqCDEp7Inlg6kovMofsNRaGg==" }, - "@typescript-eslint/typescript-estree@8.55.0_typescript@5.9.3": { - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "@typescript-eslint/typescript-estree@8.52.0_typescript@5.9.3": { + "integrity": "sha512-XP3LClsCc0FsTK5/frGjolyADTh3QmsLp6nKd476xNI9CsSsLnmn4f0jrzNoAulmxlmNIpeXuHYeEQv61Q6qeQ==", "dependencies": [ "@typescript-eslint/project-service", "@typescript-eslint/tsconfig-utils", @@ -3024,14 +2997,14 @@ "@typescript-eslint/visitor-keys", "debug@4.4.3", "minimatch@9.0.5", - "semver@7.7.4", + "semver@7.7.3", "tinyglobby", "ts-api-utils", "typescript" ] }, - "@typescript-eslint/utils@8.55.0_eslint@9.39.2_typescript@5.9.3": { - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "@typescript-eslint/utils@8.52.0_eslint@9.39.2_typescript@5.9.3": { + "integrity": "sha512-wYndVMWkweqHpEpwPhwqE2lnD2DxC6WVLupU/DOt/0/v+/+iQbbzO3jOHjmBMnhu0DgLULvOaU4h4pwHYi2oRQ==", "dependencies": [ "@eslint-community/eslint-utils", "@typescript-eslint/scope-manager", @@ -3041,8 +3014,8 @@ "typescript" ] }, - "@typescript-eslint/visitor-keys@8.55.0": { - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "@typescript-eslint/visitor-keys@8.52.0": { + "integrity": "sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==", "dependencies": [ "@typescript-eslint/types", "eslint-visitor-keys@4.2.1" @@ -3061,16 +3034,16 @@ "tinyrainbow" ] }, - "@vitest/mocker@3.2.4_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "@vitest/mocker@3.2.4_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dependencies": [ "@vitest/spy", "estree-walker@3.0.3", "magic-string", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ], "optionalPeers": [ - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ] }, "@vitest/pretty-format@3.2.4": { @@ -3252,8 +3225,8 @@ "pathe" ] }, - "astro@5.17.3_rollup@4.57.1_ioredis@5.9.2_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_vite@6.4.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_zod@3.25.76": { - "integrity": "sha512-69dcfPe8LsHzklwj+hl+vunWUbpMB6pmg35mACjetxbJeUNNys90JaBM8ZiwsPK689SAj/4Zqb1ayaANls9/MA==", + "astro@5.18.0_rollup@4.55.1_ioredis@5.9.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_vite@6.4.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_zod@3.25.76": { + "integrity": "sha512-CHiohwJIS4L0G6/IzE1Fx3dgWqXBCXus/od0eGUfxrZJD2um2pE7ehclMmgL/fXqbU7NfE1Ze2pq34h2QaA6iQ==", "dependencies": [ "@astrojs/compiler", "@astrojs/internal-helpers", @@ -3261,7 +3234,7 @@ "@astrojs/telemetry", "@capsizecss/unpack", "@oslojs/encoding", - "@rollup/pluginutils@5.3.0_rollup@4.57.1", + "@rollup/pluginutils@5.3.0_rollup@4.55.1", "acorn@8.15.0", "aria-query", "axobject-query", @@ -3298,8 +3271,8 @@ "picomatch@4.0.3", "prompts", "rehype", - "semver@7.7.4", - "shiki@3.22.0", + "semver@7.7.3", + "shiki@3.23.0", "smol-toml", "svgo", "tinyexec@1.0.2", @@ -3310,8 +3283,8 @@ "unist-util-visit", "unstorage", "vfile", - "vite@6.4.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", - "vitefu@1.1.1_vite@6.4.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2", + "vite@6.4.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", + "vitefu@1.1.1_vite@6.4.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2", "xxhash-wasm", "yargs-parser@21.1.1", "yocto-spinner", @@ -3355,8 +3328,8 @@ "base64-js@1.5.1": { "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "baseline-browser-mapping@2.9.19": { - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "baseline-browser-mapping@2.9.14": { + "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", "bin": true }, "birpc@0.2.14": { @@ -3487,8 +3460,8 @@ "camelcase@8.0.0": { "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==" }, - "caniuse-lite@1.0.30001769": { - "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==" + "caniuse-lite@1.0.30001764": { + "integrity": "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==" }, "canonicalize@2.1.0": { "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", @@ -3795,8 +3768,8 @@ "base-64" ] }, - "devalue@5.6.2": { - "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==" + "devalue@5.6.3": { + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==" }, "devlop@1.1.0": { "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", @@ -3852,8 +3825,8 @@ "ee-first@1.1.1": { "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "electron-to-chromium@1.5.286": { - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==" + "electron-to-chromium@1.5.267": { + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==" }, "emoji-regex-xs@1.0.0": { "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==" @@ -3904,8 +3877,8 @@ "es-errors" ] }, - "es-toolkit@1.44.0": { - "integrity": "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==" + "es-toolkit@1.43.0": { + "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==" }, "esbuild-wasm@0.25.12": { "integrity": "sha512-rZqkjL3Y6FwLpSHzLnaEy8Ps6veCNo1kZa9EOfJvmWtBq5dJH4iVjfmOO6Mlkv9B0tt9WFPFmb/VxlgJOnueNg==", @@ -4124,8 +4097,8 @@ "estraverse" ] }, - "esrap@2.2.3": { - "integrity": "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==", + "esrap@2.2.1": { + "integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==", "dependencies": [ "@jridgewell/sourcemap-codec" ] @@ -4229,8 +4202,8 @@ "fast-json-stable-stringify@2.1.0": { "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "fast-json-stringify@6.3.0_ajv@8.17.1": { - "integrity": "sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==", + "fast-json-stringify@6.1.1_ajv@8.17.1": { + "integrity": "sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==", "dependencies": [ "@fastify/merge-json-schemas", "ajv@8.17.1", @@ -4255,8 +4228,8 @@ "fastify-plugin@5.1.0": { "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==" }, - "fastify@5.7.4": { - "integrity": "sha512-e6l5NsRdaEP8rdD8VR0ErJASeyaRbzXYpmkrpr2SuvuMq6Si3lvsaVy5C+7gLanEkvjpMDzBXWE5HPeb/hgTxA==", + "fastify@5.6.2": { + "integrity": "sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==", "dependencies": [ "@fastify/ajv-compiler", "@fastify/error", @@ -4271,7 +4244,7 @@ "process-warning@5.0.0", "rfdc", "secure-json-parse", - "semver@7.7.4", + "semver@7.7.3", "toad-cache" ] }, @@ -4322,8 +4295,8 @@ "uint8array-extras" ] }, - "file-type@21.3.0": { - "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", + "file-type@21.2.0": { + "integrity": "sha512-vCYBgFOrJQLoTzDyAXAL/RFfKnXXpUYt4+tipVy26nJJhT7ftgGETf2tAQF59EEL61i3MrorV/PG6tf7LJK7eg==", "dependencies": [ "@tokenizer/inflate", "strtok3@10.3.4", @@ -4447,8 +4420,8 @@ "is-stream" ] }, - "get-tsconfig@4.13.6": { - "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", + "get-tsconfig@4.13.0": { + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dependencies": [ "resolve-pkg-maps" ] @@ -4629,28 +4602,9 @@ "html-escaper@3.0.3": { "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" }, - "html-to-text@9.0.5": { - "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", - "dependencies": [ - "@selderee/plugin-htmlparser2", - "deepmerge", - "dom-serializer", - "htmlparser2", - "selderee" - ] - }, "html-void-elements@3.0.0": { "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==" }, - "htmlparser2@8.0.2": { - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dependencies": [ - "domelementtype", - "domhandler", - "domutils", - "entities@4.5.0" - ] - }, "http-assert@1.5.0": { "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", "dependencies": [ @@ -4741,24 +4695,24 @@ "@inquirer/core@8.2.4" ] }, - "inquirer@12.11.1_@types+node@22.19.10": { + "inquirer@12.11.1_@types+node@22.19.3": { "integrity": "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@22.19.10", + "@inquirer/core@10.3.2_@types+node@22.19.3", "@inquirer/prompts", - "@inquirer/type@3.0.10_@types+node@22.19.10", - "@types/node@22.19.10", + "@inquirer/type@3.0.10_@types+node@22.19.3", + "@types/node@22.19.3", "mute-stream@2.0.0", "run-async", "rxjs" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ] }, - "ioredis@5.9.2": { - "integrity": "sha512-tAAg/72/VxOUW7RQSX1pIxJVucYKcjFjfvj60L57jrZpYCHC3XN0WCQ3sNYL4Gmvv+7GPvTAjc+KSdeNuE8oWQ==", + "ioredis@5.9.1": { + "integrity": "sha512-BXNqFQ66oOsR82g9ajFFsR8ZKrjVvYCLyeML9IvSMAsP56XH2VXBdZjmI11p65nXXJxTEt1hie3J2QeFJVgrtQ==", "dependencies": [ "@ioredis/commands", "cluster-key-slot", @@ -5022,9 +4976,6 @@ "ky@1.14.2": { "integrity": "sha512-q3RBbsO5A5zrPhB6CaCS8ZUv+NWCXv6JJT4Em0i264G9W0fdPB8YRfnnEi7Dm7X7omAkBIPojzYJ2D1oHTHqug==" }, - "leac@0.6.0": { - "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==" - }, "levn@0.4.1": { "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dependencies": [ @@ -5037,7 +4988,7 @@ "dependencies": [ "cookie@1.1.1", "process-warning@4.0.1", - "set-cookie-parser@2.7.2" + "set-cookie-parser" ] }, "load-esm@1.0.3": { @@ -5547,7 +5498,7 @@ "glob-to-regexp", "sharp@0.33.5", "stoppable", - "undici@7.18.2", + "undici@7.14.0", "workerd", "ws", "youch", @@ -5596,10 +5547,10 @@ "mute-stream@2.0.0": { "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==" }, - "mysql2@3.18.2_@types+node@22.19.10": { + "mysql2@3.18.2_@types+node@22.19.3": { "integrity": "sha512-UfEShBFAZZEAKjySnTUuE7BgqkYT4mx+RjoJ5aqtmwSSvNcJ/QxQPXz/y3jSxNiVRedPfgccmuBtiPCSiEEytw==", "dependencies": [ - "@types/node@22.19.10", + "@types/node@22.19.3", "aws-ssl-profiles", "denque", "generate-function", @@ -5834,13 +5785,6 @@ "entities@6.0.1" ] }, - "parseley@0.12.1": { - "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", - "dependencies": [ - "leac", - "peberminta" - ] - }, "parseurl@1.3.3": { "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, @@ -5862,9 +5806,6 @@ "pathval@2.0.1": { "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==" }, - "peberminta@0.9.0": { - "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==" - }, "peek-readable@4.1.0": { "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" }, @@ -5883,17 +5824,17 @@ "picomatch@4.0.3": { "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" }, - "pino-abstract-transport@3.0.0": { - "integrity": "sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==", + "pino-abstract-transport@2.0.0": { + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", "dependencies": [ "split2" ] }, - "pino-std-serializers@7.1.0": { - "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==" + "pino-std-serializers@7.0.0": { + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==" }, - "pino@10.3.1": { - "integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==", + "pino@10.1.0": { + "integrity": "sha512-0zZC2ygfdqvqK8zJIr1e+wT1T/L+LF6qvqvbzEQ6tiMAoTqEVK9a1K3YRu8HEUvGEvNqZyPJTtb2sNIoTkB83w==", "dependencies": [ "@pinojs/redact", "atomic-sleep", @@ -5963,8 +5904,8 @@ "preact@10.19.6": { "integrity": "sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==" }, - "preact@10.28.3": { - "integrity": "sha512-tCmoRkPQLpBeWzpmbhryairGnhW9tKV6c6gr/w+RhoRoKEJwsjzipwp//1oCpGPOchvSLaAPlpcJi9MwMmoPyA==" + "preact@10.28.2": { + "integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==" }, "prelude-ls@1.2.1": { "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" @@ -6298,31 +6239,31 @@ ], "bin": true }, - "rolldown@1.0.0-rc.3": { - "integrity": "sha512-Po/YZECDOqVXjIXrtC5h++a5NLvKAQNrd9ggrIG3sbDfGO5BqTUsrI6l8zdniKRp3r5Tp/2JTrXqx4GIguFCMw==", + "rolldown@1.0.0-beta.59": { + "integrity": "sha512-Slm000Gd8/AO9z4Kxl4r8mp/iakrbAuJ1L+7ddpkNxgQ+Vf37WPvY63l3oeyZcfuPD1DRrUYBsRPIXSOhvOsmw==", "dependencies": [ - "@oxc-project/types@0.112.0", - "@rolldown/pluginutils@1.0.0-rc.3" + "@oxc-project/types@0.107.0", + "@rolldown/pluginutils@1.0.0-beta.59" ], "optionalDependencies": [ - "@rolldown/binding-android-arm64@1.0.0-rc.3", - "@rolldown/binding-darwin-arm64@1.0.0-rc.3", - "@rolldown/binding-darwin-x64@1.0.0-rc.3", - "@rolldown/binding-freebsd-x64@1.0.0-rc.3", - "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.3", - "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.3", - "@rolldown/binding-linux-arm64-musl@1.0.0-rc.3", - "@rolldown/binding-linux-x64-gnu@1.0.0-rc.3", - "@rolldown/binding-linux-x64-musl@1.0.0-rc.3", - "@rolldown/binding-openharmony-arm64@1.0.0-rc.3", - "@rolldown/binding-wasm32-wasi@1.0.0-rc.3", - "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.3", - "@rolldown/binding-win32-x64-msvc@1.0.0-rc.3" + "@rolldown/binding-android-arm64@1.0.0-beta.59", + "@rolldown/binding-darwin-arm64@1.0.0-beta.59", + "@rolldown/binding-darwin-x64@1.0.0-beta.59", + "@rolldown/binding-freebsd-x64@1.0.0-beta.59", + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.59", + "@rolldown/binding-linux-arm64-gnu@1.0.0-beta.59", + "@rolldown/binding-linux-arm64-musl@1.0.0-beta.59", + "@rolldown/binding-linux-x64-gnu@1.0.0-beta.59", + "@rolldown/binding-linux-x64-musl@1.0.0-beta.59", + "@rolldown/binding-openharmony-arm64@1.0.0-beta.59", + "@rolldown/binding-wasm32-wasi@1.0.0-beta.59", + "@rolldown/binding-win32-arm64-msvc@1.0.0-beta.59", + "@rolldown/binding-win32-x64-msvc@1.0.0-beta.59" ], "bin": true }, - "rollup@4.57.1": { - "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", + "rollup@4.55.1": { + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", "dependencies": [ "@types/estree" ], @@ -6400,18 +6341,12 @@ "secure-json-parse@4.1.0": { "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==" }, - "selderee@0.11.0": { - "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", - "dependencies": [ - "parseley" - ] - }, "semver@6.3.1": { "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": true }, - "semver@7.7.4": { - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "semver@7.7.3": { + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "bin": true }, "send@0.19.2": { @@ -6463,9 +6398,6 @@ "set-cookie-parser@2.7.2": { "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==" }, - "set-cookie-parser@3.0.1": { - "integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==" - }, "setimmediate@1.0.5": { "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, @@ -6477,7 +6409,7 @@ "dependencies": [ "color", "detect-libc", - "semver@7.7.4" + "semver@7.7.3" ], "optionalDependencies": [ "@img/sharp-darwin-arm64@0.33.5", @@ -6507,7 +6439,7 @@ "dependencies": [ "@img/colour", "detect-libc", - "semver@7.7.4" + "semver@7.7.3" ], "optionalDependencies": [ "@img/sharp-darwin-arm64@0.34.5", @@ -6559,15 +6491,15 @@ "@types/hast" ] }, - "shiki@3.22.0": { - "integrity": "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==", + "shiki@3.23.0": { + "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==", "dependencies": [ - "@shikijs/core@3.22.0", - "@shikijs/engine-javascript@3.22.0", - "@shikijs/engine-oniguruma@3.22.0", - "@shikijs/langs@3.22.0", - "@shikijs/themes@3.22.0", - "@shikijs/types@3.22.0", + "@shikijs/core@3.23.0", + "@shikijs/engine-javascript@3.23.0", + "@shikijs/engine-oniguruma@3.23.0", + "@shikijs/langs@3.23.0", + "@shikijs/themes@3.23.0", + "@shikijs/types@3.23.0", "@shikijs/vscode-textmate", "@types/hast" ] @@ -6762,8 +6694,8 @@ "has-flag" ] }, - "svelte@5.50.1_acorn@8.15.0": { - "integrity": "sha512-/Jlom4ddkISyVHXpM2O5dXP9pYnaiFrVQzPbIL1/pEoOa77ZunCb6nDgUCTNCQ/X3t64z9ukrK6R+BbB3kPR3A==", + "svelte@5.46.1_acorn@8.15.0": { + "integrity": "sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==", "dependencies": [ "@jridgewell/remapping", "@jridgewell/sourcemap-codec", @@ -6807,8 +6739,8 @@ "any-promise" ] }, - "thread-stream@4.0.0": { - "integrity": "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==", + "thread-stream@3.1.0": { + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", "dependencies": [ "real-require" ] @@ -6910,7 +6842,7 @@ "picomatch@4.0.3", "rolldown@1.0.0-beta.57", "rolldown-plugin-dts", - "semver@7.7.4", + "semver@7.7.3", "tinyexec@1.0.2", "tinyglobby", "tree-kill", @@ -6999,8 +6931,8 @@ "undici@6.23.0": { "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==" }, - "undici@7.18.2": { - "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==" + "undici@7.14.0": { + "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==" }, "unenv@2.0.0-rc.21": { "integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==", @@ -7084,8 +7016,8 @@ "unist-util-is" ] }, - "unist-util-visit@5.1.0": { - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "unist-util-visit@5.0.0": { + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dependencies": [ "@types/unist", "unist-util-is", @@ -7095,14 +7027,14 @@ "unpipe@1.0.0": { "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, - "unrun@0.2.27": { - "integrity": "sha512-Mmur1UJpIbfxasLOhPRvox/QS4xBiDii71hMP7smfRthGcwFL2OAmYRgduLANOAU4LUkvVamuP+02U+c90jlrw==", + "unrun@0.2.24": { + "integrity": "sha512-xa4/O5q2jmI6EqxweJ+sOy5cyORZWcsgmi8pmABVSUyg24Fh44qJrneUHavZEMsbJbghHYWKSraFy5hDCb/m4w==", "dependencies": [ - "rolldown@1.0.0-rc.3" + "rolldown@1.0.0-beta.59" ], "bin": true }, - "unstorage@1.17.4_ioredis@5.9.2": { + "unstorage@1.17.4_ioredis@5.9.1": { "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", "dependencies": [ "anymatch", @@ -7186,21 +7118,21 @@ "vfile-message" ] }, - "vite-node@3.2.4_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "vite-node@3.2.4_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dependencies": [ "cac", "debug@4.4.3", "es-module-lexer", "pathe", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ], "bin": true }, - "vite@6.4.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3": { + "vite@6.4.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3": { "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dependencies": [ - "@types/node@22.19.10", + "@types/node@22.19.3", "esbuild@0.25.12", "fdir", "picomatch@4.0.3", @@ -7214,16 +7146,16 @@ "fsevents" ], "optionalPeers": [ - "@types/node@22.19.10", + "@types/node@22.19.3", "tsx", "yaml" ], "bin": true }, - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3": { + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3": { "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dependencies": [ - "@types/node@22.19.10", + "@types/node@22.19.3", "esbuild@0.27.3", "fdir", "picomatch@4.0.3", @@ -7237,35 +7169,35 @@ "fsevents" ], "optionalPeers": [ - "@types/node@22.19.10", + "@types/node@22.19.3", "tsx", "yaml" ], "bin": true }, - "vitefu@1.1.1_vite@6.4.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "vitefu@1.1.1_vite@6.4.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "dependencies": [ - "vite@6.4.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@6.4.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ], "optionalPeers": [ - "vite@6.4.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@6.4.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ] }, - "vitefu@1.1.1_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2": { + "vitefu@1.1.1_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "dependencies": [ - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ], "optionalPeers": [ - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3" ] }, - "vitest@3.2.4_@types+node@22.19.10_vite@7.3.1__@types+node@22.19.10__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_tsx@4.21.0_yaml@2.8.2": { + "vitest@3.2.4_@types+node@22.19.3_vite@7.3.1__@types+node@22.19.3__tsx@4.21.0__yaml@2.8.2__picomatch@4.0.3_tsx@4.21.0_yaml@2.8.2": { "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dependencies": [ "@types/chai", - "@types/node@22.19.10", + "@types/node@22.19.3", "@vitest/expect", "@vitest/mocker", "@vitest/pretty-format", @@ -7285,12 +7217,12 @@ "tinyglobby", "tinypool", "tinyrainbow", - "vite@7.3.1_@types+node@22.19.10_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", + "vite@7.3.1_@types+node@22.19.3_tsx@4.21.0_yaml@2.8.2_picomatch@4.0.3", "vite-node", "why-is-node-running" ], "optionalPeers": [ - "@types/node@22.19.10" + "@types/node@22.19.3" ], "bin": true }, @@ -7352,7 +7284,7 @@ "scripts": true, "bin": true }, - "wrangler@4.35.0_@cloudflare+workers-types@4.20260210.0_unenv@2.0.0-rc.21_workerd@1.20250906.0": { + "wrangler@4.35.0_@cloudflare+workers-types@4.20260109.0_unenv@2.0.0-rc.21_workerd@1.20250906.0": { "integrity": "sha512-HbyXtbrh4Fi3mU8ussY85tVdQ74qpVS1vctUgaPc+bPrXBTqfDLkZ6VRtHAVF/eBhz4SFmhJtCQpN1caY2Ak8A==", "dependencies": [ "@cloudflare/kv-asset-handler", diff --git a/test/smoke/harness/backdoor.ts b/test/smoke/harness/backdoor.ts new file mode 100644 index 00000000..316e826c --- /dev/null +++ b/test/smoke/harness/backdoor.ts @@ -0,0 +1,165 @@ +import type { Federation } from "@fedify/fedify/federation"; +import { Create, Follow, Note, Undo } from "@fedify/vocab"; +import { store } from "./store.ts"; + +function json(data: unknown, status = 200): Response { + return new Response(JSON.stringify(data), { + status, + headers: { "Content-Type": "application/json" }, + }); +} + +// Build recipient manually — Mastodon's WebFinger requires HTTPS but our +// harness only has HTTP. Parse the handle (user@domain) to construct the +// actor URI and inbox URL directly. +function parseRecipient( + handle: string, +): { inboxId: URL; actorId: URL } { + const [user, domain] = handle.split("@"); + const inboxId = new URL(`http://${domain}/users/${user}/inbox`); + // Mastodon generates https:// actor URIs; use that as the canonical id + const actorId = new URL(`https://${domain}/users/${user}`); + return { inboxId, actorId }; +} + +export async function handleBackdoor( + request: Request, + federation: Federation, +): Promise { + const url = new URL(request.url); + + if (url.pathname === "/_test/health") { + return new Response("OK"); + } + + if (url.pathname === "/_test/reset" && request.method === "POST") { + store.clear(); + return json({ ok: true }); + } + + if (url.pathname === "/_test/inbox") { + return json(store.all()); + } + + if (url.pathname === "/_test/inbox/latest") { + const item = store.latest(); + if (item == null) return json(null, 404); + return json(item); + } + + if (url.pathname === "/_test/create-note" && request.method === "POST") { + const body = await request.json(); + const { to, content } = body as { to: string; content: string }; + + const ctx = federation.createContext( + new URL(request.url), + undefined as void, + ); + + const { actorId, inboxId } = parseRecipient(to); + const recipient = { id: actorId, inboxId }; + + const noteId = crypto.randomUUID(); + const note = new Note({ + id: new URL(`${ctx.canonicalOrigin}/notes/${noteId}`), + attribution: ctx.getActorUri("testuser"), + content, + to: new URL("https://www.w3.org/ns/activitystreams#Public"), + ccs: [actorId], + }); + + const activity = new Create({ + id: new URL(`${ctx.canonicalOrigin}/activities/${noteId}`), + actor: ctx.getActorUri("testuser"), + object: note, + to: new URL("https://www.w3.org/ns/activitystreams#Public"), + ccs: [actorId], + }); + + try { + await ctx.sendActivity( + { identifier: "testuser" }, + recipient, + activity, + { immediate: true }, + ); + } catch (e) { + return json({ error: `Failed to send: ${e}` }, 500); + } + + return json({ ok: true, noteId }); + } + + if (url.pathname === "/_test/follow" && request.method === "POST") { + const body = await request.json(); + const { target } = body as { target: string }; + + const ctx = federation.createContext( + new URL(request.url), + undefined as void, + ); + + const { actorId, inboxId } = parseRecipient(target); + const recipient = { id: actorId, inboxId }; + + const follow = new Follow({ + id: new URL( + `${ctx.canonicalOrigin}/activities/${crypto.randomUUID()}`, + ), + actor: ctx.getActorUri("testuser"), + object: actorId, + }); + + try { + await ctx.sendActivity( + { identifier: "testuser" }, + recipient, + follow, + { immediate: true }, + ); + } catch (e) { + return json({ error: `Failed to send: ${e}` }, 500); + } + + return json({ ok: true }); + } + + if (url.pathname === "/_test/unfollow" && request.method === "POST") { + const body = await request.json(); + const { target } = body as { target: string }; + + const ctx = federation.createContext( + new URL(request.url), + undefined as void, + ); + + const { actorId, inboxId } = parseRecipient(target); + const recipient = { id: actorId, inboxId }; + + const undo = new Undo({ + id: new URL( + `${ctx.canonicalOrigin}/activities/${crypto.randomUUID()}`, + ), + actor: ctx.getActorUri("testuser"), + object: new Follow({ + actor: ctx.getActorUri("testuser"), + object: actorId, + }), + }); + + try { + await ctx.sendActivity( + { identifier: "testuser" }, + recipient, + undo, + { immediate: true }, + ); + } catch (e) { + return json({ error: `Failed to send: ${e}` }, 500); + } + + return json({ ok: true }); + } + + return new Response("Not Found", { status: 404 }); +} diff --git a/test/smoke/harness/deno.json b/test/smoke/harness/deno.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/test/smoke/harness/deno.json @@ -0,0 +1 @@ +{} diff --git a/test/smoke/harness/federation.ts b/test/smoke/harness/federation.ts new file mode 100644 index 00000000..baac0f98 --- /dev/null +++ b/test/smoke/harness/federation.ts @@ -0,0 +1,98 @@ +import { createFederation, MemoryKvStore } from "@fedify/fedify/federation"; +import { generateCryptoKeyPair } from "@fedify/fedify/sig"; +import { Accept, Activity, Create, Follow, Person } from "@fedify/vocab"; +import { store } from "./store.ts"; + +const ORIGIN = Deno.env.get("HARNESS_ORIGIN") ?? + "http://fedify-harness:3001"; + +const rsaKeyPair = await generateCryptoKeyPair("RSASSA-PKCS1-v1_5"); + +const federation = createFederation({ + kv: new MemoryKvStore(), + origin: ORIGIN, + allowPrivateAddress: true, + skipSignatureVerification: true, +}); + +federation + .setActorDispatcher("/users/{identifier}", async (ctx, identifier) => { + if (identifier !== "testuser") return null; + const keys = await ctx.getActorKeyPairs(identifier); + return new Person({ + id: ctx.getActorUri(identifier), + preferredUsername: identifier, + name: "Fedify Smoke Test User", + inbox: ctx.getInboxUri(identifier), + outbox: ctx.getOutboxUri(identifier), + followers: ctx.getFollowersUri(identifier), + url: ctx.getActorUri(identifier), + publicKey: keys[0].cryptographicKey, + assertionMethods: keys.map((k) => k.multikey), + }); + }) + .setKeyPairsDispatcher((_ctx, identifier) => { + if (identifier !== "testuser") return []; + return [rsaKeyPair]; + }); + +federation + .setInboxListeners("/users/{identifier}/inbox", "/inbox") + .on(Follow, async (ctx, follow) => { + const followerUri = follow.actorId; + store.push({ + id: follow.id?.href ?? crypto.randomUUID(), + type: "Follow", + receivedAt: new Date().toISOString(), + }); + if (!ctx.recipient || !followerUri) return; + + // Build the recipient manually instead of calling getActor(), because + // Mastodon generates https:// actor URIs but only serves HTTP. + // Rewrite the scheme so sendActivity POSTs over plain HTTP. + const httpActorUri = followerUri.href.replace(/^https:\/\//, "http://"); + const recipient = { + id: followerUri, + inboxId: new URL(`${httpActorUri}/inbox`), + }; + + const accept = new Accept({ + actor: ctx.getActorUri(ctx.recipient), + object: follow, + }); + await ctx.sendActivity( + { identifier: ctx.recipient }, + recipient, + accept, + { immediate: true }, + ); + }) + .on(Create, (_ctx, create) => { + store.push({ + id: create.id?.href ?? crypto.randomUUID(), + type: "Create", + receivedAt: new Date().toISOString(), + }); + }) + .on(Activity, (_ctx, activity) => { + // Don't double-store Create or Follow activities (already handled above) + if (!(activity instanceof Create) && !(activity instanceof Follow)) { + store.push({ + id: activity.id?.href ?? crypto.randomUUID(), + type: activity.constructor.name, + receivedAt: new Date().toISOString(), + }); + } + }); + +federation.setOutboxDispatcher( + "/users/{identifier}/outbox", + (_ctx, _identifier, _cursor) => ({ items: [] }), +); + +federation.setFollowersDispatcher( + "/users/{identifier}/followers", + (_ctx, _identifier, _cursor) => ({ items: [] }), +); + +export { federation }; diff --git a/test/smoke/harness/main.ts b/test/smoke/harness/main.ts new file mode 100644 index 00000000..d7eb8c0d --- /dev/null +++ b/test/smoke/harness/main.ts @@ -0,0 +1,20 @@ +import { federation } from "./federation.ts"; +import { handleBackdoor } from "./backdoor.ts"; + +const PORT = parseInt(Deno.env.get("HARNESS_PORT") ?? "3001"); + +Deno.serve({ port: PORT, hostname: "0.0.0.0" }, async (request: Request) => { + const url = new URL(request.url); + + // Backdoor test-control routes + if (url.pathname.startsWith("/_test/")) { + return await handleBackdoor(request, federation); + } + + // Federation routes (actor, inbox, webfinger, etc.) + return await federation.fetch(request, { + contextData: undefined, + onNotFound: () => new Response("Not Found", { status: 404 }), + onNotAcceptable: () => new Response("Not Acceptable", { status: 406 }), + }); +}); diff --git a/test/smoke/harness/store.ts b/test/smoke/harness/store.ts new file mode 100644 index 00000000..19de3402 --- /dev/null +++ b/test/smoke/harness/store.ts @@ -0,0 +1,22 @@ +export interface ReceivedActivity { + id: string; + type: string; + receivedAt: string; +} + +const inbox: ReceivedActivity[] = []; + +export const store = { + push(a: ReceivedActivity): void { + inbox.push(a); + }, + latest(): ReceivedActivity | null { + return inbox.at(-1) ?? null; + }, + all(): ReceivedActivity[] { + return [...inbox]; + }, + clear(): void { + inbox.splice(0); + }, +}; diff --git a/test/smoke/mastodon/disable_force_ssl.rb b/test/smoke/mastodon/disable_force_ssl.rb new file mode 100644 index 00000000..0fbfaee4 --- /dev/null +++ b/test/smoke/mastodon/disable_force_ssl.rb @@ -0,0 +1,3 @@ +# Disable force_ssl for smoke tests so HTTP works without HTTPS proxy. +# Mastodon production mode enables force_ssl regardless of LOCAL_HTTPS. +Rails.application.config.force_ssl = false diff --git a/test/smoke/mastodon/docker-compose.yml b/test/smoke/mastodon/docker-compose.yml new file mode 100644 index 00000000..b3ecd9cc --- /dev/null +++ b/test/smoke/mastodon/docker-compose.yml @@ -0,0 +1,91 @@ +volumes: + harness-node-modules: + +networks: + smoke: + driver: bridge + +services: + db: + image: postgres:15-alpine + environment: + POSTGRES_DB: mastodon + POSTGRES_USER: mastodon + POSTGRES_PASSWORD: mastodon + networks: [smoke] + healthcheck: + test: ["CMD", "pg_isready", "-U", "mastodon"] + interval: 5s + retries: 10 + + redis: + image: redis:7-alpine + networks: [smoke] + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + retries: 10 + + # Fedify test harness — runs inside the Docker network so Mastodon's + # Resolv::DNS can resolve "fedify-harness" natively via Docker DNS. + fedify-harness: + image: denoland/deno:2.7.1 + working_dir: /workspace + volumes: + - ../../../:/workspace + - harness-node-modules:/workspace/node_modules + command: + - run + - --allow-net + - --allow-env + - --allow-read + - --allow-write + - --unstable-temporal + - test/smoke/harness/main.ts + environment: + HARNESS_ORIGIN: "http://fedify-harness:3001" + networks: [smoke] + ports: ["3001:3001"] + healthcheck: + test: + [ + "CMD", + "deno", + "eval", + "const r = await fetch('http://localhost:3001/_test/health'); if (!r.ok) Deno.exit(1);", + ] + interval: 5s + retries: 30 + + mastodon-web: + image: ghcr.io/mastodon/mastodon:v4.3.9 + command: bundle exec rails s -p 3000 -b 0.0.0.0 + env_file: mastodon.env + volumes: + - ./disable_force_ssl.rb:/opt/mastodon/config/initializers/zz_disable_force_ssl.rb:ro + networks: + smoke: + aliases: [mastodon] + ports: ["3000:3000"] + depends_on: + db: { condition: service_healthy } + redis: { condition: service_healthy } + healthcheck: + test: + [ + "CMD-SHELL", + "curl -sf http://localhost:3000/health | grep -q OK", + ] + interval: 10s + retries: 18 + + mastodon-sidekiq: + image: ghcr.io/mastodon/mastodon:v4.3.9 + command: bundle exec sidekiq -q ingress -q default -q push + env_file: mastodon.env + volumes: + - ./disable_force_ssl.rb:/opt/mastodon/config/initializers/zz_disable_force_ssl.rb:ro + networks: [smoke] + depends_on: + mastodon-web: { condition: service_healthy } + fedify-harness: { condition: service_healthy } diff --git a/test/smoke/mastodon/mastodon.env b/test/smoke/mastodon/mastodon.env new file mode 100644 index 00000000..16fee3a2 --- /dev/null +++ b/test/smoke/mastodon/mastodon.env @@ -0,0 +1,24 @@ +# Mastodon configuration for smoke tests. +# SECRET_KEY_BASE, OTP_SECRET, VAPID_*, and ACTIVE_RECORD_ENCRYPTION_* +# are appended by CI (see .github/workflows/smoke-mastodon.yml). + +LOCAL_DOMAIN=mastodon:3000 +ALTERNATE_DOMAINS=localhost:3000 +LOCAL_HTTPS=false +RAILS_ENV=production +DB_HOST=db +DB_PORT=5432 +DB_NAME=mastodon +DB_USER=mastodon +DB_PASS=mastodon +REDIS_HOST=redis +REDIS_PORT=6379 +SMTP_SERVER=localhost +SMTP_PORT=25 +SMTP_FROM_ADDRESS=noreply@localhost +SMTP_AUTH_METHOD=none +SMTP_OPENSSL_VERIFY_MODE=none +SMTP_DELIVERY_METHOD=none +ES_ENABLED=false +RAILS_LOG_TO_STDOUT=true +ALLOWED_PRIVATE_ADDRESSES=0.0.0.0/0 diff --git a/test/smoke/mastodon/provision.sh b/test/smoke/mastodon/provision.sh new file mode 100755 index 00000000..112576bb --- /dev/null +++ b/test/smoke/mastodon/provision.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +set -euo pipefail + +COMPOSE="docker compose -f test/smoke/mastodon/docker-compose.yml" + +echo "→ Creating test user..." +$COMPOSE exec -T mastodon-web bin/tootctl accounts create \ + testuser --email=test@localhost --confirmed \ + || true # may already exist on re-run + +echo "→ Approving and activating test user..." +$COMPOSE exec -T mastodon-web bin/rails runner - <<'RUBY' +user = Account.find_local('testuser').user +user.update!(approved: true, confirmed_at: Time.now.utc) +user.approve! if user.respond_to?(:approve!) +RUBY + +echo "→ Generating API token via Rails..." +# Use a unique marker so we can extract just the token from rails runner +# output, which may include deprecation warnings or other noise on stdout. +RAW=$($COMPOSE exec -T mastodon-web bin/rails runner - <<'RUBY' 2>&1 | tr -d '\r' +user = Account.find_local('testuser').user +app = Doorkeeper::Application.find_or_create_by!(name: 'smoke-test') do |a| + a.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob' + a.scopes = 'read write follow' +end +token = Doorkeeper::AccessToken.find_or_create_for( + application: app, + resource_owner: user, + scopes: Doorkeeper::OAuth::Scopes.from_string('read write follow'), + expires_in: nil, + use_refresh_token: false +) +print "SMOKE_TOKEN=#{token.token}" +RUBY +) + +TOKEN=$(echo "$RAW" | grep -oP 'SMOKE_TOKEN=\K\S+' | tail -1) + +if [ -z "$TOKEN" ]; then + echo "✗ Failed to generate API token" + exit 1 +fi + +# Verify token works with a simple API call +echo "→ Verifying token..." +HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' \ + -H "Authorization: Bearer $TOKEN" \ + http://localhost:3000/api/v1/accounts/verify_credentials) +echo " verify_credentials → HTTP $HTTP_CODE" +if [ "$HTTP_CODE" != "200" ]; then + echo "✗ Token verification failed (HTTP $HTTP_CODE)" + exit 1 +fi + +echo "→ Pre-registering Fedify remote account in Mastodon..." +# Mastodon's WebFinger resolution hardcodes HTTPS, but our harness is HTTP. +# Insert the remote account directly into Mastodon's database with values +# matching the harness actor dispatcher configuration. +HARNESS_ORIGIN="http://fedify-harness:3001" +$COMPOSE exec -T -e HARNESS_ORIGIN="$HARNESS_ORIGIN" \ + mastodon-web bin/rails runner - <<'RUBY' +origin = ENV.fetch('HARNESS_ORIGIN') +account = Account.find_or_initialize_by( + username: 'testuser', + domain: 'fedify-harness:3001' +) +account.update!( + protocol: :activitypub, + uri: "#{origin}/users/testuser", + url: "#{origin}/users/testuser", + inbox_url: "#{origin}/users/testuser/inbox", + shared_inbox_url: "#{origin}/inbox", + outbox_url: "#{origin}/users/testuser/outbox", + followers_url: "#{origin}/users/testuser/followers", + display_name: 'Fedify Smoke Test User', + note: '', + actor_type: 'Person' +) +print "REGISTERED=#{account.id}" +RUBY + +echo "→ Fetching Fedify actor public key..." +# The harness is already running inside Docker. Fetch its actor document +# and store the public key so Mastodon can verify HTTP signatures without +# needing WebFinger (which hardcodes HTTPS). +$COMPOSE exec -T mastodon-web bin/rails runner - <<'RUBY' +require 'net/http' +require 'json' + +uri = URI('http://fedify-harness:3001/users/testuser') +req = Net::HTTP::Get.new(uri) +req['Accept'] = 'application/activity+json' +res = Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) } + +unless res.is_a?(Net::HTTPSuccess) + abort "Failed to fetch actor: HTTP #{res.code}" +end + +actor = JSON.parse(res.body) +pem = actor.dig('publicKey', 'publicKeyPem') +abort "No publicKey in actor document" if pem.nil? + +account = Account.find_by!(username: 'testuser', domain: 'fedify-harness:3001') +account.update!(public_key: pem) +print "KEY_STORED=#{account.id}" +RUBY + +echo "→ Creating follow relationship (Fedify → Mastodon) in DB..." +# Ensure the Fedify account follows the Mastodon account in the DB. +# This guarantees that when Mastodon posts a status, it will deliver +# to the Fedify inbox via the followers path (StatusReachFinder). +$COMPOSE exec -T mastodon-web bin/rails runner - <<'RUBY' +fedify_account = Account.find_by!(username: 'testuser', domain: 'fedify-harness:3001') +local_account = Account.find_local('testuser') +follow = Follow.find_or_create_by!(account: fedify_account, target_account: local_account) +print "FOLLOW=#{follow.id}" +RUBY + +echo "→ Writing test env..." +cat > test/smoke/.env.test <( + label: string, + fn: () => Promise, +): Promise { + const deadline = Date.now() + POLL_TIMEOUT_MS; + let lastError: unknown = null; + while (Date.now() < deadline) { + try { + const result = await fn(); + if (result !== null) return result; + } catch (err) { + lastError = err; + } + await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS)); + } + const suffix = lastError instanceof Error + ? ` (last error: ${lastError.message})` + : ""; + throw new Error(`Timed out waiting for: ${label}${suffix}`); +} + +function pollHarnessInbox( + activityType: string, +): Promise<{ type: string; id: string }> { + return poll(`${activityType} in harness inbox`, async () => { + const res = await fetch(`${HARNESS_URL}/_test/inbox`); + const items = await res.json() as { type: string; id: string }[]; + return items.find((a) => a.type === activityType) ?? null; + }); +} + +async function serverGet(path: string): Promise { + const res = await fetch(`${SERVER_URL}${path}`, { + headers: { Authorization: `Bearer ${SERVER_TOKEN}` }, + }); + if (!res.ok) { + const body = await res.text(); + throw new Error(`Server GET ${path} → ${res.status}: ${body}`); + } + return res.json(); +} + +async function serverPost( + path: string, + body?: Record, +): Promise { + const res = await fetch(`${SERVER_URL}${path}`, { + method: "POST", + headers: { + Authorization: `Bearer ${SERVER_TOKEN}`, + "Content-Type": body ? "application/json" : "text/plain", + }, + body: body ? JSON.stringify(body) : undefined, + }); + if (!res.ok) { + const text = await res.text(); + throw new Error(`Server POST ${path} → ${res.status}: ${text}`); + } + return res.json(); +} + +async function harnessPost( + path: string, + body?: Record, +): Promise { + const res = await fetch(`${HARNESS_URL}${path}`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: body ? JSON.stringify(body) : undefined, + }); + if (!res.ok) { + const text = await res.text(); + throw new Error(`Harness POST ${path} → ${res.status}: ${text}`); + } + return res.json(); +} + +// --------------------------------------------------------------------------- +// Shared types +// --------------------------------------------------------------------------- + +type RemoteAccount = { id: string; acct: string }; +type Relationship = { + id: string; + following: boolean; + followed_by: boolean; +}; + +// Resolved once by the first follow scenario and reused by later scenarios. +let fedifyAccountId: string | undefined; + +async function lookupFedifyAccount(): Promise { + if (fedifyAccountId) return fedifyAccountId; + + const handle = `testuser@${HARNESS_HOST}`; + + const searchResult = await poll("Fedify user resolvable", async () => { + const results = await serverGet( + `/api/v1/accounts/search?q=${ + encodeURIComponent(`@${handle}`) + }&resolve=false&limit=5`, + ) as RemoteAccount[]; + const match = results?.find((a) => + a.acct === handle || a.acct === `@${handle}` + ); + return match ?? null; + }); + + fedifyAccountId = searchResult.id; + return fedifyAccountId; +} + +async function assertNotFollowing( + accountId: string, + direction: "following" | "followed_by", +): Promise { + const rels = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const rel = rels.find((r) => r.id === accountId); + if (rel && rel[direction]) { + throw new Error( + `Expected ${direction} to be false, but it was true (account ${accountId})`, + ); + } +} + +async function ensureNotFollowing( + accountId: string, + direction: "following" | "followed_by", +): Promise { + const rels = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const rel = rels.find((r) => r.id === accountId); + if (rel?.[direction]) { + if (direction === "following") { + await serverPost(`/api/v1/accounts/${accountId}/unfollow`); + } else { + // Ask the harness to send Undo Follow to clear followed_by + await harnessPost("/_test/unfollow", { + target: `testuser@${SERVER_INTERNAL_HOST}`, + }); + } + // Wait for the relationship to actually clear + await poll(`${direction} cleared`, async () => { + const updated = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const r = updated.find((r) => r.id === accountId); + return r && !r[direction] ? r : null; + }); + } +} + +// --------------------------------------------------------------------------- +// Scenario: Mastodon → Fedify (Follow) +// --------------------------------------------------------------------------- + +async function testFollowMastodonToFedify(): Promise { + await harnessPost("/_test/reset"); + const accountId = await lookupFedifyAccount(); + await ensureNotFollowing(accountId, "following"); + await assertNotFollowing(accountId, "following"); + await serverPost(`/api/v1/accounts/${accountId}/follow`); + + await pollHarnessInbox("Follow"); + + await poll("follow accepted", async () => { + const rels = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const rel = rels.find((r) => r.id === accountId); + return rel?.following ? rel : null; + }); +} + +// --------------------------------------------------------------------------- +// Scenario: Fedify → Mastodon (Follow) +// --------------------------------------------------------------------------- + +async function testFollowFedifyToMastodon(): Promise { + await harnessPost("/_test/reset"); + const accountId = await lookupFedifyAccount(); + await ensureNotFollowing(accountId, "followed_by"); + await assertNotFollowing(accountId, "followed_by"); + + await harnessPost("/_test/follow", { + target: `testuser@${SERVER_INTERNAL_HOST}`, + }); + + await poll("followed_by on Mastodon", async () => { + const rels = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const rel = rels.find((r) => r.id === accountId); + return rel?.followed_by ? rel : null; + }); + + await pollHarnessInbox("Accept"); +} + +// --------------------------------------------------------------------------- +// Scenario: Fedify → Mastodon (Create Note) +// --------------------------------------------------------------------------- + +async function testCreateNote(): Promise { + await harnessPost("/_test/reset"); + + const content = `Smoke test ${Date.now()}`; + await harnessPost("/_test/create-note", { + to: `testuser@${SERVER_INTERNAL_HOST}`, + content, + }); + + type Status = { id: string; content: string }; + + await poll("note on Mastodon timeline", async () => { + const statuses = await serverGet( + "/api/v1/timelines/home?limit=20", + ) as Status[]; + return statuses.find((s) => s.content.includes(content)) ?? null; + }); +} + +// --------------------------------------------------------------------------- +// Scenario: Mastodon → Fedify (Reply) +// --------------------------------------------------------------------------- + +async function testReply(): Promise { + await harnessPost("/_test/reset"); + + // Find a note from the Fedify harness on the Mastodon timeline to reply to. + type Status = { id: string; content: string; account: { acct: string } }; + const parent = await poll("find Fedify note to reply to", async () => { + const statuses = await serverGet( + "/api/v1/timelines/home?limit=20", + ) as Status[]; + return statuses.find((s) => s.account.acct.includes(HARNESS_HOST)) ?? + null; + }); + + const handle = `@testuser@${HARNESS_HOST}`; + const replyContent = `Reply smoke test ${Date.now()} ${handle}`; + + await serverPost("/api/v1/statuses", { + status: replyContent, + in_reply_to_id: parent.id, + }); + + await pollHarnessInbox("Create"); +} + +// --------------------------------------------------------------------------- +// Scenario: Mastodon → Fedify (Unfollow) +// --------------------------------------------------------------------------- + +async function testUnfollowMastodonFromFedify(): Promise { + await harnessPost("/_test/reset"); + + const accountId = await lookupFedifyAccount(); + await serverPost(`/api/v1/accounts/${accountId}/unfollow`); + + await pollHarnessInbox("Undo"); + + await poll("unfollow confirmed", async () => { + const rels = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const rel = rels.find((r) => r.id === accountId); + return rel && !rel.following ? rel : null; + }); +} + +// --------------------------------------------------------------------------- +// Scenario: Fedify → Mastodon (Unfollow) +// --------------------------------------------------------------------------- + +async function testUnfollowFedifyFromMastodon(): Promise { + await harnessPost("/_test/reset"); + + const accountId = await lookupFedifyAccount(); + + await harnessPost("/_test/unfollow", { + target: `testuser@${SERVER_INTERNAL_HOST}`, + }); + + await poll("unfollow confirmed on Mastodon", async () => { + const rels = await serverGet( + `/api/v1/accounts/relationships?id[]=${accountId}`, + ) as Relationship[]; + const rel = rels.find((r) => r.id === accountId); + return rel && !rel.followed_by ? rel : null; + }); +} + +// --------------------------------------------------------------------------- +// Entry point +// --------------------------------------------------------------------------- + +try { + const scenarios: [string, () => Promise][] = [ + ["Mastodon → Fedify (Follow)", testFollowMastodonToFedify], + ["Fedify → Mastodon (Follow)", testFollowFedifyToMastodon], + ["Fedify → Mastodon (Create Note)", testCreateNote], + ["Mastodon → Fedify (Reply)", testReply], + ["Mastodon → Fedify (Unfollow)", testUnfollowMastodonFromFedify], + ["Fedify → Mastodon (Unfollow)", testUnfollowFedifyFromMastodon], + ]; + + let failed = false; + for (const [name, fn] of scenarios) { + try { + await fn(); + console.log(`✓ ${name}`); + } catch (err) { + console.error(`✗ ${name}:`, err); + failed = true; + } + } + + Deno.exit(failed ? 1 : 0); +} catch (err) { + console.error("\n✗ Unexpected error:", err); + Deno.exit(1); +}