From 86aa6d6ec05204046cb4762fec2054142a84db03 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Mon, 13 Apr 2026 02:10:40 +0000 Subject: [PATCH 01/26] Create examples/nuxt with Claude Opus 4.6 --- deno.lock | 990 +++++++++--------- examples/nuxt/.gitignore | 5 + examples/nuxt/README.md | 45 + examples/nuxt/app.vue | 13 + examples/nuxt/nuxt.config.ts | 9 + examples/nuxt/package.json | 27 + examples/nuxt/pages/index.vue | 287 +++++ .../nuxt/pages/users/[identifier]/index.vue | 71 ++ .../pages/users/[identifier]/posts/[id].vue | 61 ++ examples/nuxt/public/demo-profile.png | Bin 0 -> 51021 bytes examples/nuxt/public/fedify-logo.svg | 180 ++++ examples/nuxt/public/style.css | 505 +++++++++ examples/nuxt/public/theme.js | 7 + examples/nuxt/server/api/events.get.ts | 36 + examples/nuxt/server/api/follow.post.ts | 42 + examples/nuxt/server/api/home.get.ts | 51 + examples/nuxt/server/api/post.post.ts | 44 + .../server/api/posts/[identifier]/[id].get.ts | 33 + .../server/api/profile/[identifier].get.ts | 29 + examples/nuxt/server/api/search.get.ts | 37 + examples/nuxt/server/api/unfollow.post.ts | 46 + examples/nuxt/server/federation.ts | 163 +++ examples/nuxt/server/plugins/logging.ts | 25 + examples/nuxt/server/sse.ts | 21 + examples/nuxt/server/store.ts | 50 + examples/nuxt/tsconfig.json | 3 + examples/test-examples/mod.ts | 13 + pnpm-lock.yaml | 473 ++++----- pnpm-workspace.yaml | 1 + 29 files changed, 2477 insertions(+), 790 deletions(-) create mode 100644 examples/nuxt/.gitignore create mode 100644 examples/nuxt/README.md create mode 100644 examples/nuxt/app.vue create mode 100644 examples/nuxt/nuxt.config.ts create mode 100644 examples/nuxt/package.json create mode 100644 examples/nuxt/pages/index.vue create mode 100644 examples/nuxt/pages/users/[identifier]/index.vue create mode 100644 examples/nuxt/pages/users/[identifier]/posts/[id].vue create mode 100644 examples/nuxt/public/demo-profile.png create mode 100644 examples/nuxt/public/fedify-logo.svg create mode 100644 examples/nuxt/public/style.css create mode 100644 examples/nuxt/public/theme.js create mode 100644 examples/nuxt/server/api/events.get.ts create mode 100644 examples/nuxt/server/api/follow.post.ts create mode 100644 examples/nuxt/server/api/home.get.ts create mode 100644 examples/nuxt/server/api/post.post.ts create mode 100644 examples/nuxt/server/api/posts/[identifier]/[id].get.ts create mode 100644 examples/nuxt/server/api/profile/[identifier].get.ts create mode 100644 examples/nuxt/server/api/search.get.ts create mode 100644 examples/nuxt/server/api/unfollow.post.ts create mode 100644 examples/nuxt/server/federation.ts create mode 100644 examples/nuxt/server/plugins/logging.ts create mode 100644 examples/nuxt/server/sse.ts create mode 100644 examples/nuxt/server/store.ts create mode 100644 examples/nuxt/tsconfig.json diff --git a/deno.lock b/deno.lock index 0a79f5092..bcbfec309 100644 --- a/deno.lock +++ b/deno.lock @@ -2,28 +2,27 @@ "version": "5", "specifiers": { "jsr:@alinea/suite@~0.6.3": "0.6.3", - "jsr:@david/console-static-text@0.3": "0.3.0", + "jsr:@david/console-static-text@0.3": "0.3.4", "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:@david/which@~0.4.1": "0.4.2", "jsr:@deno/esbuild-plugin@^1.2.0": "1.2.1", - "jsr:@deno/loader@~0.3.10": "0.3.11", - "jsr:@deno/loader@~0.3.2": "0.3.11", + "jsr:@deno/loader@~0.3.10": "0.3.14", + "jsr:@deno/loader@~0.3.2": "0.3.14", "jsr:@fresh/build-id@1": "1.0.1", - "jsr:@fresh/core@2": "2.2.0", - "jsr:@fresh/core@^2.1.4": "2.2.2", - "jsr:@fresh/core@^2.2.0": "2.2.0", + "jsr:@fresh/core@2": "2.3.0", + "jsr:@fresh/core@^2.1.4": "2.3.0", + "jsr:@fresh/core@^2.2.0": "2.3.0", "jsr:@fresh/plugin-vite@^1.0.7": "1.0.8", "jsr:@hongminhee/localtunnel@0.3": "0.3.0", - "jsr:@hono/hono@^4.7.1": "4.12.4", - "jsr:@hono/hono@^4.8.3": "4.12.12", + "jsr:@hono/hono@^4.7.1": "4.12.15", + "jsr:@hono/hono@^4.8.3": "4.12.15", "jsr:@logtape/file@^2.0.5": "2.0.5", "jsr:@logtape/logtape@^1.0.4": "1.3.7", "jsr:@logtape/logtape@^2.0.5": "2.0.5", "jsr:@optique/config@^1.0.2": "1.0.2", "jsr:@optique/core@^1.0.2": "1.0.2", "jsr:@optique/run@^1.0.2": "1.0.2", - "jsr:@standard-schema/spec@^1.1.0": "1.1.0", "jsr:@std/assert@0.224": "0.224.0", "jsr:@std/assert@0.226": "0.226.0", "jsr:@std/assert@^1.0.13": "1.0.19", @@ -32,22 +31,23 @@ "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.10", + "jsr:@std/fmt@^1.0.7": "1.0.10", + "jsr:@std/fmt@^1.0.8": "1.0.10", "jsr:@std/fs@0.224": "0.224.0", "jsr:@std/fs@1": "1.0.23", "jsr:@std/fs@^1.0.19": "1.0.23", "jsr:@std/fs@^1.0.3": "1.0.23", - "jsr:@std/html@^1.0.5": "1.0.5", - "jsr:@std/http@^1.0.21": "1.0.25", + "jsr:@std/html@^1.0.5": "1.0.6", + "jsr:@std/http@^1.0.21": "1.1.0", "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/internal@1": "1.0.13", + "jsr:@std/internal@^1.0.12": "1.0.13", "jsr:@std/io@0.225": "0.225.3", "jsr:@std/json@^1.0.2": "1.0.3", "jsr:@std/jsonc@^1.0.2": "1.0.2", "jsr:@std/media-types@^1.1.0": "1.1.0", + "jsr:@std/net@^1.0.6": "1.0.6", "jsr:@std/path@0.224": "0.224.0", "jsr:@std/path@1": "1.1.4", "jsr:@std/path@^1.0.6": "1.1.4", @@ -61,52 +61,51 @@ "jsr:@std/yaml@^1.0.8": "1.0.12", "jsr:@valibot/valibot@^1.2.0": "1.3.1", "npm:@alinea/suite@~0.6.3": "0.6.3", - "npm:@astrojs/node@^10.0.3": "10.0.4_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3_@types+node@24.12.0_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3", + "npm:@astrojs/node@^10.0.3": "10.0.5_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3", "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:@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@24.12.0__tsx@4.21.0__yaml@2.8.3_@cloudflare+workers-types@4.20260403.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "npm:@cloudflare/workers-types@^4.20250529.0": "4.20260403.1", - "npm:@cloudflare/workers-types@^4.20250906.0": "4.20260403.1", - "npm:@deno/astro-adapter@~0.3.2": "0.3.2_@opentelemetry+api@1.9.1_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3_@types+node@24.12.0_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3", + "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@24.12.2__tsx@4.21.0__yaml@2.8.3_@cloudflare+workers-types@4.20260417.1_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "npm:@cloudflare/workers-types@^4.20250529.0": "4.20260417.1", + "npm:@cloudflare/workers-types@^4.20250906.0": "4.20260417.1", + "npm:@deno/astro-adapter@~0.3.2": "0.3.2_@opentelemetry+api@1.9.1_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3", "npm:@fxts/core@^1.21.1": "1.26.0", "npm:@hongminhee/localtunnel@0.3": "0.3.0", - "npm:@inquirer/prompts@^7.8.4": "7.10.1_@types+node@24.12.0", - "npm:@jimp/core@^1.6.0": "1.6.0", - "npm:@jimp/wasm-webp@^1.6.0": "1.6.0", + "npm:@inquirer/prompts@^7.8.4": "7.10.1_@types+node@24.12.2", + "npm:@jimp/core@^1.6.0": "1.6.1", + "npm:@jimp/wasm-webp@^1.6.0": "1.6.1", "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.17_reflect-metadata@0.2.2_rxjs@7.8.2", - "npm:@nurodev/astro-bun@^2.1.2": "2.1.2_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3", + "npm:@nestjs/common@^11.0.1": "11.1.19_reflect-metadata@0.2.2_rxjs@7.8.2", + "npm:@nurodev/astro-bun@^2.1.2": "2.1.2_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3", "npm:@nuxt/kit@4": "4.4.2", "npm:@nuxt/schema@4": "4.4.2", "npm:@opentelemetry/api@^1.9.0": "1.9.1", - "npm:@opentelemetry/context-async-hooks@^2.5.0": "2.6.1_@opentelemetry+api@1.9.1", - "npm:@opentelemetry/core@^2.5.0": "2.6.1_@opentelemetry+api@1.9.1", - "npm:@opentelemetry/sdk-trace-base@^2.5.0": "2.6.1_@opentelemetry+api@1.9.1", + "npm:@opentelemetry/context-async-hooks@^2.5.0": "2.7.0_@opentelemetry+api@1.9.1", + "npm:@opentelemetry/core@^2.5.0": "2.7.0_@opentelemetry+api@1.9.1", + "npm:@opentelemetry/sdk-trace-base@^2.5.0": "2.7.0_@opentelemetry+api@1.9.1", "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.9.0_preact@10.29.0", - "npm:@preact/signals@^2.3.2": "2.9.0_preact@10.29.0", - "npm:@preact/signals@^2.5.1": "2.9.0_preact@10.29.0", - "npm:@prefresh/vite@^2.4.8": "2.4.12_preact@10.29.0_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3", - "npm:@solidjs/start@^1.3.0": "1.3.2_vinxi@0.5.11__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2__@types+node@24.12.0__ioredis@5.10.1__mysql2@3.20.0___@types+node@24.12.0__rolldown@1.0.0-rc.12___@emnapi+core@1.9.2___@emnapi+runtime@1.9.2__tsx@4.21.0__yaml@2.8.3_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2_@types+node@24.12.0_ioredis@5.10.1_mysql2@3.20.0__@types+node@24.12.0_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_solid-js@1.9.12_tsx@4.21.0_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_yaml@2.8.3", + "npm:@preact/signals@^2.3.2": "2.9.0_preact@10.29.1", + "npm:@preact/signals@^2.5.1": "2.9.0_preact@10.29.1", + "npm:@prefresh/vite@^2.4.8": "2.4.12_preact@10.29.1_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3", + "npm:@solidjs/start@^1.3.0": "1.3.2_vinxi@0.5.11__@types+node@24.12.2__ioredis@5.10.1__mysql2@3.22.1___@types+node@24.12.2__rolldown@1.0.0-rc.16__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_mysql2@3.22.1__@types+node@24.12.2_rolldown@1.0.0-rc.16_solid-js@1.9.12_tsx@4.21.0_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_yaml@2.8.3", "npm:@standard-schema/spec@^1.1.0": "1.1.0", - "npm:@sveltejs/kit@2": "2.55.0_@opentelemetry+api@1.9.1_@sveltejs+vite-plugin-svelte@7.0.0__svelte@5.55.1__vite@7.3.1___@types+node@24.12.0___tsx@4.21.0___yaml@2.8.3__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_svelte@5.55.1_typescript@6.0.2_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", + "npm:@sveltejs/kit@2": "2.57.1_@opentelemetry+api@1.9.1_@sveltejs+vite-plugin-svelte@7.0.0__svelte@5.55.4__vite@7.3.2___@types+node@24.12.2___tsx@4.21.0___yaml@2.8.3__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_svelte@5.55.4_typescript@6.0.3_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", "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.15", - "npm:@types/node@^24.2.1": "24.12.0", - "npm:@typescript-eslint/parser@^8.49.0": "8.58.0_eslint@9.39.4_typescript@6.0.2", - "npm:@typescript-eslint/utils@8": "8.58.0_eslint@9.39.4_typescript@6.0.2", + "npm:@types/node@^22.16.0": "22.19.17", + "npm:@types/node@^24.2.1": "24.12.2", + "npm:@typescript-eslint/parser@^8.49.0": "8.58.2_eslint@9.39.4_typescript@6.0.3", + "npm:@typescript-eslint/utils@8": "8.58.2_eslint@9.39.4_typescript@6.0.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": "5.18.1_@types+node@24.12.0_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3", + "npm:astro@^5.17.3": "5.18.1_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3", "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", @@ -125,47 +124,46 @@ "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.8.4", + "npm:fastify@^5.2.0": "5.8.5", "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.11", - "npm:hono@^4.8.3": "4.12.10", + "npm:hono@^4.8.3": "4.12.14", "npm:icojs@~0.19.5": "0.19.5_@jimp+custom@0.22.12", "npm:inquirer-toggle@^1.0.1": "1.0.1", - "npm:inquirer@^12.9.4": "12.11.1_@types+node@24.12.0", + "npm:inquirer@^12.9.4": "12.11.1_@types+node@24.12.2", "npm:ioredis@^5.8.2": "5.10.1", - "npm:jimp@^1.6.0": "1.6.0", + "npm:jimp@^1.6.0": "1.6.1", "npm:json-canon@^1.0.1": "1.0.1", "npm:json-preserve-indent@^1.1.3": "1.1.3", "npm:jsonld@9": "9.0.0", "npm:koa@2": "2.16.4", "npm:miniflare@^4.20250523.0": "4.20250906.0", - "npm:mysql2@^3.18.0": "3.20.0_@types+node@24.12.0", + "npm:mysql2@^3.18.0": "3.22.1_@types+node@24.12.2", "npm:ora@^8.2.0": "8.2.0", "npm:pkijs@^3.2.5": "3.4.0", "npm:pkijs@^3.3.3": "3.4.0", - "npm:postgres@^3.4.7": "3.4.8", - "npm:preact-render-to-string@^6.6.3": "6.6.5_preact@10.29.0", + "npm:postgres@^3.4.7": "3.4.9", + "npm:preact-render-to-string@^6.6.3": "6.6.7_preact@10.29.1", "npm:preact@10.19.6": "10.19.6", - "npm:preact@^10.27.0": "10.29.0", - "npm:preact@^10.27.2": "10.29.0", - "npm:preact@^10.28.2": "10.29.0", - "npm:preact@^10.28.3": "10.29.0", + "npm:preact@^10.27.2": "10.29.1", + "npm:preact@^10.28.2": "10.29.1", + "npm:preact@^10.29.1": "10.29.1", "npm:rollup@^4.50.0": "4.60.1", "npm:shiki@^1.6.4": "1.29.2", "npm:smol-toml@^1.6.0": "1.6.1", "npm:srvx@~0.8.7": "0.8.16", "npm:structured-field-values@^2.0.4": "2.0.4", - "npm:tsdown@~0.21.6": "0.21.7_typescript@6.0.2_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2", + "npm:tsdown@~0.21.6": "0.21.9_typescript@6.0.3", "npm:tsx@^4.19.4": "4.21.0", "npm:uri-template-router@1": "1.0.0", "npm:url-template@^3.1.1": "3.1.1", - "npm:valibot@^1.2.0": "1.3.1_typescript@6.0.2", - "npm:vite@^7.1.3": "7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "npm:vite@^7.1.4": "7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "npm:vitest@3.2": "3.2.4_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "npm:wrangler@^4.17.0": "4.35.0_@cloudflare+workers-types@4.20260403.1", - "npm:wrangler@^4.21.1": "4.35.0_@cloudflare+workers-types@4.20260403.1", + "npm:valibot@^1.2.0": "1.3.1_typescript@6.0.3", + "npm:vite@^7.1.3": "7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "npm:vite@^7.1.4": "7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "npm:vitest@3.2": "3.2.4_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "npm:wrangler@^4.17.0": "4.35.0_@cloudflare+workers-types@4.20260417.1", + "npm:wrangler@^4.21.1": "4.35.0_@cloudflare+workers-types@4.20260417.1", "npm:yaml@^2.8.1": "2.8.3" }, "jsr": { @@ -175,6 +173,9 @@ "@david/console-static-text@0.3.0": { "integrity": "2dfb46ecee525755f7989f94ece30bba85bd8ffe3e8666abc1bf926e1ee0698d" }, + "@david/console-static-text@0.3.4": { + "integrity": "1c596f500b075ff3c8bab1d328ca7148a88067fd9a506b16a73eeaf230c229fd" + }, "@david/dax@0.43.2": { "integrity": "8c7df175465d994c0e3568e3eb91102768c2f1c86d2a513d7fc4cab13f9cb328", "dependencies": [ @@ -197,6 +198,9 @@ "@david/which@0.4.1": { "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" }, + "@david/which@0.4.2": { + "integrity": "440ee262bc0673b57a39ad4d0dc5673e515ddd41c049a55b2588a0881e5d4a8c" + }, "@deno/esbuild-plugin@1.2.1": { "integrity": "df629467913adc1f960149fdfa3a3430ba8c20381c310fba096db244e6c3c9f6", "dependencies": [ @@ -205,8 +209,8 @@ "npm:esbuild@~0.25.5" ] }, - "@deno/loader@0.3.11": { - "integrity": "7c62f4f09cdfc34e66ba25b5a775a1830cbb5266b3e39f67b0f620c75484df8d" + "@deno/loader@0.3.14": { + "integrity": "97bc63a6cc2d27a60bcdc953f588c5213331d866d44212eebb24cebfb9b011ca" }, "@fresh/build-id@1.0.1": { "integrity": "12a2ec25fd52ae9ec68c26848a5696cd1c9b537f7c983c7e56e4fb1e7e816c20", @@ -214,32 +218,8 @@ "jsr:@std/encoding" ] }, - "@fresh/core@2.2.0": { - "integrity": "b3c00f82288a2c4c8ec85e4abb67b080b366ec5971860f2f2898eb281ea1a80f", - "dependencies": [ - "jsr:@deno/esbuild-plugin", - "jsr:@fresh/build-id", - "jsr:@std/encoding", - "jsr:@std/fmt@^1.0.8", - "jsr:@std/fs@^1.0.19", - "jsr:@std/html", - "jsr:@std/http", - "jsr:@std/jsonc", - "jsr:@std/media-types", - "jsr:@std/path@^1.1.2", - "jsr:@std/semver", - "jsr:@std/uuid", - "npm:@opentelemetry/api", - "npm:@preact/signals@^2.2.1", - "npm:esbuild-wasm", - "npm:esbuild@0.25.7", - "npm:preact-render-to-string", - "npm:preact@^10.27.0", - "npm:preact@^10.27.2" - ] - }, - "@fresh/core@2.2.2": { - "integrity": "c34873df58457720f7b915a65fef6fe5cd7215f237cf4d1064d1925b320de96c", + "@fresh/core@2.3.0": { + "integrity": "c98fd9c4cf223f68150d8de0ebc89e68070a277c132579c3b9e4f81dfdba822f", "dependencies": [ "jsr:@deno/esbuild-plugin", "jsr:@fresh/build-id", @@ -250,6 +230,7 @@ "jsr:@std/http", "jsr:@std/jsonc", "jsr:@std/media-types", + "jsr:@std/net", "jsr:@std/path@^1.1.2", "jsr:@std/semver", "jsr:@std/uuid", @@ -259,7 +240,7 @@ "npm:esbuild@0.25.7", "npm:preact-render-to-string", "npm:preact@^10.28.2", - "npm:preact@^10.28.3" + "npm:preact@^10.29.1" ] }, "@fresh/plugin-vite@1.0.8": { @@ -285,11 +266,8 @@ "jsr:@logtape/logtape@^1.0.4" ] }, - "@hono/hono@4.12.4": { - "integrity": "3b80b0165bbcaf8ddf23afc593e40416da8e9a27cb3dd460a1f04c7a44583030" - }, - "@hono/hono@4.12.12": { - "integrity": "dc765178d38b5c4619b358062f6aa5514f7205bb0530b2823ff6265bec69c535" + "@hono/hono@4.12.15": { + "integrity": "06a0aef73d9072e73b8db570b81a5b56a94095d697578202a87fccdf04ce352d" }, "@logtape/file@2.0.5": { "integrity": "368621b15b73fd63c137e47ae43411e350627683ce7e0b4492af3ccb159e098b", @@ -308,7 +286,7 @@ "integrity": "9ba458a3cb2f00f83d36a70f942782cd2c622fd72c527f59e5f8234c780c4b30", "dependencies": [ "jsr:@optique/core", - "npm:@standard-schema/spec@^1.1.0" + "npm:@standard-schema/spec" ] }, "@optique/core@1.0.2": { @@ -320,9 +298,6 @@ "jsr:@optique/core" ] }, - "@standard-schema/spec@1.1.0": { - "integrity": "2ccd54513cd9c960bd155ab569b1a901bc99c6f9ad29559d3f38a28c91c1822d" - }, "@std/assert@0.224.0": { "integrity": "8643233ec7aec38a940a8264a6e3eed9bfa44e7a71cc6b3c8874213ff401967f", "dependencies": [ @@ -360,6 +335,9 @@ "@std/fmt@1.0.9": { "integrity": "2487343e8899fb2be5d0e3d35013e54477ada198854e52dd05ed0422eddcabe0" }, + "@std/fmt@1.0.10": { + "integrity": "90dfba288802ac6de82fb31d0917eb9e4450b9925b954d5e51fc29ac07419db5" + }, "@std/fs@0.224.0": { "integrity": "52a5ec89731ac0ca8f971079339286f88c571a4d61686acf75833f03a89d8e69", "dependencies": [ @@ -373,11 +351,11 @@ "jsr:@std/path@^1.1.4" ] }, - "@std/html@1.0.5": { - "integrity": "4e2d693f474cae8c16a920fa5e15a3b72267b94b84667f11a50c6dd1cb18d35e" + "@std/html@1.0.6": { + "integrity": "eaf759c8141e0733ca30eb49e4c08d8e6ca442b85c4d51f9894a56f502993e08" }, - "@std/http@1.0.25": { - "integrity": "577b4252290af1097132812b339fffdd55fb0f4aeb98ff11bdbf67998aa17193", + "@std/http@1.1.0": { + "integrity": "265cd9a589fea924c5bb0bbed8bebb4bb2fa19129f760bd014e78dbd7a365a51", "dependencies": [ "jsr:@std/encoding" ] @@ -391,6 +369,9 @@ "@std/internal@1.0.12": { "integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027" }, + "@std/internal@1.0.13": { + "integrity": "2f9546691d4ac2d32859c82dff284aaeac980ddeca38430d07941e7e288725c0" + }, "@std/io@0.225.3": { "integrity": "27b07b591384d12d7b568f39e61dff966b8230559122df1e9fd11cc068f7ddd1", "dependencies": [ @@ -409,6 +390,9 @@ "@std/media-types@1.1.0": { "integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4" }, + "@std/net@1.0.6": { + "integrity": "110735f93e95bb9feb95790a8b1d1bf69ec0dc74f3f97a00a76ea5efea25500c" + }, "@std/path@0.224.0": { "integrity": "55bca6361e5a6d158b9380e82d4981d82d338ec587de02951e2b7c3a24910ee6" }, @@ -439,9 +423,6 @@ "@std/yaml@1.0.12": { "integrity": "7deabca4545bcedd07c5f69ea53acea71b8b4c67562f224e17b90d75944cb20c" }, - "@valibot/valibot@1.2.0": { - "integrity": "61c118a4d027ed55912caf381c78f0a178f335f46ad0c4bcb136498dc1ef2285" - }, "@valibot/valibot@1.3.1": { "integrity": "635faaec9d32a25efca7b4614e7a07306cc03937bfd0679e05530d31081bc501" } @@ -488,8 +469,8 @@ "vfile" ] }, - "@astrojs/node@10.0.4_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3_@types+node@24.12.0_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3": { - "integrity": "sha512-7pVgiVSscQHRC2WqjlXcnbbcKMYp2GXrYpmuvdGg5zgA8J1lFm2vmwVhHZFuZK3Ik5PzoxiDROaEgoDGLbfhLw==", + "@astrojs/node@10.0.5_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3": { + "integrity": "sha512-rgZiU9nD7zmM3fdmOVuobcNHAyXWx2HXXDLTuxjVCTQ+QmHmL5zkZZhNIL5NjlQtDRAU1i5fVaXp7nAKdET30w==", "dependencies": [ "@astrojs/internal-helpers@0.8.0", "astro", @@ -782,7 +763,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@24.12.0__tsx@4.21.0__yaml@2.8.3_@cloudflare+workers-types@4.20260403.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "@cloudflare/vitest-pool-workers@0.8.71_@vitest+runner@3.2.4_@vitest+snapshot@3.2.4_vitest@3.2.4__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@cloudflare+workers-types@4.20260417.1_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-keu2HCLQfRNwbmLBCDXJgCFpANTaYnQpE01fBOo4CNwiWHUT7SZGN7w64RKiSWRHyYppStXBuE5Ng7F42+flpg==", "dependencies": [ "@vitest/runner", @@ -822,8 +803,8 @@ "os": ["win32"], "cpu": ["x64"] }, - "@cloudflare/workers-types@4.20260403.1": { - "integrity": "sha512-p6oSNt3yUwcxSoXZ7qCog7+kgQbkSx1Beoci7TMb/xbRF05VR0cO/p1XUE2SLHZ7IgSIc3tNMpFKa0L0fa3Lzg==" + "@cloudflare/workers-types@4.20260417.1": { + "integrity": "sha512-ke3GkFfFyfSxdLRR6LPbnfYAu3RNKqX0eYfu/FNnluBN9rLgYVqT+QEPgSEx1yq7XTOok+Bub1td9xvknaOz4A==" }, "@colors/colors@1.5.0": { "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" @@ -834,7 +815,7 @@ "@jridgewell/trace-mapping@0.3.9" ] }, - "@deno/astro-adapter@0.3.2_@opentelemetry+api@1.9.1_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3_@types+node@24.12.0_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3": { + "@deno/astro-adapter@0.3.2_@opentelemetry+api@1.9.1_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3": { "integrity": "sha512-nN0kQGobRs2XE3R+O/DWYQanEWpteJNsIf5TD65787qFEw2CrqkFNcNolZFJiKUF/2Y/TKyOLRjMS3F6auECVg==", "dependencies": [ "@opentelemetry/api", @@ -858,7 +839,7 @@ "integrity": "sha512-6lMpxpt9BOmqHKGs9Xm6DP4LlZTBFer/ZjHvP3FcW3IaUWYIWC7dw5RFZnvw4fP57kAVcm1dp3IF+Y50qhBvAw==", "dependencies": [ "ky", - "undici@6.24.1" + "undici@6.25.0" ] }, "@emnapi/core@1.9.2": { @@ -1792,38 +1773,38 @@ "@inquirer/ansi@1.0.2": { "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==" }, - "@inquirer/checkbox@4.3.2_@types+node@24.12.0": { + "@inquirer/checkbox@4.3.2_@types+node@24.12.2": { "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/confirm@5.1.21_@types+node@24.12.0": { + "@inquirer/confirm@5.1.21_@types+node@24.12.2": { "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0" + "@inquirer/core@10.3.2_@types+node@24.12.2", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/core@10.3.2_@types+node@24.12.0": { + "@inquirer/core@10.3.2_@types+node@24.12.2": { "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dependencies": [ "@inquirer/ansi", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "cli-width", "mute-stream@2.0.0", "signal-exit", @@ -1831,7 +1812,7 @@ "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "@inquirer/core@8.2.4": { @@ -1840,7 +1821,7 @@ "@inquirer/figures", "@inquirer/type@1.5.5", "@types/mute-stream", - "@types/node@20.19.37", + "@types/node@20.19.39", "@types/wrap-ansi", "ansi-escapes", "cli-spinners", @@ -1852,79 +1833,79 @@ "wrap-ansi@6.2.0" ] }, - "@inquirer/editor@4.2.23_@types+node@24.12.0": { + "@inquirer/editor@4.2.23_@types+node@24.12.2": { "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", "@inquirer/external-editor", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0" + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/expand@4.0.23_@types+node@24.12.0": { + "@inquirer/expand@4.0.23_@types+node@24.12.2": { "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/external-editor@1.0.3_@types+node@24.12.0": { + "@inquirer/external-editor@1.0.3_@types+node@24.12.2": { "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dependencies": [ - "@types/node@24.12.0", + "@types/node@24.12.2", "chardet", "iconv-lite@0.7.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "@inquirer/figures@1.0.15": { "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==" }, - "@inquirer/input@4.3.1_@types+node@24.12.0": { + "@inquirer/input@4.3.1_@types+node@24.12.2": { "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0" + "@inquirer/core@10.3.2_@types+node@24.12.2", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/number@3.0.23_@types+node@24.12.0": { + "@inquirer/number@3.0.23_@types+node@24.12.2": { "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0" + "@inquirer/core@10.3.2_@types+node@24.12.2", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/password@4.0.23_@types+node@24.12.0": { + "@inquirer/password@4.0.23_@types+node@24.12.2": { "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@24.12.0", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0" + "@inquirer/core@10.3.2_@types+node@24.12.2", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/prompts@7.10.1_@types+node@24.12.0": { + "@inquirer/prompts@7.10.1_@types+node@24.12.2": { "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dependencies": [ "@inquirer/checkbox", @@ -1937,49 +1918,49 @@ "@inquirer/rawlist", "@inquirer/search", "@inquirer/select", - "@types/node@24.12.0" + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/rawlist@4.1.11_@types+node@24.12.0": { + "@inquirer/rawlist@4.1.11_@types+node@24.12.2": { "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/search@3.2.2_@types+node@24.12.0": { + "@inquirer/search@3.2.2_@types+node@24.12.2": { "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dependencies": [ - "@inquirer/core@10.3.2_@types+node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, - "@inquirer/select@4.4.2_@types+node@24.12.0": { + "@inquirer/select@4.4.2_@types+node@24.12.2": { "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", "@inquirer/figures", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "yoctocolors-cjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "@inquirer/type@1.5.5": { @@ -1988,13 +1969,13 @@ "mute-stream@1.0.0" ] }, - "@inquirer/type@3.0.10_@types+node@24.12.0": { + "@inquirer/type@3.0.10_@types+node@24.12.2": { "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dependencies": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "@ioredis/commands@1.5.1": { @@ -2038,15 +2019,15 @@ "tinycolor2" ] }, - "@jimp/core@1.6.0": { - "integrity": "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w==", + "@jimp/core@1.6.1": { + "integrity": "sha512-+BoKC5G6hkrSy501zcJ2EpfnllP+avPevcBfRcZe/CW+EwEfY6X1EZ8QWyT7NpDIvEEJb1fdJnMMfUnFkxmw9A==", "dependencies": [ "@jimp/file-ops", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "await-to-js", "exif-parser", - "file-type@16.5.4", + "file-type@21.3.4", "mime@3.0.0" ] }, @@ -2056,155 +2037,155 @@ "@jimp/core@0.22.12" ] }, - "@jimp/diff@1.6.0": { - "integrity": "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw==", + "@jimp/diff@1.6.1": { + "integrity": "sha512-YkKDPdHjLgo1Api3+Bhc0GLAygldlpt97NfOKoNg1U6IUNXA6X2MgosCjPfSBiSvJvrrz1fsIR+/4cfYXBI/HQ==", "dependencies": [ "@jimp/plugin-resize", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "pixelmatch@5.3.0" ] }, - "@jimp/file-ops@1.6.0": { - "integrity": "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ==" + "@jimp/file-ops@1.6.1": { + "integrity": "sha512-T+gX6osHjprbDRad0/B71Evyre7ZdVY1z/gFGEG9Z8KOtZPKboWvPeP2UjbZYWQLy9UKCPQX1FNAnDiOPkJL7w==" }, - "@jimp/js-bmp@1.6.0": { - "integrity": "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw==", + "@jimp/js-bmp@1.6.1": { + "integrity": "sha512-xzWzNT4/u5zGrTT3Tme9sGU7YzIKxi13+BCQwLqACbt5DXf9SAfdzRkopZQnmDko+6In5nqaT89Gjs43/WdnYQ==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "bmp-ts" ] }, - "@jimp/js-gif@1.6.0": { - "integrity": "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g==", + "@jimp/js-gif@1.6.1": { + "integrity": "sha512-YjY2W26rQa05XhanYhRZ7dingCiNN+T2Ymb1JiigIbABY0B28wHE3v3Cf1/HZPWGu0hOg36ylaKgV5KxF2M58w==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", "gifwrap", "omggif" ] }, - "@jimp/js-jpeg@1.6.0": { - "integrity": "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA==", + "@jimp/js-jpeg@1.6.1": { + "integrity": "sha512-HT9H3yOmlOFzYmdI15IYdfy6ggQhSRIaHeA+OTJSEORXBqEo97sUZu/DsgHIcX5NJ7TkJBTgZ9BZXsV6UbsyMg==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", "jpeg-js" ] }, - "@jimp/js-png@1.6.0": { - "integrity": "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg==", + "@jimp/js-png@1.6.1": { + "integrity": "sha512-SZ/KVhI5UjcSzzlXsXdIi/LhJ7UShf2NkMOtVrbZQcGzsqNtynAelrOXeoTxcanfVqmNhAoVHg8yR2cYoqrYjA==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", "pngjs@7.0.0" ] }, - "@jimp/js-tiff@1.6.0": { - "integrity": "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw==", + "@jimp/js-tiff@1.6.1": { + "integrity": "sha512-jDG/eJquID1M4MBlKMmDRBmz2TpXMv7TUyu2nIRUxhlUc2ogC82T+VQUkca9GJH1BBJ9dx5sSE5dGkWNjIbZxw==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", "utif2" ] }, - "@jimp/plugin-blit@1.6.0": { - "integrity": "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA==", + "@jimp/plugin-blit@1.6.1": { + "integrity": "sha512-MwnI7C7K81uWddY9FLw1fCOIy6SsPIUftUz36Spt7jisCn8/40DhQMlSxpxTNelnZb/2SnloFimQfRZAmHLOqQ==", "dependencies": [ "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/plugin-blur@1.6.0": { - "integrity": "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw==", + "@jimp/plugin-blur@1.6.1": { + "integrity": "sha512-lIo7Tzp5jQu30EFFSK/phXANK3citKVEjepDjQ6ljHoIFtuMRrnybnmI2Md24ulvWlDaz+hh3n6qrMb8ydwhZQ==", "dependencies": [ - "@jimp/core@1.6.0", - "@jimp/utils@1.6.0" + "@jimp/core@1.6.1", + "@jimp/utils@1.6.1" ] }, - "@jimp/plugin-circle@1.6.0": { - "integrity": "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw==", + "@jimp/plugin-circle@1.6.1": { + "integrity": "sha512-kK1PavY6cKHNNKce37vdV4Tmpc1/zDKngGoeOV3j+EMatoHFZUinV3s6F9aWryPs3A0xhCLZgdJ6Zeea1d5LCQ==", "dependencies": [ "@jimp/types", "zod@3.25.76" ] }, - "@jimp/plugin-color@1.6.0": { - "integrity": "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA==", + "@jimp/plugin-color@1.6.1": { + "integrity": "sha512-LtUN1vAP+LRlZAtTNVhDRSiXx+26Kbz3zJaG6a5k59gQ95jgT5mknnF8lxkHcqJthM4MEk3/tPxkdJpEybyF/A==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "tinycolor2", "zod@3.25.76" ] }, - "@jimp/plugin-contain@1.6.0": { - "integrity": "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ==", + "@jimp/plugin-contain@1.6.1": { + "integrity": "sha512-m0qhrfA8jkTqretGv4w+T/ADFR4GwBpE0sCOC2uJ0dzr44/ddOMsIdrpi89kabqYiPYIrxkgdCVCLm3zn1Vkkg==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/plugin-blit", "@jimp/plugin-resize", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/plugin-cover@1.6.0": { - "integrity": "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA==", + "@jimp/plugin-cover@1.6.1": { + "integrity": "sha512-hZytnsth0zoll6cPf434BrT+p/v569Wr5tyO6Dp0dH1IDPhzhB5F38sZGMLDo7bzQiN9JFVB3fxkcJ/WYCJ3Mg==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/plugin-crop", "@jimp/plugin-resize", "@jimp/types", "zod@3.25.76" ] }, - "@jimp/plugin-crop@1.6.0": { - "integrity": "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang==", + "@jimp/plugin-crop@1.6.1": { + "integrity": "sha512-EerRSLlclXyKDnYc/H9w/1amZW7b7v3OGi/VlerPd2M/pAu5X8TkyYWtfqYCXnNp1Ixtd8oCo9zGfY9zoXT4rg==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/plugin-displace@1.6.0": { - "integrity": "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q==", + "@jimp/plugin-displace@1.6.1": { + "integrity": "sha512-K07QVl7xQwIfD6KfxRV/c3E9e7ZBXxUXdWuvoTWcKHL2qV48MOF5Nqbz/aJW4ThnQARIsxvYlZjPFiqkCjlU+g==", "dependencies": [ "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/plugin-dither@1.6.0": { - "integrity": "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ==", + "@jimp/plugin-dither@1.6.1": { + "integrity": "sha512-+2V+GCV2WycMoX1/z977TkZ8Zq/4MVSKElHYatgUqtwXMi2fDK2gKYU2g9V39IqFvTJsTIsK0+58VFz/ROBVew==", "dependencies": [ "@jimp/types" ] }, - "@jimp/plugin-fisheye@1.6.0": { - "integrity": "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA==", + "@jimp/plugin-fisheye@1.6.1": { + "integrity": "sha512-XtS5ZyoZ0vxZxJ6gkqI63SivhtI58vX95foMPM+cyzYkRsJXMOYCr8DScxF5bp4Xr003NjYm/P+7+08tibwzHA==", "dependencies": [ "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/plugin-flip@1.6.0": { - "integrity": "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg==", + "@jimp/plugin-flip@1.6.1": { + "integrity": "sha512-ws38W/sGj7LobNRayQ83garxiktOyWxM5vO/y4a/2cy9v65SLEUzVkrj+oeAaUSSObdz4HcCEla7XtGlnAGAaA==", "dependencies": [ "@jimp/types", "zod@3.25.76" ] }, - "@jimp/plugin-hash@1.6.0": { - "integrity": "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q==", + "@jimp/plugin-hash@1.6.1": { + "integrity": "sha512-sZt6ZcMX6i8vFWb4GYnw0pR/o9++ef0dTVcboTB5B/g7nrxCODIB4wfEkJ/YqZM5wUvol77K1qeS0/rVO6z21A==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/js-bmp", "@jimp/js-jpeg", "@jimp/js-png", @@ -2212,21 +2193,21 @@ "@jimp/plugin-color", "@jimp/plugin-resize", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "any-base" ] }, - "@jimp/plugin-mask@1.6.0": { - "integrity": "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA==", + "@jimp/plugin-mask@1.6.1": { + "integrity": "sha512-SIG0/FcmEj3tkwFxc7fAGLO8o4uNzMpSOdQOhbCgxefQKq5wOVMk9BQx/sdMPBwtMLr9WLq0GzLA/rk6t2v20A==", "dependencies": [ "@jimp/types", "zod@3.25.76" ] }, - "@jimp/plugin-print@1.6.0": { - "integrity": "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A==", + "@jimp/plugin-print@1.6.1": { + "integrity": "sha512-BYVz/X3Xzv8XYilVeDy11NOp0h7BTDjlOtu0BekIFHP1yHVd24AXNzbOy52XlzYZWQ0Dl36HOHEpl/nSNrzc6w==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/js-jpeg", "@jimp/js-png", "@jimp/plugin-blit", @@ -2238,45 +2219,45 @@ "zod@3.25.76" ] }, - "@jimp/plugin-quantize@1.6.0": { - "integrity": "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg==", + "@jimp/plugin-quantize@1.6.1": { + "integrity": "sha512-J2En9PLURfP+vwYDtuZ9T8yBW6BWYZBScydAjRiPBmJfEhTcNQqiiQODrZf7EqbbX/Sy5H6dAeRiqkgoV9N6Ww==", "dependencies": [ "image-q", "zod@3.25.76" ] }, - "@jimp/plugin-resize@1.6.0": { - "integrity": "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA==", + "@jimp/plugin-resize@1.6.1": { + "integrity": "sha512-CLkrtJoIz2HdWnpYiN6p8KYcPc00rCH/SUu6o+lfZL05Q4uhecJlnvXuj9x+U6mDn3ldPmJj6aZqMHuUJzdVqg==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/types", "zod@3.25.76" ] }, - "@jimp/plugin-rotate@1.6.0": { - "integrity": "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw==", + "@jimp/plugin-rotate@1.6.1": { + "integrity": "sha512-nOjVjbbj705B02ksysKnh0POAwEBXZtJ9zQ5qC+X7Tavl3JNn+P3BzQovbBxLPSbUSld6XID9z5ijin4PtOAUg==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/plugin-crop", "@jimp/plugin-resize", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/plugin-threshold@1.6.0": { - "integrity": "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w==", + "@jimp/plugin-threshold@1.6.1": { + "integrity": "sha512-JOKv9F8s6tnVLf4sB/2fF0F339EFnHvgEdFYugO6VhowKLsap0pEZmLyE/DlRnYtIj2RddHZVxVMp/eKJ04l2Q==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/plugin-color", "@jimp/plugin-hash", "@jimp/types", - "@jimp/utils@1.6.0", + "@jimp/utils@1.6.1", "zod@3.25.76" ] }, - "@jimp/types@1.6.0": { - "integrity": "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg==", + "@jimp/types@1.6.1": { + "integrity": "sha512-leI7YbveTNi565m910XgIOwXyuu074H5qazAD1357HImJSv2hqxnWXpwxQbadGWZ7goZRYBDZy5lpqud0p7q5w==", "dependencies": [ "zod@3.25.76" ] @@ -2287,15 +2268,15 @@ "regenerator-runtime" ] }, - "@jimp/utils@1.6.0": { - "integrity": "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA==", + "@jimp/utils@1.6.1": { + "integrity": "sha512-veFPRd93FCnS7AgmCkPgARVGoDRrJ9cm1ujuNyA+UfQ5VKbED2002sm5XfFLFwTsKC8j04heTrwe+tU1dluXOw==", "dependencies": [ "@jimp/types", "tinycolor2" ] }, - "@jimp/wasm-webp@1.6.0": { - "integrity": "sha512-P0zUpK6n2XIAn8bt0F6rhSn1+FgteBTrL+TBb6Oqw8v5qEDJoNYkd6LlfZYN8YwtRBTBdZ8GFnWsg2Sar+qOkA==", + "@jimp/wasm-webp@1.6.1": { + "integrity": "sha512-t+Wqkde4xQHP/UZ4bDiDo3pbhFz32E7FvQCUkuFdJDmEDl6gPCs6LQiQVBmumUQYTeVLiLtLzlM9j8s7yF0sXQ==", "dependencies": [ "@jsquash/webp", "zod@3.25.76" @@ -2390,18 +2371,18 @@ "@multiformats/base-x@4.0.1": { "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, - "@napi-rs/wasm-runtime@1.1.2_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { - "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", + "@napi-rs/wasm-runtime@1.1.4_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dependencies": [ "@emnapi/core", "@emnapi/runtime", "@tybys/wasm-util" ] }, - "@nestjs/common@11.1.17_reflect-metadata@0.2.2_rxjs@7.8.2": { - "integrity": "sha512-hLODw5Abp8OQgA+mUO4tHou4krKgDtUcM9j5Ihxncst9XeyxYBTt2bwZm4e4EQr5E352S4Fyy6V3iFx9ggxKAg==", + "@nestjs/common@11.1.19_reflect-metadata@0.2.2_rxjs@7.8.2": { + "integrity": "sha512-qeiTt2tv+e5QyDKqG8HlVZb2wx64FEaSGFJouqTSRs+kG44iTfl3xlz1XqVped+rihx4hmjWgL5gkhtdK3E6+Q==", "dependencies": [ - "file-type@21.3.2", + "file-type@21.3.4", "iterare", "load-esm", "reflect-metadata", @@ -2430,7 +2411,7 @@ "fastq" ] }, - "@nurodev/astro-bun@2.1.2_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3": { + "@nurodev/astro-bun@2.1.2_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3": { "integrity": "sha512-CXzh0q+jOodmqtZ/YMyS7DTqmFC2zafv4C7GQMBDoBDRcx7CONzxCk/rK2uaKHoh3+AvSPo3hXnTp6oLfIpl5g==", "dependencies": [ "astro", @@ -2470,35 +2451,35 @@ "defu", "pathe@2.0.3", "pkg-types@2.3.0", - "std-env@4.0.0" + "std-env@4.1.0" ] }, "@opentelemetry/api@1.9.1": { "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==" }, - "@opentelemetry/context-async-hooks@2.6.1_@opentelemetry+api@1.9.1": { - "integrity": "sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ==", + "@opentelemetry/context-async-hooks@2.7.0_@opentelemetry+api@1.9.1": { + "integrity": "sha512-MWXggArM+Y11mPS8VOrqxOj+YMGQSRuvhM91eSBX4xFpJa05mpkeVvM8pPux5ElkEjV5RMgrkisrlP/R83SpBQ==", "dependencies": [ "@opentelemetry/api" ] }, - "@opentelemetry/core@2.6.1_@opentelemetry+api@1.9.1": { - "integrity": "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==", + "@opentelemetry/core@2.7.0_@opentelemetry+api@1.9.1": { + "integrity": "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==", "dependencies": [ "@opentelemetry/api", "@opentelemetry/semantic-conventions" ] }, - "@opentelemetry/resources@2.6.1_@opentelemetry+api@1.9.1": { - "integrity": "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==", + "@opentelemetry/resources@2.7.0_@opentelemetry+api@1.9.1": { + "integrity": "sha512-K+oi0hNMv94EpZbnW3eyu2X6SGVpD3O5DhG2NIp65Hc7lhAj9brRXTAVzh3wB82+q3ThakEf7Zd7RsFUqcTc7A==", "dependencies": [ "@opentelemetry/api", "@opentelemetry/core", "@opentelemetry/semantic-conventions" ] }, - "@opentelemetry/sdk-trace-base@2.6.1_@opentelemetry+api@1.9.1": { - "integrity": "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==", + "@opentelemetry/sdk-trace-base@2.7.0_@opentelemetry+api@1.9.1": { + "integrity": "sha512-Yg9zEXJB50DLVLpsKPk7NmNqlPlS+OvqhJGh0A8oawIOTPOwlm4eXs9BMJV7L79lvEwI+dWtAj+YjTyddV336A==", "dependencies": [ "@opentelemetry/api", "@opentelemetry/core", @@ -2512,8 +2493,8 @@ "@oslojs/encoding@1.1.0": { "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==" }, - "@oxc-project/types@0.122.0": { - "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==" + "@oxc-project/types@0.126.0": { + "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==" }, "@parcel/watcher-android-arm64@2.5.6": { "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", @@ -2659,26 +2640,26 @@ "@preact/signals-core@1.14.1": { "integrity": "sha512-vxPpfXqrwUe9lpjqfYNjAF/0RF/eFGeLgdJzdmIIZjpOnTmGmAB4BjWone562mJGMRP4frU6iZ6ei3PDsu52Ng==" }, - "@preact/signals@2.9.0_preact@10.29.0": { + "@preact/signals@2.9.0_preact@10.29.1": { "integrity": "sha512-hYrY0KyUqkDgOl1qba/JGn6y81pXnurn21PMaxfcMwdncdZ3M/oVdmpTvEnsGjh48dIwDVc7bjWHqIsngSjYug==", "dependencies": [ "@preact/signals-core", - "preact@10.29.0" + "preact@10.29.1" ] }, "@prefresh/babel-plugin@0.5.3": { "integrity": "sha512-57LX2SHs4BX2s1IwCjNzTE2OJeEepRCNf1VTEpbNcUyHfMO68eeOWGDIt4ob9aYlW6PEWZ1SuwNikuoIXANDtQ==" }, - "@prefresh/core@1.5.9_preact@10.29.0": { + "@prefresh/core@1.5.9_preact@10.29.1": { "integrity": "sha512-IKBKCPaz34OFVC+adiQ2qaTF5qdztO2/4ZPf4KsRTgjKosWqxVXmEbxCiUydYZRY8GVie+DQlKzQr9gt6HQ+EQ==", "dependencies": [ - "preact@10.29.0" + "preact@10.29.1" ] }, "@prefresh/utils@1.2.1": { "integrity": "sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==" }, - "@prefresh/vite@2.4.12_preact@10.29.0_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3": { + "@prefresh/vite@2.4.12_preact@10.29.1_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3": { "integrity": "sha512-FY1fzXpUjiuosznMV0YM7XAOPZjB5FIdWS0W24+XnlxYkt9hNAwwsiKYn+cuTEoMtD/ZVazS5QVssBr9YhpCQA==", "dependencies": [ "@babel/core", @@ -2686,8 +2667,8 @@ "@prefresh/core", "@prefresh/utils", "@rollup/pluginutils@4.2.1", - "preact@10.29.0", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "preact@10.29.1", + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ] }, "@quansync/fs@1.0.0": { @@ -2696,85 +2677,87 @@ "quansync@1.0.0" ] }, - "@rolldown/binding-android-arm64@1.0.0-rc.12": { - "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", + "@rolldown/binding-android-arm64@1.0.0-rc.16": { + "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", "os": ["android"], "cpu": ["arm64"] }, - "@rolldown/binding-darwin-arm64@1.0.0-rc.12": { - "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", + "@rolldown/binding-darwin-arm64@1.0.0-rc.16": { + "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", "os": ["darwin"], "cpu": ["arm64"] }, - "@rolldown/binding-darwin-x64@1.0.0-rc.12": { - "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", + "@rolldown/binding-darwin-x64@1.0.0-rc.16": { + "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", "os": ["darwin"], "cpu": ["x64"] }, - "@rolldown/binding-freebsd-x64@1.0.0-rc.12": { - "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", + "@rolldown/binding-freebsd-x64@1.0.0-rc.16": { + "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", "os": ["freebsd"], "cpu": ["x64"] }, - "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12": { - "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16": { + "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", "os": ["linux"], "cpu": ["arm"] }, - "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12": { - "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", + "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16": { + "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", "os": ["linux"], "cpu": ["arm64"] }, - "@rolldown/binding-linux-arm64-musl@1.0.0-rc.12": { - "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", + "@rolldown/binding-linux-arm64-musl@1.0.0-rc.16": { + "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", "os": ["linux"], "cpu": ["arm64"] }, - "@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12": { - "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", + "@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.16": { + "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", "os": ["linux"], "cpu": ["ppc64"] }, - "@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12": { - "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", + "@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16": { + "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", "os": ["linux"], "cpu": ["s390x"] }, - "@rolldown/binding-linux-x64-gnu@1.0.0-rc.12": { - "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", + "@rolldown/binding-linux-x64-gnu@1.0.0-rc.16": { + "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", "os": ["linux"], "cpu": ["x64"] }, - "@rolldown/binding-linux-x64-musl@1.0.0-rc.12": { - "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", + "@rolldown/binding-linux-x64-musl@1.0.0-rc.16": { + "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", "os": ["linux"], "cpu": ["x64"] }, - "@rolldown/binding-openharmony-arm64@1.0.0-rc.12": { - "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", + "@rolldown/binding-openharmony-arm64@1.0.0-rc.16": { + "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", "os": ["openharmony"], "cpu": ["arm64"] }, - "@rolldown/binding-wasm32-wasi@1.0.0-rc.12_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { - "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", + "@rolldown/binding-wasm32-wasi@1.0.0-rc.16": { + "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", "dependencies": [ + "@emnapi/core", + "@emnapi/runtime", "@napi-rs/wasm-runtime" ], "cpu": ["wasm32"] }, - "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12": { - "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", + "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16": { + "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", "os": ["win32"], "cpu": ["arm64"] }, - "@rolldown/binding-win32-x64-msvc@1.0.0-rc.12": { - "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", + "@rolldown/binding-win32-x64-msvc@1.0.0-rc.16": { + "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", "os": ["win32"], "cpu": ["x64"] }, - "@rolldown/pluginutils@1.0.0-rc.12": { - "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==" + "@rolldown/pluginutils@1.0.0-rc.16": { + "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==" }, "@rollup/plugin-alias@6.0.0_rollup@4.60.1": { "integrity": "sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==", @@ -3104,7 +3087,7 @@ "@sindresorhus/merge-streams@4.0.0": { "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==" }, - "@solidjs/start@1.3.2_vinxi@0.5.11__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2__@types+node@24.12.0__ioredis@5.10.1__mysql2@3.20.0___@types+node@24.12.0__rolldown@1.0.0-rc.12___@emnapi+core@1.9.2___@emnapi+runtime@1.9.2__tsx@4.21.0__yaml@2.8.3_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2_@types+node@24.12.0_ioredis@5.10.1_mysql2@3.20.0__@types+node@24.12.0_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_solid-js@1.9.12_tsx@4.21.0_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_yaml@2.8.3": { + "@solidjs/start@1.3.2_vinxi@0.5.11__@types+node@24.12.2__ioredis@5.10.1__mysql2@3.22.1___@types+node@24.12.2__rolldown@1.0.0-rc.16__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_mysql2@3.22.1__@types+node@24.12.2_rolldown@1.0.0-rc.16_solid-js@1.9.12_tsx@4.21.0_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_yaml@2.8.3": { "integrity": "sha512-tasDl3utVbtP0rr4InB3ntBIFV2upvEiFrOOCkRrAA3yBfjx9elpxnc94sJQXo65PNYdAAAkPIC6h93vLrtwHg==", "dependencies": [ "@tanstack/server-functions-plugin", @@ -3137,8 +3120,8 @@ "acorn@8.16.0" ] }, - "@sveltejs/kit@2.55.0_@opentelemetry+api@1.9.1_@sveltejs+vite-plugin-svelte@7.0.0__svelte@5.55.1__vite@7.3.1___@types+node@24.12.0___tsx@4.21.0___yaml@2.8.3__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_svelte@5.55.1_typescript@6.0.2_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { - "integrity": "sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==", + "@sveltejs/kit@2.57.1_@opentelemetry+api@1.9.1_@sveltejs+vite-plugin-svelte@7.0.0__svelte@5.55.4__vite@7.3.2___@types+node@24.12.2___tsx@4.21.0___yaml@2.8.3__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_svelte@5.55.4_typescript@6.0.3_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { + "integrity": "sha512-VRdSbB96cI1EnRh09CqmnQqP/YJvET5buj8S6k7CxaJqBJD4bw4fRKDjcarAj/eX9k2eHifQfDH8NtOh+ZxxPw==", "dependencies": [ "@opentelemetry/api", "@standard-schema/spec", @@ -3156,7 +3139,7 @@ "sirv", "svelte", "typescript", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ], "optionalPeers": [ "@opentelemetry/api", @@ -3164,18 +3147,18 @@ ], "bin": true }, - "@sveltejs/vite-plugin-svelte@7.0.0_svelte@5.55.1_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "@sveltejs/vite-plugin-svelte@7.0.0_svelte@5.55.4_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g==", "dependencies": [ "deepmerge", "magic-string", "obug", "svelte", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "vitefu@1.1.3_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "vitefu@1.1.3_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ] }, - "@tanstack/directive-functions-plugin@1.121.21_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "@tanstack/directive-functions-plugin@1.121.21_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-B9z/HbF7gJBaRHieyX7f2uQ4LpLLAVAEutBZipH6w+CYD6RHRJvSVPzECGHF7icFhNWTiJQL2QR6K07s59yzEw==", "dependencies": [ "@babel/code-frame@7.26.2", @@ -3185,7 +3168,7 @@ "@tanstack/router-utils", "babel-dead-code-elimination", "tiny-invariant", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ] }, "@tanstack/router-utils@1.161.6": { @@ -3202,7 +3185,7 @@ "tinyglobby" ] }, - "@tanstack/server-functions-plugin@1.121.21_@types+node@24.12.0_tsx@4.21.0_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_yaml@2.8.3": { + "@tanstack/server-functions-plugin@1.121.21_@types+node@24.12.2_tsx@4.21.0_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_yaml@2.8.3": { "integrity": "sha512-a05fzK+jBGacsSAc1vE8an7lpBh4H0PyIEcivtEyHLomgSeElAJxm9E2It/0nYRZ5Lh23m0okbhzJNaYWZpAOg==", "dependencies": [ "@babel/code-frame@7.26.2", @@ -3236,7 +3219,7 @@ "@types/amqplib@0.10.8": { "integrity": "sha512-vtDp8Pk1wsE/AuQ8/Rgtm6KUZYqcnTgNvEHwzCkX8rL7AGsC6zqAfKAAJhUZXFhM/Pp++tbnUHiam/8vVpPztA==", "dependencies": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "@types/babel__core@7.20.5": { @@ -3333,7 +3316,7 @@ "@types/mute-stream@0.0.4": { "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", "dependencies": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "@types/nlcst@2.0.3": { @@ -3345,20 +3328,20 @@ "@types/node@16.9.1": { "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" }, - "@types/node@20.19.37": { - "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "@types/node@20.19.39": { + "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", "dependencies": [ "undici-types@6.21.0" ] }, - "@types/node@22.19.15": { - "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "@types/node@22.19.17": { + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", "dependencies": [ "undici-types@6.21.0" ] }, - "@types/node@24.12.0": { - "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "@types/node@24.12.2": { + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", "dependencies": [ "undici-types@7.16.0" ] @@ -3375,8 +3358,8 @@ "@types/wrap-ansi@3.0.0": { "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==" }, - "@typescript-eslint/parser@8.58.0_eslint@9.39.4_typescript@6.0.2": { - "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", + "@typescript-eslint/parser@8.58.2_eslint@9.39.4_typescript@6.0.3": { + "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==", "dependencies": [ "@typescript-eslint/scope-manager", "@typescript-eslint/types", @@ -3387,8 +3370,8 @@ "typescript" ] }, - "@typescript-eslint/project-service@8.58.0_typescript@6.0.2": { - "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", + "@typescript-eslint/project-service@8.58.2_typescript@6.0.3": { + "integrity": "sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==", "dependencies": [ "@typescript-eslint/tsconfig-utils", "@typescript-eslint/types", @@ -3396,24 +3379,24 @@ "typescript" ] }, - "@typescript-eslint/scope-manager@8.58.0": { - "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", + "@typescript-eslint/scope-manager@8.58.2": { + "integrity": "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==", "dependencies": [ "@typescript-eslint/types", "@typescript-eslint/visitor-keys" ] }, - "@typescript-eslint/tsconfig-utils@8.58.0_typescript@6.0.2": { - "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", + "@typescript-eslint/tsconfig-utils@8.58.2_typescript@6.0.3": { + "integrity": "sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==", "dependencies": [ "typescript" ] }, - "@typescript-eslint/types@8.58.0": { - "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==" + "@typescript-eslint/types@8.58.2": { + "integrity": "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==" }, - "@typescript-eslint/typescript-estree@8.58.0_typescript@6.0.2": { - "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", + "@typescript-eslint/typescript-estree@8.58.2_typescript@6.0.3": { + "integrity": "sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==", "dependencies": [ "@typescript-eslint/project-service", "@typescript-eslint/tsconfig-utils", @@ -3427,8 +3410,8 @@ "typescript" ] }, - "@typescript-eslint/utils@8.58.0_eslint@9.39.4_typescript@6.0.2": { - "integrity": "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==", + "@typescript-eslint/utils@8.58.2_eslint@9.39.4_typescript@6.0.3": { + "integrity": "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==", "dependencies": [ "@eslint-community/eslint-utils", "@typescript-eslint/scope-manager", @@ -3438,8 +3421,8 @@ "typescript" ] }, - "@typescript-eslint/visitor-keys@8.58.0": { - "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", + "@typescript-eslint/visitor-keys@8.58.2": { + "integrity": "sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==", "dependencies": [ "@typescript-eslint/types", "eslint-visitor-keys@5.0.1" @@ -3489,7 +3472,7 @@ ], "bin": true }, - "@vinxi/plugin-directives@0.5.1_vinxi@0.5.11__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2__@types+node@24.12.0__ioredis@5.10.1__mysql2@3.20.0___@types+node@24.12.0__rolldown@1.0.0-rc.12___@emnapi+core@1.9.2___@emnapi+runtime@1.9.2__tsx@4.21.0__yaml@2.8.3_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2_@types+node@24.12.0_ioredis@5.10.1_mysql2@3.20.0__@types+node@24.12.0_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_tsx@4.21.0_yaml@2.8.3": { + "@vinxi/plugin-directives@0.5.1_vinxi@0.5.11__@types+node@24.12.2__ioredis@5.10.1__mysql2@3.22.1___@types+node@24.12.2__rolldown@1.0.0-rc.16__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_mysql2@3.22.1__@types+node@24.12.2_rolldown@1.0.0-rc.16_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-pH/KIVBvBt7z7cXrUH/9uaqcdxjegFC7+zvkZkdOyWzs+kQD5KPf3cl8kC+5ayzXHT+OMlhGhyitytqN3cGmHg==", "dependencies": [ "@babel/parser@7.29.2", @@ -3504,7 +3487,7 @@ "vinxi" ] }, - "@vinxi/server-components@0.5.1_vinxi@0.5.11__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2__@types+node@24.12.0__ioredis@5.10.1__mysql2@3.20.0___@types+node@24.12.0__rolldown@1.0.0-rc.12___@emnapi+core@1.9.2___@emnapi+runtime@1.9.2__tsx@4.21.0__yaml@2.8.3_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2_@types+node@24.12.0_ioredis@5.10.1_mysql2@3.20.0__@types+node@24.12.0_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_tsx@4.21.0_yaml@2.8.3": { + "@vinxi/server-components@0.5.1_vinxi@0.5.11__@types+node@24.12.2__ioredis@5.10.1__mysql2@3.22.1___@types+node@24.12.2__rolldown@1.0.0-rc.16__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_mysql2@3.22.1__@types+node@24.12.2_rolldown@1.0.0-rc.16_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-0BsG95qac3dkhfdRZxqzqYWJE4NvPL7ILlV43B6K6ho1etXWB2e5b0IxsUAUbyqpqiXM7mSRivojuXjb2G4OsQ==", "dependencies": [ "@vinxi/plugin-directives", @@ -3527,16 +3510,16 @@ "tinyrainbow" ] }, - "@vitest/mocker@3.2.4_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "@vitest/mocker@3.2.4_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dependencies": [ "@vitest/spy", "estree-walker@3.0.3", "magic-string", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ], "optionalPeers": [ - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ] }, "@vitest/pretty-format@3.2.4": { @@ -3783,15 +3766,16 @@ "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", "bin": true }, - "astro-integration-kit@0.18.0_astro@5.18.1__@types+node@24.12.0__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.2__yaml@2.8.3": { + "astro-integration-kit@0.18.0_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3": { "integrity": "sha512-Z0QW5IQjosuKQDEGYYkvUX6EhEtrmE4/oViqWz23QveV8U7AuyFsTdg00WRNPevWZl/5a4lLUeDpv4bCRynRRg==", "dependencies": [ "astro", "pathe@1.1.2", "recast" - ] + ], + "deprecated": true }, - "astro@5.18.1_@types+node@24.12.0_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.2_yaml@2.8.3": { + "astro@5.18.1_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3": { "integrity": "sha512-m4VWilWZ+Xt6NPoYzC4CgGZim/zQUO7WFL0RHCH0AiEavF1153iC3+me2atDvXpf/yX4PyGUeD8wZLq1cirT3g==", "dependencies": [ "@astrojs/compiler", @@ -3841,7 +3825,7 @@ "shiki@3.23.0", "smol-toml", "svgo", - "tinyexec@1.0.4", + "tinyexec@1.1.1", "tinyglobby", "tsconfck", "ultrahtml", @@ -3849,8 +3833,8 @@ "unist-util-visit", "unstorage", "vfile", - "vite@6.4.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "vitefu@1.1.3_vite@6.4.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", + "vite@6.4.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "vitefu@1.1.3_vite@6.4.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", "xxhash-wasm", "yargs-parser@21.1.1", "yocto-spinner", @@ -3934,8 +3918,8 @@ "bare-events@2.8.2": { "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==" }, - "bare-fs@4.6.0": { - "integrity": "sha512-2YkS7NuiJceSEbyEOdSNLE9tsGd+f4+f7C+Nik/MCk27SYdwIMPT/yRKvg++FZhQXgk0KWJKJyXX9RhVV0RGqA==", + "bare-fs@4.7.1": { + "integrity": "sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==", "dependencies": [ "bare-events", "bare-path", @@ -3953,8 +3937,8 @@ "bare-os" ] }, - "bare-stream@2.12.0_bare-events@2.8.2": { - "integrity": "sha512-w28i8lkBgREV3rPXGbgK+BO66q+ZpKqRWrZLiCdmmUlLPrQ45CzkvRhN+7lnv00Gpi2zy5naRxnUFAxCECDm9g==", + "bare-stream@2.13.0_bare-events@2.8.2": { + "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==", "dependencies": [ "bare-events", "streamx", @@ -3976,8 +3960,8 @@ "base64-js@1.5.1": { "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "baseline-browser-mapping@2.10.13": { - "integrity": "sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==", + "baseline-browser-mapping@2.10.19": { + "integrity": "sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==", "bin": true }, "bindings@1.5.0": { @@ -4034,15 +4018,15 @@ "wrap-ansi@9.0.2" ] }, - "brace-expansion@1.1.13": { - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "brace-expansion@1.1.14": { + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dependencies": [ "balanced-match@1.0.2", "concat-map" ] }, - "brace-expansion@2.0.3": { - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "brace-expansion@2.1.0": { + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dependencies": [ "balanced-match@1.0.2" ] @@ -4162,8 +4146,8 @@ "camelcase@8.0.0": { "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==" }, - "caniuse-lite@1.0.30001784": { - "integrity": "sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw==" + "caniuse-lite@1.0.30001788": { + "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==" }, "canonicalize@2.1.0": { "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", @@ -4495,7 +4479,7 @@ "undici-types@5.28.4" ] }, - "db0@0.3.4_mysql2@3.20.0__@types+node@24.12.0_@types+node@24.12.0": { + "db0@0.3.4_mysql2@3.22.1__@types+node@24.12.2_@types+node@24.12.2": { "integrity": "sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==", "dependencies": [ "mysql2" @@ -4562,8 +4546,8 @@ "define-lazy-prop@3.0.0": { "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==" }, - "defu@6.1.6": { - "integrity": "sha512-f8mefEW4WIVg4LckePx3mALjQSPQgFlg9U8yaPdlsbdYcHQyj9n2zL2LJEA52smeYxOvmd/nB7TpMtHGMTHcug==" + "defu@6.1.7": { + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==" }, "delegates@1.0.0": { "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" @@ -4595,8 +4579,8 @@ "base-64" ] }, - "devalue@5.6.4": { - "integrity": "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==" + "devalue@5.7.1": { + "integrity": "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA==" }, "devlop@1.1.0": { "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", @@ -4638,11 +4622,11 @@ "dot-prop@10.1.0": { "integrity": "sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==", "dependencies": [ - "type-fest@5.5.0" + "type-fest@5.6.0" ] }, - "dotenv@17.4.0": { - "integrity": "sha512-kCKF62fwtzwYm0IGBNjRUjtJgMfGapII+FslMHIjMR5KTnwEmBmWLDRSnc3XSNP8bNy34tekgQyDT0hr7pERRQ==" + "dotenv@17.4.2": { + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==" }, "dset@3.1.4": { "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==" @@ -4667,8 +4651,8 @@ "ee-first@1.1.1": { "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "electron-to-chromium@1.5.331": { - "integrity": "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q==" + "electron-to-chromium@1.5.340": { + "integrity": "sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==" }, "emoji-regex-xs@1.0.0": { "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==" @@ -4958,11 +4942,10 @@ "estraverse" ] }, - "esrap@2.2.4": { - "integrity": "sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==", + "esrap@2.2.5": { + "integrity": "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig==", "dependencies": [ - "@jridgewell/sourcemap-codec", - "@typescript-eslint/types" + "@jridgewell/sourcemap-codec" ] }, "esrecurse@4.3.0": { @@ -5126,8 +5109,8 @@ "fastify-plugin@5.1.0": { "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==" }, - "fastify@5.8.4": { - "integrity": "sha512-sa42J1xylbBAYUWALSBoyXKPDUvM3OoNOibIefA+Oha57FryXKKCZarA1iDntOCWp3O35voZLuDg2mdODXtPzQ==", + "fastify@5.8.5": { + "integrity": "sha512-Yqptv59pQzPgQUSIm87hMqHJmdkb1+GPxdE6vW6FRyVE9G86mt7rOghitiU4JHRaTyDUk9pfeKmDeu70lAwM4Q==", "dependencies": [ "@fastify/ajv-compiler", "@fastify/error", @@ -5193,8 +5176,8 @@ "uint8array-extras" ] }, - "file-type@21.3.2": { - "integrity": "sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==", + "file-type@21.3.4": { + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", "dependencies": [ "@tokenizer/inflate", "strtok3@10.3.5", @@ -5251,8 +5234,8 @@ "flattie@1.1.1": { "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==" }, - "follow-redirects@1.15.11": { - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==" + "follow-redirects@1.16.0": { + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==" }, "fontace@0.4.1": { "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", @@ -5343,8 +5326,8 @@ "is-stream@4.0.1" ] }, - "get-tsconfig@4.13.7": { - "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "get-tsconfig@4.14.0": { + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", "dependencies": [ "resolve-pkg-maps" ] @@ -5581,14 +5564,14 @@ "highlight.js@10.7.3": { "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" }, - "hono@4.12.10": { - "integrity": "sha512-mx/p18PLy5og9ufies2GOSUqep98Td9q4i/EF6X7yJgAiIopxqdfIO3jbqsi3jRgTgw88jMDEzVKi+V2EF+27w==" + "hono@4.12.14": { + "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==" }, "hookable@5.5.3": { "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==" }, - "hookable@6.1.0": { - "integrity": "sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw==" + "hookable@6.1.1": { + "integrity": "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==" }, "html-entities@2.3.3": { "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" @@ -5704,8 +5687,8 @@ "import-meta-resolve@4.2.0": { "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==" }, - "import-without-cache@0.2.5": { - "integrity": "sha512-B6Lc2s6yApwnD2/pMzFh/d5AVjdsDXjgkeJ766FmFuJELIGHNycKRj+l3A39yZPM4CchqNCB4RITEAYB1KUM6A==" + "import-without-cache@0.3.3": { + "integrity": "sha512-bDxwDdF04gm550DfZHgffvlX+9kUlcz32UD0AeBTmVPFiWkrexF2XVmiuFFbDhiFuP8fQkrkvI2KdSNPYWAXkQ==" }, "imurmurhash@0.1.4": { "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" @@ -5719,20 +5702,20 @@ "@inquirer/core@8.2.4" ] }, - "inquirer@12.11.1_@types+node@24.12.0": { + "inquirer@12.11.1_@types+node@24.12.2": { "integrity": "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==", "dependencies": [ "@inquirer/ansi", - "@inquirer/core@10.3.2_@types+node@24.12.0", + "@inquirer/core@10.3.2_@types+node@24.12.2", "@inquirer/prompts", - "@inquirer/type@3.0.10_@types+node@24.12.0", - "@types/node@24.12.0", + "@inquirer/type@3.0.10_@types+node@24.12.2", + "@types/node@24.12.2", "mute-stream@2.0.0", "run-async", "rxjs" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ] }, "ioredis@5.10.1": { @@ -5900,10 +5883,10 @@ "@pkgjs/parseargs" ] }, - "jimp@1.6.0": { - "integrity": "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg==", + "jimp@1.6.1": { + "integrity": "sha512-hNQh6rZtWfSVWSNVmvq87N5BPJsNH7k7I7qyrXf9DOma9xATQk3fsyHazCQe51nCjdkoWdTmh0vD7bjVSLoxxw==", "dependencies": [ - "@jimp/core@1.6.0", + "@jimp/core@1.6.1", "@jimp/diff", "@jimp/js-bmp", "@jimp/js-gif", @@ -5929,7 +5912,7 @@ "@jimp/plugin-rotate", "@jimp/plugin-threshold", "@jimp/types", - "@jimp/utils@1.6.0" + "@jimp/utils@1.6.1" ] }, "jiti@1.21.7": { @@ -6105,7 +6088,7 @@ "mlly", "node-forge", "pathe@2.0.3", - "std-env@4.0.0", + "std-env@4.1.0", "tinyclip", "ufo", "untun", @@ -6164,8 +6147,8 @@ "lru-cache@10.4.3": { "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, - "lru-cache@11.2.7": { - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==" + "lru-cache@11.3.5": { + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==" }, "lru-cache@5.1.1": { "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", @@ -6665,7 +6648,7 @@ "glob-to-regexp", "sharp@0.33.5", "stoppable", - "undici@7.24.4", + "undici@7.24.8", "workerd", "ws", "youch@4.1.0-beta.10", @@ -6682,19 +6665,19 @@ "minimatch@3.1.5": { "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dependencies": [ - "brace-expansion@1.1.13" + "brace-expansion@1.1.14" ] }, "minimatch@5.1.9": { "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dependencies": [ - "brace-expansion@2.0.3" + "brace-expansion@2.1.0" ] }, "minimatch@9.0.9": { "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dependencies": [ - "brace-expansion@2.0.3" + "brace-expansion@2.1.0" ] }, "minipass@7.1.3": { @@ -6730,10 +6713,10 @@ "mute-stream@2.0.0": { "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==" }, - "mysql2@3.20.0_@types+node@24.12.0": { - "integrity": "sha512-eCLUs7BNbgA6nf/MZXsaBO1SfGs0LtLVrJD3WeWq+jPLDWkSufTD+aGMwykfUVPdZnblaUK1a8G/P63cl9FkKg==", + "mysql2@3.22.1_@types+node@24.12.2": { + "integrity": "sha512-48+9UXehKyxxiP2pqCxUq+MSFvX+v41jwsSpFDQO/jAoFuAELutBGJUhWJnDbe82/OBlIhSBMC82WeonmznT/Q==", "dependencies": [ - "@types/node@24.12.0", + "@types/node@24.12.2", "aws-ssl-profiles", "denque", "generate-function", @@ -6771,7 +6754,7 @@ "neotraverse@0.6.18": { "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==" }, - "nitropack@2.13.3_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2_@types+node@24.12.0_mysql2@3.20.0__@types+node@24.12.0_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2": { + "nitropack@2.13.3_@types+node@24.12.2_mysql2@3.22.1__@types+node@24.12.2_rolldown@1.0.0-rc.16": { "integrity": "sha512-C8vO7RxkU0AQ3HbYUumuG6MVM5JjRaBchke/rYFOp3EvrLtTBHZYhDVGECdpa27vNuOYRzm3GtQMn2YDOjDJLA==", "dependencies": [ "@cloudflare/kv-asset-handler@0.4.2", @@ -6831,7 +6814,7 @@ "serve-placeholder", "serve-static@2.2.1", "source-map@0.7.6", - "std-env@4.0.0", + "std-env@4.1.0", "ufo", "ultrahtml", "uncrypto", @@ -7112,7 +7095,7 @@ "path-scurry@2.0.2": { "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dependencies": [ - "lru-cache@11.2.7", + "lru-cache@11.3.5", "minipass" ] }, @@ -7228,31 +7211,31 @@ "pngjs@7.0.0": { "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==" }, - "postcss@8.5.8": { - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "postcss@8.5.10": { + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "dependencies": [ "nanoid", "picocolors", "source-map-js" ] }, - "postgres@3.4.8": { - "integrity": "sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==" + "postgres@3.4.9": { + "integrity": "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw==" }, "powershell-utils@0.1.0": { "integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==" }, - "preact-render-to-string@6.6.5_preact@10.29.0": { - "integrity": "sha512-O6MHzYNIKYaiSX3bOw0gGZfEbOmlIDtDfWwN1JJdc/T3ihzRT6tGGSEWE088dWrEDGa1u7101q+6fzQnO9XCPA==", + "preact-render-to-string@6.6.7_preact@10.29.1": { + "integrity": "sha512-3XdbsX3+vn9dQW+jJI/FsI9rlkgl6dbeUpqLsChak6jp3j3auFqBCkno7VChbMFs5Q8ylBj6DrUkKRwtVN3nvw==", "dependencies": [ - "preact@10.29.0" + "preact@10.29.1" ] }, "preact@10.19.6": { "integrity": "sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==" }, - "preact@10.29.0": { - "integrity": "sha512-wSAGyk2bYR1c7t3SZ3jHcM6xy0lcBcDel6lODcs9ME6Th++Dx2KU+6D3HD8wMMKGA8Wpw7OMd3/4RGzYRpzwRg==" + "preact@10.29.1": { + "integrity": "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg==" }, "prelude-ls@1.2.1": { "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" @@ -7553,9 +7536,10 @@ "resolve-pkg-maps@1.0.0": { "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==" }, - "resolve@1.22.11": { - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "resolve@1.22.12": { + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dependencies": [ + "es-errors", "is-core-module", "path-parse", "supports-preserve-symlinks-flag" @@ -7611,7 +7595,7 @@ "rfdc@1.4.1": { "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" }, - "rolldown-plugin-dts@0.23.2_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_typescript@6.0.2_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { + "rolldown-plugin-dts@0.23.2_rolldown@1.0.0-rc.16_typescript@6.0.3": { "integrity": "sha512-PbSqLawLgZBGcOGT3yqWBGn4cX+wh2nt5FuBGdcMHyOhoukmjbhYAl8NT9sE4U38Cm9tqLOIQeOrvzeayM0DLQ==", "dependencies": [ "@babel/generator@8.0.0-rc.3", @@ -7631,8 +7615,8 @@ "typescript" ] }, - "rolldown@1.0.0-rc.12_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { - "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", + "rolldown@1.0.0-rc.16": { + "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", "dependencies": [ "@oxc-project/types", "@rolldown/pluginutils" @@ -7656,7 +7640,7 @@ ], "bin": true }, - "rollup-plugin-visualizer@7.0.1_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_rollup@4.60.1_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { + "rollup-plugin-visualizer@7.0.1_rolldown@1.0.0-rc.16_rollup@4.60.1": { "integrity": "sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==", "dependencies": [ "open", @@ -7806,14 +7790,14 @@ "serialize-javascript@7.0.5": { "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==" }, - "seroval-plugins@1.5.1_seroval@1.5.1": { - "integrity": "sha512-4FbuZ/TMl02sqv0RTFexu0SP6V+ywaIe5bAWCCEik0fk17BhALgwvUDVF7e3Uvf9pxmwCEJsRPmlkUE6HdzLAw==", + "seroval-plugins@1.5.2_seroval@1.5.2": { + "integrity": "sha512-qpY0Cl+fKYFn4GOf3cMiq6l72CpuVaawb6ILjubOQ+diJ54LfOWaSSPsaswN8DRPIPW4Yq+tE1k5aKd7ILyaFg==", "dependencies": [ "seroval" ] }, - "seroval@1.5.1": { - "integrity": "sha512-OwrZRZAfhHww0WEnKHDY8OM0U/Qs8OTfIDWhUD4BLpNJUfXK4cGmjiagGze086m+mhI+V2nD0gfbHEnJjb9STA==" + "seroval@1.5.2": { + "integrity": "sha512-xcRN39BdsnO9Tf+VzsE7b3JyTJASItIV1FVFewJKCFcW4s4haIKS3e6vj8PGB9qBwC7tnuOywQMdv5N4qkzi7Q==" }, "serve-placeholder@2.0.2": { "integrity": "sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==", @@ -7954,8 +7938,8 @@ "@types/hast" ] }, - "side-channel-list@1.0.0": { - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "side-channel-list@1.0.1": { + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "dependencies": [ "es-errors", "object-inspect" @@ -8002,8 +7986,8 @@ "is-arrayish" ] }, - "simple-xml-to-json@1.2.4": { - "integrity": "sha512-3MY16e0ocMHL7N1ufpdObURGyX+lCo0T/A+y6VCwosLdH1HSda4QZl1Sdt/O+2qWp48WFi26XEp5rF0LoaL0Dg==" + "simple-xml-to-json@1.2.7": { + "integrity": "sha512-mz9VXphOxQWX3eQ/uXCtm6upltoN0DLx8Zb5T4TFC4FHB7S9FDPGre8CfLWqPWQQH/GrQYd2AXhhVM5LDpYx6Q==" }, "sirv@3.0.2": { "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", @@ -8101,8 +8085,8 @@ "std-env@3.10.0": { "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==" }, - "std-env@4.0.0": { - "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==" + "std-env@4.1.0": { + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==" }, "stdin-discarder@0.2.2": { "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==" @@ -8220,8 +8204,8 @@ "supports-preserve-symlinks-flag@1.0.0": { "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, - "svelte@5.55.1": { - "integrity": "sha512-QjvU7EFemf6mRzdMGlAFttMWtAAVXrax61SZYHdkD6yoVGQ89VeyKfZD4H1JrV1WLmJBxWhFch9H6ig/87VGjw==", + "svelte@5.55.4": { + "integrity": "sha512-q8DFohk6vUswSng95IZb9nzWJnbINZsK7OiM1snAa3qCjJBL0ZQpvMyAaVXjUukdM75J/m8UE8xwqat8Ors/zQ==", "dependencies": [ "@jridgewell/remapping", "@jridgewell/sourcemap-codec", @@ -8344,11 +8328,11 @@ "tinyexec@0.3.2": { "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==" }, - "tinyexec@1.0.4": { - "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==" + "tinyexec@1.1.1": { + "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==" }, - "tinyglobby@0.2.15": { - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "tinyglobby@0.2.16": { + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dependencies": [ "fdir", "picomatch@4.0.4" @@ -8412,13 +8396,13 @@ "trough@2.2.0": { "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==" }, - "ts-api-utils@2.5.0_typescript@6.0.2": { + "ts-api-utils@2.5.0_typescript@6.0.3": { "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dependencies": [ "typescript" ] }, - "tsconfck@3.1.6_typescript@6.0.2": { + "tsconfck@3.1.6_typescript@6.0.3": { "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", "dependencies": [ "typescript" @@ -8428,21 +8412,21 @@ ], "bin": true }, - "tsdown@0.21.7_typescript@6.0.2_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { - "integrity": "sha512-ukKIxKQzngkWvOYJAyptudclkm4VQqbjq+9HF5K5qDO8GJsYtMh8gIRwicbnZEnvFPr6mquFwYAVZ8JKt3rY2g==", + "tsdown@0.21.9_typescript@6.0.3": { + "integrity": "sha512-tZPv2zMaMnjj9H9h0SDqpSXa9YWVZWHlG46DnSgNTFX6aq001MSI8kuBzJumr/u099nWj+1v5S7rhbnHk5jCHA==", "dependencies": [ "ansis", "cac@7.0.0", "defu", "empathic", - "hookable@6.1.0", + "hookable@6.1.1", "import-without-cache", "obug", "picomatch@4.0.4", "rolldown", "rolldown-plugin-dts", "semver@7.7.4", - "tinyexec@1.0.4", + "tinyexec@1.1.1", "tinyglobby", "tree-kill", "typescript", @@ -8483,8 +8467,8 @@ "type-fest@4.41.0": { "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==" }, - "type-fest@5.5.0": { - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", + "type-fest@5.6.0": { + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", "dependencies": [ "tagged-tag" ] @@ -8496,8 +8480,8 @@ "mime-types@2.1.35" ] }, - "typescript@6.0.2": { - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "typescript@6.0.3": { + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "bin": true }, "ufo@1.6.3": { @@ -8543,11 +8527,11 @@ "undici-types@7.16.0": { "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" }, - "undici@6.24.1": { - "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==" + "undici@6.25.0": { + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==" }, - "undici@7.24.4": { - "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==" + "undici@7.24.8": { + "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==" }, "unenv@1.10.0": { "integrity": "sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==", @@ -8598,8 +8582,8 @@ "ohash" ] }, - "unimport@6.0.2": { - "integrity": "sha512-ZSOkrDw380w+KIPniY3smyXh2h7H9v2MNr9zejDuh239o5sdea44DRAYrv+rfUi2QGT186P2h0GPGKvy8avQ5g==", + "unimport@6.1.0": { + "integrity": "sha512-ocgNKyiqj7Hw7oHt7A7D3za3fq28eShe1EloL6hsoQgn7CF51Y4CqFT9ISG3rEy0JpA8CCz/sY5h5OovOn62VQ==", "dependencies": [ "acorn@8.16.0", "escape-string-regexp@5.0.0", @@ -8704,14 +8688,14 @@ "webpack-virtual-modules" ] }, - "unrun@0.2.34_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2": { - "integrity": "sha512-LyaghRBR++r7svhDK6tnDz2XaYHWdneBOA0jbS8wnRsHerI9MFljX4fIiTgbbNbEVzZ0C9P1OjWLLe1OqoaaEw==", + "unrun@0.2.36": { + "integrity": "sha512-ICAGv44LHSKjCdI4B4rk99lJLHXBweutO4MUwu3cavMlYtXID0Tn5e1Kwe/Uj6BSAuHHXfi1JheFVCYhcXHfAg==", "dependencies": [ "rolldown" ], "bin": true }, - "unstorage@1.17.5_db0@0.3.4__mysql2@3.20.0___@types+node@24.12.0__@types+node@24.12.0_ioredis@5.10.1_@types+node@24.12.0_mysql2@3.20.0__@types+node@24.12.0": { + "unstorage@1.17.5_db0@0.3.4__mysql2@3.22.1___@types+node@24.12.2__@types+node@24.12.2_ioredis@5.10.1_@types+node@24.12.2_mysql2@3.22.1__@types+node@24.12.2": { "integrity": "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==", "dependencies": [ "anymatch", @@ -8720,7 +8704,7 @@ "destr", "h3@1.15.11", "ioredis", - "lru-cache@11.2.7", + "lru-cache@11.3.5", "node-fetch-native", "ofetch", "ufo" @@ -8804,7 +8788,7 @@ "utils-merge@1.0.1": { "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, - "valibot@1.3.1_typescript@6.0.2": { + "valibot@1.3.1_typescript@6.0.3": { "integrity": "sha512-sfdRir/QFM0JaF22hqTroPc5xy4DimuGQVKFrzF1YfGwaS1nJot3Y8VqMdLO2Lg27fMzat2yD3pY5PbAYO39Gg==", "dependencies": [ "typescript" @@ -8837,7 +8821,7 @@ "vfile-message" ] }, - "vinxi@0.5.11_@emnapi+core@1.9.2_@emnapi+runtime@1.9.2_@types+node@24.12.0_ioredis@5.10.1_mysql2@3.20.0__@types+node@24.12.0_rolldown@1.0.0-rc.12__@emnapi+core@1.9.2__@emnapi+runtime@1.9.2_tsx@4.21.0_yaml@2.8.3": { + "vinxi@0.5.11_@types+node@24.12.2_ioredis@5.10.1_mysql2@3.22.1__@types+node@24.12.2_rolldown@1.0.0-rc.16_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-82Qm+EG/b2PRFBvXBbz1lgWBGcd9totIL6SJhnrZYfakjloTVG9+5l6gfO6dbCCtztm5pqWFzLY0qpZ3H3ww/w==", "dependencies": [ "@babel/core", @@ -8872,24 +8856,24 @@ "unctx", "unenv@1.10.0", "unstorage", - "vite@6.4.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", + "vite@6.4.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", "zod@4.3.6" ], "bin": true }, - "vite-node@3.2.4_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "vite-node@3.2.4_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dependencies": [ "cac@6.7.14", "debug@4.4.3", "es-module-lexer", "pathe@2.0.3", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ], "bin": true }, - "vite-plugin-solid@2.11.11_solid-js@1.9.12_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { - "integrity": "sha512-YMZCXsLw9kyuvQFEdwLP27fuTQJLmjNoHy90AOJnbRuJ6DwShUxKFo38gdFrWn9v11hnGicKCZEaeI/TFs6JKw==", + "vite-plugin-solid@2.11.12_solid-js@1.9.12_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { + "integrity": "sha512-FgjPcx2OwX9h6f28jli7A4bG7PP3te8uyakE5iqsmpq3Jqi1TWLgSroC9N6cMfGRU2zXsl4Q6ISvTr2VL0QHpA==", "dependencies": [ "@babel/core", "@types/babel__core", @@ -8897,14 +8881,14 @@ "merge-anything", "solid-js", "solid-refresh", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", - "vitefu@1.1.3_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", + "vitefu@1.1.3_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ] }, - "vite@6.4.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { - "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "vite@6.4.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { + "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", "dependencies": [ - "@types/node@24.12.0", + "@types/node@24.12.2", "esbuild@0.25.12", "fdir", "picomatch@4.0.4", @@ -8918,16 +8902,16 @@ "fsevents" ], "optionalPeers": [ - "@types/node@24.12.0", + "@types/node@24.12.2", "tsx", "yaml" ], "bin": true }, - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "dependencies": [ - "@types/node@24.12.0", + "@types/node@24.12.2", "esbuild@0.27.7", "fdir", "picomatch@4.0.4", @@ -8941,29 +8925,29 @@ "fsevents" ], "optionalPeers": [ - "@types/node@24.12.0", + "@types/node@24.12.2", "tsx", "yaml" ], "bin": true }, - "vitefu@1.1.3_vite@6.4.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "vitefu@1.1.3_vite@6.4.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==" }, - "vitefu@1.1.3_vite@7.3.1__@types+node@24.12.0__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "vitefu@1.1.3_vite@7.3.2__@types+node@24.12.2__tsx@4.21.0__yaml@2.8.3_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", "dependencies": [ - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ], "optionalPeers": [ - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3" + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3" ] }, - "vitest@3.2.4_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3": { + "vitest@3.2.4_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3": { "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dependencies": [ "@types/chai", - "@types/node@24.12.0", + "@types/node@24.12.2", "@vitest/expect", "@vitest/mocker", "@vitest/pretty-format", @@ -8983,12 +8967,12 @@ "tinyglobby", "tinypool", "tinyrainbow", - "vite@7.3.1_@types+node@24.12.0_tsx@4.21.0_yaml@2.8.3", + "vite@7.3.2_@types+node@24.12.2_tsx@4.21.0_yaml@2.8.3", "vite-node", "why-is-node-running" ], "optionalPeers": [ - "@types/node@24.12.0" + "@types/node@24.12.2" ], "bin": true }, @@ -9060,7 +9044,7 @@ "scripts": true, "bin": true }, - "wrangler@4.35.0_@cloudflare+workers-types@4.20260403.1": { + "wrangler@4.35.0_@cloudflare+workers-types@4.20260417.1": { "integrity": "sha512-HbyXtbrh4Fi3mU8ussY85tVdQ74qpVS1vctUgaPc+bPrXBTqfDLkZ6VRtHAVF/eBhz4SFmhJtCQpN1caY2Ak8A==", "dependencies": [ "@cloudflare/kv-asset-handler@0.4.0", @@ -9252,7 +9236,7 @@ "zod@3.25.76" ] }, - "zod-to-ts@1.2.0_typescript@6.0.2_zod@3.25.76": { + "zod-to-ts@1.2.0_typescript@6.0.3_zod@3.25.76": { "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", "dependencies": [ "typescript", diff --git a/examples/nuxt/.gitignore b/examples/nuxt/.gitignore new file mode 100644 index 000000000..d86952676 --- /dev/null +++ b/examples/nuxt/.gitignore @@ -0,0 +1,5 @@ +node_modules +dist +.output +.nuxt +.data diff --git a/examples/nuxt/README.md b/examples/nuxt/README.md new file mode 100644 index 000000000..ae1c90a06 --- /dev/null +++ b/examples/nuxt/README.md @@ -0,0 +1,45 @@ + + +Fedify-Nuxt integration example application +=========================================== + +A comprehensive example of building a federated server application using +[Fedify] with [Nuxt]. This example demonstrates how to create an +ActivityPub-compatible federated social media server that can interact with +other federated platforms like [Mastodon], [Misskey], and other ActivityPub +implementations using the Fedify and [Nuxt]. + +[Fedify]: https://fedify.dev +[Nuxt]: https://nuxt.com/ +[Mastodon]: https://mastodon.social/ +[Misskey]: https://misskey.io/ + + +Running the example +------------------- + +~~~~ sh +pnpm dev +~~~~ + + +Communicate with other federated servers +---------------------------------------- + +1. Tunnel your local server to the internet using `fedify tunnel` + + ~~~~ sh + fedify tunnel 3000 + ~~~~ + +2. Open the tunneled URL in your browser and check that the server is running + properly. + +3. Search your handle and follow from other federated servers such as + [Mastodon] or [Misskey]. + + > [!NOTE] + > [ActivityPub Academy] is a great resource to learn how to interact + > with other federated servers using ActivityPub protocol. + +[ActivityPub Academy]: https://www.activitypub.academy/ diff --git a/examples/nuxt/app.vue b/examples/nuxt/app.vue new file mode 100644 index 000000000..420f15557 --- /dev/null +++ b/examples/nuxt/app.vue @@ -0,0 +1,13 @@ + + + diff --git a/examples/nuxt/nuxt.config.ts b/examples/nuxt/nuxt.config.ts new file mode 100644 index 000000000..d3f3a3fa0 --- /dev/null +++ b/examples/nuxt/nuxt.config.ts @@ -0,0 +1,9 @@ +export default defineNuxtConfig({ + modules: ["@fedify/nuxt"], + fedify: { + federationModule: "~/server/federation", + }, + ssr: true, + devServer: { host: "0.0.0.0" }, + vite: { server: { allowedHosts: true } }, +}); diff --git a/examples/nuxt/package.json b/examples/nuxt/package.json new file mode 100644 index 000000000..d7610eff2 --- /dev/null +++ b/examples/nuxt/package.json @@ -0,0 +1,27 @@ +{ + "name": "nuxt-example", + "version": "0.0.1", + "private": true, + "type": "module", + "description": "Fedify app with Nuxt integration", + "scripts": { + "dev": "nuxt dev", + "build": "nuxt build", + "preview": "nuxt preview", + "start": "node .output/server/index.mjs" + }, + "dependencies": { + "@fedify/fedify": "workspace:^", + "@fedify/nuxt": "workspace:^", + "@fedify/vocab": "workspace:^", + "@logtape/logtape": "catalog:", + "nuxt": "catalog:", + "h3": "catalog:", + "vue": "^3.5.13", + "x-forwarded-fetch": "^0.2.0" + }, + "devDependencies": { + "typescript": "catalog:", + "@types/node": "catalog:" + } +} diff --git a/examples/nuxt/pages/index.vue b/examples/nuxt/pages/index.vue new file mode 100644 index 000000000..51779f2cc --- /dev/null +++ b/examples/nuxt/pages/index.vue @@ -0,0 +1,287 @@ + + + + + diff --git a/examples/nuxt/pages/users/[identifier]/index.vue b/examples/nuxt/pages/users/[identifier]/index.vue new file mode 100644 index 000000000..afd73d7bc --- /dev/null +++ b/examples/nuxt/pages/users/[identifier]/index.vue @@ -0,0 +1,71 @@ + + + diff --git a/examples/nuxt/pages/users/[identifier]/posts/[id].vue b/examples/nuxt/pages/users/[identifier]/posts/[id].vue new file mode 100644 index 000000000..e71e80d6a --- /dev/null +++ b/examples/nuxt/pages/users/[identifier]/posts/[id].vue @@ -0,0 +1,61 @@ + + + diff --git a/examples/nuxt/public/demo-profile.png b/examples/nuxt/public/demo-profile.png new file mode 100644 index 0000000000000000000000000000000000000000..2c9883bcc5654c5c8e9396e183f51999e83eeda2 GIT binary patch literal 51021 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 +FedifyFedify diff --git a/examples/nuxt/public/style.css b/examples/nuxt/public/style.css new file mode 100644 index 000000000..6cd70d7b7 --- /dev/null +++ b/examples/nuxt/public/style.css @@ -0,0 +1,505 @@ +:root { + --background: #ffffff; + --foreground: #171717; +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + background: var(--background); + color: var(--foreground); + font-size: 16px; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, + Cantarell, sans-serif; +} + +a { + color: #3b82f6; + text-decoration: none; +} +a:hover { + text-decoration: underline; +} + +/* Profile Header */ +.profile-header { + display: flex; + gap: 2rem; + padding: 2rem; + margin-bottom: 2rem; + border-radius: 1rem; + color: white; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +.avatar-section { + flex-shrink: 0; +} + +.avatar { + width: 7.5rem; + height: 7.5rem; + border-radius: 50%; + object-fit: cover; + border: 4px solid rgba(255, 255, 255, 0.2); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); +} + +.user-info { + display: flex; + flex-direction: column; + justify-content: center; + flex: 1; +} + +.user-name { + font-size: 2.25rem; + font-weight: bold; + margin: 0 0 0.5rem 0; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.user-handle { + font-size: 1.25rem; + font-weight: 500; + margin-bottom: 1rem; + opacity: 0.9; +} + +.user-bio { + font-size: 1.125rem; + line-height: 1.625; + opacity: 0.95; + margin: 0; +} + +/* Profile Container & Content */ +.profile-container { + max-width: 56rem; + margin: 0 auto; + display: flex; + flex-direction: column; + justify-content: center; + align-content: center; + padding: 2rem; + min-height: 100vh; +} + +.profile-content { + display: grid; + gap: 2rem; +} + +.info-card { + border-radius: 0.75rem; + border: 1px solid rgba(0, 0, 0, 0.05); + background: var(--background); + color: var(--foreground); + padding: 2rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); +} + +.info-card h3 { + font-size: 1.5rem; + font-weight: 600; + margin: 0 0 1.5rem 0; +} + +.info-grid { + display: grid; + gap: 1rem; +} + +.info-item { + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 0.75rem 0; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); +} + +.info-item:last-child { + border-bottom: none; +} + +.info-label { + font-size: 0.875rem; + font-weight: 600; + color: color-mix(in srgb, var(--foreground) 60%, transparent); +} + +.fedify-anchor { + display: inline-flex; + align-items: center; + gap: 0.25rem; + height: 1.5rem; + padding: 0.125rem 0.25rem; + border-radius: 0.375rem; + background: #7dd3fc; + color: white; + font-weight: 500; + text-decoration: none; +} + +.fedify-anchor::before { + content: ""; + display: inline-block; + width: 16px; + height: 16px; + background-image: url("/fedify-logo.svg"); + background-size: 16px 16px; + vertical-align: middle; + margin-bottom: 0.125rem; +} + +/* Post Form */ +.post-form { + max-width: 56rem; + margin: 2rem auto; + padding: 1.5rem; + border-radius: 0.75rem; + border: 1px solid rgba(0, 0, 0, 0.1); + background: var(--background); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); +} + +.form-group { + margin-bottom: 1rem; +} + +.form-label { + display: block; + font-size: 1.125rem; + font-weight: 600; + margin-bottom: 0.5rem; + color: var(--foreground); +} + +.form-textarea { + width: 100%; + resize: vertical; + border-radius: 0.5rem; + border: 1px solid rgba(0, 0, 0, 0.2); + padding: 0.75rem; + font-size: 1rem; + background: var(--background); + color: var(--foreground); + transition: border-color 0.2s, box-shadow 0.2s; + font-family: inherit; +} + +.form-textarea:focus { + outline: none; + border-color: #3b82f6; + box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3); +} + +.post-button { + padding: 0.5rem 1.5rem; + border: none; + border-radius: 0.5rem; + font-size: 1rem; + font-weight: 600; + color: white; + cursor: pointer; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + transition: transform 0.2s, box-shadow 0.2s; +} + +.post-button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +/* Posts Container & Grid */ +.posts-container { + max-width: 56rem; + margin: 0 auto; + padding: 0 2rem; +} + +.posts-title { + font-size: 1.5rem; + font-weight: bold; + margin-bottom: 1.5rem; + color: var(--foreground); +} + +.posts-grid { + display: grid; + gap: 1.5rem; +} + +.post-card { + border-radius: 0.75rem; + border: 1px solid rgba(0, 0, 0, 0.1); + background: var(--background); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); + transition: transform 0.2s, box-shadow 0.2s; +} + +.post-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); +} + +.post-link { + display: block; + padding: 1.5rem; + text-decoration: none; + color: inherit; +} +.post-link:hover { + text-decoration: none; +} + +.post-header { + display: flex; + align-items: center; + gap: 0.75rem; + margin-bottom: 1rem; +} + +.post-avatar { + width: 3rem; + height: 3rem; + border-radius: 50%; + object-fit: cover; + border: 2px solid #e5e7eb; +} + +.post-user-info { + flex: 1; +} + +.post-user-name { + font-size: 1.125rem; + font-weight: 600; + margin: 0 0 0.25rem 0; + color: var(--foreground); +} + +.post-user-handle { + font-size: 0.875rem; + opacity: 0.7; + color: var(--foreground); + margin: 0; +} + +.post-content { + font-size: 1rem; + line-height: 1.625; + color: var(--foreground); +} + +.post-content p { + margin: 0; +} + +/* Post Detail */ +.post-detail-container { + max-width: 56rem; + margin: 0 auto; + padding: 2rem; +} + +.post-detail-card { + border-radius: 0.75rem; + border: 1px solid rgba(0, 0, 0, 0.1); + background: var(--background); + padding: 2rem; + margin-bottom: 2rem; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); +} + +.post-detail-author { + display: flex; + align-items: flex-start; + gap: 1rem; + padding-bottom: 1.5rem; + margin-bottom: 1.5rem; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + text-decoration: none; + color: inherit; +} +.post-detail-author:hover { + text-decoration: none; +} + +.author-avatar { + width: 4rem; + height: 4rem; + border-radius: 50%; + object-fit: cover; + border: 2px solid #e5e7eb; +} + +.author-info { + flex: 1; +} + +.author-name { + font-size: 1.5rem; + font-weight: bold; + margin: 0 0 0.25rem 0; + color: var(--foreground); +} + +.author-handle { + font-size: 1rem; + font-weight: 500; + opacity: 0.7; + margin: 0 0 0.5rem 0; + color: var(--foreground); +} + +.post-timestamp { + font-size: 0.875rem; + opacity: 0.6; + color: var(--foreground); +} + +.post-detail-content { + padding: 1.5rem 0; + font-size: 1.125rem; + line-height: 1.625; + color: var(--foreground); +} + +.post-detail-content p { + margin: 0; +} + +.back-link { + display: inline-block; + margin-bottom: 1.5rem; + padding: 0.5rem 1rem; + border-radius: 0.5rem; + font-weight: 500; + color: var(--foreground); + background: color-mix(in srgb, var(--foreground) 10%, transparent); + text-decoration: none; + transition: background 0.2s; +} + +.back-link:hover { + background: color-mix(in srgb, var(--foreground) 15%, transparent); + text-decoration: none; +} + +/* Home Page */ +.home-container { + max-width: 780px; + margin: 2rem auto; + display: grid; + gap: 1rem; + padding: 1rem; +} + +.home-logo { + display: block; + width: 8rem; + height: 8rem; + margin: 0 auto; +} + +.home-banner { + display: flex; + flex-wrap: wrap; + justify-content: center; + font-family: monospace; + line-height: 1.2; + white-space: pre; +} + +.home-handle { + font-family: monospace; + background: #f3f4f6; + color: #000; + padding: 0.25rem 0.5rem; + border-radius: 0.375rem; + user-select: all; +} + +.follower-item { + font-family: monospace; + background: #f3f4f6; + color: #000; + padding: 0.25rem 0.5rem; + border-radius: 0.375rem; +} + +.follower-list { + display: flex; + flex-direction: column; + gap: 0.25rem; + width: max-content; + list-style: none; +} + +/* Responsive */ +@media (max-width: 768px) { + .profile-container { + padding: 1rem; + } + + .profile-header { + flex-direction: column; + align-items: center; + gap: 1rem; + text-align: center; + } + + .user-name { + font-size: 1.875rem; + } + + .info-item { + flex-direction: column; + align-items: flex-start; + gap: 0.25rem; + } + + .posts-container { + padding: 0 1rem; + } + + .post-form { + padding: 1rem; + } + + .post-detail-container { + padding: 1rem; + } + + .post-detail-card { + padding: 1.5rem; + } + + .author-avatar { + width: 3.5rem; + height: 3.5rem; + } + + .author-name { + font-size: 1.25rem; + } + + .post-detail-content { + font-size: 1rem; + } +} diff --git a/examples/nuxt/public/theme.js b/examples/nuxt/public/theme.js new file mode 100644 index 000000000..8d521d625 --- /dev/null +++ b/examples/nuxt/public/theme.js @@ -0,0 +1,7 @@ +"use strict"; +var mq = window.matchMedia("(prefers-color-scheme: dark)"); +document.body.classList.add(mq.matches ? "dark" : "light"); +mq.addEventListener("change", function (e) { + document.body.classList.remove("light", "dark"); + document.body.classList.add(e.matches ? "dark" : "light"); +}); diff --git a/examples/nuxt/server/api/events.get.ts b/examples/nuxt/server/api/events.get.ts new file mode 100644 index 000000000..e2f710e0d --- /dev/null +++ b/examples/nuxt/server/api/events.get.ts @@ -0,0 +1,36 @@ +import { setResponseHeader } from "h3"; +import { addClient, removeClient } from "../sse"; + +export default defineEventHandler(async (event) => { + setResponseHeader(event, "Content-Type", "text/event-stream"); + setResponseHeader(event, "Cache-Control", "no-cache"); + setResponseHeader(event, "Connection", "keep-alive"); + + const stream = new ReadableStream({ + start(controller) { + const encoder = new TextEncoder(); + const client = { + send(data: string) { + controller.enqueue(encoder.encode(`data: ${data}\n\n`)); + }, + close() { + controller.close(); + }, + }; + + addClient(client); + + event.node.req.on("close", () => { + removeClient(client); + }); + }, + }); + + return new Response(stream, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + "Connection": "keep-alive", + }, + }); +}); diff --git a/examples/nuxt/server/api/follow.post.ts b/examples/nuxt/server/api/follow.post.ts new file mode 100644 index 000000000..f71deff09 --- /dev/null +++ b/examples/nuxt/server/api/follow.post.ts @@ -0,0 +1,42 @@ +import { Follow, type Object as APObject } from "@fedify/vocab"; +import { readBody, sendRedirect, toWebRequest } from "h3"; +import federation from "../federation"; +import { broadcastEvent } from "../sse"; +import { followingStore } from "../store"; + +export default defineEventHandler(async (event) => { + const body = await readBody(event); + const targetUri = body?.uri; + if (typeof targetUri !== "string" || !targetUri.trim()) { + return sendRedirect(event, "/", 303); + } + + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + const identifier = "demo"; + + const target = await ctx.lookupObject(targetUri) as APObject | null; + if (target?.id == null) { + return sendRedirect(event, "/", 303); + } + + await ctx.sendActivity( + { identifier }, + target, + new Follow({ + id: new URL( + `#follows/${target.id.href}`, + ctx.getActorUri(identifier), + ), + actor: ctx.getActorUri(identifier), + object: target.id, + }), + ); + + const { Person } = await import("@fedify/vocab"); + if (target instanceof Person) { + followingStore.set(target.id.href, target); + } + broadcastEvent(); + return sendRedirect(event, "/", 303); +}); diff --git a/examples/nuxt/server/api/home.get.ts b/examples/nuxt/server/api/home.get.ts new file mode 100644 index 000000000..53da585b1 --- /dev/null +++ b/examples/nuxt/server/api/home.get.ts @@ -0,0 +1,51 @@ +import { toWebRequest } from "h3"; +import federation from "../federation"; +import { followingStore, postStore, relationStore } from "../store"; + +export default defineEventHandler(async (event) => { + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + const identifier = "demo"; + const actorUri = ctx.getActorUri(identifier); + const host = new URL(actorUri).host; + + const followers = await Promise.all( + Array.from(relationStore.entries()).map(async ([uri, person]) => ({ + uri, + name: person.name?.toString() ?? null, + handle: person.preferredUsername + ? `@${person.preferredUsername}@${person.id?.hostname ?? ""}` + : uri, + icon: (await person.getIcon(ctx))?.url?.href ?? null, + })), + ); + + const following = await Promise.all( + Array.from(followingStore.entries()).map(async ([uri, person]) => ({ + uri, + name: person.name?.toString() ?? null, + handle: person.preferredUsername + ? `@${person.preferredUsername}@${person.id?.hostname ?? ""}` + : uri, + icon: (await person.getIcon(ctx))?.url?.href ?? null, + })), + ); + + const allPosts = postStore.getAll(); + const posts = allPosts.map((p) => ({ + url: p.url?.href ?? p.id?.href ?? "", + id: p.id?.href ?? "", + content: p.content?.toString() ?? "", + published: p.published?.toString() ?? null, + })); + + return { + identifier, + host, + name: "Fedify Demo", + summary: "This is a Fedify Demo account.", + followers, + following, + posts, + }; +}); diff --git a/examples/nuxt/server/api/post.post.ts b/examples/nuxt/server/api/post.post.ts new file mode 100644 index 000000000..03245ac3d --- /dev/null +++ b/examples/nuxt/server/api/post.post.ts @@ -0,0 +1,44 @@ +import { Create, Note } from "@fedify/vocab"; +import { readBody, sendRedirect, toWebRequest } from "h3"; +import federation from "../federation"; +import { postStore } from "../store"; + +export default defineEventHandler(async (event) => { + const body = await readBody(event); + const content = body?.content; + if (typeof content !== "string" || !content.trim()) { + return sendRedirect(event, "/", 303); + } + + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + const identifier = "demo"; + const id = crypto.randomUUID(); + const attribution = ctx.getActorUri(identifier); + const url = new URL(`/users/${identifier}/posts/${id}`, attribution); + const post = new Note({ + id: url, + attribution, + content: content.trim(), + url, + }); + try { + postStore.append([post]); + const note = await ctx.getObject(Note, { identifier, id }); + await ctx.sendActivity( + { identifier }, + "followers", + new Create({ + id: new URL("#activity", attribution), + object: note, + actors: note?.attributionIds, + tos: note?.toIds, + ccs: note?.ccIds, + }), + ); + } catch { + postStore.delete(url); + } + + return sendRedirect(event, "/", 303); +}); diff --git a/examples/nuxt/server/api/posts/[identifier]/[id].get.ts b/examples/nuxt/server/api/posts/[identifier]/[id].get.ts new file mode 100644 index 000000000..67812a7a8 --- /dev/null +++ b/examples/nuxt/server/api/posts/[identifier]/[id].get.ts @@ -0,0 +1,33 @@ +import { Note } from "@fedify/vocab"; +import { toWebRequest } from "h3"; +import federation from "../../../federation"; + +export default defineEventHandler(async (event) => { + const identifier = event.context.params?.identifier as string; + const id = event.context.params?.id as string; + if (identifier !== "demo" || !id) { + return null; + } + + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + const actor = await ctx.getActor(identifier); + const noteObj = await ctx.getObject(Note, { identifier, id }); + if (!actor || !noteObj) return null; + + const icon = await actor.getIcon(ctx); + const actorUri = ctx.getActorUri(identifier); + const host = new URL(actorUri).host; + + return { + identifier, + host, + author: { + name: actor.name?.toString() ?? "Fedify Demo", + icon: icon?.url?.href ?? null, + }, + content: noteObj.content?.toString() ?? "", + published: noteObj.published?.toString() ?? null, + url: noteObj.url?.href ?? noteObj.id?.href ?? "", + }; +}); diff --git a/examples/nuxt/server/api/profile/[identifier].get.ts b/examples/nuxt/server/api/profile/[identifier].get.ts new file mode 100644 index 000000000..2804da243 --- /dev/null +++ b/examples/nuxt/server/api/profile/[identifier].get.ts @@ -0,0 +1,29 @@ +import { toWebRequest } from "h3"; +import federation from "../../federation"; +import { followingStore, relationStore } from "../../store"; + +export default defineEventHandler(async (event) => { + const identifier = event.context.params?.identifier as string; + if (identifier !== "demo") { + return null; + } + + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + const actor = await ctx.getActor(identifier); + if (!actor) return null; + + const icon = await actor.getIcon(ctx); + const actorUri = ctx.getActorUri(identifier); + const host = new URL(actorUri).host; + + return { + identifier, + host, + name: actor.name?.toString() ?? "Fedify Demo", + summary: actor.summary?.toString() ?? null, + icon: icon?.url?.href ?? null, + followingCount: followingStore.size, + followersCount: relationStore.size, + }; +}); diff --git a/examples/nuxt/server/api/search.get.ts b/examples/nuxt/server/api/search.get.ts new file mode 100644 index 000000000..aee9c7d39 --- /dev/null +++ b/examples/nuxt/server/api/search.get.ts @@ -0,0 +1,37 @@ +import { Person } from "@fedify/vocab"; +import { getQuery, toWebRequest } from "h3"; +import federation from "../federation"; +import { followingStore } from "../store"; + +export default defineEventHandler(async (event) => { + const query = getQuery(event); + const q = query.q as string | undefined; + if (!q || !q.trim()) { + return { result: null }; + } + + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + + try { + const target = await ctx.lookupObject(q.trim()); + if (target instanceof Person && target.id) { + const iconUrl = await target.getIcon(ctx); + return { + result: { + uri: target.id.href, + name: target.name?.toString() ?? null, + handle: target.preferredUsername + ? `@${target.preferredUsername}@${target.id.hostname}` + : target.id.href, + icon: iconUrl?.url?.href ?? null, + isFollowing: followingStore.has(target.id.href), + }, + }; + } + } catch { + // lookup failed + } + + return { result: null }; +}); diff --git a/examples/nuxt/server/api/unfollow.post.ts b/examples/nuxt/server/api/unfollow.post.ts new file mode 100644 index 000000000..516005eb9 --- /dev/null +++ b/examples/nuxt/server/api/unfollow.post.ts @@ -0,0 +1,46 @@ +import { Follow, type Object as APObject, Undo } from "@fedify/vocab"; +import { readBody, sendRedirect, toWebRequest } from "h3"; +import federation from "../federation"; +import { broadcastEvent } from "../sse"; +import { followingStore } from "../store"; + +export default defineEventHandler(async (event) => { + const body = await readBody(event); + const targetUri = body?.uri; + if (typeof targetUri !== "string" || !targetUri.trim()) { + return sendRedirect(event, "/", 303); + } + + const request = toWebRequest(event); + const ctx = federation.createContext(request, undefined); + const identifier = "demo"; + + const target = await ctx.lookupObject(targetUri) as APObject | null; + if (target?.id == null) { + return sendRedirect(event, "/", 303); + } + + await ctx.sendActivity( + { identifier }, + target, + new Undo({ + id: new URL( + `#undo-follows/${target.id.href}`, + ctx.getActorUri(identifier), + ), + actor: ctx.getActorUri(identifier), + object: new Follow({ + id: new URL( + `#follows/${target.id.href}`, + ctx.getActorUri(identifier), + ), + actor: ctx.getActorUri(identifier), + object: target.id, + }), + }), + ); + + followingStore.delete(target.id.href); + broadcastEvent(); + return sendRedirect(event, "/", 303); +}); diff --git a/examples/nuxt/server/federation.ts b/examples/nuxt/server/federation.ts new file mode 100644 index 000000000..de471c749 --- /dev/null +++ b/examples/nuxt/server/federation.ts @@ -0,0 +1,163 @@ +import { + createFederation, + generateCryptoKeyPair, + InProcessMessageQueue, + MemoryKvStore, +} from "@fedify/fedify"; +import { + Accept, + Endpoints, + Follow, + Image, + Note, + Person, + PUBLIC_COLLECTION, + type Recipient, + Undo, +} from "@fedify/vocab"; +import { broadcastEvent } from "./sse"; +import { keyPairsStore, postStore, relationStore } from "./store"; + +const federation = createFederation({ + kv: new MemoryKvStore(), + queue: new InProcessMessageQueue(), +}); + +const IDENTIFIER = "demo"; + +federation + .setActorDispatcher( + "/users/{identifier}", + async (context, identifier) => { + if (identifier != IDENTIFIER) { + return null; + } + const keyPairs = await context.getActorKeyPairs(identifier); + return new Person({ + id: context.getActorUri(identifier), + name: "Fedify Demo", + summary: "This is a Fedify Demo account.", + preferredUsername: identifier, + icon: new Image({ url: new URL("/demo-profile.png", context.url) }), + url: new URL("/", context.url), + inbox: context.getInboxUri(identifier), + followers: context.getFollowersUri(identifier), + endpoints: new Endpoints({ sharedInbox: context.getInboxUri() }), + publicKey: keyPairs[0].cryptographicKey, + assertionMethods: keyPairs.map((keyPair) => keyPair.multikey), + }); + }, + ) + .setKeyPairsDispatcher(async (_, identifier) => { + if (identifier != IDENTIFIER) { + return []; + } + const keyPairs = keyPairsStore.get(identifier); + if (keyPairs) { + return keyPairs; + } + const { privateKey, publicKey } = await generateCryptoKeyPair(); + keyPairsStore.set(identifier, [{ privateKey, publicKey }]); + return [{ privateKey, publicKey }]; + }); + +federation + .setInboxListeners("/users/{identifier}/inbox", "/inbox") + .on(Follow, async (context, follow) => { + if ( + follow.id == null || + follow.actorId == null || + follow.objectId == null + ) { + return; + } + const result = context.parseUri(follow.objectId); + if (result?.type !== "actor" || result.identifier !== IDENTIFIER) { + return; + } + const follower = await follow.getActor(context) as Person; + if (!follower?.id) { + throw new Error("follower is null"); + } + await context.sendActivity( + { identifier: result.identifier }, + follower, + new Accept({ + id: new URL( + `#accepts/${follower.id.href}`, + context.getActorUri(IDENTIFIER), + ), + actor: follow.objectId, + object: follow, + }), + ); + relationStore.set(follower.id.href, follower); + broadcastEvent(); + }) + .on(Undo, async (context, undo) => { + const activity = await undo.getObject(context); + if (activity instanceof Follow) { + if (activity.id == null) { + return; + } + if (undo.actorId == null) { + return; + } + relationStore.delete(undo.actorId.href); + broadcastEvent(); + } else { + console.debug(undo); + } + }); + +federation.setObjectDispatcher( + Note, + "/users/{identifier}/posts/{id}", + (ctx, values) => { + const id = ctx.getObjectUri(Note, values); + const post = postStore.get(id); + if (post == null) return null; + return new Note({ + id, + attribution: ctx.getActorUri(values.identifier), + to: PUBLIC_COLLECTION, + cc: ctx.getFollowersUri(values.identifier), + content: post.content, + mediaType: "text/html", + published: post.published, + url: id, + }); + }, +); + +federation + .setFollowersDispatcher( + "/users/{identifier}/followers", + () => { + const followers = Array.from(relationStore.values()); + const items: Recipient[] = followers.map((f) => ({ + id: f.id, + inboxId: f.inboxId, + endpoints: f.endpoints, + })); + return { items }; + }, + ); + +federation.setNodeInfoDispatcher("/nodeinfo/2.1", (ctx) => { + return { + software: { + name: "fedify-nuxt", + version: "0.0.1", + homepage: new URL(ctx.canonicalOrigin), + }, + protocols: ["activitypub"], + usage: { + users: { total: 1, activeHalfyear: 1, activeMonth: 1 }, + localPosts: postStore.getAll().length, + localComments: 0, + }, + }; +}); + +export default federation; diff --git a/examples/nuxt/server/plugins/logging.ts b/examples/nuxt/server/plugins/logging.ts new file mode 100644 index 000000000..97a87a814 --- /dev/null +++ b/examples/nuxt/server/plugins/logging.ts @@ -0,0 +1,25 @@ +import { configure, getConsoleSink } from "@logtape/logtape"; +import { AsyncLocalStorage } from "node:async_hooks"; + +export default defineNitroPlugin(async () => { + await configure({ + contextLocalStorage: new AsyncLocalStorage(), + sinks: { + console: getConsoleSink(), + }, + filters: {}, + loggers: [ + { + category: ["default", "example"], + lowestLevel: "debug", + sinks: ["console"], + }, + { category: "fedify", lowestLevel: "info", sinks: ["console"] }, + { + category: ["logtape", "meta"], + lowestLevel: "warning", + sinks: ["console"], + }, + ], + }); +}); diff --git a/examples/nuxt/server/sse.ts b/examples/nuxt/server/sse.ts new file mode 100644 index 000000000..c1af7c9b4 --- /dev/null +++ b/examples/nuxt/server/sse.ts @@ -0,0 +1,21 @@ +type EventClient = { + send: (data: string) => void; + close: () => void; +}; + +const clients = new Set(); + +export function addClient(client: EventClient): void { + clients.add(client); +} + +export function removeClient(client: EventClient): void { + clients.delete(client); +} + +export function broadcastEvent(): void { + const data = JSON.stringify({ type: "update" }); + for (const client of clients) { + client.send(data); + } +} diff --git a/examples/nuxt/server/store.ts b/examples/nuxt/server/store.ts new file mode 100644 index 000000000..8c987f07a --- /dev/null +++ b/examples/nuxt/server/store.ts @@ -0,0 +1,50 @@ +import { Note, Person } from "@fedify/vocab"; + +declare global { + var keyPairsStore: Map>; + var relationStore: Map; + var postStore: PostStore; + var followingStore: Map; +} + +class PostStore { + #map: Map = new Map(); + #timeline: URL[] = []; + constructor() {} + append(posts: Note[]) { + posts.filter((p) => p.id && !this.#map.has(p.id.toString())) + .forEach((p) => { + this.#map.set(p.id!.toString(), p); + this.#timeline.push(p.id!); + }); + } + get(id: URL) { + return this.#map.get(id.toString()); + } + getAll() { + return this.#timeline.toReversed() + .map((id) => id.toString()) + .map((id) => this.#map.get(id)!) + .filter((p) => p); + } + delete(id: URL) { + const existed = this.#map.delete(id.toString()); + if (existed) { + this.#timeline = this.#timeline.filter((i) => i.href !== id.href); + } + } +} + +const keyPairsStore = globalThis.keyPairsStore ?? new Map(); +const relationStore = globalThis.relationStore ?? new Map(); +const postStore = globalThis.postStore ?? new PostStore(); +const followingStore = globalThis.followingStore ?? new Map(); + +// this is just a hack for the demo +// never do this in production, use safe and secure storage +globalThis.keyPairsStore = keyPairsStore; +globalThis.relationStore = relationStore; +globalThis.postStore = postStore; +globalThis.followingStore = followingStore; + +export { followingStore, keyPairsStore, postStore, relationStore }; diff --git a/examples/nuxt/tsconfig.json b/examples/nuxt/tsconfig.json new file mode 100644 index 000000000..4b34df157 --- /dev/null +++ b/examples/nuxt/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.nuxt/tsconfig.json" +} diff --git a/examples/test-examples/mod.ts b/examples/test-examples/mod.ts index 07d185046..1883d62f7 100644 --- a/examples/test-examples/mod.ts +++ b/examples/test-examples/mod.ts @@ -269,6 +269,19 @@ const SERVER_EXAMPLES: ServerExample[] = [ actor: "demo", readyUrl: "http://localhost:4321/", }, + { + // Nuxt sample using @fedify/nuxt; actor path is /users/{identifier}. + // Built with nuxt build; served with node .output/server/index.mjs + // on port 3000. + name: "nuxt", + dir: "nuxt", + buildCmd: ["pnpm", "build"], + startCmd: ["pnpm", "start"], + port: 3000, + actor: "demo", + readyUrl: "http://localhost:3000/", + readyTimeout: 30_000, + }, ]; const SCRIPT_EXAMPLES: ScriptExample[] = [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2adbabf1..21d2b8ae4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,12 @@ catalogs: '@nestjs/common': specifier: ^11.0.1 version: 11.1.4 + '@nuxt/kit': + specifier: ^4.4.2 + version: 4.4.2 + '@nuxt/schema': + specifier: ^4.4.2 + version: 4.4.2 '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -664,6 +670,40 @@ importers: specifier: 'catalog:' version: 5.9.3 + examples/nuxt: + dependencies: + '@fedify/fedify': + specifier: workspace:^ + version: link:../../packages/fedify + '@fedify/nuxt': + specifier: workspace:^ + version: link:../../packages/nuxt + '@fedify/vocab': + specifier: workspace:^ + version: link:../../packages/vocab + '@logtape/logtape': + specifier: 'catalog:' + version: 2.0.5 + h3: + specifier: 'catalog:' + version: 1.15.3 + nuxt: + specifier: 'catalog:' + version: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@parcel/watcher@2.5.6)(@types/node@22.19.1)(@vue/compiler-sfc@3.5.33)(cac@6.7.14)(db0@0.3.4(mysql2@3.22.2(@types/node@22.19.1)))(ioredis@5.10.1)(lightningcss@1.30.1)(magicast@0.5.2)(mysql2@3.22.2(@types/node@22.19.1))(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-rc.12)(rollup@4.60.2))(rollup@4.60.2)(terser@5.46.1)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))(yaml@2.8.3) + vue: + specifier: ^3.5.13 + version: 3.5.33(typescript@5.9.3) + x-forwarded-fetch: + specifier: ^0.2.0 + version: 0.2.0 + devDependencies: + '@types/node': + specifier: 'catalog:' + version: 22.19.1 + typescript: + specifier: 'catalog:' + version: 5.9.3 + examples/solidstart: dependencies: '@fedify/fedify': @@ -1967,10 +2007,6 @@ packages: resolution: {integrity: sha512-AmwWFx1m8G/a5cXkxLxTiWl+YEoWuoFLUCwqMlNuWO1tqAYITQAbCRPUkyBHv1VOFgfjVOqEj6L3u15J5ZCzTA==} engines: {node: ^20.19.0 || >=22.12.0} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} @@ -1987,11 +2023,6 @@ packages: resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.27.7': - resolution: {integrity: sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.29.2': resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} @@ -2028,10 +2059,6 @@ packages: resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.27.7': - resolution: {integrity: sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -2282,21 +2309,12 @@ packages: '@dxup/unimport@0.1.2': resolution: {integrity: sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==} - '@emnapi/core@1.4.3': - resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/core@1.9.1': resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} - '@emnapi/runtime@1.4.5': - resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} - '@emnapi/runtime@1.9.1': resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} - '@emnapi/wasi-threads@1.0.2': - resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} - '@emnapi/wasi-threads@1.2.0': resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} @@ -3717,9 +3735,6 @@ packages: resolution: {integrity: sha512-P0zUpK6n2XIAn8bt0F6rhSn1+FgteBTrL+TBb6Oqw8v5qEDJoNYkd6LlfZYN8YwtRBTBdZ8GFnWsg2Sar+qOkA==} engines: {node: '>=18'} - '@jridgewell/gen-mapping@0.3.11': - resolution: {integrity: sha512-C512c1ytBTio4MrpWKlJpyFHT6+qfFL8SZ58zBzJ1OOzUEjHeF1BtjY2fH7n4x/g2OV/KiiMLAivOp1DXmiMMw==} - '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -5541,9 +5556,6 @@ packages: peerDependencies: vinxi: ^0.5.7 - '@speed-highlight/core@1.2.12': - resolution: {integrity: sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA==} - '@speed-highlight/core@1.2.15': resolution: {integrity: sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==} @@ -7098,9 +7110,6 @@ packages: birpc@0.2.14: resolution: {integrity: sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA==} - birpc@2.4.0: - resolution: {integrity: sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==} - birpc@2.9.0: resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} @@ -7436,9 +7445,6 @@ packages: confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - confbox@0.2.2: - resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} - confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} @@ -7457,9 +7463,6 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-es@1.2.2: - resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - cookie-es@1.2.3: resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} @@ -8397,9 +8400,6 @@ packages: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} - exsolve@1.0.7: - resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} - exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} @@ -8694,6 +8694,7 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@13.0.6: @@ -8702,7 +8703,7 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} @@ -9246,10 +9247,6 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.5.1: - resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -9493,10 +9490,6 @@ packages: resolution: {integrity: sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==} engines: {node: '>=13.2.0'} - local-pkg@1.1.1: - resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} - engines: {node: '>=14'} - local-pkg@1.1.2: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} @@ -9871,10 +9864,6 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -9894,9 +9883,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} - mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} @@ -10069,9 +10055,6 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-mock-http@1.0.1: - resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==} - node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} @@ -10441,9 +10424,6 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pkg-types@2.2.0: - resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} - pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} @@ -10887,9 +10867,6 @@ packages: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} - quansync@0.2.10: - resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} - quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -11762,6 +11739,7 @@ packages: tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} @@ -11812,9 +11790,6 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.0.1: - resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinyexec@1.0.4: resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} engines: {node: '>=18'} @@ -12068,9 +12043,6 @@ packages: uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -13121,13 +13093,13 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.11 - '@jridgewell/trace-mapping': 0.3.28 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@antfu/install-pkg@1.1.0': dependencies: package-manager-detector: 1.3.0 - tinyexec: 1.0.1 + tinyexec: 1.0.4 '@antfu/utils@8.1.1': {} @@ -13229,7 +13201,7 @@ snapshots: '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.28 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/generator@8.0.0-rc.3': @@ -13237,7 +13209,7 @@ snapshots: '@babel/parser': 8.0.0-rc.3 '@babel/types': 8.0.0-rc.3 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.28 + '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 jsesc: 3.1.0 @@ -13321,8 +13293,6 @@ snapshots: '@babel/helper-string-parser@8.0.0-rc.3': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-identifier@8.0.0-rc.3': {} @@ -13334,10 +13304,6 @@ snapshots: '@babel/template': 7.28.6 '@babel/types': 7.29.0 - '@babel/parser@7.27.7': - dependencies: - '@babel/types': 7.27.7 - '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -13385,11 +13351,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.27.7': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -13604,33 +13565,17 @@ snapshots: '@dxup/unimport@0.1.2': {} - '@emnapi/core@1.4.3': - dependencies: - '@emnapi/wasi-threads': 1.0.2 - tslib: 2.8.1 - optional: true - '@emnapi/core@1.9.1': dependencies: '@emnapi/wasi-threads': 1.2.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.4.5': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.9.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.2': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.2.0': dependencies: tslib: 2.8.1 @@ -14115,8 +14060,8 @@ snapshots: debug: 4.4.1 globals: 15.15.0 kolorist: 1.8.0 - local-pkg: 1.1.1 - mlly: 1.7.4 + local-pkg: 1.1.2 + mlly: 1.8.2 transitivePeerDependencies: - supports-color @@ -14341,12 +14286,12 @@ snapshots: '@img/sharp-wasm32@0.33.5': dependencies: - '@emnapi/runtime': 1.4.5 + '@emnapi/runtime': 1.9.1 optional: true '@img/sharp-wasm32@0.34.3': dependencies: - '@emnapi/runtime': 1.4.5 + '@emnapi/runtime': 1.9.1 optional: true '@img/sharp-wasm32@0.34.5': @@ -14544,7 +14489,7 @@ snapshots: '@isaacs/fs-minipass@4.0.1': dependencies: - minipass: 7.1.2 + minipass: 7.1.3 '@jimp/bmp@0.22.12(@jimp/custom@0.22.12)': dependencies: @@ -14769,27 +14714,22 @@ snapshots: '@jsquash/webp': 1.5.0 zod: 3.25.76 - '@jridgewell/gen-mapping@0.3.11': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.3 - '@jridgewell/trace-mapping': 0.3.28 - '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/sourcemap-codec': 1.5.3 - '@jridgewell/trace-mapping': 0.3.28 + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: - '@jridgewell/gen-mapping': 0.3.11 - '@jridgewell/trace-mapping': 0.3.28 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/source-map@0.3.11': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.28 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/sourcemap-codec@1.5.3': {} @@ -14798,7 +14738,7 @@ snapshots: '@jridgewell/trace-mapping@0.3.28': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.3 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.31': dependencies: @@ -14808,7 +14748,7 @@ snapshots: '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.3 + '@jridgewell/sourcemap-codec': 1.5.5 '@js-sdsl/ordered-map@4.4.2': {} @@ -14884,8 +14824,8 @@ snapshots: '@napi-rs/wasm-runtime@0.2.11': dependencies: - '@emnapi/core': 1.4.3 - '@emnapi/runtime': 1.4.5 + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 '@tybys/wasm-util': 0.9.0 optional: true @@ -15111,7 +15051,7 @@ snapshots: simple-git: 3.36.0 sirv: 3.0.2 structured-clone-es: 2.0.0 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 vite: 7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) vite-plugin-inspect: 11.3.3(@nuxt/kit@4.4.2(magicast@0.5.2))(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)) vite-plugin-vue-tracer: 1.3.0(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))(vue@3.5.33(typescript@5.9.3)) @@ -15141,7 +15081,7 @@ snapshots: rc9: 3.0.1 scule: 1.3.0 semver: 7.7.4 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 ufo: 1.6.3 unctx: 2.5.0 untyped: 2.0.0 @@ -15524,7 +15464,7 @@ snapshots: '@opentelemetry/instrumentation': 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 forwarded-parse: 2.1.2 - semver: 7.7.2 + semver: 7.7.4 transitivePeerDependencies: - supports-color @@ -15666,7 +15606,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.14.2 require-in-the-middle: 7.5.2 - semver: 7.7.2 + semver: 7.7.4 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -15678,7 +15618,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.14.2 require-in-the-middle: 7.5.2 - semver: 7.7.2 + semver: 7.7.4 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -15690,7 +15630,7 @@ snapshots: '@types/shimmer': 1.2.0 import-in-the-middle: 1.14.2 require-in-the-middle: 7.5.2 - semver: 7.7.2 + semver: 7.7.4 shimmer: 1.2.1 transitivePeerDependencies: - supports-color @@ -16643,8 +16583,6 @@ snapshots: - supports-color - vite - '@speed-highlight/core@1.2.12': {} - '@speed-highlight/core@1.2.15': {} '@standard-schema/spec@1.0.0': {} @@ -16704,7 +16642,7 @@ snapshots: '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.3)(vite@7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)))(svelte@5.38.3)(vite@7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))': dependencies: '@sveltejs/vite-plugin-svelte': 6.1.3(svelte@5.38.3)(vite@7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)) - debug: 4.4.1 + debug: 4.4.3 svelte: 5.38.3 vite: 7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) transitivePeerDependencies: @@ -16713,7 +16651,7 @@ snapshots: '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.3)(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)))(svelte@5.38.3)(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))': dependencies: '@sveltejs/vite-plugin-svelte': 6.1.3(svelte@5.38.3)(vite@7.3.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)) - debug: 4.4.1 + debug: 4.4.3 svelte: 5.38.3 vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) transitivePeerDependencies: @@ -16760,9 +16698,9 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 enhanced-resolve: 5.18.2 - jiti: 2.5.1 + jiti: 2.6.1 lightningcss: 1.30.1 - magic-string: 0.30.17 + magic-string: 0.30.21 source-map-js: 1.2.1 tailwindcss: 4.1.11 @@ -16770,9 +16708,9 @@ snapshots: dependencies: '@jridgewell/remapping': 2.3.5 enhanced-resolve: 5.18.3 - jiti: 2.5.1 + jiti: 2.6.1 lightningcss: 1.30.1 - magic-string: 0.30.17 + magic-string: 0.30.21 source-map-js: 1.2.1 tailwindcss: 4.1.12 @@ -16922,7 +16860,7 @@ snapshots: babel-dead-code-elimination: 1.0.12 diff: 8.0.4 pathe: 2.0.3 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 transitivePeerDependencies: - supports-color @@ -16946,7 +16884,7 @@ snapshots: '@tokenizer/inflate@0.2.7': dependencies: - debug: 4.4.1 + debug: 4.4.3 fflate: 0.8.2 token-types: 6.0.3 transitivePeerDependencies: @@ -17422,7 +17360,7 @@ snapshots: '@typescript-eslint/types': 8.41.0 '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 + debug: 4.4.3 eslint: 9.32.0(jiti@2.6.1) typescript: 5.9.2 transitivePeerDependencies: @@ -17456,7 +17394,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.3) '@typescript-eslint/types': 8.41.0 - debug: 4.4.1 + debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -17465,7 +17403,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.2) '@typescript-eslint/types': 8.41.0 - debug: 4.4.1 + debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -17474,7 +17412,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.3) '@typescript-eslint/types': 8.41.0 - debug: 4.4.1 + debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -17483,7 +17421,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) '@typescript-eslint/types': 8.50.0 - debug: 4.4.1 + debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -17546,7 +17484,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.3) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.1 + debug: 4.4.3 eslint: 8.57.1 ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: @@ -17559,7 +17497,7 @@ snapshots: '@typescript-eslint/types': 8.38.0 '@typescript-eslint/typescript-estree': 8.38.0(typescript@5.9.3) '@typescript-eslint/utils': 8.38.0(eslint@9.32.0(jiti@2.6.1))(typescript@5.9.3) - debug: 4.4.1 + debug: 4.4.3 eslint: 9.32.0(jiti@2.6.1) ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 @@ -17571,7 +17509,7 @@ snapshots: '@typescript-eslint/types': 8.41.0 '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) '@typescript-eslint/utils': 8.41.0(eslint@9.32.0(jiti@2.6.1))(typescript@5.9.2) - debug: 4.4.1 + debug: 4.4.3 eslint: 9.32.0(jiti@2.6.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 @@ -17604,11 +17542,11 @@ snapshots: dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.1 + debug: 4.4.3 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.4 ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 @@ -17621,11 +17559,11 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.38.0(typescript@5.9.3) '@typescript-eslint/types': 8.38.0 '@typescript-eslint/visitor-keys': 8.38.0 - debug: 4.4.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.4 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -17637,11 +17575,11 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.2) '@typescript-eslint/types': 8.41.0 '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.4 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -17653,11 +17591,11 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.3) '@typescript-eslint/types': 8.41.0 '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.4 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -17669,10 +17607,10 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) '@typescript-eslint/types': 8.50.0 '@typescript-eslint/visitor-keys': 8.50.0 - debug: 4.4.1 + debug: 4.4.3 minimatch: 9.0.5 - semver: 7.7.2 - tinyglobby: 0.2.15 + semver: 7.7.4 + tinyglobby: 0.2.16 ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -17687,7 +17625,7 @@ snapshots: debug: 4.4.3 minimatch: 10.2.5 semver: 7.7.4 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 ts-api-utils: 2.5.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -17775,7 +17713,7 @@ snapshots: '@typescript/vfs@1.6.1(typescript@5.9.3)': dependencies: - debug: 4.4.1 + debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -17851,8 +17789,8 @@ snapshots: dependencies: '@mapbox/node-pre-gyp': 2.0.3 '@rollup/pluginutils': 5.3.0(rollup@4.60.2) - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 @@ -17878,7 +17816,7 @@ snapshots: h3: 1.15.11 http-shutdown: 1.2.2 jiti: 1.21.7 - mlly: 1.7.4 + mlly: 1.8.2 node-forge: 1.4.0 pathe: 1.1.2 std-env: 3.10.0 @@ -17889,10 +17827,10 @@ snapshots: '@vinxi/plugin-directives@0.5.1(vinxi@0.5.11(@types/node@24.3.0)(db0@0.3.4(mysql2@3.22.2(@types/node@24.3.0)))(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.30.1)(mysql2@3.22.2(@types/node@24.3.0))(rolldown@1.0.0-rc.12)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))': dependencies: '@babel/parser': 7.29.2 - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) acorn-loose: 8.5.2 - acorn-typescript: 1.4.13(acorn@8.15.0) + acorn-typescript: 1.4.13(acorn@8.16.0) astring: 1.9.0 magicast: 0.2.11 recast: 0.23.11 @@ -17902,9 +17840,9 @@ snapshots: '@vinxi/server-components@0.5.1(vinxi@0.5.11(@types/node@24.3.0)(db0@0.3.4(mysql2@3.22.2(@types/node@24.3.0)))(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.30.1)(mysql2@3.22.2(@types/node@24.3.0))(rolldown@1.0.0-rc.12)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))': dependencies: '@vinxi/plugin-directives': 0.5.1(vinxi@0.5.11(@types/node@24.3.0)(db0@0.3.4(mysql2@3.22.2(@types/node@24.3.0)))(ioredis@5.10.1)(jiti@2.6.1)(lightningcss@1.30.1)(mysql2@3.22.2(@types/node@24.3.0))(rolldown@1.0.0-rc.12)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)) - acorn: 8.15.0 + acorn: 8.16.0 acorn-loose: 8.5.2 - acorn-typescript: 1.4.13(acorn@8.15.0) + acorn-typescript: 1.4.13(acorn@8.16.0) astring: 1.9.0 magicast: 0.2.11 recast: 0.23.11 @@ -17915,7 +17853,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) - '@rolldown/pluginutils': 1.0.0-rc.12 + '@rolldown/pluginutils': 1.0.0-rc.13 '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0) vite: 7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) vue: 3.5.33(typescript@5.9.3) @@ -17945,7 +17883,7 @@ snapshots: dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.21 optionalDependencies: vite: 7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) @@ -17962,7 +17900,7 @@ snapshots: '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 + magic-string: 0.30.21 pathe: 2.0.3 '@vitest/spy@3.2.4': @@ -18022,7 +17960,7 @@ snapshots: '@vue/compiler-core@3.5.17': dependencies: - '@babel/parser': 7.27.7 + '@babel/parser': 7.29.2 '@vue/shared': 3.5.17 entities: 4.5.0 estree-walker: 2.0.2 @@ -18048,14 +17986,14 @@ snapshots: '@vue/compiler-sfc@3.5.17': dependencies: - '@babel/parser': 7.27.7 + '@babel/parser': 7.29.2 '@vue/compiler-core': 3.5.17 '@vue/compiler-dom': 3.5.17 '@vue/compiler-ssr': 3.5.17 '@vue/shared': 3.5.17 estree-walker: 2.0.2 - magic-string: 0.30.17 - postcss: 8.5.6 + magic-string: 0.30.21 + postcss: 8.5.10 source-map-js: 1.2.1 '@vue/compiler-sfc@3.5.33': @@ -18102,7 +18040,7 @@ snapshots: '@vue/devtools-kit@7.7.7': dependencies: '@vue/devtools-shared': 7.7.7 - birpc: 2.4.0 + birpc: 2.9.0 hookable: 5.5.3 mitt: 3.0.1 perfect-debounce: 1.0.0 @@ -18125,9 +18063,9 @@ snapshots: '@vue/language-core@2.1.10(typescript@5.9.3)': dependencies: '@volar/language-core': 2.4.15 - '@vue/compiler-dom': 3.5.17 + '@vue/compiler-dom': 3.5.33 '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.17 + '@vue/shared': 3.5.33 alien-signals: 0.2.2 minimatch: 9.0.5 muggle-string: 0.4.1 @@ -18158,7 +18096,7 @@ snapshots: '@vue/reactivity': 3.5.17 '@vue/runtime-core': 3.5.17 '@vue/shared': 3.5.17 - csstype: 3.1.3 + csstype: 3.2.3 '@vue/runtime-dom@3.5.33': dependencies: @@ -18188,7 +18126,7 @@ snapshots: '@types/web-bluetooth': 0.0.21 '@vueuse/metadata': 12.8.2 '@vueuse/shared': 12.8.2(typescript@5.9.3) - vue: 3.5.17(typescript@5.9.3) + vue: 3.5.33(typescript@5.9.3) transitivePeerDependencies: - typescript @@ -18196,7 +18134,7 @@ snapshots: dependencies: '@vueuse/core': 12.8.2(typescript@5.9.3) '@vueuse/shared': 12.8.2(typescript@5.9.3) - vue: 3.5.17(typescript@5.9.3) + vue: 3.5.33(typescript@5.9.3) optionalDependencies: focus-trap: 7.6.5 fuse.js: 7.3.0 @@ -18207,7 +18145,7 @@ snapshots: '@vueuse/shared@12.8.2(typescript@5.9.3)': dependencies: - vue: 3.5.17(typescript@5.9.3) + vue: 3.5.33(typescript@5.9.3) transitivePeerDependencies: - typescript @@ -18224,21 +18162,21 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-attributes@1.9.5(acorn@8.15.0): + acorn-import-attributes@1.9.5(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.15.0): + acorn-jsx@5.3.2(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 acorn-loose@8.5.2: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-typescript@1.4.13(acorn@8.15.0): + acorn-typescript@1.4.13(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 acorn-walk@8.3.2: {} @@ -18686,8 +18624,6 @@ snapshots: birpc@0.2.14: {} - birpc@2.4.0: {} - birpc@2.9.0: {} birpc@4.0.0: {} @@ -19036,8 +18972,6 @@ snapshots: confbox@0.1.8: {} - confbox@0.2.2: {} - confbox@0.2.4: {} consola@3.4.2: {} @@ -19050,8 +18984,6 @@ snapshots: convert-source-map@2.0.0: {} - cookie-es@1.2.2: {} - cookie-es@1.2.3: {} cookie-es@2.0.1: {} @@ -19942,7 +19874,7 @@ snapshots: get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.0(eslint@9.32.0(jiti@2.6.1))(typescript@5.9.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.0(eslint@9.32.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.32.0(jiti@2.6.1)))(eslint@9.32.0(jiti@2.6.1)))(eslint@9.32.0(jiti@2.6.1)) @@ -19957,7 +19889,7 @@ snapshots: get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.1) @@ -19972,7 +19904,7 @@ snapshots: get-tsconfig: 4.10.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 unrs-resolver: 1.11.1 optionalDependencies: eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.38.0(eslint@9.32.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.32.0(jiti@2.6.1)) @@ -20148,7 +20080,7 @@ snapshots: eslint-plugin-react-hooks@7.1.1(eslint@9.32.0(jiti@2.6.1)): dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.27.7 + '@babel/parser': 7.29.2 eslint: 9.32.0(jiti@2.6.1) hermes-parser: 0.25.1 zod: 3.25.76 @@ -20323,14 +20255,14 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 espree@9.6.1: dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 3.4.3 esprima@4.0.1: {} @@ -20341,7 +20273,7 @@ snapshots: esrap@2.1.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.3 + '@jridgewell/sourcemap-codec': 1.5.5 esrecurse@4.3.0: dependencies: @@ -20431,8 +20363,6 @@ snapshots: transitivePeerDependencies: - supports-color - exsolve@1.0.7: {} - exsolve@1.0.8: {} extend-shallow@2.0.1: @@ -20760,7 +20690,7 @@ snapshots: foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 9.0.5 - minipass: 7.1.2 + minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 @@ -20849,14 +20779,14 @@ snapshots: h3@1.15.3: dependencies: - cookie-es: 1.2.2 + cookie-es: 1.2.3 crossws: 0.3.5 - defu: 6.1.4 + defu: 6.1.7 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.1 + node-mock-http: 1.0.4 radix3: 1.1.2 - ufo: 1.6.1 + ufo: 1.6.3 uncrypto: 0.1.3 hachure-fill@0.5.2: {} @@ -21092,15 +21022,15 @@ snapshots: import-in-the-middle@1.14.2: dependencies: - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) cjs-module-lexer: 1.4.3 module-details-from-path: 1.0.4 import-in-the-middle@2.0.1: dependencies: - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) cjs-module-lexer: 1.4.3 module-details-from-path: 1.0.4 @@ -21218,7 +21148,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.2 + semver: 7.7.4 is-callable@1.2.7: {} @@ -21427,8 +21357,6 @@ snapshots: jiti@1.21.7: {} - jiti@2.5.1: {} - jiti@2.6.1: {} jpeg-js@0.4.4: {} @@ -21644,7 +21572,7 @@ snapshots: lightningcss@1.30.1: dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.2 optionalDependencies: lightningcss-darwin-arm64: 1.30.1 lightningcss-darwin-x64: 1.30.1 @@ -21690,12 +21618,6 @@ snapshots: load-esm@1.0.2: {} - local-pkg@1.1.1: - dependencies: - mlly: 1.7.4 - pkg-types: 2.2.0 - quansync: 0.2.10 - local-pkg@1.1.2: dependencies: mlly: 1.8.2 @@ -21769,7 +21691,7 @@ snapshots: magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.3 + '@jridgewell/sourcemap-codec': 1.5.5 magic-string@0.30.21: dependencies: @@ -22174,7 +22096,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.3 decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -22286,27 +22208,18 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} - minipass@7.1.3: {} minisearch@7.1.2: {} minizlib@3.0.2: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 mitt@3.0.1: {} mkdirp@3.0.1: {} - mlly@1.7.4: - dependencies: - acorn: 8.15.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.1 - mlly@1.8.2: dependencies: acorn: 8.16.0 @@ -22680,8 +22593,6 @@ snapshots: node-gyp-build@4.8.4: {} - node-mock-http@1.0.1: {} - node-mock-http@1.0.4: {} node-releases@2.0.38: {} @@ -22755,7 +22666,7 @@ snapshots: scule: 1.3.0 semver: 7.7.4 std-env: 4.1.0 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 ufo: 1.6.3 ultrahtml: 1.6.0 uncrypto: 0.1.3 @@ -23146,7 +23057,7 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 path-scurry@2.0.2: dependencies: @@ -23232,18 +23143,12 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.7.4 - pathe: 2.0.3 - - pkg-types@2.2.0: - dependencies: - confbox: 0.2.2 - exsolve: 1.0.7 + mlly: 1.8.2 pathe: 2.0.3 pkg-types@2.3.0: dependencies: - confbox: 0.2.2 + confbox: 0.2.4 exsolve: 1.0.8 pathe: 2.0.3 @@ -23274,7 +23179,7 @@ snapshots: postcss-calc@10.1.1(postcss@8.5.10): dependencies: postcss: 8.5.10 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.1 postcss-value-parser: 4.2.0 postcss-colormin@7.0.9(postcss@8.5.10): @@ -23330,7 +23235,7 @@ snapshots: postcss-load-config@4.0.2(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.1 + yaml: 2.8.3 optionalDependencies: postcss: 8.5.6 @@ -23446,9 +23351,9 @@ snapshots: dependencies: postcss: 8.5.6 - postcss-scss@4.0.9(postcss@8.5.6): + postcss-scss@4.0.9(postcss@8.5.10): dependencies: - postcss: 8.5.6 + postcss: 8.5.10 postcss-selector-parser@6.1.2: dependencies: @@ -23605,8 +23510,6 @@ snapshots: dependencies: side-channel: 1.1.0 - quansync@0.2.10: {} - quansync@0.2.11: {} quansync@1.0.0: {} @@ -23855,7 +23758,7 @@ snapshots: require-in-the-middle@7.5.2: dependencies: - debug: 4.4.1 + debug: 4.4.3 module-details-from-path: 1.0.4 resolve: 1.22.10 transitivePeerDependencies: @@ -23863,7 +23766,7 @@ snapshots: require-in-the-middle@8.0.1: dependencies: - debug: 4.4.1 + debug: 4.4.3 module-details-from-path: 1.0.4 transitivePeerDependencies: - supports-color @@ -24218,7 +24121,7 @@ snapshots: dependencies: color: 4.2.3 detect-libc: 2.0.4 - semver: 7.7.2 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.33.5 '@img/sharp-darwin-x64': 0.33.5 @@ -24244,7 +24147,7 @@ snapshots: dependencies: color: 4.2.3 detect-libc: 2.0.4 - semver: 7.7.2 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.3 '@img/sharp-darwin-x64': 0.34.3 @@ -24652,7 +24555,7 @@ snapshots: sucrase@3.35.0: dependencies: - '@jridgewell/gen-mapping': 0.3.11 + '@jridgewell/gen-mapping': 0.3.13 commander: 4.1.1 glob: 10.4.5 lines-and-columns: 1.2.4 @@ -24689,8 +24592,8 @@ snapshots: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - postcss: 8.5.6 - postcss-scss: 4.0.9(postcss@8.5.6) + postcss: 8.5.10 + postcss-scss: 4.0.9(postcss@8.5.10) postcss-selector-parser: 7.1.0 optionalDependencies: svelte: 5.38.3 @@ -24776,7 +24679,7 @@ snapshots: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 - minipass: 7.1.2 + minipass: 7.1.3 minizlib: 3.0.2 mkdirp: 3.0.1 yallist: 5.0.0 @@ -24796,7 +24699,7 @@ snapshots: terser@5.46.1: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -24832,14 +24735,12 @@ snapshots: tinyexec@0.3.2: {} - tinyexec@1.0.1: {} - tinyexec@1.0.4: {} tinyglobby@0.2.14: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 tinyglobby@0.2.15: dependencies: @@ -25079,8 +24980,6 @@ snapshots: uc.micro@2.1.0: {} - ufo@1.6.1: {} - ufo@1.6.3: {} uid@2.0.2: @@ -25107,7 +25006,7 @@ snapshots: unctx@2.5.0: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 estree-walker: 3.0.3 magic-string: 0.30.21 unplugin: 2.3.11 @@ -25136,16 +25035,16 @@ snapshots: unenv@2.0.0-rc.17: dependencies: - defu: 6.1.4 - exsolve: 1.0.7 + defu: 6.1.7 + exsolve: 1.0.8 ohash: 2.0.11 pathe: 2.0.3 - ufo: 1.6.1 + ufo: 1.6.3 unenv@2.0.0-rc.21: dependencies: defu: 6.1.7 - exsolve: 1.0.7 + exsolve: 1.0.8 ohash: 2.0.11 pathe: 2.0.3 ufo: 1.6.3 @@ -25258,7 +25157,7 @@ snapshots: unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 - acorn: 8.15.0 + acorn: 8.16.0 picomatch: 4.0.4 webpack-virtual-modules: 0.6.2 @@ -25490,7 +25389,7 @@ snapshots: vite-dev-rpc@1.1.0(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)): dependencies: - birpc: 2.4.0 + birpc: 2.9.0 vite: 7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) vite-hot-client: 2.1.0(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3)) @@ -25504,7 +25403,7 @@ snapshots: debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.3(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) + vite: 7.3.2(@types/node@24.3.0)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) transitivePeerDependencies: - '@types/node' - jiti @@ -25547,7 +25446,7 @@ snapshots: picocolors: 1.1.1 picomatch: 4.0.4 tiny-invariant: 1.3.3 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 vite: 7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3) vscode-uri: 3.1.0 optionalDependencies: @@ -25597,7 +25496,7 @@ snapshots: vite@5.4.19(@types/node@22.19.1)(lightningcss@1.30.1)(terser@5.46.1): dependencies: esbuild: 0.21.5 - postcss: 8.5.6 + postcss: 8.5.10 rollup: 4.44.1 optionalDependencies: '@types/node': 22.19.1 @@ -25610,9 +25509,9 @@ snapshots: esbuild: 0.25.5 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.6 + postcss: 8.5.10 rollup: 4.44.1 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 optionalDependencies: '@types/node': 24.3.0 fsevents: 2.3.3 @@ -25645,8 +25544,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.10 - rollup: 4.44.1 - tinyglobby: 0.2.15 + rollup: 4.60.2 + tinyglobby: 0.2.16 optionalDependencies: '@types/node': 22.19.1 fsevents: 2.3.3 @@ -25662,8 +25561,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.10 - rollup: 4.44.1 - tinyglobby: 0.2.15 + rollup: 4.60.2 + tinyglobby: 0.2.16 optionalDependencies: '@types/node': 24.3.0 fsevents: 2.3.3 @@ -25856,7 +25755,7 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.4 scule: 1.3.0 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 unplugin: 3.0.0 unplugin-utils: 0.3.1 vue: 3.5.33(typescript@5.9.3) @@ -26147,7 +26046,7 @@ snapshots: dependencies: '@poppinss/colors': 4.1.6 '@poppinss/dumper': 0.6.5 - '@speed-highlight/core': 1.2.12 + '@speed-highlight/core': 1.2.15 cookie: 1.0.2 youch-core: 0.3.3 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index da386e5f5..a1ec58f4e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -37,6 +37,7 @@ packages: - examples/express - examples/koa - examples/next-integration +- examples/nuxt - examples/fastify - examples/next14-app-router - examples/next15-app-router From a45344f9ed0f8cd44321da864ba814cc09130018 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Wed, 15 Apr 2026 08:00:50 +0000 Subject: [PATCH 02/26] Replace `~~/server` to `#server` --- examples/nuxt/nuxt.config.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/nuxt/nuxt.config.ts b/examples/nuxt/nuxt.config.ts index d3f3a3fa0..b6642ac66 100644 --- a/examples/nuxt/nuxt.config.ts +++ b/examples/nuxt/nuxt.config.ts @@ -1,8 +1,6 @@ export default defineNuxtConfig({ modules: ["@fedify/nuxt"], - fedify: { - federationModule: "~/server/federation", - }, + fedify: { federationModule: "#server/federation" }, ssr: true, devServer: { host: "0.0.0.0" }, vite: { server: { allowedHosts: true } }, From 783e20cc6e9b64b6f7b1578a37135abe583c0cd3 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 18 Apr 2026 22:13:05 +0000 Subject: [PATCH 03/26] Format files --- .../example/public/style.css | 5 +- .../example/public/theme.js | 2 +- examples/nuxt/public/fedify-logo.svg | 394 ++++++++++-------- examples/nuxt/public/theme.js | 2 +- 4 files changed, 221 insertions(+), 182 deletions(-) diff --git a/.agents/skills/create-example-app-with-integration/example/public/style.css b/.agents/skills/create-example-app-with-integration/example/public/style.css index 3d8b3e6e5..6cd70d7b7 100644 --- a/.agents/skills/create-example-app-with-integration/example/public/style.css +++ b/.agents/skills/create-example-app-with-integration/example/public/style.css @@ -20,8 +20,9 @@ body { background: var(--background); color: var(--foreground); font-size: 16px; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, - Oxygen, Ubuntu, Cantarell, sans-serif; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, + Cantarell, sans-serif; } a { diff --git a/.agents/skills/create-example-app-with-integration/example/public/theme.js b/.agents/skills/create-example-app-with-integration/example/public/theme.js index 8d521d625..3da2aaacf 100644 --- a/.agents/skills/create-example-app-with-integration/example/public/theme.js +++ b/.agents/skills/create-example-app-with-integration/example/public/theme.js @@ -1,5 +1,5 @@ "use strict"; -var mq = window.matchMedia("(prefers-color-scheme: dark)"); +const mq = globalThis.window.matchMedia("(prefers-color-scheme: dark)"); document.body.classList.add(mq.matches ? "dark" : "light"); mq.addEventListener("change", function (e) { document.body.classList.remove("light", "dark"); diff --git a/examples/nuxt/public/fedify-logo.svg b/examples/nuxt/public/fedify-logo.svg index 812c62a32..e9d2e54ea 100644 --- a/examples/nuxt/public/fedify-logo.svg +++ b/examples/nuxt/public/fedify-logo.svg @@ -1,180 +1,218 @@ FedifyFedify + width="48" + height="48" + viewBox="0 0 112 112" + version="1.1" + id="svg5" + sodipodi:docname="fedify-logo.svg" + xml:space="preserve" + inkscape:version="1.4.3 (0d15f75, 2025-12-25)" + inkscape:export-filename="demo-profile.png" + inkscape:export-xdpi="1024" + inkscape:export-ydpi="1024" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/" +> + FedifyFedify + diff --git a/examples/nuxt/public/theme.js b/examples/nuxt/public/theme.js index 8d521d625..3da2aaacf 100644 --- a/examples/nuxt/public/theme.js +++ b/examples/nuxt/public/theme.js @@ -1,5 +1,5 @@ "use strict"; -var mq = window.matchMedia("(prefers-color-scheme: dark)"); +const mq = globalThis.window.matchMedia("(prefers-color-scheme: dark)"); document.body.classList.add(mq.matches ? "dark" : "light"); mq.addEventListener("change", function (e) { document.body.classList.remove("light", "dark"); From 9e4a89bfc67fc0f41affbb768b12caa1cdc8e139 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 18 Apr 2026 22:13:29 +0000 Subject: [PATCH 04/26] Apply necessary reviews --- examples/nuxt/server/api/events.get.ts | 2 +- examples/nuxt/server/api/post.post.ts | 13 +++++++++---- examples/nuxt/server/federation.ts | 21 +++++++++------------ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/examples/nuxt/server/api/events.get.ts b/examples/nuxt/server/api/events.get.ts index e2f710e0d..8fad50104 100644 --- a/examples/nuxt/server/api/events.get.ts +++ b/examples/nuxt/server/api/events.get.ts @@ -1,7 +1,7 @@ import { setResponseHeader } from "h3"; import { addClient, removeClient } from "../sse"; -export default defineEventHandler(async (event) => { +export default defineEventHandler((event) => { setResponseHeader(event, "Content-Type", "text/event-stream"); setResponseHeader(event, "Cache-Control", "no-cache"); setResponseHeader(event, "Connection", "keep-alive"); diff --git a/examples/nuxt/server/api/post.post.ts b/examples/nuxt/server/api/post.post.ts index 03245ac3d..6a13a9df8 100644 --- a/examples/nuxt/server/api/post.post.ts +++ b/examples/nuxt/server/api/post.post.ts @@ -1,7 +1,12 @@ import { Create, Note } from "@fedify/vocab"; -import { readBody, sendRedirect, toWebRequest } from "h3"; -import federation from "../federation"; -import { postStore } from "../store"; +import { + defineEventHandler, + readBody, + sendRedirect, + toWebRequest, +} from "@nuxt/nitro-server/h3"; +import federation from "../federation.ts"; +import { postStore } from "../store.ts"; export default defineEventHandler(async (event) => { const body = await readBody(event); @@ -29,7 +34,7 @@ export default defineEventHandler(async (event) => { { identifier }, "followers", new Create({ - id: new URL("#activity", attribution), + id: new URL(`#create/${id}`, attribution), object: note, actors: note?.attributionIds, tos: note?.toIds, diff --git a/examples/nuxt/server/federation.ts b/examples/nuxt/server/federation.ts index de471c749..64c671019 100644 --- a/examples/nuxt/server/federation.ts +++ b/examples/nuxt/server/federation.ts @@ -15,8 +15,8 @@ import { type Recipient, Undo, } from "@fedify/vocab"; -import { broadcastEvent } from "./sse"; -import { keyPairsStore, postStore, relationStore } from "./store"; +import { broadcastEvent } from "./sse.ts"; +import { keyPairsStore, postStore, relationStore } from "./store.ts"; const federation = createFederation({ kv: new MemoryKvStore(), @@ -96,18 +96,15 @@ federation }) .on(Undo, async (context, undo) => { const activity = await undo.getObject(context); - if (activity instanceof Follow) { - if (activity.id == null) { - return; - } - if (undo.actorId == null) { - return; - } - relationStore.delete(undo.actorId.href); - broadcastEvent(); - } else { + if (!(activity instanceof Follow)) { console.debug(undo); + return; } + if (activity.id == null || undo.actorId == null) return; + const demoActorUri = context.getActorUri(IDENTIFIER); + if (activity.objectId?.href !== demoActorUri.href) return; + relationStore.delete(undo.actorId.href); + broadcastEvent(); }); federation.setObjectDispatcher( From 190a7b01111f1fd163464c71406e686c0714bebd Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sun, 19 Apr 2026 06:52:47 +0000 Subject: [PATCH 05/26] Move `@nuxt/kit` to peerDependencies for efficiency in `@fedify/nuxt` This makes mod.d.ts from 50k+ lines to only 32 lines --- packages/nuxt/package.json | 4 ++-- pnpm-lock.yaml | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index b8eb1d0e5..6190d4103 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -50,8 +50,8 @@ ], "peerDependencies": { "@fedify/fedify": "workspace:^", - "@nuxt/kit": "catalog:", - "@nuxt/schema": "catalog:", + "@nuxt/kit": "^4.4.2", + "@nuxt/schema": "^4.4.2", "h3": "catalog:", "nuxt": "catalog:" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21d2b8ae4..d13cf517b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,12 +27,6 @@ catalogs: '@nestjs/common': specifier: ^11.0.1 version: 11.1.4 - '@nuxt/kit': - specifier: ^4.4.2 - version: 4.4.2 - '@nuxt/schema': - specifier: ^4.4.2 - version: 4.4.2 '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -1451,10 +1445,10 @@ importers: specifier: workspace:^ version: link:../fedify '@nuxt/kit': - specifier: 'catalog:' + specifier: ^4.4.2 version: 4.4.2(magicast@0.5.2) '@nuxt/schema': - specifier: 'catalog:' + specifier: ^4.4.2 version: 4.4.2 h3: specifier: 'catalog:' From 35dee115782de07eb445abd7a3a0d222f825d3b3 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 08:20:06 +0000 Subject: [PATCH 06/26] Fix logger Co-authored-by: Copilot --- examples/nuxt/server/logging.ts | 23 +++++++++++++++++++++++ examples/nuxt/server/plugins/logging.ts | 24 ++---------------------- 2 files changed, 25 insertions(+), 22 deletions(-) create mode 100644 examples/nuxt/server/logging.ts diff --git a/examples/nuxt/server/logging.ts b/examples/nuxt/server/logging.ts new file mode 100644 index 000000000..c4c497c0c --- /dev/null +++ b/examples/nuxt/server/logging.ts @@ -0,0 +1,23 @@ +import { configure, getConsoleSink } from "@logtape/logtape"; +import { AsyncLocalStorage } from "node:async_hooks"; + +export default configure({ + contextLocalStorage: new AsyncLocalStorage(), + sinks: { + console: getConsoleSink(), + }, + filters: {}, + loggers: [ + { + category: ["nuxt", "example"], + lowestLevel: "debug", + sinks: ["console"], + }, + { category: "fedify", lowestLevel: "info", sinks: ["console"] }, + { + category: ["logtape", "meta"], + lowestLevel: "warning", + sinks: ["console"], + }, + ], +}); diff --git a/examples/nuxt/server/plugins/logging.ts b/examples/nuxt/server/plugins/logging.ts index 97a87a814..e52d96936 100644 --- a/examples/nuxt/server/plugins/logging.ts +++ b/examples/nuxt/server/plugins/logging.ts @@ -1,25 +1,5 @@ -import { configure, getConsoleSink } from "@logtape/logtape"; -import { AsyncLocalStorage } from "node:async_hooks"; +import loggingConfigured from "../logging"; export default defineNitroPlugin(async () => { - await configure({ - contextLocalStorage: new AsyncLocalStorage(), - sinks: { - console: getConsoleSink(), - }, - filters: {}, - loggers: [ - { - category: ["default", "example"], - lowestLevel: "debug", - sinks: ["console"], - }, - { category: "fedify", lowestLevel: "info", sinks: ["console"] }, - { - category: ["logtape", "meta"], - lowestLevel: "warning", - sinks: ["console"], - }, - ], - }); + await loggingConfigured; }); From bcae97ea9f6214cba426f2659121390a38c13471 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 18:49:58 +0000 Subject: [PATCH 07/26] Guard SSE send failures and clean up stream handling - Wrap each client.send() in broadcastEvent() with a try-catch so a throw from one client does not abort the fanout loop or propagate into federation handlers (Follow/Undo processing). - Remove redundant setResponseHeader calls in events.get.ts; the Response constructor already sets identical headers. - Wrap controller.enqueue in a try-catch to handle writes to already- closed streams. - Call client.close() in the "close" event handler so the ReadableStream controller is properly finalized when the connection drops. Assisted-by: Claude Code:claude-sonnet-4-6 --- examples/nuxt/server/api/events.get.ts | 12 ++++++------ examples/nuxt/server/sse.ts | 6 +++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/nuxt/server/api/events.get.ts b/examples/nuxt/server/api/events.get.ts index 8fad50104..97c3348a9 100644 --- a/examples/nuxt/server/api/events.get.ts +++ b/examples/nuxt/server/api/events.get.ts @@ -1,17 +1,16 @@ -import { setResponseHeader } from "h3"; import { addClient, removeClient } from "../sse"; export default defineEventHandler((event) => { - setResponseHeader(event, "Content-Type", "text/event-stream"); - setResponseHeader(event, "Cache-Control", "no-cache"); - setResponseHeader(event, "Connection", "keep-alive"); - const stream = new ReadableStream({ start(controller) { const encoder = new TextEncoder(); const client = { send(data: string) { - controller.enqueue(encoder.encode(`data: ${data}\n\n`)); + try { + controller.enqueue(encoder.encode(`data: ${data}\n\n`)); + } catch { + removeClient(client); + } }, close() { controller.close(); @@ -22,6 +21,7 @@ export default defineEventHandler((event) => { event.node.req.on("close", () => { removeClient(client); + client.close(); }); }, }); diff --git a/examples/nuxt/server/sse.ts b/examples/nuxt/server/sse.ts index c1af7c9b4..af3671946 100644 --- a/examples/nuxt/server/sse.ts +++ b/examples/nuxt/server/sse.ts @@ -16,6 +16,10 @@ export function removeClient(client: EventClient): void { export function broadcastEvent(): void { const data = JSON.stringify({ type: "update" }); for (const client of clients) { - client.send(data); + try { + client.send(data); + } catch { + clients.delete(client); + } } } From f3f57944cf95d1a65f31cbebe7afcada97f7f45b Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 18:50:11 +0000 Subject: [PATCH 08/26] Make federation activity delivery non-fatal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Network or remote-server errors from lookupObject() and sendActivity() previously surfaced as 500 responses. Local state mutations and SSE notifications should proceed regardless of delivery outcome. - post.post.ts: call broadcastEvent() immediately after postStore update so SSE clients see new posts; wrap sendActivity in try-catch so delivery failure does not roll back the post. - follow.post.ts: isolate lookupObject failure with an early redirect; wrap sendActivity so delivery failure does not prevent followingStore update or the 303 redirect. Also replace the dynamic import of Person with a static import. - unfollow.post.ts: same pattern — lookupObject failure redirects early; sendActivity failure does not block followingStore cleanup. Assisted-by: Claude Code:claude-sonnet-4-6 --- examples/nuxt/server/api/follow.post.ts | 38 +++++++++++++--------- examples/nuxt/server/api/post.post.ts | 6 ++-- examples/nuxt/server/api/unfollow.post.ts | 39 ++++++++++++++--------- 3 files changed, 51 insertions(+), 32 deletions(-) diff --git a/examples/nuxt/server/api/follow.post.ts b/examples/nuxt/server/api/follow.post.ts index f71deff09..97736cf9c 100644 --- a/examples/nuxt/server/api/follow.post.ts +++ b/examples/nuxt/server/api/follow.post.ts @@ -1,4 +1,4 @@ -import { Follow, type Object as APObject } from "@fedify/vocab"; +import { Follow, Person, type Object as APObject } from "@fedify/vocab"; import { readBody, sendRedirect, toWebRequest } from "h3"; import federation from "../federation"; import { broadcastEvent } from "../sse"; @@ -15,25 +15,33 @@ export default defineEventHandler(async (event) => { const ctx = federation.createContext(request, undefined); const identifier = "demo"; - const target = await ctx.lookupObject(targetUri) as APObject | null; + let target: APObject | null = null; + try { + target = await ctx.lookupObject(targetUri) as APObject | null; + } catch { + return sendRedirect(event, "/", 303); + } if (target?.id == null) { return sendRedirect(event, "/", 303); } - await ctx.sendActivity( - { identifier }, - target, - new Follow({ - id: new URL( - `#follows/${target.id.href}`, - ctx.getActorUri(identifier), - ), - actor: ctx.getActorUri(identifier), - object: target.id, - }), - ); + try { + await ctx.sendActivity( + { identifier }, + target, + new Follow({ + id: new URL( + `#follows/${target.id.href}`, + ctx.getActorUri(identifier), + ), + actor: ctx.getActorUri(identifier), + object: target.id, + }), + ); + } catch { + // Delivery failure is non-fatal; continue updating local state. + } - const { Person } = await import("@fedify/vocab"); if (target instanceof Person) { followingStore.set(target.id.href, target); } diff --git a/examples/nuxt/server/api/post.post.ts b/examples/nuxt/server/api/post.post.ts index 6a13a9df8..0de9c322d 100644 --- a/examples/nuxt/server/api/post.post.ts +++ b/examples/nuxt/server/api/post.post.ts @@ -6,6 +6,7 @@ import { toWebRequest, } from "@nuxt/nitro-server/h3"; import federation from "../federation.ts"; +import { broadcastEvent } from "../sse.ts"; import { postStore } from "../store.ts"; export default defineEventHandler(async (event) => { @@ -27,8 +28,9 @@ export default defineEventHandler(async (event) => { content: content.trim(), url, }); + postStore.append([post]); + broadcastEvent(); try { - postStore.append([post]); const note = await ctx.getObject(Note, { identifier, id }); await ctx.sendActivity( { identifier }, @@ -42,7 +44,7 @@ export default defineEventHandler(async (event) => { }), ); } catch { - postStore.delete(url); + // Delivery failure is non-fatal; local state is already updated. } return sendRedirect(event, "/", 303); diff --git a/examples/nuxt/server/api/unfollow.post.ts b/examples/nuxt/server/api/unfollow.post.ts index 516005eb9..8f3895946 100644 --- a/examples/nuxt/server/api/unfollow.post.ts +++ b/examples/nuxt/server/api/unfollow.post.ts @@ -15,30 +15,39 @@ export default defineEventHandler(async (event) => { const ctx = federation.createContext(request, undefined); const identifier = "demo"; - const target = await ctx.lookupObject(targetUri) as APObject | null; + let target: APObject | null = null; + try { + target = await ctx.lookupObject(targetUri) as APObject | null; + } catch { + return sendRedirect(event, "/", 303); + } if (target?.id == null) { return sendRedirect(event, "/", 303); } - await ctx.sendActivity( - { identifier }, - target, - new Undo({ - id: new URL( - `#undo-follows/${target.id.href}`, - ctx.getActorUri(identifier), - ), - actor: ctx.getActorUri(identifier), - object: new Follow({ + try { + await ctx.sendActivity( + { identifier }, + target, + new Undo({ id: new URL( - `#follows/${target.id.href}`, + `#undo-follows/${target.id.href}`, ctx.getActorUri(identifier), ), actor: ctx.getActorUri(identifier), - object: target.id, + object: new Follow({ + id: new URL( + `#follows/${target.id.href}`, + ctx.getActorUri(identifier), + ), + actor: ctx.getActorUri(identifier), + object: target.id, + }), }), - }), - ); + ); + } catch { + // Delivery failure is non-fatal; continue updating local state. + } followingStore.delete(target.id.href); broadcastEvent(); From b7853446657149a2fc9c32ad30c425eaa844bbcc Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 18:50:22 +0000 Subject: [PATCH 09/26] Fix frontend runtime errors and navigation issues - app.vue: add defer: true to the /theme.js script so it executes after the document body is available; without it the script throws when accessing document.body.classList during head parsing. - pages/index.vue: guard against stale search responses by tracking a latestSearchRequest counter; responses that arrive after a newer request has been issued are discarded to prevent the follow/unfollow form from pointing at the wrong actor. - posts/[id].vue: replace with to avoid full page reloads on navigation back to the home page. Assisted-by: Claude Code:claude-sonnet-4-6 --- examples/nuxt/app.vue | 2 +- examples/nuxt/pages/index.vue | 6 +++++- examples/nuxt/pages/users/[identifier]/posts/[id].vue | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/nuxt/app.vue b/examples/nuxt/app.vue index 420f15557..eb55b503f 100644 --- a/examples/nuxt/app.vue +++ b/examples/nuxt/app.vue @@ -8,6 +8,6 @@ useHead({ { rel: "stylesheet", href: "/style.css" }, { rel: "icon", type: "image/svg+xml", href: "/fedify-logo.svg" }, ], - script: [{ src: "/theme.js" }], + script: [{ src: "/theme.js", defer: true }], }); diff --git a/examples/nuxt/pages/index.vue b/examples/nuxt/pages/index.vue index 51779f2cc..b02a58086 100644 --- a/examples/nuxt/pages/index.vue +++ b/examples/nuxt/pages/index.vue @@ -179,6 +179,7 @@ const searchResult = ref<{ } | null>(null); let searchTimeout: ReturnType | null = null; +let latestSearchRequest = 0; function onSearchInput() { if (searchTimeout) clearTimeout(searchTimeout); @@ -187,10 +188,13 @@ function onSearchInput() { searchResult.value = null; return; } + const requestId = ++latestSearchRequest; const res = await $fetch<{ result: typeof searchResult.value }>( `/api/search?q=${encodeURIComponent(searchQuery.value)}`, ); - searchResult.value = res.result; + if (requestId === latestSearchRequest) { + searchResult.value = res.result; + } }, 300); } diff --git a/examples/nuxt/pages/users/[identifier]/posts/[id].vue b/examples/nuxt/pages/users/[identifier]/posts/[id].vue index e71e80d6a..c28114567 100644 --- a/examples/nuxt/pages/users/[identifier]/posts/[id].vue +++ b/examples/nuxt/pages/users/[identifier]/posts/[id].vue @@ -1,6 +1,6 @@ From 241a6098110ba436b563e7b2278021d01e039356 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 18:50:28 +0000 Subject: [PATCH 10/26] Minor code quality and documentation fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - search.get.ts: surface lookup errors via console.debug instead of swallowing them silently, aiding development diagnostics. - README.md: fix wording — "using the Fedify and [Nuxt]" → "using [Fedify] and [Nuxt]". Assisted-by: Claude Code:claude-sonnet-4-6 --- examples/nuxt/README.md | 2 +- examples/nuxt/server/api/search.get.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/nuxt/README.md b/examples/nuxt/README.md index ae1c90a06..a00c277af 100644 --- a/examples/nuxt/README.md +++ b/examples/nuxt/README.md @@ -7,7 +7,7 @@ A comprehensive example of building a federated server application using [Fedify] with [Nuxt]. This example demonstrates how to create an ActivityPub-compatible federated social media server that can interact with other federated platforms like [Mastodon], [Misskey], and other ActivityPub -implementations using the Fedify and [Nuxt]. +implementations using [Fedify] and [Nuxt]. [Fedify]: https://fedify.dev [Nuxt]: https://nuxt.com/ diff --git a/examples/nuxt/server/api/search.get.ts b/examples/nuxt/server/api/search.get.ts index aee9c7d39..0a928e377 100644 --- a/examples/nuxt/server/api/search.get.ts +++ b/examples/nuxt/server/api/search.get.ts @@ -29,8 +29,8 @@ export default defineEventHandler(async (event) => { }, }; } - } catch { - // lookup failed + } catch (error) { + console.debug("Actor lookup failed:", q, error); } return { result: null }; From ba4163d4e0ec4fd8ee201b5a19f5432c046b4432 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 19:46:24 +0000 Subject: [PATCH 11/26] Reorder imports in follow.post.ts to satisfy deno fmt Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/api/follow.post.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/nuxt/server/api/follow.post.ts b/examples/nuxt/server/api/follow.post.ts index 97736cf9c..88032d403 100644 --- a/examples/nuxt/server/api/follow.post.ts +++ b/examples/nuxt/server/api/follow.post.ts @@ -1,4 +1,4 @@ -import { Follow, Person, type Object as APObject } from "@fedify/vocab"; +import { Follow, type Object as APObject, Person } from "@fedify/vocab"; import { readBody, sendRedirect, toWebRequest } from "h3"; import federation from "../federation"; import { broadcastEvent } from "../sse"; From a37a3bbc909e4e5f2f3930d99e54a5a2fe5bb3a6 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 19:54:24 +0000 Subject: [PATCH 12/26] Tighten federation handling in the Nuxt example - Validate the fetched follower with `instanceof Person` instead of an unchecked `as Person` cast, so non-Person actors and null returns surface explicitly instead of being stored. - Derive the Accept activity ID from the Follow activity's `id` rather than the follower's URI, so repeated follows from the same actor get unique Accept IDs and remote servers do not deduplicate them. - Escape HTML in the Note dispatcher before exposing user-composed text as `text/html`. Federated consumers were previously served raw compose-form input as HTML. Assisted-by: Claude Code:claude-opus-4-7 --- deno.lock | 16 ---------------- examples/nuxt/server/federation.ts | 21 ++++++++++++++++----- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/deno.lock b/deno.lock index bcbfec309..7f2628187 100644 --- a/deno.lock +++ b/deno.lock @@ -58,7 +58,6 @@ "jsr:@std/semver@^1.0.6": "1.0.8", "jsr:@std/testing@0.224": "0.224.0", "jsr:@std/uuid@^1.0.9": "1.1.0", - "jsr:@std/yaml@^1.0.8": "1.0.12", "jsr:@valibot/valibot@^1.2.0": "1.3.1", "npm:@alinea/suite@~0.6.3": "0.6.3", "npm:@astrojs/node@^10.0.3": "10.0.5_astro@5.18.1__@types+node@24.12.2__ioredis@5.10.1__tsx@4.21.0__typescript@6.0.3__yaml@2.8.3_@types+node@24.12.2_ioredis@5.10.1_tsx@4.21.0_typescript@6.0.3_yaml@2.8.3", @@ -170,9 +169,6 @@ "@alinea/suite@0.6.3": { "integrity": "7d24a38729663b84d8a263d64ff7e3f8c72ac7cbb1db8ec5f414d0416b6b72e2" }, - "@david/console-static-text@0.3.0": { - "integrity": "2dfb46ecee525755f7989f94ece30bba85bd8ffe3e8666abc1bf926e1ee0698d" - }, "@david/console-static-text@0.3.4": { "integrity": "1c596f500b075ff3c8bab1d328ca7148a88067fd9a506b16a73eeaf230c229fd" }, @@ -195,9 +191,6 @@ "jsr:@std/path@1" ] }, - "@david/which@0.4.1": { - "integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e" - }, "@david/which@0.4.2": { "integrity": "440ee262bc0673b57a39ad4d0dc5673e515ddd41c049a55b2588a0881e5d4a8c" }, @@ -332,9 +325,6 @@ "@std/fmt@0.224.0": { "integrity": "e20e9a2312a8b5393272c26191c0a68eda8d2c4b08b046bad1673148f1d69851" }, - "@std/fmt@1.0.9": { - "integrity": "2487343e8899fb2be5d0e3d35013e54477ada198854e52dd05ed0422eddcabe0" - }, "@std/fmt@1.0.10": { "integrity": "90dfba288802ac6de82fb31d0917eb9e4450b9925b954d5e51fc29ac07419db5" }, @@ -366,9 +356,6 @@ "jsr:@std/fmt@0.224" ] }, - "@std/internal@1.0.12": { - "integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027" - }, "@std/internal@1.0.13": { "integrity": "2f9546691d4ac2d32859c82dff284aaeac980ddeca38430d07941e7e288725c0" }, @@ -420,9 +407,6 @@ "jsr:@std/bytes" ] }, - "@std/yaml@1.0.12": { - "integrity": "7deabca4545bcedd07c5f69ea53acea71b8b4c67562f224e17b90d75944cb20c" - }, "@valibot/valibot@1.3.1": { "integrity": "635faaec9d32a25efca7b4614e7a07306cc03937bfd0679e05530d31081bc501" } diff --git a/examples/nuxt/server/federation.ts b/examples/nuxt/server/federation.ts index 64c671019..c83d1686e 100644 --- a/examples/nuxt/server/federation.ts +++ b/examples/nuxt/server/federation.ts @@ -18,6 +18,17 @@ import { import { broadcastEvent } from "./sse.ts"; import { keyPairsStore, postStore, relationStore } from "./store.ts"; +function escapeHtml(value: string): string { + return value.replace(/[&<>"']/g, (c) => + ({ + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + })[c]!); +} + const federation = createFederation({ kv: new MemoryKvStore(), queue: new InProcessMessageQueue(), @@ -75,16 +86,16 @@ federation if (result?.type !== "actor" || result.identifier !== IDENTIFIER) { return; } - const follower = await follow.getActor(context) as Person; - if (!follower?.id) { - throw new Error("follower is null"); + const follower = await follow.getActor(context); + if (!(follower instanceof Person) || follower.id == null) { + throw new Error("follower is not a Person"); } await context.sendActivity( { identifier: result.identifier }, follower, new Accept({ id: new URL( - `#accepts/${follower.id.href}`, + `#accepts/${encodeURIComponent(follow.id.href)}`, context.getActorUri(IDENTIFIER), ), actor: follow.objectId, @@ -119,7 +130,7 @@ federation.setObjectDispatcher( attribution: ctx.getActorUri(values.identifier), to: PUBLIC_COLLECTION, cc: ctx.getFollowersUri(values.identifier), - content: post.content, + content: escapeHtml(post.content), mediaType: "text/html", published: post.published, url: id, From 22eef3662c7f6eafec1823443825f13b00cf4a7e Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 19:55:16 +0000 Subject: [PATCH 13/26] Tighten typing and dedup logic in the Nuxt example - post.post.ts: type the request body as `{ content?: unknown }` so `content` enters the handler as `unknown` and is narrowed only by the runtime `typeof content !== "string"` check. - store.ts: rewrite `PostStore.append` as an explicit `for...of` loop that checks `#map.has(key)` immediately before each insert. The previous filter/forEach chain ran the predicate in a single pass, so duplicate IDs within the same input batch all passed the filter and were pushed onto the timeline. Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/api/post.post.ts | 2 +- examples/nuxt/server/store.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/nuxt/server/api/post.post.ts b/examples/nuxt/server/api/post.post.ts index 0de9c322d..127c6eacd 100644 --- a/examples/nuxt/server/api/post.post.ts +++ b/examples/nuxt/server/api/post.post.ts @@ -10,7 +10,7 @@ import { broadcastEvent } from "../sse.ts"; import { postStore } from "../store.ts"; export default defineEventHandler(async (event) => { - const body = await readBody(event); + const body = await readBody<{ content?: unknown }>(event); const content = body?.content; if (typeof content !== "string" || !content.trim()) { return sendRedirect(event, "/", 303); diff --git a/examples/nuxt/server/store.ts b/examples/nuxt/server/store.ts index 8c987f07a..31eb164d0 100644 --- a/examples/nuxt/server/store.ts +++ b/examples/nuxt/server/store.ts @@ -12,11 +12,13 @@ class PostStore { #timeline: URL[] = []; constructor() {} append(posts: Note[]) { - posts.filter((p) => p.id && !this.#map.has(p.id.toString())) - .forEach((p) => { - this.#map.set(p.id!.toString(), p); - this.#timeline.push(p.id!); - }); + for (const p of posts) { + if (!p.id) continue; + const key = p.id.toString(); + if (this.#map.has(key)) continue; + this.#map.set(key, p); + this.#timeline.push(p.id); + } } get(id: URL) { return this.#map.get(id.toString()); From 518b77731b9c99d4576d3bfba555ff0e4a7cc37c Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 19:57:25 +0000 Subject: [PATCH 14/26] Stabilize SSR rendering and clean up frontend bits - pages/index.vue and posts/[id].vue: pin `formatDate` to "en-US" locale and "UTC" timezone. The previous `toLocaleString(undefined)` resolved to runtime locale/TZ on each side, so SSR output diverged from client output and triggered Vue hydration mismatches. - pages/users/[identifier]/index.vue: remove the "Posts" info card. Its link pointed at `/`, which only goes back to the home page; no dedicated posts listing exists yet, so the card was misleading. - public/theme.js (example) and example/public/theme.js (skill template): replace `globalThis.window.matchMedia` with `globalThis.matchMedia`. Both files are browser-only, so the `globalThis.window` indirection added no SSR safety, and Deno's no-window lint rule forbids the `window` global. Assisted-by: Claude Code:claude-opus-4-7 --- .../example/public/theme.js | 2 +- examples/nuxt/pages/index.vue | 3 ++- examples/nuxt/pages/users/[identifier]/index.vue | 6 ------ examples/nuxt/pages/users/[identifier]/posts/[id].vue | 3 ++- examples/nuxt/public/theme.js | 2 +- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.agents/skills/create-example-app-with-integration/example/public/theme.js b/.agents/skills/create-example-app-with-integration/example/public/theme.js index 3da2aaacf..7b20d9638 100644 --- a/.agents/skills/create-example-app-with-integration/example/public/theme.js +++ b/.agents/skills/create-example-app-with-integration/example/public/theme.js @@ -1,5 +1,5 @@ "use strict"; -const mq = globalThis.window.matchMedia("(prefers-color-scheme: dark)"); +const mq = globalThis.matchMedia("(prefers-color-scheme: dark)"); document.body.classList.add(mq.matches ? "dark" : "light"); mq.addEventListener("change", function (e) { document.body.classList.remove("light", "dark"); diff --git a/examples/nuxt/pages/index.vue b/examples/nuxt/pages/index.vue index b02a58086..ab6c98692 100644 --- a/examples/nuxt/pages/index.vue +++ b/examples/nuxt/pages/index.vue @@ -199,12 +199,13 @@ function onSearchInput() { } function formatDate(dateStr: string): string { - return new Date(dateStr).toLocaleString(undefined, { + return new Date(dateStr).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit", + timeZone: "UTC", }); } diff --git a/examples/nuxt/pages/users/[identifier]/index.vue b/examples/nuxt/pages/users/[identifier]/index.vue index afd73d7bc..d81827d3b 100644 --- a/examples/nuxt/pages/users/[identifier]/index.vue +++ b/examples/nuxt/pages/users/[identifier]/index.vue @@ -44,12 +44,6 @@ -
diff --git a/examples/nuxt/pages/users/[identifier]/posts/[id].vue b/examples/nuxt/pages/users/[identifier]/posts/[id].vue index c28114567..9bc47fd6b 100644 --- a/examples/nuxt/pages/users/[identifier]/posts/[id].vue +++ b/examples/nuxt/pages/users/[identifier]/posts/[id].vue @@ -50,12 +50,13 @@ useHead({ }); function formatDate(dateStr: string): string { - return new Date(dateStr).toLocaleString(undefined, { + return new Date(dateStr).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit", + timeZone: "UTC", }); } diff --git a/examples/nuxt/public/theme.js b/examples/nuxt/public/theme.js index 3da2aaacf..7b20d9638 100644 --- a/examples/nuxt/public/theme.js +++ b/examples/nuxt/public/theme.js @@ -1,5 +1,5 @@ "use strict"; -const mq = globalThis.window.matchMedia("(prefers-color-scheme: dark)"); +const mq = globalThis.matchMedia("(prefers-color-scheme: dark)"); document.body.classList.add(mq.matches ? "dark" : "light"); mq.addEventListener("change", function (e) { document.body.classList.remove("light", "dark"); From 7bc5c3ff7b42018ca60a82b0569221f65723b0b4 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 19:58:32 +0000 Subject: [PATCH 15/26] Document tunnel-only dev settings and align Nuxt deps - examples/nuxt/nuxt.config.ts: add an inline comment above `devServer.host: "0.0.0.0"` and `vite.server.allowedHosts: true` noting they are intentional for tunnel-based federation testing and not recommended defaults. Without the note, consumers copying the file may propagate the looser settings. - packages/nuxt/package.json: replace the explicit `^4.4.2` range for `@nuxt/kit` and `@nuxt/schema` with `catalog:`, matching the sibling peers (`h3`, `nuxt`) and the existing `pnpm-workspace.yaml` catalog entries. Future Nuxt bumps now update one location instead of two. Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/nuxt.config.ts | 3 +++ packages/nuxt/package.json | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/nuxt/nuxt.config.ts b/examples/nuxt/nuxt.config.ts index b6642ac66..be3badafa 100644 --- a/examples/nuxt/nuxt.config.ts +++ b/examples/nuxt/nuxt.config.ts @@ -2,6 +2,9 @@ export default defineNuxtConfig({ modules: ["@fedify/nuxt"], fedify: { federationModule: "#server/federation" }, ssr: true, + // The settings below loosen dev-server defenses to support tunnel-based + // federation testing (e.g., `fedify tunnel`). Not recommended for general + // Nuxt projects — remove or tighten before reusing this config. devServer: { host: "0.0.0.0" }, vite: { server: { allowedHosts: true } }, }); diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 6190d4103..b8eb1d0e5 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -50,8 +50,8 @@ ], "peerDependencies": { "@fedify/fedify": "workspace:^", - "@nuxt/kit": "^4.4.2", - "@nuxt/schema": "^4.4.2", + "@nuxt/kit": "catalog:", + "@nuxt/schema": "catalog:", "h3": "catalog:", "nuxt": "catalog:" }, From cae3b1a407353541280f81b2d3b99f6ff0d0fc7e Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 20:55:13 +0000 Subject: [PATCH 16/26] Silence noisy WebFinger and key-generation log lines in examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beginners running the Nuxt example or generating one from the integration-package skill saw two scary log lines that did not indicate any real problem: an `ERR` from `fedify·webfinger·server` about the missing actor handle mapper, and a `WRN` from `fedify·sig·key` about the unspecified key-pair algorithm. Register a handle mapper that maps the WebFinger username to the single demo identifier, and request both RSASSA-PKCS1-v1_5 and Ed25519 key pairs explicitly so the example also publishes a modern signing key alongside the Mastodon-compatible RSA key. Assisted-by: Claude Code:claude-opus-4-7 --- .../example/src/federation.ts | 9 ++++++--- examples/nuxt/server/federation.ts | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.agents/skills/create-example-app-with-integration/example/src/federation.ts b/.agents/skills/create-example-app-with-integration/example/src/federation.ts index 898a7c91b..b9b2d32af 100644 --- a/.agents/skills/create-example-app-with-integration/example/src/federation.ts +++ b/.agents/skills/create-example-app-with-integration/example/src/federation.ts @@ -46,6 +46,7 @@ federation }); }, ) + .mapHandle((_, username) => username === IDENTIFIER ? IDENTIFIER : null) .setKeyPairsDispatcher(async (_, identifier) => { if (identifier != IDENTIFIER) { return []; @@ -54,9 +55,11 @@ federation if (keyPairs) { return keyPairs; } - const { privateKey, publicKey } = await generateCryptoKeyPair(); - keyPairsStore.set(identifier, [{ privateKey, publicKey }]); - return [{ privateKey, publicKey }]; + const rsa = await generateCryptoKeyPair("RSASSA-PKCS1-v1_5"); + const ed25519 = await generateCryptoKeyPair("Ed25519"); + const newKeyPairs = [rsa, ed25519]; + keyPairsStore.set(identifier, newKeyPairs); + return newKeyPairs; }); federation diff --git a/examples/nuxt/server/federation.ts b/examples/nuxt/server/federation.ts index c83d1686e..fd12a1f3b 100644 --- a/examples/nuxt/server/federation.ts +++ b/examples/nuxt/server/federation.ts @@ -59,6 +59,7 @@ federation }); }, ) + .mapHandle((_, username) => username === IDENTIFIER ? IDENTIFIER : null) .setKeyPairsDispatcher(async (_, identifier) => { if (identifier != IDENTIFIER) { return []; @@ -67,9 +68,11 @@ federation if (keyPairs) { return keyPairs; } - const { privateKey, publicKey } = await generateCryptoKeyPair(); - keyPairsStore.set(identifier, [{ privateKey, publicKey }]); - return [{ privateKey, publicKey }]; + const rsa = await generateCryptoKeyPair("RSASSA-PKCS1-v1_5"); + const ed25519 = await generateCryptoKeyPair("Ed25519"); + const newKeyPairs = [rsa, ed25519]; + keyPairsStore.set(identifier, newKeyPairs); + return newKeyPairs; }); federation From 11bcfcb572981a0d221b4714c313c22e04ee22f7 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 21:01:37 +0000 Subject: [PATCH 17/26] Update lockfile --- pnpm-lock.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d13cf517b..21d2b8ae4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,12 @@ catalogs: '@nestjs/common': specifier: ^11.0.1 version: 11.1.4 + '@nuxt/kit': + specifier: ^4.4.2 + version: 4.4.2 + '@nuxt/schema': + specifier: ^4.4.2 + version: 4.4.2 '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -1445,10 +1451,10 @@ importers: specifier: workspace:^ version: link:../fedify '@nuxt/kit': - specifier: ^4.4.2 + specifier: 'catalog:' version: 4.4.2(magicast@0.5.2) '@nuxt/schema': - specifier: ^4.4.2 + specifier: 'catalog:' version: 4.4.2 h3: specifier: 'catalog:' From f6675722c3fbab4dcc6366a4212c2a67dc653bf3 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 21:13:21 +0000 Subject: [PATCH 18/26] Tighten ActivityPub correctness in the Nuxt example Set `published` on locally created Notes so timeline, post detail, and federated Create payloads carry an actual timestamp instead of serializing as null. Validate the route identifier inside the followers dispatcher so `/users//followers` no longer leaks the demo account's follower list. Other dispatchers in the same module already use the same `IDENTIFIER` guard. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/api/post.post.ts | 1 + examples/nuxt/server/federation.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/nuxt/server/api/post.post.ts b/examples/nuxt/server/api/post.post.ts index 127c6eacd..2ccbd33c0 100644 --- a/examples/nuxt/server/api/post.post.ts +++ b/examples/nuxt/server/api/post.post.ts @@ -26,6 +26,7 @@ export default defineEventHandler(async (event) => { id: url, attribution, content: content.trim(), + published: Temporal.Now.instant(), url, }); postStore.append([post]); diff --git a/examples/nuxt/server/federation.ts b/examples/nuxt/server/federation.ts index fd12a1f3b..03e34ce8d 100644 --- a/examples/nuxt/server/federation.ts +++ b/examples/nuxt/server/federation.ts @@ -144,7 +144,8 @@ federation.setObjectDispatcher( federation .setFollowersDispatcher( "/users/{identifier}/followers", - () => { + (_ctx, identifier) => { + if (identifier !== IDENTIFIER) return null; const followers = Array.from(relationStore.values()); const items: Recipient[] = followers.map((f) => ({ id: f.id, From 68a08735bc56743d778d628e515813182e5254a4 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 21:14:00 +0000 Subject: [PATCH 19/26] Tighten typing in Nuxt example handlers Align post.post.ts imports with the other handlers: pull h3 helpers from `h3` (the path other handlers use), drop the redundant `defineEventHandler` import that Nitro auto-imports, and remove the `.ts` extensions on local module imports. Narrow `query.q` properly in the search handler. `getQuery` returns `string | string[]` for repeated parameters, so the previous `as string` cast crashed at runtime when callers sent `?q=a&q=b`. The handler now picks the first value, type-checks it, and reuses the trimmed string for `lookupObject`. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/api/post.post.ts | 13 ++++--------- examples/nuxt/server/api/search.get.ts | 7 ++++--- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/examples/nuxt/server/api/post.post.ts b/examples/nuxt/server/api/post.post.ts index 2ccbd33c0..cf689d063 100644 --- a/examples/nuxt/server/api/post.post.ts +++ b/examples/nuxt/server/api/post.post.ts @@ -1,13 +1,8 @@ import { Create, Note } from "@fedify/vocab"; -import { - defineEventHandler, - readBody, - sendRedirect, - toWebRequest, -} from "@nuxt/nitro-server/h3"; -import federation from "../federation.ts"; -import { broadcastEvent } from "../sse.ts"; -import { postStore } from "../store.ts"; +import { readBody, sendRedirect, toWebRequest } from "h3"; +import federation from "../federation"; +import { broadcastEvent } from "../sse"; +import { postStore } from "../store"; export default defineEventHandler(async (event) => { const body = await readBody<{ content?: unknown }>(event); diff --git a/examples/nuxt/server/api/search.get.ts b/examples/nuxt/server/api/search.get.ts index 0a928e377..602274493 100644 --- a/examples/nuxt/server/api/search.get.ts +++ b/examples/nuxt/server/api/search.get.ts @@ -5,8 +5,9 @@ import { followingStore } from "../store"; export default defineEventHandler(async (event) => { const query = getQuery(event); - const q = query.q as string | undefined; - if (!q || !q.trim()) { + const raw = Array.isArray(query.q) ? query.q[0] : query.q; + const q = typeof raw === "string" ? raw.trim() : ""; + if (!q) { return { result: null }; } @@ -14,7 +15,7 @@ export default defineEventHandler(async (event) => { const ctx = federation.createContext(request, undefined); try { - const target = await ctx.lookupObject(q.trim()); + const target = await ctx.lookupObject(q); if (target instanceof Person && target.id) { const iconUrl = await target.getIcon(ctx); return { From 2bed7e292f574d540a16d71922ec1f06dbcf836b Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 21:14:31 +0000 Subject: [PATCH 20/26] Polish frontend lifecycle and link safety Move the home page's `onBeforeUnmount` registration out of the `onMounted` callback so Vue's setup-time hook contract is satisfied and the EventSource is reliably closed when the component unmounts. Surface fetch errors separately from missing resources on the profile and post detail pages so transient network failures no longer render the same "Not found" title as legitimate 404s. Add `rel="noopener noreferrer"` on the Fedify badge links opened with `target="_blank"`. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/pages/index.vue | 13 ++++++++----- examples/nuxt/pages/users/[identifier]/index.vue | 7 +++++-- .../nuxt/pages/users/[identifier]/posts/[id].vue | 6 ++++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/nuxt/pages/index.vue b/examples/nuxt/pages/index.vue index ab6c98692..97cdece26 100644 --- a/examples/nuxt/pages/index.vue +++ b/examples/nuxt/pages/index.vue @@ -157,7 +157,7 @@
Powered by - + Fedify
@@ -209,14 +209,17 @@ function formatDate(dateStr: string): string { }); } +let eventSource: EventSource | null = null; + onMounted(() => { - const eventSource = new EventSource("/api/events"); + eventSource = new EventSource("/api/events"); eventSource.onmessage = () => { refresh(); }; - onBeforeUnmount(() => { - eventSource.close(); - }); +}); + +onBeforeUnmount(() => { + eventSource?.close(); }); diff --git a/examples/nuxt/pages/users/[identifier]/index.vue b/examples/nuxt/pages/users/[identifier]/index.vue index d81827d3b..825c7b4aa 100644 --- a/examples/nuxt/pages/users/[identifier]/index.vue +++ b/examples/nuxt/pages/users/[identifier]/index.vue @@ -37,6 +37,7 @@ href="https://fedify.dev" class="fedify-anchor" target="_blank" + rel="noopener noreferrer" > Fedify @@ -55,10 +56,12 @@ const route = useRoute(); const identifier = route.params.identifier as string; -const { data } = await useFetch(`/api/profile/${identifier}`); +const { data, error } = await useFetch(`/api/profile/${identifier}`); useHead({ - title: data.value + title: error.value + ? "Error - Fedify Nuxt Example" + : data.value ? `${data.value.name} - Fedify Nuxt Example` : "Not Found - Fedify Nuxt Example", }); diff --git a/examples/nuxt/pages/users/[identifier]/posts/[id].vue b/examples/nuxt/pages/users/[identifier]/posts/[id].vue index 9bc47fd6b..fb0a96092 100644 --- a/examples/nuxt/pages/users/[identifier]/posts/[id].vue +++ b/examples/nuxt/pages/users/[identifier]/posts/[id].vue @@ -41,10 +41,12 @@ const route = useRoute(); const identifier = route.params.identifier as string; const id = route.params.id as string; -const { data } = await useFetch(`/api/posts/${identifier}/${id}`); +const { data, error } = await useFetch(`/api/posts/${identifier}/${id}`); useHead({ - title: data.value + title: error.value + ? "Error - Fedify Nuxt Example" + : data.value ? `Post - ${data.value.author.name} - Fedify Nuxt Example` : "Not Found - Fedify Nuxt Example", }); From 461b1023e89c5b496a04d793f41ecdb406ae32bb Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sat, 25 Apr 2026 21:26:56 +0000 Subject: [PATCH 21/26] Reorder pnpm workspace --- pnpm-workspace.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a1ec58f4e..6ad706490 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -37,10 +37,10 @@ packages: - examples/express - examples/koa - examples/next-integration -- examples/nuxt - examples/fastify - examples/next14-app-router - examples/next15-app-router +- examples/nuxt - examples/solidstart - examples/sveltekit-sample From 003d86a2fdf9e02b5d566088658659af0d5fa513 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sun, 26 Apr 2026 19:11:00 +0000 Subject: [PATCH 22/26] Drop unused deps from the Nuxt example `vue` is a transitive dependency of Nuxt and pinning it directly risks drifting from the version Nuxt expects. `x-forwarded-fetch` is not imported anywhere in the example or wired into nuxt.config. Remove both and refresh the lockfile. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/package.json | 4 +--- pnpm-lock.yaml | 6 ------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/examples/nuxt/package.json b/examples/nuxt/package.json index d7610eff2..a5ced5ca4 100644 --- a/examples/nuxt/package.json +++ b/examples/nuxt/package.json @@ -16,9 +16,7 @@ "@fedify/vocab": "workspace:^", "@logtape/logtape": "catalog:", "nuxt": "catalog:", - "h3": "catalog:", - "vue": "^3.5.13", - "x-forwarded-fetch": "^0.2.0" + "h3": "catalog:" }, "devDependencies": { "typescript": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21d2b8ae4..196f0d86e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -690,12 +690,6 @@ importers: nuxt: specifier: 'catalog:' version: 4.4.2(@babel/core@7.29.0)(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@parcel/watcher@2.5.6)(@types/node@22.19.1)(@vue/compiler-sfc@3.5.33)(cac@6.7.14)(db0@0.3.4(mysql2@3.22.2(@types/node@22.19.1)))(ioredis@5.10.1)(lightningcss@1.30.1)(magicast@0.5.2)(mysql2@3.22.2(@types/node@22.19.1))(optionator@0.9.4)(rolldown@1.0.0-rc.12)(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-rc.12)(rollup@4.60.2))(rollup@4.60.2)(terser@5.46.1)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.1)(terser@5.46.1)(tsx@4.20.3)(yaml@2.8.3))(yaml@2.8.3) - vue: - specifier: ^3.5.13 - version: 3.5.33(typescript@5.9.3) - x-forwarded-fetch: - specifier: ^0.2.0 - version: 0.2.0 devDependencies: '@types/node': specifier: 'catalog:' From a888000dd3f794b1f9e2cbb75232544cb1f0f7ce Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sun, 26 Apr 2026 19:11:59 +0000 Subject: [PATCH 23/26] Type readBody in follow/unfollow handlers Pass `{ uri?: unknown }` to `readBody` so `body?.uri` enters the handler typed as `unknown` and only narrows to `string` after the runtime check, mirroring the typing already in place in `post.post.ts`. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/api/follow.post.ts | 2 +- examples/nuxt/server/api/unfollow.post.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/nuxt/server/api/follow.post.ts b/examples/nuxt/server/api/follow.post.ts index 88032d403..3e70ddcfb 100644 --- a/examples/nuxt/server/api/follow.post.ts +++ b/examples/nuxt/server/api/follow.post.ts @@ -5,7 +5,7 @@ import { broadcastEvent } from "../sse"; import { followingStore } from "../store"; export default defineEventHandler(async (event) => { - const body = await readBody(event); + const body = await readBody<{ uri?: unknown }>(event); const targetUri = body?.uri; if (typeof targetUri !== "string" || !targetUri.trim()) { return sendRedirect(event, "/", 303); diff --git a/examples/nuxt/server/api/unfollow.post.ts b/examples/nuxt/server/api/unfollow.post.ts index 8f3895946..ee4b1934c 100644 --- a/examples/nuxt/server/api/unfollow.post.ts +++ b/examples/nuxt/server/api/unfollow.post.ts @@ -5,7 +5,7 @@ import { broadcastEvent } from "../sse"; import { followingStore } from "../store"; export default defineEventHandler(async (event) => { - const body = await readBody(event); + const body = await readBody<{ uri?: unknown }>(event); const targetUri = body?.uri; if (typeof targetUri !== "string" || !targetUri.trim()) { return sendRedirect(event, "/", 303); From 8a91f8e8af3eb9c69159ac81aef97dd2bc603b86 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sun, 26 Apr 2026 19:13:04 +0000 Subject: [PATCH 24/26] Tighten Nuxt example navigation and search race Move the search debounce's `latestSearchRequest` increment to the top of the timeout callback so clearing the input invalidates any in-flight `/api/search` response. The previous order let a slow prior fetch overwrite the just-cleared `searchResult`. Convert the post detail page's author link from a raw anchor to `` so navigating to the author profile uses Nuxt's client-side router instead of triggering a full page reload, in line with the back-link conversion already applied to the page. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/pages/index.vue | 2 +- examples/nuxt/pages/users/[identifier]/posts/[id].vue | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/nuxt/pages/index.vue b/examples/nuxt/pages/index.vue index 97cdece26..db97d74b4 100644 --- a/examples/nuxt/pages/index.vue +++ b/examples/nuxt/pages/index.vue @@ -184,11 +184,11 @@ let latestSearchRequest = 0; function onSearchInput() { if (searchTimeout) clearTimeout(searchTimeout); searchTimeout = setTimeout(async () => { + const requestId = ++latestSearchRequest; if (!searchQuery.value.trim()) { searchResult.value = null; return; } - const requestId = ++latestSearchRequest; const res = await $fetch<{ result: typeof searchResult.value }>( `/api/search?q=${encodeURIComponent(searchQuery.value)}`, ); diff --git a/examples/nuxt/pages/users/[identifier]/posts/[id].vue b/examples/nuxt/pages/users/[identifier]/posts/[id].vue index fb0a96092..722c1f6e9 100644 --- a/examples/nuxt/pages/users/[identifier]/posts/[id].vue +++ b/examples/nuxt/pages/users/[identifier]/posts/[id].vue @@ -2,9 +2,9 @@
← Back to home
- +

{{ data.content }}

From a88e6117b0a6c2f827eef2783d5007f8a57b2c97 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sun, 26 Apr 2026 19:13:39 +0000 Subject: [PATCH 25/26] Drop empty PostStore constructor in Nuxt example The class only declared a no-op explicit constructor; field initializers cover what was needed, so let the implicit default constructor handle it. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/store.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/nuxt/server/store.ts b/examples/nuxt/server/store.ts index 31eb164d0..837884ab7 100644 --- a/examples/nuxt/server/store.ts +++ b/examples/nuxt/server/store.ts @@ -10,7 +10,6 @@ declare global { class PostStore { #map: Map = new Map(); #timeline: URL[] = []; - constructor() {} append(posts: Note[]) { for (const p of posts) { if (!p.id) continue; From 190da99a52f896ccada5e1df2c7e38cb42f3ccc1 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Sun, 26 Apr 2026 20:36:03 +0000 Subject: [PATCH 26/26] Harden inbox actor handling and Note dispatcher Use the `isActor()` predicate from `@fedify/vocab` instead of `instanceof Person` when accepting an incoming Follow. Throwing on non-Person actors caused Fedify to treat the inbox delivery as failed and the remote server to retry indefinitely, even though `Service`, `Application`, `Group`, and `Organization` are all valid ActivityPub actors. Validate the path identifier inside the Note object dispatcher so the demo follows the same `IDENTIFIER` guard pattern already used by the actor, key-pairs, and followers dispatchers in this file. The current `postStore` shape makes the mismatch unreachable, but the explicit guard makes the invariant local instead of relying on how posts happen to be keyed. https://github.com/fedify-dev/fedify/pull/676 Assisted-by: Claude Code:claude-opus-4-7 --- examples/nuxt/server/federation.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/nuxt/server/federation.ts b/examples/nuxt/server/federation.ts index 03e34ce8d..375a7e080 100644 --- a/examples/nuxt/server/federation.ts +++ b/examples/nuxt/server/federation.ts @@ -9,6 +9,7 @@ import { Endpoints, Follow, Image, + isActor, Note, Person, PUBLIC_COLLECTION, @@ -90,9 +91,7 @@ federation return; } const follower = await follow.getActor(context); - if (!(follower instanceof Person) || follower.id == null) { - throw new Error("follower is not a Person"); - } + if (!isActor(follower) || follower.id == null) return; await context.sendActivity( { identifier: result.identifier }, follower, @@ -125,6 +124,7 @@ federation.setObjectDispatcher( Note, "/users/{identifier}/posts/{id}", (ctx, values) => { + if (values.identifier !== IDENTIFIER) return null; const id = ctx.getObjectUri(Note, values); const post = postStore.get(id); if (post == null) return null;