From 85f1c22e6aa423d10cd619e34ebf98e7e7599514 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:15:08 +0100 Subject: [PATCH 01/26] feat: add nitrov3 support --- packages/evlog/build.config.ts | 2 + packages/evlog/package.json | 9 ++- packages/evlog/src/nitro.ts | 21 +++++++ packages/evlog/src/nitro/plugin.ts | 23 +------- packages/evlog/src/nitrov3/plugin.ts | 86 ++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 packages/evlog/src/nitro.ts create mode 100644 packages/evlog/src/nitrov3/plugin.ts diff --git a/packages/evlog/build.config.ts b/packages/evlog/build.config.ts index beba681..daf5889 100644 --- a/packages/evlog/build.config.ts +++ b/packages/evlog/build.config.ts @@ -5,6 +5,7 @@ export default defineBuildConfig({ { input: 'src/index', name: 'index' }, { input: 'src/nuxt/module', name: 'nuxt/module' }, { input: 'src/nitro/plugin', name: 'nitro/plugin' }, + { input: 'src/nitrov3/plugin', name: 'nitrov3/plugin' }, { input: 'src/runtime/client/log', name: 'runtime/client/log' }, { input: 'src/runtime/client/plugin', name: 'runtime/client/plugin' }, { input: 'src/runtime/server/useLogger', name: 'runtime/server/useLogger' }, @@ -32,5 +33,6 @@ export default defineBuildConfig({ 'nitropack', 'nitropack/runtime', 'ofetch', + 'nitro' ], }) diff --git a/packages/evlog/package.json b/packages/evlog/package.json index 24f160f..18a9794 100644 --- a/packages/evlog/package.json +++ b/packages/evlog/package.json @@ -78,12 +78,14 @@ "nitropack": "^2.13.1", "nuxt": "^4.3.0", "typescript": "^5.9.3", - "unbuild": "^3.6.1" + "unbuild": "^3.6.1", + "nitro": "^3.0.1-alpha.2" }, "peerDependencies": { "h3": "^1.15.5", "nitropack": "^2.13.1", - "ofetch": "^1.5.1" + "ofetch": "^1.5.1", + "nitro": "^3.0.1-alpha.2" }, "peerDependenciesMeta": { "h3": { @@ -94,6 +96,9 @@ }, "ofetch": { "optional": true + }, + "nitro": { + "optional": true } } } diff --git a/packages/evlog/src/nitro.ts b/packages/evlog/src/nitro.ts new file mode 100644 index 0000000..9322d74 --- /dev/null +++ b/packages/evlog/src/nitro.ts @@ -0,0 +1,21 @@ +function matchesPattern(path: string, pattern: string): boolean { + // Convert glob pattern to regex + const regexPattern = pattern + .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special regex chars except * and ? + .replace(/\*\*/g, '{{GLOBSTAR}}') // Temp placeholder for ** + .replace(/\*/g, '[^/]*') // * matches anything except / + .replace(/{{GLOBSTAR}}/g, '.*') // ** matches anything including / + .replace(/\?/g, '[^/]') // ? matches single char except / + + const regex = new RegExp(`^${regexPattern}$`) + return regex.test(path) +} + +export function shouldLog(path: string, include?: string[]): boolean { + // If no include patterns, log everything + if (!include || include.length === 0) { + return true + } + // Log only if path matches at least one include pattern + return include.some(pattern => matchesPattern(path, pattern)) +} diff --git a/packages/evlog/src/nitro/plugin.ts b/packages/evlog/src/nitro/plugin.ts index 0d51409..8c9f133 100644 --- a/packages/evlog/src/nitro/plugin.ts +++ b/packages/evlog/src/nitro/plugin.ts @@ -1,6 +1,7 @@ import { defineNitroPlugin, useRuntimeConfig } from 'nitropack/runtime' import { createRequestLogger, initLogger } from '../logger' import type { RequestLogger, ServerEvent } from '../types' +import { shouldLog } from '../nitro' interface EvlogConfig { env?: Record @@ -8,28 +9,6 @@ interface EvlogConfig { include?: string[] } -function matchesPattern(path: string, pattern: string): boolean { - // Convert glob pattern to regex - const regexPattern = pattern - .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special regex chars except * and ? - .replace(/\*\*/g, '{{GLOBSTAR}}') // Temp placeholder for ** - .replace(/\*/g, '[^/]*') // * matches anything except / - .replace(/{{GLOBSTAR}}/g, '.*') // ** matches anything including / - .replace(/\?/g, '[^/]') // ? matches single char except / - - const regex = new RegExp(`^${regexPattern}$`) - return regex.test(path) -} - -function shouldLog(path: string, include?: string[]): boolean { - // If no include patterns, log everything - if (!include || include.length === 0) { - return true - } - // Log only if path matches at least one include pattern - return include.some(pattern => matchesPattern(path, pattern)) -} - function getResponseStatus(event: ServerEvent): number { // Node.js style if (event.node?.res?.statusCode) { diff --git a/packages/evlog/src/nitrov3/plugin.ts b/packages/evlog/src/nitrov3/plugin.ts new file mode 100644 index 0000000..4e896a6 --- /dev/null +++ b/packages/evlog/src/nitrov3/plugin.ts @@ -0,0 +1,86 @@ +import { definePlugin } from 'nitro' +import { useRuntimeConfig } from 'nitro/runtime-config' +import type { CaptureError } from 'nitro/types' +import type { HTTPEvent } from 'nitro/h3' +import { parseURL } from 'ufo' +import { createRequestLogger, initLogger } from '../logger' +import { shouldLog } from '../nitro' +import type { RequestLogger } from '../types' + +interface EvlogConfig { + env?: Record + pretty?: boolean + include?: string[] +} + +// currently nitro/v3 doesnt export hook types correctly +// https://github.com/nitrojs/nitro/blob/8882bc9e1dbf2d342e73097f22a2156f70f50575/src/types/runtime/nitro.ts#L48-L53 +interface NitroRuntimeHooks { + close: () => void; + error: CaptureError; + request: (event: HTTPEvent) => void | Promise; + response: (res: Response, event: HTTPEvent) => void | Promise; +} +// Hookable core type not available so we build it our self +type Hooks = { + hook: ( + name: THookName, + listener: NitroRuntimeHooks[THookName] + ) => void; +} + +export default definePlugin((nitroApp) => { + const config = useRuntimeConfig() + const evlogConfig = config.evlog as EvlogConfig | undefined + + initLogger({ + env: evlogConfig?.env, + pretty: evlogConfig?.pretty, + }) + + const hooks = nitroApp.hooks as Hooks + + + hooks.hook('request', (event) => { + const e = event + + const { method } = e.req + const requestId = e.req.context?.requestId as string | undefined ?? crypto.randomUUID() + + const { + pathname + } = parseURL(e.req.url) + + // Skip logging for routes not matching include patterns + if (!shouldLog(pathname, evlogConfig?.include)) { + return + } + + const log = createRequestLogger({ + method: method, + path: pathname, + requestId, + }) + if (!e.req.context) { + e.req.context = {} + } + e.req.context.log = log + }) + + hooks.hook('response', (res, event) => { + const e = event + const log = e.req.context?.log as RequestLogger | undefined + if (log) { + log.set({ status: res.status }) + log.emit() + } + }) + + hooks.hook('error', (error, { event }) => { + const e = event + const log = e?.req.context?.log as RequestLogger | undefined + if (log) { + log.error(error as Error) + } + }) +}) From 3fc91f75ae029a06650013d3041c753d6a8a1cca Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:15:22 +0100 Subject: [PATCH 02/26] chore: add ufo package to dependencies --- bun.lock | 39 +++++++++++++++++++++++++++++++++++---- package.json | 1 + 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/bun.lock b/bun.lock index 2dfea06..57b3c20 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "evlog-monorepo", @@ -10,6 +11,7 @@ "eslint": "^9.39.2", "turbo": "^2.7.6", "typescript": "^5.9.3", + "ufo": "^1.6.3", "vitest": "^4.0.18", "vue-tsc": "^3.2.4", }, @@ -38,6 +40,16 @@ "rolldown": "latest", }, }, + "apps/nitrov3-playground": { + "name": "nitrov3-playground", + "dependencies": { + "evlog": "workspace:*", + }, + "devDependencies": { + "nitro": "latest", + "rolldown": "latest", + }, + }, "apps/playground": { "name": "evlog-playground", "dependencies": { @@ -49,7 +61,7 @@ }, "packages/evlog": { "name": "evlog", - "version": "1.0.0", + "version": "1.0.1", "dependencies": { "@nuxt/kit": "^4.3.0", }, @@ -59,6 +71,7 @@ "@nuxt/test-utils": "^3.23.0", "changelogen": "^0.6.2", "h3": "^1.15.5", + "nitro": "^3.0.1-alpha.2", "nitropack": "^2.13.1", "nuxt": "^4.3.0", "typescript": "^5.9.3", @@ -66,11 +79,13 @@ }, "peerDependencies": { "h3": "^1.15.5", + "nitro": "^3.0.1-alpha.2", "nitropack": "^2.13.1", "ofetch": "^1.5.1", }, "optionalPeers": [ "h3", + "nitro", "nitropack", "ofetch", ], @@ -2075,6 +2090,8 @@ "nitropack": ["nitropack@2.13.1", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.2", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-replace": "^6.0.3", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^1.2.0", "archiver": "^7.0.1", "c12": "^3.3.3", "chokidar": "^5.0.0", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.1.0", "crossws": "^0.3.5", "db0": "^0.3.4", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^10.1.0", "esbuild": "^0.27.2", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.8", "globby": "^16.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.5", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.9.1", "jiti": "^2.6.1", "klona": "^2.0.6", "knitwork": "^1.3.0", "listhen": "^1.9.0", "magic-string": "^0.30.21", "magicast": "^0.5.1", "mime": "^4.1.0", "mlly": "^1.8.0", "node-fetch-native": "^1.6.7", "node-mock-http": "^1.0.4", "ofetch": "^1.5.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "pretty-bytes": "^7.1.0", "radix3": "^1.1.2", "rollup": "^4.55.1", "rollup-plugin-visualizer": "^6.0.5", "scule": "^1.3.0", "semver": "^7.7.3", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.1", "source-map": "^0.7.6", "std-env": "^3.10.0", "ufo": "^1.6.3", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.5.0", "unenv": "^2.0.0-rc.24", "unimport": "^5.6.0", "unplugin-utils": "^0.3.1", "unstorage": "^1.17.4", "untyped": "^2.0.0", "unwasm": "^0.5.3", "youch": "^4.1.0-beta.13", "youch-core": "^0.3.3" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-2dDj89C4wC2uzG7guF3CnyG+zwkZosPEp7FFBGHB3AJo11AywOolWhyQJFHDzve8COvGxJaqscye9wW2IrUsNw=="], + "nitrov3-playground": ["nitrov3-playground@workspace:apps/nitrov3-playground"], + "node-abi": ["node-abi@3.87.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ=="], "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], @@ -2729,7 +2746,7 @@ "unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="], - "unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "unstorage": ["unstorage@2.0.0-alpha.5", "", { "peerDependencies": { "@azure/app-configuration": "^1.9.0", "@azure/cosmos": "^4.7.0", "@azure/data-tables": "^13.3.1", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.29.1", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.12.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.35.6", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.8.2", "lru-cache": "^11.2.2", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-Sj8btci21Twnd6M+N+MHhjg3fVn6lAPElPmvFTe0Y/wR0WImErUdA1PzlAaUavHylJ7uDiFwlZDQKm0elG4b7g=="], "untun": ["untun@0.1.3", "", { "dependencies": { "citty": "^0.1.5", "consola": "^3.2.3", "pathe": "^1.1.1" }, "bin": { "untun": "bin/untun.mjs" } }, "sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ=="], @@ -2907,10 +2924,14 @@ "@nuxt/fonts/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "@nuxt/fonts/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "@nuxt/nitro-server/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + "@nuxt/nitro-server/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "@nuxt/telemetry/@nuxt/kit": ["@nuxt/kit@3.21.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "knitwork": "^1.3.0", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-KMTLK/dsGaQioZzkYUvgfN9le4grNW54aNcA1jqzgVZLcFVy4jJfrJr5WZio9NT2EMfajdoZ+V28aD7BRr4Zfw=="], "@nuxt/telemetry/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], @@ -2933,6 +2954,8 @@ "@nuxtjs/i18n/unplugin-vue-router": ["unplugin-vue-router@0.16.2", "", { "dependencies": { "@babel/generator": "^7.28.5", "@vue-macros/common": "^3.1.1", "@vue/language-core": "^3.1.3", "ast-walker-scope": "^0.8.3", "chokidar": "^4.0.3", "json5": "^2.2.3", "local-pkg": "^1.1.2", "magic-string": "^0.30.21", "mlly": "^1.8.0", "muggle-string": "^0.4.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "scule": "^1.3.0", "tinyglobby": "^0.2.15", "unplugin": "^2.3.10", "unplugin-utils": "^0.3.1", "yaml": "^2.8.1" }, "peerDependencies": { "@vue/compiler-sfc": "^3.5.17", "vue-router": "^4.6.0" }, "optionalPeers": ["vue-router"] }, "sha512-lE6ZjnHaXfS2vFI/PSEwdKcdOo5RwAbCKUnPBIN9YwLgSWas3x+qivzQvJa/uxhKzJldE6WK43aDKjGj9Rij9w=="], + "@nuxtjs/i18n/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "@nuxtjs/mcp-toolkit/@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="], "@parcel/watcher-wasm/napi-wasm": ["napi-wasm@1.1.3", "", { "bundled": true }, "sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg=="], @@ -3013,18 +3036,24 @@ "fontless/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "fontless/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], "globals/type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], "globby/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + "h3-next/crossws": ["crossws@0.4.3", "", { "peerDependencies": { "srvx": ">=0.7.1" }, "optionalPeers": ["srvx"] }, "sha512-lmf5mtwHiToP3HumOx53cqS0T5TK8GMBpsbSCXRB5OuszbltTgGOO4B1WhrDYqTeXOk3BAemibNjJx8E0/ecNw=="], + "hast-util-raw/parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "impound/unplugin-utils": ["unplugin-utils@0.2.5", "", { "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" } }, "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg=="], + "ipx/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "jsonc-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "jsonc-eslint-parser/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], @@ -3053,12 +3082,12 @@ "nitro/ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="], - "nitro/unstorage": ["unstorage@2.0.0-alpha.5", "", { "peerDependencies": { "@azure/app-configuration": "^1.9.0", "@azure/cosmos": "^4.7.0", "@azure/data-tables": "^13.3.1", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.29.1", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.12.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.35.6", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.8.2", "lru-cache": "^11.2.2", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-Sj8btci21Twnd6M+N+MHhjg3fVn6lAPElPmvFTe0Y/wR0WImErUdA1PzlAaUavHylJ7uDiFwlZDQKm0elG4b7g=="], - "nitropack/cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], "nitropack/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + "nitropack/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "node-emoji/@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], @@ -3071,6 +3100,8 @@ "nuxt-og-image/execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="], + "nuxt-og-image/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "nypm/citty": ["citty@0.2.0", "", {}, "sha512-8csy5IBFI2ex2hTVpaHN2j+LNE199AgiI7y4dMintrr8i0lQiFn+0AWMZrWdHKIgMOer65f8IThysYhoReqjWA=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], diff --git a/package.json b/package.json index 4484843..7798ea3 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "eslint": "^9.39.2", "turbo": "^2.7.6", "typescript": "^5.9.3", + "ufo": "^1.6.3", "vitest": "^4.0.18", "vue-tsc": "^3.2.4" }, From d55f9675d34fc35fb4e17f48168bb6f4b3465d0d Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:15:35 +0100 Subject: [PATCH 03/26] docs: add note for early Nitro v3 support in installation guide --- apps/docs/content/1.getting-started/2.installation.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/docs/content/1.getting-started/2.installation.md b/apps/docs/content/1.getting-started/2.installation.md index 000910b..05d2dfa 100644 --- a/apps/docs/content/1.getting-started/2.installation.md +++ b/apps/docs/content/1.getting-started/2.installation.md @@ -61,6 +61,10 @@ export default defineNitroConfig({ }) ``` +::callout{icon="i-lucide-info" color="info"} +For early Nitro v3 support, use `evlog/nitrov3` instead of `evlog/nitro`. +:: + ## Standalone TypeScript For scripts, workers, CLI tools, or any TypeScript project: From e25ae9b5d739960bc1433fdb32227fa38452ebef Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:15:50 +0100 Subject: [PATCH 04/26] chore: initialize nitrov3 playground --- apps/nitro-playground/nitro.config.ts | 2 +- apps/nitrov3-playground/.gitignore | 8 + apps/nitrov3-playground/README.md | 18 +++ apps/nitrov3-playground/bun.lock | 171 ++++++++++++++++++++ apps/nitrov3-playground/index.html | 20 +++ apps/nitrov3-playground/nitro.config.ts | 7 + apps/nitrov3-playground/package.json | 16 ++ apps/nitrov3-playground/public/styles.css | 71 ++++++++ apps/nitrov3-playground/routes/api/index.ts | 10 ++ apps/nitrov3-playground/tsconfig.json | 8 + 10 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 apps/nitrov3-playground/.gitignore create mode 100644 apps/nitrov3-playground/README.md create mode 100644 apps/nitrov3-playground/bun.lock create mode 100644 apps/nitrov3-playground/index.html create mode 100644 apps/nitrov3-playground/nitro.config.ts create mode 100644 apps/nitrov3-playground/package.json create mode 100644 apps/nitrov3-playground/public/styles.css create mode 100644 apps/nitrov3-playground/routes/api/index.ts create mode 100644 apps/nitrov3-playground/tsconfig.json diff --git a/apps/nitro-playground/nitro.config.ts b/apps/nitro-playground/nitro.config.ts index 3ecb0e0..f6b052a 100644 --- a/apps/nitro-playground/nitro.config.ts +++ b/apps/nitro-playground/nitro.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from 'nitro' export default defineConfig({ serverDir: './', - // plugins: ['evlog/nitro'], TODO: update on v3 release + plugins: ['./node_modules/evlog/nitro'], }) diff --git a/apps/nitrov3-playground/.gitignore b/apps/nitrov3-playground/.gitignore new file mode 100644 index 0000000..d547d8a --- /dev/null +++ b/apps/nitrov3-playground/.gitignore @@ -0,0 +1,8 @@ +node_modules +dist +.data +.nitro +.cache +.output +.env +.env.local diff --git a/apps/nitrov3-playground/README.md b/apps/nitrov3-playground/README.md new file mode 100644 index 0000000..ce15a30 --- /dev/null +++ b/apps/nitrov3-playground/README.md @@ -0,0 +1,18 @@ +# Nitro starter + +Create your API and deploy it anywhere with this Nitro starter. + +## Getting started + +```bash +npm install +npm run dev +``` + +## Deploying + +```bash +npm run build +``` + +Then checkout the [Nitro documentation](https://v3.nitro.build/deploy) to learn more about the different deployment presets. diff --git a/apps/nitrov3-playground/bun.lock b/apps/nitrov3-playground/bun.lock new file mode 100644 index 0000000..a6c7fe5 --- /dev/null +++ b/apps/nitrov3-playground/bun.lock @@ -0,0 +1,171 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "devDependencies": { + "nitro": "latest", + "rolldown": "latest", + }, + }, + }, + "packages": { + "@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], + + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], + + "@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.110.0", "", { "os": "android", "cpu": "arm" }, "sha512-43fMTO8/5bMlqfOiNSZNKUzIqeLIYuB9Hr1Ohyf58B1wU11S2dPGibTXOGNaWsfgHy99eeZ1bSgeIHy/fEYqbw=="], + + "@oxc-minify/binding-android-arm64": ["@oxc-minify/binding-android-arm64@0.110.0", "", { "os": "android", "cpu": "arm64" }, "sha512-5oQrnn9eK/ccOp80PTrNj0Vq893NPNNRryjGpOIVsYNgWFuoGCfpnKg68oEFcN8bArizYAqw4nvgHljEnar69w=="], + + "@oxc-minify/binding-darwin-arm64": ["@oxc-minify/binding-darwin-arm64@0.110.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dqBDgTG9tF2z2lrZp9E8wU+Godz1i8gCGSei2eFKS2hRploBOD5dmOLp1j4IMornkPvSQmbwB3uSjPq7fjx4EA=="], + + "@oxc-minify/binding-darwin-x64": ["@oxc-minify/binding-darwin-x64@0.110.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U0AqabqaooDOpYmeeOye8wClv8PSScELXgOfYqyqgrwH9J9KrpCE1jL8Rlqgz68QbL4mPw3V6sKiiHssI4CLeQ=="], + + "@oxc-minify/binding-freebsd-x64": ["@oxc-minify/binding-freebsd-x64@0.110.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-H0w8o/Wo1072WSdLfhwwrpFpwZnPpjQODlHuRYkTfsSSSJbTxQtjJd4uxk7YJsRv5RQp69y0I7zvdH6f8Xueyw=="], + + "@oxc-minify/binding-linux-arm-gnueabihf": ["@oxc-minify/binding-linux-arm-gnueabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-qd6sW0AvEVYZhbVVMGtmKZw3b1zDYGIW+54Uh42moWRAj6i4Jhk/LGr6r9YNZpOINeuvZfkFuEeDD/jbu7xPUA=="], + + "@oxc-minify/binding-linux-arm-musleabihf": ["@oxc-minify/binding-linux-arm-musleabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7WXP0aXMrWSn0ScppUBi3jf68ebfBG0eri8kxLmBOVSBj6jw1repzkHMITJMBeLr5d0tT/51qFEptiAk2EP2iA=="], + + "@oxc-minify/binding-linux-arm64-gnu": ["@oxc-minify/binding-linux-arm64-gnu@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-LYfADrq5x1W5gs+u9OIbMbDQNYkAECTXX0ufnAuf3oGmO51rF98kGFR5qJqC/6/csokDyT3wwTpxhE0TkcF/Og=="], + + "@oxc-minify/binding-linux-arm64-musl": ["@oxc-minify/binding-linux-arm64-musl@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-53GjCVY8kvymk9P6qNDh6zyblcehF5QHstq9QgCjv13ONGRnSHjeds0PxIwiihD7h295bxsWs84DN39syLPH4Q=="], + + "@oxc-minify/binding-linux-ppc64-gnu": ["@oxc-minify/binding-linux-ppc64-gnu@0.110.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-li8XcN81dxbJDMBESnTgGhoiAQ+CNIdM0QGscZ4duVPjCry1RpX+5FJySFbGqG3pk4s9ZzlL/vtQtbRzZIZOzg=="], + + "@oxc-minify/binding-linux-riscv64-gnu": ["@oxc-minify/binding-linux-riscv64-gnu@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-SweKfsnLKShu6UFV8mwuj1d1wmlNoL/FlAxPUzwjEBgwiT2HQkY24KnjBH+TIA+//1O83kzmWKvvs4OuEhdIEQ=="], + + "@oxc-minify/binding-linux-riscv64-musl": ["@oxc-minify/binding-linux-riscv64-musl@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-oH8G4aFMP8XyTsEpdANC5PQyHgSeGlopHZuW1rpyYcaErg5YaK0vXjQ4EM5HVvPm+feBV24JjxgakTnZoF3aOQ=="], + + "@oxc-minify/binding-linux-s390x-gnu": ["@oxc-minify/binding-linux-s390x-gnu@0.110.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-W9na+Vza7XVUlpf8wMt4QBfH35KeTENEmnpPUq3NSlbQHz8lSlSvhAafvo43NcKvHAXV3ckD/mUf2VkqSdbklg=="], + + "@oxc-minify/binding-linux-x64-gnu": ["@oxc-minify/binding-linux-x64-gnu@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XJdA4mmmXOjJxSRgNJXsDP7Xe8h3gQhmb56hUcCrvq5d+h5UcEi2pR8rxsdIrS8QmkLuBA3eHkGK8E27D7DTgQ=="], + + "@oxc-minify/binding-linux-x64-musl": ["@oxc-minify/binding-linux-x64-musl@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QqzvALuOTtSckI8x467R4GNArzYDb/yEh6aNzLoeaY1O7vfT7SPDwlOEcchaTznutpeS9Dy8gUS/AfqtUHaufw=="], + + "@oxc-minify/binding-openharmony-arm64": ["@oxc-minify/binding-openharmony-arm64@0.110.0", "", { "os": "none", "cpu": "arm64" }, "sha512-gAMssLs2Q3+uhLZxanh1DF+27Kaug3cf4PXb9AB7XK81DR+LVcKySXaoGYoOs20Co0fFSphd6rRzKge2qDK3dA=="], + + "@oxc-minify/binding-wasm32-wasi": ["@oxc-minify/binding-wasm32-wasi@0.110.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-7Wqi5Zjl022bs2zXq+ICdalDPeDuCH/Nhbi8q2isLihAonMVIT0YH2hqqnNEylRNGYck+FJ6gRZwMpGCgrNxPg=="], + + "@oxc-minify/binding-win32-arm64-msvc": ["@oxc-minify/binding-win32-arm64-msvc@0.110.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZPx+0Tj4dqn41ecyoGotlvekQKy6JxJCixn9Rw7h/dafZ3eDuBcEVh3c2ZoldXXsyMIt5ywI8IWzFZsjNedd5Q=="], + + "@oxc-minify/binding-win32-ia32-msvc": ["@oxc-minify/binding-win32-ia32-msvc@0.110.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-H0Oyd3RWBfpEyvJIrFK94RYiY7KKSQl11Ym7LMDwLEagelIAfRCkt1amHZhFa/S3ZRoaOJFXzEw4YKeSsjVFsg=="], + + "@oxc-minify/binding-win32-x64-msvc": ["@oxc-minify/binding-win32-x64-msvc@0.110.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Hr3nK90+qXKJ2kepXwFIcNfQQIOBecB4FFCyaMMypthoEEhVP08heRynj4eSXZ8NL9hLjs3fQzH8PJXfpznRnQ=="], + + "@oxc-project/types": ["@oxc-project/types@0.110.0", "", {}, "sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow=="], + + "@oxc-transform/binding-android-arm-eabi": ["@oxc-transform/binding-android-arm-eabi@0.110.0", "", { "os": "android", "cpu": "arm" }, "sha512-sE9dxvqqAax1YYJ3t7j+h5ZSI9jl6dYuDfngl6ieZUrIy5P89/8JKVgAzgp8o3wQSo7ndpJvYsi1K4ZqrmbP7w=="], + + "@oxc-transform/binding-android-arm64": ["@oxc-transform/binding-android-arm64@0.110.0", "", { "os": "android", "cpu": "arm64" }, "sha512-nqtbP4aMCtsCZ6qpHlHaQoWVHSBtlKzwaAgwEOvR+9DWqHjk31BHvpGiDXlMeed6CVNpl3lCbWgygb3RcSjcfw=="], + + "@oxc-transform/binding-darwin-arm64": ["@oxc-transform/binding-darwin-arm64@0.110.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oeSeHnL4Z4cMXtc8V0/rwoVn0dgwlS9q0j6LcHn9dIhtFEdp3W0iSBF8YmMQA+E7sILeLDjsHmHE4Kp0sOScXw=="], + + "@oxc-transform/binding-darwin-x64": ["@oxc-transform/binding-darwin-x64@0.110.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-nL9K5x7OuZydobAGPylsEW9d4APs2qEkIBLMgQPA+kY8dtVD3IR87QsTbs4l4DBQYyun/+ay6qVCDlxqxdX2Jg=="], + + "@oxc-transform/binding-freebsd-x64": ["@oxc-transform/binding-freebsd-x64@0.110.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GS29zXXirDQhZEUq8xKJ1azAWMuUy3Ih3W5Bc5ddk12LRthO5wRLFcKIyeHpAXCoXymQ+LmxbMtbPf84GPxouw=="], + + "@oxc-transform/binding-linux-arm-gnueabihf": ["@oxc-transform/binding-linux-arm-gnueabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-glzDHak8ISyZJemCUi7RCvzNSl+MQ1ly9RceT2qRufhUsvNZ4C/2QLJ1HJwd2N6E88bO4laYn+RofdRzNnGGEA=="], + + "@oxc-transform/binding-linux-arm-musleabihf": ["@oxc-transform/binding-linux-arm-musleabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-8JThvgJ2FRoTVfbp7e4wqeZqCZbtudM06SfZmNzND9kPNu/LVYygIR+72RWs+xm4bWkuYHg/islo/boNPtMT5Q=="], + + "@oxc-transform/binding-linux-arm64-gnu": ["@oxc-transform/binding-linux-arm64-gnu@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IRh21Ub/g4bkHoErZ0AUWMlWfoZaS0A6EaOVtbcY70RSYIMlrsbjiFwJCzM+b/1DD1rXbH5tsGcH7GweTbfRqg=="], + + "@oxc-transform/binding-linux-arm64-musl": ["@oxc-transform/binding-linux-arm64-musl@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-e5JN94/oy+wevk76q+LMr+2klTTcO60uXa+Wkq558Ms7mdF2TvkKFI++d/JeiuIwJLTi/BxQ4qdT5FWcsHM/ug=="], + + "@oxc-transform/binding-linux-ppc64-gnu": ["@oxc-transform/binding-linux-ppc64-gnu@0.110.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y3/Tnnz1GvDpmv8FXBIKtdZPsdZklOEPdrL6NHrN5i2u54BOkybFaDSptgWF53wOrJlTrcmAVSE6fRKK9XCM2Q=="], + + "@oxc-transform/binding-linux-riscv64-gnu": ["@oxc-transform/binding-linux-riscv64-gnu@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-Y0E35iA9/v9jlkNcP6tMJ+ZFOS0rLsWDqG6rU9z+X2R3fBFJBO9UARIK6ngx8upxk81y1TFR2CmBFhupfYdH6Q=="], + + "@oxc-transform/binding-linux-riscv64-musl": ["@oxc-transform/binding-linux-riscv64-musl@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-JOUSYFfHjBUs7xp2FHmZHb8eTYD/oEu0NklS6JgUauqnoXZHiTLPLVW2o2uVCqldnabYHcomuwI2iqVFYJNhTw=="], + + "@oxc-transform/binding-linux-s390x-gnu": ["@oxc-transform/binding-linux-s390x-gnu@0.110.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-7blgoXF9D3Ngzb7eun23pNrHJpoV/TtE6LObwlZ3Nmb4oZ6Z+yMvBVaoW68NarbmvNGfZ95zrOjgm6cVETLYBA=="], + + "@oxc-transform/binding-linux-x64-gnu": ["@oxc-transform/binding-linux-x64-gnu@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-YQ2joGWCVDZVEU2cD/r/w49hVjDm/Qu1BvC/7zs8LvprzdLS/HyMXGF2oA0puw0b+AqgYaz3bhwKB2xexHyITQ=="], + + "@oxc-transform/binding-linux-x64-musl": ["@oxc-transform/binding-linux-x64-musl@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-fkjr5qE632ULmNgvFXWDR/8668WxERz3tU7TQFp6JebPBneColitjSkdx6VKNVXEoMmQnOvBIGeP5tUNT384oA=="], + + "@oxc-transform/binding-openharmony-arm64": ["@oxc-transform/binding-openharmony-arm64@0.110.0", "", { "os": "none", "cpu": "arm64" }, "sha512-HWH9Zj+lMrdSTqFRCZsvDWMz7OnMjbdGsm3xURXWfRZpuaz0bVvyuZNDQXc4FyyhRDsemICaJbU1bgeIpUJDGw=="], + + "@oxc-transform/binding-wasm32-wasi": ["@oxc-transform/binding-wasm32-wasi@0.110.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ejdxHmYfIcHDPhZUe3WklViLt9mDEJE5BzcW7+R1vc5i/5JFA8D0l7NUSsHBJ7FB8Bu9gF+5iMDm6cXGAgaghw=="], + + "@oxc-transform/binding-win32-arm64-msvc": ["@oxc-transform/binding-win32-arm64-msvc@0.110.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-9VTwpXCZs7xkV+mKhQ62dVk7KLnLXtEUxNS2T4nLz3iMl1IJbA4h5oltK0JoobtiUAnbkV53QmMVGW8+Nh3bDQ=="], + + "@oxc-transform/binding-win32-ia32-msvc": ["@oxc-transform/binding-win32-ia32-msvc@0.110.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-5y0fzuNON7/F2hh2P94vANFaRPJ/3DI1hVl5rseCT8VUVqOGIjWaza0YS/D1g6t1WwycW2LWDMi2raOKoWU5GQ=="], + + "@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.110.0", "", { "os": "win32", "cpu": "x64" }, "sha512-QROrowwlrApI1fEScMknGWKM6GTM/Z2xwMnDqvSaEmzNazBsDUlE08Jasw610hFEsYAVU2K5sp/YaCa9ORdP4A=="], + + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.1", "", { "os": "android", "cpu": "arm64" }, "sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm" }, "sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.1", "", { "os": "linux", "cpu": "x64" }, "sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.1", "", { "os": "linux", "cpu": "x64" }, "sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.1", "", { "os": "none", "cpu": "arm64" }, "sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.1", "", {}, "sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA=="], + + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + + "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], + + "crossws": ["crossws@0.4.3", "", { "peerDependencies": { "srvx": ">=0.7.1" }, "optionalPeers": ["srvx"] }, "sha512-lmf5mtwHiToP3HumOx53cqS0T5TK8GMBpsbSCXRB5OuszbltTgGOO4B1WhrDYqTeXOk3BAemibNjJx8E0/ecNw=="], + + "db0": ["db0@0.3.4", "", { "peerDependencies": { "@electric-sql/pglite": "*", "@libsql/client": "*", "better-sqlite3": "*", "drizzle-orm": "*", "mysql2": "*", "sqlite3": "*" }, "optionalPeers": ["@electric-sql/pglite", "@libsql/client", "better-sqlite3", "drizzle-orm", "mysql2", "sqlite3"] }, "sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw=="], + + "h3": ["h3@2.0.1-rc.11", "", { "dependencies": { "rou3": "^0.7.12", "srvx": "^0.10.1" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"] }, "sha512-2myzjCqy32c1As9TjZW9fNZXtLqNedjFSrdFy2AjFBQQ3LzrnGoDdFDYfC0tV2e4vcyfJ2Sfo/F6NQhO2Ly/Mw=="], + + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "nf3": ["nf3@0.3.6", "", {}, "sha512-/XRUUILTAyuy1XunyVQuqGp8aEmZ2TfRTn8Rji+FA4xqv20qzL4jV7Reqbuey2XucKgPeRVcEYGScmJM0UnB6Q=="], + + "nitro": ["nitro@3.0.1-alpha.2", "", { "dependencies": { "consola": "^3.4.2", "crossws": "^0.4.3", "db0": "^0.3.4", "h3": "^2.0.1-rc.11", "jiti": "^2.6.1", "nf3": "^0.3.5", "ofetch": "^2.0.0-alpha.3", "ohash": "^2.0.11", "oxc-minify": "^0.110.0", "oxc-transform": "^0.110.0", "srvx": "^0.10.1", "undici": "^7.18.2", "unenv": "^2.0.0-rc.24", "unstorage": "^2.0.0-alpha.5" }, "peerDependencies": { "rolldown": ">=1.0.0-beta.0", "rollup": "^4", "vite": "^7 || ^8 || >=8.0.0-0", "xml2js": "^0.6.2" }, "optionalPeers": ["rolldown", "rollup", "vite", "xml2js"], "bin": { "nitro": "dist/cli/index.mjs" } }, "sha512-YviDY5J/trS821qQ1fpJtpXWIdPYiOizC/meHavlm1Hfuhx//H+Egd1+4C5SegJRgtWMnRPW9n//6Woaw81cTQ=="], + + "ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="], + + "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], + + "oxc-minify": ["oxc-minify@0.110.0", "", { "optionalDependencies": { "@oxc-minify/binding-android-arm-eabi": "0.110.0", "@oxc-minify/binding-android-arm64": "0.110.0", "@oxc-minify/binding-darwin-arm64": "0.110.0", "@oxc-minify/binding-darwin-x64": "0.110.0", "@oxc-minify/binding-freebsd-x64": "0.110.0", "@oxc-minify/binding-linux-arm-gnueabihf": "0.110.0", "@oxc-minify/binding-linux-arm-musleabihf": "0.110.0", "@oxc-minify/binding-linux-arm64-gnu": "0.110.0", "@oxc-minify/binding-linux-arm64-musl": "0.110.0", "@oxc-minify/binding-linux-ppc64-gnu": "0.110.0", "@oxc-minify/binding-linux-riscv64-gnu": "0.110.0", "@oxc-minify/binding-linux-riscv64-musl": "0.110.0", "@oxc-minify/binding-linux-s390x-gnu": "0.110.0", "@oxc-minify/binding-linux-x64-gnu": "0.110.0", "@oxc-minify/binding-linux-x64-musl": "0.110.0", "@oxc-minify/binding-openharmony-arm64": "0.110.0", "@oxc-minify/binding-wasm32-wasi": "0.110.0", "@oxc-minify/binding-win32-arm64-msvc": "0.110.0", "@oxc-minify/binding-win32-ia32-msvc": "0.110.0", "@oxc-minify/binding-win32-x64-msvc": "0.110.0" } }, "sha512-KWGTzPo83QmGrXC4ml83PM9HDwUPtZFfasiclUvTV4i3/0j7xRRqINVkrL77CbQnoWura3CMxkRofjQKVDuhBw=="], + + "oxc-transform": ["oxc-transform@0.110.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm-eabi": "0.110.0", "@oxc-transform/binding-android-arm64": "0.110.0", "@oxc-transform/binding-darwin-arm64": "0.110.0", "@oxc-transform/binding-darwin-x64": "0.110.0", "@oxc-transform/binding-freebsd-x64": "0.110.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.110.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.110.0", "@oxc-transform/binding-linux-arm64-gnu": "0.110.0", "@oxc-transform/binding-linux-arm64-musl": "0.110.0", "@oxc-transform/binding-linux-ppc64-gnu": "0.110.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.110.0", "@oxc-transform/binding-linux-riscv64-musl": "0.110.0", "@oxc-transform/binding-linux-s390x-gnu": "0.110.0", "@oxc-transform/binding-linux-x64-gnu": "0.110.0", "@oxc-transform/binding-linux-x64-musl": "0.110.0", "@oxc-transform/binding-openharmony-arm64": "0.110.0", "@oxc-transform/binding-wasm32-wasi": "0.110.0", "@oxc-transform/binding-win32-arm64-msvc": "0.110.0", "@oxc-transform/binding-win32-ia32-msvc": "0.110.0", "@oxc-transform/binding-win32-x64-msvc": "0.110.0" } }, "sha512-/fymQNzzUoKZweH0nC5yvbI2eR0yWYusT9TEKDYVgOgYrf9Qmdez9lUFyvxKR9ycx+PTHi/reIOzqf3wkShQsw=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "rolldown": ["rolldown@1.0.0-rc.1", "", { "dependencies": { "@oxc-project/types": "=0.110.0", "@rolldown/pluginutils": "1.0.0-rc.1" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.1", "@rolldown/binding-darwin-arm64": "1.0.0-rc.1", "@rolldown/binding-darwin-x64": "1.0.0-rc.1", "@rolldown/binding-freebsd-x64": "1.0.0-rc.1", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.1", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.1", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.1", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.1", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.1", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.1", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.1", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.1", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.1" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg=="], + + "rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="], + + "srvx": ["srvx@0.10.1", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-A//xtfak4eESMWWydSRFUVvCTQbSwivnGCEf8YGPe2eHU0+Z6znfUTCPF0a7oV3sObSOcrXHlL6Bs9vVctfXdg=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "undici": ["undici@7.19.1", "", {}, "sha512-Gpq0iNm5M6cQWlyHQv9MV+uOj1jWk7LpkoE5vSp/7zjb4zMdAcUD+VL5y0nH4p9EbUklq00eVIIX/XcDHzu5xg=="], + + "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], + + "unstorage": ["unstorage@2.0.0-alpha.5", "", { "peerDependencies": { "@azure/app-configuration": "^1.9.0", "@azure/cosmos": "^4.7.0", "@azure/data-tables": "^13.3.1", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.29.1", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.12.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.35.6", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.8.2", "lru-cache": "^11.2.2", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-Sj8btci21Twnd6M+N+MHhjg3fVn6lAPElPmvFTe0Y/wR0WImErUdA1PzlAaUavHylJ7uDiFwlZDQKm0elG4b7g=="], + } +} diff --git a/apps/nitrov3-playground/index.html b/apps/nitrov3-playground/index.html new file mode 100644 index 0000000..9867eea --- /dev/null +++ b/apps/nitrov3-playground/index.html @@ -0,0 +1,20 @@ + + + + + + Nitro Starter + + + + + + +
+

This is your brand new Nitro project 🚀

+

Get started by editing the index.html and routes/api/index.ts files.

+

Learn more from 📖 Nitro Documentation

+
{{{ serverFetch("/api") }}}
+
+ + diff --git a/apps/nitrov3-playground/nitro.config.ts b/apps/nitrov3-playground/nitro.config.ts new file mode 100644 index 0000000..5fff5b9 --- /dev/null +++ b/apps/nitrov3-playground/nitro.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'nitro' + +export default defineConfig({ + serverDir: './', + // TODO: make playground work with evlog/nitrov3 + plugins: ['../../packages/evlog/src/nitrov3/plugin.ts'] +}) diff --git a/apps/nitrov3-playground/package.json b/apps/nitrov3-playground/package.json new file mode 100644 index 0000000..44993e4 --- /dev/null +++ b/apps/nitrov3-playground/package.json @@ -0,0 +1,16 @@ +{ + "name": "nitrov3-playground", + "type": "module", + "scripts": { + "build": "nitro build", + "dev": "nitro dev", + "preview": "npx srvx --prod .output/" + }, + "dependencies": { + "evlog": "workspace:*" + }, + "devDependencies": { + "nitro": "latest", + "rolldown": "latest" + } +} diff --git a/apps/nitrov3-playground/public/styles.css b/apps/nitrov3-playground/public/styles.css new file mode 100644 index 0000000..dabf6e8 --- /dev/null +++ b/apps/nitrov3-playground/public/styles.css @@ -0,0 +1,71 @@ +:root { + --bg: #f7fafc; + --card: #fff; + --muted: #6b7280; + --accent: #0ea5a4; + --code-bg: #0f172a; + --code-color: #e6eef8; + --radius: 12px; +} + +html, +body { + height: 100% +} + +body { + margin: 0; + font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; + background: var(--bg); + color: #0f172a; + display: flex; + align-items: center; + justify-content: center; + padding: 48px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.card { + background: var(--card); + padding: 28px; + border-radius: var(--radius); + max-width: 760px; + width: 100%; + box-shadow: 0 6px 20px rgba(2, 6, 23, 0.08); + border: 1px solid rgba(15, 23, 42, 0.04); +} + +h1 { + margin: 0 0 6px 0; + font-weight: 600; + font-size: 1.375rem; + color: #0f172a; +} + +p { + margin: 6px 0; + color: var(--muted) +} + +a { + color: var(--accent); + text-decoration: none +} + +code, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, "Roboto Mono", "Helvetica Neue", monospace; + font-size: 0.9rem; +} + +pre.api { + margin-top: 16px; + background: var(--code-bg); + color: var(--code-color); + padding: 12px 16px; + border-radius: 8px; + overflow: auto; + white-space: pre-wrap; + word-break: break-word; +} diff --git a/apps/nitrov3-playground/routes/api/index.ts b/apps/nitrov3-playground/routes/api/index.ts new file mode 100644 index 0000000..5efc982 --- /dev/null +++ b/apps/nitrov3-playground/routes/api/index.ts @@ -0,0 +1,10 @@ +import { useLogger } from 'evlog' +import { defineHandler } from 'nitro/h3' + +export default defineHandler((event) => { + const log = useLogger(event) + log.set({ + nitrov3: 'playground', + }) + return { message: 'Hello from API!' } +}) diff --git a/apps/nitrov3-playground/tsconfig.json b/apps/nitrov3-playground/tsconfig.json new file mode 100644 index 0000000..1099389 --- /dev/null +++ b/apps/nitrov3-playground/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": ["nitro/tsconfig"], + "compilerOptions": { + "paths": { + "~/*": ["./*"] + } + } +} From e6e9445e7a09a96baede73f5643142faa199bfb0 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:21:10 +0100 Subject: [PATCH 05/26] revert: nitro 2 playground --- apps/nitro-playground/nitro.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/nitro-playground/nitro.config.ts b/apps/nitro-playground/nitro.config.ts index f6b052a..3ecb0e0 100644 --- a/apps/nitro-playground/nitro.config.ts +++ b/apps/nitro-playground/nitro.config.ts @@ -2,5 +2,5 @@ import { defineConfig } from 'nitro' export default defineConfig({ serverDir: './', - plugins: ['./node_modules/evlog/nitro'], + // plugins: ['evlog/nitro'], TODO: update on v3 release }) From 9d005f02eae9ff5a5fcec0b4e78550d04f100af1 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:23:38 +0100 Subject: [PATCH 06/26] chore: add nitrov3 output to package.json --- packages/evlog/package.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/evlog/package.json b/packages/evlog/package.json index 18a9794..3efd56d 100644 --- a/packages/evlog/package.json +++ b/packages/evlog/package.json @@ -34,6 +34,10 @@ "./nitro": { "types": "./dist/nitro/plugin.d.mts", "import": "./dist/nitro/plugin.mjs" + }, + "./nitrov3": { + "types": "./dist/nitro3/plugin.d.mts", + "import": "./dist/nitro3/plugin.mjs" } }, "main": "./dist/index.mjs", @@ -48,6 +52,9 @@ ], "nitro": [ "./dist/nitro/plugin.d.mts" + ], + "nitrov3": [ + "./dist/nitro3/plugin.d.mts" ] } }, From 0b1592a504137f2ecb4e90459a80a811bd8f54e6 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 11:25:05 +0100 Subject: [PATCH 07/26] docs: add note for early Nitro v3 support in README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b0af0c9..91b4d11 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,8 @@ export default defineNitroConfig({ }) ``` +> **Note**: For early Nitro v3 support, use `evlog/nitrov3` instead of `evlog/nitro`. + Same API, same wide events: ```typescript From 6e7727d7637e112ca91b34da97f77bf9739e4afb Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 13:32:41 +0100 Subject: [PATCH 08/26] chore: better nitro v3 playground --- apps/nitrov3-playground/index.html | 103 +++++++- apps/nitrov3-playground/public/styles.css | 244 +++++++++++++++--- apps/nitrov3-playground/routes/api/index.ts | 13 +- .../routes/api/test/create.post.ts | 29 +++ .../routes/api/test/delete.delete.ts | 28 ++ .../routes/api/test/success.get.ts | 24 ++ .../routes/api/test/update.put.ts | 26 ++ .../routes/api/test/wide-event.get.ts | 72 ++++++ 8 files changed, 501 insertions(+), 38 deletions(-) create mode 100644 apps/nitrov3-playground/routes/api/test/create.post.ts create mode 100644 apps/nitrov3-playground/routes/api/test/delete.delete.ts create mode 100644 apps/nitrov3-playground/routes/api/test/success.get.ts create mode 100644 apps/nitrov3-playground/routes/api/test/update.put.ts create mode 100644 apps/nitrov3-playground/routes/api/test/wide-event.get.ts diff --git a/apps/nitrov3-playground/index.html b/apps/nitrov3-playground/index.html index 9867eea..5485925 100644 --- a/apps/nitrov3-playground/index.html +++ b/apps/nitrov3-playground/index.html @@ -3,7 +3,7 @@ - Nitro Starter + evlog Nitro v3 Playground @@ -11,10 +11,103 @@
-

This is your brand new Nitro project 🚀

-

Get started by editing the index.html and routes/api/index.ts files.

-

Learn more from 📖 Nitro Documentation

-
{{{ serverFetch("/api") }}}
+

evlog Nitro v3 Playground 🚀

+

Test the evlog integration with different HTTP methods. Check your terminal for wide event logs!

+
+
+

Test API Endpoints

+ +
+ + +
+ +
+ + + + +
+ +
+ +
+ +
+
+
+ + diff --git a/apps/nitrov3-playground/public/styles.css b/apps/nitrov3-playground/public/styles.css index dabf6e8..61fb186 100644 --- a/apps/nitrov3-playground/public/styles.css +++ b/apps/nitrov3-playground/public/styles.css @@ -1,71 +1,253 @@ :root { - --bg: #f7fafc; - --card: #fff; - --muted: #6b7280; - --accent: #0ea5a4; - --code-bg: #0f172a; - --code-color: #e6eef8; - --radius: 12px; + --bg: #020202; + --card: #0a0a0a; + --text: #fafafa; + --muted: #94a3b8; + --border: #27272a; + --primary: #2853FF; + --primary-hover: #3d65ff; + --success: #0ea5a4; + --warning: #f59e0b; + --danger: #ef4444; + --purple: #8b5cf6; + --code-bg: #000000; + --code-text: #e6eef8; + --radius: 8px; + --section-bg: #0f0f0f; +} + +* { + box-sizing: border-box; } html, body { - height: 100% + height: 100%; + overflow: hidden; + margin: 0; + padding: 0; } body { - margin: 0; - font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif; background: var(--bg); - color: #0f172a; + color: var(--text); display: flex; align-items: center; justify-content: center; - padding: 48px; + padding: 24px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + line-height: 1.5; } .card { background: var(--card); - padding: 28px; - border-radius: var(--radius); - max-width: 760px; + padding: 48px; + border-radius: 12px; + max-width: 920px; width: 100%; - box-shadow: 0 6px 20px rgba(2, 6, 23, 0.08); - border: 1px solid rgba(15, 23, 42, 0.04); + max-height: calc(100vh - 48px); + overflow-y: auto; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 20px 40px rgba(0, 0, 0, 0.5); + border: 1px solid var(--border); } h1 { - margin: 0 0 6px 0; - font-weight: 600; - font-size: 1.375rem; - color: #0f172a; + margin: 0 0 8px 0; + font-weight: 700; + font-size: 2rem; + color: var(--text); + letter-spacing: -0.02em; + line-height: 1.2; } p { - margin: 6px 0; - color: var(--muted) + margin: 0 0 24px 0; + color: var(--muted); + font-size: 1rem; } a { - color: var(--accent); - text-decoration: none + color: var(--primary); + text-decoration: none; + font-weight: 500; +} + +a:hover { + text-decoration: underline; } code, pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, "Roboto Mono", "Helvetica Neue", monospace; - font-size: 0.9rem; + font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; + font-size: 0.875rem; } pre.api { - margin-top: 16px; + margin-top: 24px; background: var(--code-bg); - color: var(--code-color); - padding: 12px 16px; - border-radius: 8px; + color: var(--code-text); + padding: 16px 20px; + border-radius: var(--radius); overflow: auto; white-space: pre-wrap; word-break: break-word; + font-size: 0.8125rem; + line-height: 1.6; +} + +.demo-section { + margin-top: 40px; + padding: 32px; + background: var(--section-bg); + border-radius: var(--radius); + border: 1px solid var(--border); +} + +.demo-section h2 { + margin: 0 0 24px 0; + font-size: 1.25rem; + font-weight: 700; + color: var(--text); + letter-spacing: -0.01em; +} + +.buttons { + display: flex; + gap: 12px; + margin-bottom: 16px; + flex-wrap: wrap; +} + +button { + padding: 12px 24px; + border: none; + border-radius: 6px; + font-family: inherit; + font-size: 0.9375rem; + font-weight: 600; + cursor: pointer; + transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1); + flex: 1; + min-width: fit-content; +} + +button:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); +} + +button:active { + transform: translateY(0); +} + +.btn-get { + background: var(--success); + color: white; +} + +.btn-get:hover { + background: #0d9488; +} + +.btn-post { + background: var(--purple); + color: white; +} + +.btn-post:hover { + background: #7c3aed; +} + +.btn-delete { + background: var(--danger); + color: white; +} + +.btn-delete:hover { + background: #dc2626; +} + +.btn-wide { + background: var(--primary); + color: white; + flex: 1 1 100%; +} + +.btn-wide:hover { + background: var(--primary-hover); +} + +#result { + margin-top: 20px; + padding: 20px 24px; + background: var(--code-bg); + color: var(--code-text); + border-radius: var(--radius); + font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; + font-size: 0.8125rem; + line-height: 1.7; + white-space: pre-wrap; + word-break: break-word; + min-height: 80px; + display: none; + border: 1px solid #18181b; +} + +#result.show { + display: block; + animation: fadeIn 0.2s ease-in; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(4px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.input-group { + margin-bottom: 24px; +} + +.input-group label { + display: block; + margin-bottom: 8px; + font-size: 0.875rem; + font-weight: 600; + color: var(--text); +} + +.input-group input { + width: 100%; + padding: 12px 16px; + border: 1px solid var(--border); + border-radius: 6px; + font-family: inherit; + font-size: 0.9375rem; + background: var(--code-bg); + color: var(--text); + transition: border-color 0.15s, box-shadow 0.15s; +} + +.input-group input:focus { + outline: none; + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(40, 83, 255, 0.1); +} + +.input-group input::placeholder { + color: #94a3b8; +} + +/* Subtle separator */ +.separator { + height: 1px; + background: linear-gradient(to right, transparent, var(--border), transparent); + margin: 32px 0; } diff --git a/apps/nitrov3-playground/routes/api/index.ts b/apps/nitrov3-playground/routes/api/index.ts index 5efc982..e1397f4 100644 --- a/apps/nitrov3-playground/routes/api/index.ts +++ b/apps/nitrov3-playground/routes/api/index.ts @@ -4,7 +4,16 @@ import { defineHandler } from 'nitro/h3' export default defineHandler((event) => { const log = useLogger(event) log.set({ - nitrov3: 'playground', + playground: 'nitrov3', }) - return { message: 'Hello from API!' } + return { + message: 'evlog Nitro v3 Playground', + endpoints: [ + 'GET /api/test/success', + 'POST /api/test/create', + 'PUT /api/test/update (always fails)', + 'DELETE /api/test/delete', + 'GET /api/test/wide-event', + ], + } }) diff --git a/apps/nitrov3-playground/routes/api/test/create.post.ts b/apps/nitrov3-playground/routes/api/test/create.post.ts new file mode 100644 index 0000000..bc3e5c2 --- /dev/null +++ b/apps/nitrov3-playground/routes/api/test/create.post.ts @@ -0,0 +1,29 @@ +import { defineHandler, readBody } from 'nitro/h3' +import { useLogger } from 'evlog' + +export default defineHandler(async (event) => { + const log = useLogger(event) + const body = await readBody(event) as { name: string; type: string } + + log.set({ user: { id: 456 } }) + log.set({ item: { name: body.name, type: body.type } }) + + // Simulate validation + await new Promise(resolve => setTimeout(resolve, 100)) + log.set({ validation: { passed: true, checks: ['name_length', 'type_valid'] } }) + + // Simulate database insert + await new Promise(resolve => setTimeout(resolve, 200)) + const itemId = `item_${Math.random().toString(36).substring(2, 8)}` + log.set({ database: { operation: 'insert', duration: '200ms' } }) + + // Simulate search indexing + await new Promise(resolve => setTimeout(resolve, 80)) + log.set({ search: { indexed: true, engine: 'elasticsearch' } }) + + return { + success: true, + message: 'Item created', + id: itemId, + } +}) diff --git a/apps/nitrov3-playground/routes/api/test/delete.delete.ts b/apps/nitrov3-playground/routes/api/test/delete.delete.ts new file mode 100644 index 0000000..350f187 --- /dev/null +++ b/apps/nitrov3-playground/routes/api/test/delete.delete.ts @@ -0,0 +1,28 @@ +import { defineHandler } from 'nitro/h3' +import { useLogger } from 'evlog' + +export default defineHandler(async (event) => { + const log = useLogger(event) + const itemId = 'item_123' + + log.set({ user: { id: 789 } }) + log.set({ action: 'delete_item', itemId }) + + // Simulate permission check + await new Promise(resolve => setTimeout(resolve, 100)) + log.set({ permissions: { checked: true, hasDelete: true } }) + + // Simulate database delete + await new Promise(resolve => setTimeout(resolve, 150)) + log.set({ database: { operation: 'delete', affected: 1 } }) + + // Simulate cache invalidation + await new Promise(resolve => setTimeout(resolve, 50)) + log.set({ cache: { invalidated: true, keys: [`item:${itemId}`] } }) + + return { + success: true, + message: 'Item deleted', + deletedId: itemId, + } +}) diff --git a/apps/nitrov3-playground/routes/api/test/success.get.ts b/apps/nitrov3-playground/routes/api/test/success.get.ts new file mode 100644 index 0000000..e5ffdcf --- /dev/null +++ b/apps/nitrov3-playground/routes/api/test/success.get.ts @@ -0,0 +1,24 @@ +import { defineHandler } from 'nitro/h3' +import { useLogger } from 'evlog' + +export default defineHandler(async (event) => { + const log = useLogger(event) + + log.set({ user: { id: 123, plan: 'pro' } }) + log.set({ action: 'fetch_profile' }) + + // Simulate database query + await new Promise(resolve => setTimeout(resolve, 150)) + const profile = { name: 'John Doe', email: 'john@example.com', lastLogin: new Date().toISOString() } + log.set({ profile }) + + // Simulate cache check + await new Promise(resolve => setTimeout(resolve, 50)) + log.set({ cache: { hit: true, ttl: 3600 } }) + + return { + success: true, + message: 'Profile fetched successfully', + data: profile, + } +}) diff --git a/apps/nitrov3-playground/routes/api/test/update.put.ts b/apps/nitrov3-playground/routes/api/test/update.put.ts new file mode 100644 index 0000000..c40f5f3 --- /dev/null +++ b/apps/nitrov3-playground/routes/api/test/update.put.ts @@ -0,0 +1,26 @@ +import { defineHandler, readBody } from 'nitro/h3' +import { useLogger, createError } from 'evlog' + +export default defineHandler(async (event) => { + const log = useLogger(event) + const body = await readBody(event) as { name: string; version: string } + + log.set({ user: { id: 999 } }) + log.set({ action: 'update_item', item: { name: body.name, version: body.version } }) + + // Simulate validation check + await new Promise(resolve => setTimeout(resolve, 100)) + log.set({ validation: { checked: true } }) + + // Simulate permission check that always fails + await new Promise(resolve => setTimeout(resolve, 150)) + log.set({ permissions: { checked: true, hasUpdate: false, requiredRole: 'admin' } }) + + throw createError({ + message: 'Update failed', + status: 403, + why: 'Insufficient permissions to update this resource', + fix: 'Request admin privileges or contact your team lead', + link: 'https://docs.example.com/permissions', + }) +}) diff --git a/apps/nitrov3-playground/routes/api/test/wide-event.get.ts b/apps/nitrov3-playground/routes/api/test/wide-event.get.ts new file mode 100644 index 0000000..b5acf65 --- /dev/null +++ b/apps/nitrov3-playground/routes/api/test/wide-event.get.ts @@ -0,0 +1,72 @@ +import { defineHandler } from 'nitro/h3' +import { useLogger } from 'evlog' + +export default defineHandler(async (event) => { + const log = useLogger(event) + + // User context + await new Promise(resolve => setTimeout(resolve, 80)) + log.set({ + user: { + id: 'user_789', + email: 'demo@example.com', + plan: 'enterprise', + accountAge: '2 years', + role: 'admin', + }, + session: { + device: 'desktop', + browser: 'Chrome 120', + country: 'US', + }, + }) + + // Cart information + await new Promise(resolve => setTimeout(resolve, 80)) + log.set({ + cart: { + items: 5, + total: 24999, + currency: 'USD', + discount: { + code: 'WINTER25', + savings: 8333, + }, + }, + }) + + // Payment processing + await new Promise(resolve => setTimeout(resolve, 80)) + log.set({ + payment: { + method: 'card', + cardBrand: 'visa', + cardLast4: '4242', + }, + fraud: { + score: 12, + riskLevel: 'low', + passed: true, + }, + }) + + // Performance metrics + await new Promise(resolve => setTimeout(resolve, 80)) + log.set({ + performance: { + dbQueries: 8, + cacheHits: 12, + cacheMisses: 2, + }, + flags: { + newCheckoutFlow: true, + experimentId: 'exp_checkout_v2', + }, + }) + + return { + success: true, + message: 'Wide event demo - check your terminal!', + orderId: 'ord_abc123xyz', + } +}) From ef07be70dd6a8ab3c4822b1bb4132f7595dcc91a Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 13:33:44 +0100 Subject: [PATCH 09/26] chore: expose nitro v3 at `nitro/v3` --- bun.lock | 2 +- package.json | 1 - packages/evlog/build.config.ts | 2 +- packages/evlog/package.json | 15 ++++++++------- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bun.lock b/bun.lock index 57b3c20..fb6b4e0 100644 --- a/bun.lock +++ b/bun.lock @@ -11,7 +11,6 @@ "eslint": "^9.39.2", "turbo": "^2.7.6", "typescript": "^5.9.3", - "ufo": "^1.6.3", "vitest": "^4.0.18", "vue-tsc": "^3.2.4", }, @@ -75,6 +74,7 @@ "nitropack": "^2.13.1", "nuxt": "^4.3.0", "typescript": "^5.9.3", + "ufo": "^1.6.3", "unbuild": "^3.6.1", }, "peerDependencies": { diff --git a/package.json b/package.json index 7798ea3..4484843 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "eslint": "^9.39.2", "turbo": "^2.7.6", "typescript": "^5.9.3", - "ufo": "^1.6.3", "vitest": "^4.0.18", "vue-tsc": "^3.2.4" }, diff --git a/packages/evlog/build.config.ts b/packages/evlog/build.config.ts index daf5889..9cc1c8e 100644 --- a/packages/evlog/build.config.ts +++ b/packages/evlog/build.config.ts @@ -5,7 +5,7 @@ export default defineBuildConfig({ { input: 'src/index', name: 'index' }, { input: 'src/nuxt/module', name: 'nuxt/module' }, { input: 'src/nitro/plugin', name: 'nitro/plugin' }, - { input: 'src/nitrov3/plugin', name: 'nitrov3/plugin' }, + { input: 'src/nitrov3/plugin', name: 'nitro/v3/plugin' }, { input: 'src/runtime/client/log', name: 'runtime/client/log' }, { input: 'src/runtime/client/plugin', name: 'runtime/client/plugin' }, { input: 'src/runtime/server/useLogger', name: 'runtime/server/useLogger' }, diff --git a/packages/evlog/package.json b/packages/evlog/package.json index 3efd56d..6bc94bc 100644 --- a/packages/evlog/package.json +++ b/packages/evlog/package.json @@ -35,9 +35,9 @@ "types": "./dist/nitro/plugin.d.mts", "import": "./dist/nitro/plugin.mjs" }, - "./nitrov3": { - "types": "./dist/nitro3/plugin.d.mts", - "import": "./dist/nitro3/plugin.mjs" + "./nitro/v3": { + "types": "./dist/nitro/v3/plugin.d.mts", + "import": "./dist/nitro/v3/plugin.mjs" } }, "main": "./dist/index.mjs", @@ -53,8 +53,8 @@ "nitro": [ "./dist/nitro/plugin.d.mts" ], - "nitrov3": [ - "./dist/nitro3/plugin.d.mts" + "nitro/v3": [ + "./dist/nitro/v3/plugin.d.mts" ] } }, @@ -86,7 +86,8 @@ "nuxt": "^4.3.0", "typescript": "^5.9.3", "unbuild": "^3.6.1", - "nitro": "^3.0.1-alpha.2" + "nitro": "^3.0.1-alpha.2", + "ufo": "^1.6.3" }, "peerDependencies": { "h3": "^1.15.5", @@ -108,4 +109,4 @@ "optional": true } } -} +} \ No newline at end of file From 6171d49731e5bd8c075ac4c97cda812c8a78eacb Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 27 Jan 2026 13:34:55 +0100 Subject: [PATCH 10/26] chore: update Nitro v3 references to use `evlog/nitro/v3` --- README.md | 2 +- apps/docs/content/1.getting-started/2.installation.md | 2 +- apps/nitrov3-playground/nitro.config.ts | 2 +- apps/nitrov3-playground/routes/api/index.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 91b4d11..3a29ff4 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ export default defineNitroConfig({ }) ``` -> **Note**: For early Nitro v3 support, use `evlog/nitrov3` instead of `evlog/nitro`. +> **Note**: For early Nitro v3 support, use `evlog/nitro/v3` instead of `evlog/nitro`. Same API, same wide events: diff --git a/apps/docs/content/1.getting-started/2.installation.md b/apps/docs/content/1.getting-started/2.installation.md index 05d2dfa..1186432 100644 --- a/apps/docs/content/1.getting-started/2.installation.md +++ b/apps/docs/content/1.getting-started/2.installation.md @@ -62,7 +62,7 @@ export default defineNitroConfig({ ``` ::callout{icon="i-lucide-info" color="info"} -For early Nitro v3 support, use `evlog/nitrov3` instead of `evlog/nitro`. +For early Nitro v3 support, use `evlog/nitro/v3` instead of `evlog/nitro`. :: ## Standalone TypeScript diff --git a/apps/nitrov3-playground/nitro.config.ts b/apps/nitrov3-playground/nitro.config.ts index 5fff5b9..0cc39f7 100644 --- a/apps/nitrov3-playground/nitro.config.ts +++ b/apps/nitrov3-playground/nitro.config.ts @@ -2,6 +2,6 @@ import { defineConfig } from 'nitro' export default defineConfig({ serverDir: './', - // TODO: make playground work with evlog/nitrov3 + // TODO: make playground work with evlog/nitro/v3 plugins: ['../../packages/evlog/src/nitrov3/plugin.ts'] }) diff --git a/apps/nitrov3-playground/routes/api/index.ts b/apps/nitrov3-playground/routes/api/index.ts index e1397f4..4c37660 100644 --- a/apps/nitrov3-playground/routes/api/index.ts +++ b/apps/nitrov3-playground/routes/api/index.ts @@ -4,7 +4,7 @@ import { defineHandler } from 'nitro/h3' export default defineHandler((event) => { const log = useLogger(event) log.set({ - playground: 'nitrov3', + playground: 'nitro/v3', }) return { message: 'evlog Nitro v3 Playground', From 0994c100ebcc871cedfbea4bb34b7fd34506c47f Mon Sep 17 00:00:00 2001 From: Hugo Richard Date: Tue, 27 Jan 2026 18:47:10 +0000 Subject: [PATCH 11/26] up --- .../.gitignore | 0 .../README.md | 0 .../bun.lock | 0 .../index.html | 0 .../nitro.config.ts | 2 +- .../package.json | 2 +- .../public/styles.css | 0 .../routes/api/index.ts | 0 .../routes/api/test/create.post.ts | 0 .../routes/api/test/delete.delete.ts | 0 .../routes/api/test/success.get.ts | 0 .../routes/api/test/update.put.ts | 0 .../routes/api/test/wide-event.get.ts | 0 .../tsconfig.json | 0 bun.lock | 11 +++++------ package.json | 1 + packages/evlog/build.config.ts | 2 +- packages/evlog/package.json | 6 +++--- packages/evlog/src/{nitrov3 => nitro-v3}/plugin.ts | 0 19 files changed, 12 insertions(+), 12 deletions(-) rename apps/{nitrov3-playground => nitro-v3-playground}/.gitignore (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/README.md (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/bun.lock (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/index.html (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/nitro.config.ts (70%) rename apps/{nitrov3-playground => nitro-v3-playground}/package.json (87%) rename apps/{nitrov3-playground => nitro-v3-playground}/public/styles.css (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/routes/api/index.ts (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/routes/api/test/create.post.ts (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/routes/api/test/delete.delete.ts (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/routes/api/test/success.get.ts (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/routes/api/test/update.put.ts (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/routes/api/test/wide-event.get.ts (100%) rename apps/{nitrov3-playground => nitro-v3-playground}/tsconfig.json (100%) rename packages/evlog/src/{nitrov3 => nitro-v3}/plugin.ts (100%) diff --git a/apps/nitrov3-playground/.gitignore b/apps/nitro-v3-playground/.gitignore similarity index 100% rename from apps/nitrov3-playground/.gitignore rename to apps/nitro-v3-playground/.gitignore diff --git a/apps/nitrov3-playground/README.md b/apps/nitro-v3-playground/README.md similarity index 100% rename from apps/nitrov3-playground/README.md rename to apps/nitro-v3-playground/README.md diff --git a/apps/nitrov3-playground/bun.lock b/apps/nitro-v3-playground/bun.lock similarity index 100% rename from apps/nitrov3-playground/bun.lock rename to apps/nitro-v3-playground/bun.lock diff --git a/apps/nitrov3-playground/index.html b/apps/nitro-v3-playground/index.html similarity index 100% rename from apps/nitrov3-playground/index.html rename to apps/nitro-v3-playground/index.html diff --git a/apps/nitrov3-playground/nitro.config.ts b/apps/nitro-v3-playground/nitro.config.ts similarity index 70% rename from apps/nitrov3-playground/nitro.config.ts rename to apps/nitro-v3-playground/nitro.config.ts index 0cc39f7..7e29717 100644 --- a/apps/nitrov3-playground/nitro.config.ts +++ b/apps/nitro-v3-playground/nitro.config.ts @@ -3,5 +3,5 @@ import { defineConfig } from 'nitro' export default defineConfig({ serverDir: './', // TODO: make playground work with evlog/nitro/v3 - plugins: ['../../packages/evlog/src/nitrov3/plugin.ts'] + plugins: ['../../packages/evlog/src/nitro-v3/plugin.ts'] }) diff --git a/apps/nitrov3-playground/package.json b/apps/nitro-v3-playground/package.json similarity index 87% rename from apps/nitrov3-playground/package.json rename to apps/nitro-v3-playground/package.json index 44993e4..374688f 100644 --- a/apps/nitrov3-playground/package.json +++ b/apps/nitro-v3-playground/package.json @@ -1,5 +1,5 @@ { - "name": "nitrov3-playground", + "name": "evlog-nitro-v3-playground", "type": "module", "scripts": { "build": "nitro build", diff --git a/apps/nitrov3-playground/public/styles.css b/apps/nitro-v3-playground/public/styles.css similarity index 100% rename from apps/nitrov3-playground/public/styles.css rename to apps/nitro-v3-playground/public/styles.css diff --git a/apps/nitrov3-playground/routes/api/index.ts b/apps/nitro-v3-playground/routes/api/index.ts similarity index 100% rename from apps/nitrov3-playground/routes/api/index.ts rename to apps/nitro-v3-playground/routes/api/index.ts diff --git a/apps/nitrov3-playground/routes/api/test/create.post.ts b/apps/nitro-v3-playground/routes/api/test/create.post.ts similarity index 100% rename from apps/nitrov3-playground/routes/api/test/create.post.ts rename to apps/nitro-v3-playground/routes/api/test/create.post.ts diff --git a/apps/nitrov3-playground/routes/api/test/delete.delete.ts b/apps/nitro-v3-playground/routes/api/test/delete.delete.ts similarity index 100% rename from apps/nitrov3-playground/routes/api/test/delete.delete.ts rename to apps/nitro-v3-playground/routes/api/test/delete.delete.ts diff --git a/apps/nitrov3-playground/routes/api/test/success.get.ts b/apps/nitro-v3-playground/routes/api/test/success.get.ts similarity index 100% rename from apps/nitrov3-playground/routes/api/test/success.get.ts rename to apps/nitro-v3-playground/routes/api/test/success.get.ts diff --git a/apps/nitrov3-playground/routes/api/test/update.put.ts b/apps/nitro-v3-playground/routes/api/test/update.put.ts similarity index 100% rename from apps/nitrov3-playground/routes/api/test/update.put.ts rename to apps/nitro-v3-playground/routes/api/test/update.put.ts diff --git a/apps/nitrov3-playground/routes/api/test/wide-event.get.ts b/apps/nitro-v3-playground/routes/api/test/wide-event.get.ts similarity index 100% rename from apps/nitrov3-playground/routes/api/test/wide-event.get.ts rename to apps/nitro-v3-playground/routes/api/test/wide-event.get.ts diff --git a/apps/nitrov3-playground/tsconfig.json b/apps/nitro-v3-playground/tsconfig.json similarity index 100% rename from apps/nitrov3-playground/tsconfig.json rename to apps/nitro-v3-playground/tsconfig.json diff --git a/bun.lock b/bun.lock index fb6b4e0..115a1ca 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "evlog-monorepo", @@ -39,8 +38,8 @@ "rolldown": "latest", }, }, - "apps/nitrov3-playground": { - "name": "nitrov3-playground", + "apps/nitro-v3-playground": { + "name": "evlog-nitro-v3-playground", "dependencies": { "evlog": "workspace:*", }, @@ -63,6 +62,7 @@ "version": "1.0.1", "dependencies": { "@nuxt/kit": "^4.3.0", + "ufo": "^1.6.3", }, "devDependencies": { "@nuxt/devtools": "^3.1.1", @@ -74,7 +74,6 @@ "nitropack": "^2.13.1", "nuxt": "^4.3.0", "typescript": "^5.9.3", - "ufo": "^1.6.3", "unbuild": "^3.6.1", }, "peerDependencies": { @@ -1518,6 +1517,8 @@ "evlog-nitro-playground": ["evlog-nitro-playground@workspace:apps/nitro-playground"], + "evlog-nitro-v3-playground": ["evlog-nitro-v3-playground@workspace:apps/nitro-v3-playground"], + "evlog-playground": ["evlog-playground@workspace:apps/playground"], "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], @@ -2090,8 +2091,6 @@ "nitropack": ["nitropack@2.13.1", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.2", "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-replace": "^6.0.3", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^1.2.0", "archiver": "^7.0.1", "c12": "^3.3.3", "chokidar": "^5.0.0", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.1.0", "crossws": "^0.3.5", "db0": "^0.3.4", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^10.1.0", "esbuild": "^0.27.2", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.8", "globby": "^16.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.5", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.9.1", "jiti": "^2.6.1", "klona": "^2.0.6", "knitwork": "^1.3.0", "listhen": "^1.9.0", "magic-string": "^0.30.21", "magicast": "^0.5.1", "mime": "^4.1.0", "mlly": "^1.8.0", "node-fetch-native": "^1.6.7", "node-mock-http": "^1.0.4", "ofetch": "^1.5.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "pretty-bytes": "^7.1.0", "radix3": "^1.1.2", "rollup": "^4.55.1", "rollup-plugin-visualizer": "^6.0.5", "scule": "^1.3.0", "semver": "^7.7.3", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.1", "source-map": "^0.7.6", "std-env": "^3.10.0", "ufo": "^1.6.3", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.5.0", "unenv": "^2.0.0-rc.24", "unimport": "^5.6.0", "unplugin-utils": "^0.3.1", "unstorage": "^1.17.4", "untyped": "^2.0.0", "unwasm": "^0.5.3", "youch": "^4.1.0-beta.13", "youch-core": "^0.3.3" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-2dDj89C4wC2uzG7guF3CnyG+zwkZosPEp7FFBGHB3AJo11AywOolWhyQJFHDzve8COvGxJaqscye9wW2IrUsNw=="], - "nitrov3-playground": ["nitrov3-playground@workspace:apps/nitrov3-playground"], - "node-abi": ["node-abi@3.87.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ=="], "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], diff --git a/package.json b/package.json index 4484843..2eb4553 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "scripts": { "dev": "turbo run dev --filter=evlog-playground", "dev:nitro": "turbo run dev --filter=evlog-nitro-playground", + "dev:nitro:v3": "turbo run dev --filter=evlog-nitro-v3-playground", "dev:prepare": "turbo run dev:prepare", "dev:docs": "turbo run dev --filter=evlog-docs", "docs": "turbo run dev --filter=evlog-docs", diff --git a/packages/evlog/build.config.ts b/packages/evlog/build.config.ts index 9cc1c8e..bf253d3 100644 --- a/packages/evlog/build.config.ts +++ b/packages/evlog/build.config.ts @@ -5,7 +5,7 @@ export default defineBuildConfig({ { input: 'src/index', name: 'index' }, { input: 'src/nuxt/module', name: 'nuxt/module' }, { input: 'src/nitro/plugin', name: 'nitro/plugin' }, - { input: 'src/nitrov3/plugin', name: 'nitro/v3/plugin' }, + { input: 'src/nitro-v3/plugin', name: 'nitro/v3/plugin' }, { input: 'src/runtime/client/log', name: 'runtime/client/log' }, { input: 'src/runtime/client/plugin', name: 'runtime/client/plugin' }, { input: 'src/runtime/server/useLogger', name: 'runtime/server/useLogger' }, diff --git a/packages/evlog/package.json b/packages/evlog/package.json index 6bc94bc..e2d78e8 100644 --- a/packages/evlog/package.json +++ b/packages/evlog/package.json @@ -74,7 +74,8 @@ "typecheck": "echo 'Typecheck handled by build'" }, "dependencies": { - "@nuxt/kit": "^4.3.0" + "@nuxt/kit": "^4.3.0", + "ufo": "^1.6.3" }, "devDependencies": { "@nuxt/devtools": "^3.1.1", @@ -86,8 +87,7 @@ "nuxt": "^4.3.0", "typescript": "^5.9.3", "unbuild": "^3.6.1", - "nitro": "^3.0.1-alpha.2", - "ufo": "^1.6.3" + "nitro": "^3.0.1-alpha.2" }, "peerDependencies": { "h3": "^1.15.5", diff --git a/packages/evlog/src/nitrov3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts similarity index 100% rename from packages/evlog/src/nitrov3/plugin.ts rename to packages/evlog/src/nitro-v3/plugin.ts From 90e2c4551d6beb2780c5287e2b50850bffad2830 Mon Sep 17 00:00:00 2001 From: schplitt Date: Sat, 31 Jan 2026 13:56:55 +0100 Subject: [PATCH 12/26] feat(nitro-v3): align EvlogError with Nitro v3 HTTPError contract --- .../1.getting-started/1.introduction.md | 2 + .../1.getting-started/2.installation.md | 2 +- .../1.getting-started/3.quick-start.md | 6 +- .../2.core-concepts/2.structured-errors.md | 6 +- packages/evlog/src/nitro-v3/error.ts | 116 ++++++++++++++++++ packages/evlog/src/nitro-v3/plugin.ts | 2 + 6 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 packages/evlog/src/nitro-v3/error.ts diff --git a/apps/docs/content/1.getting-started/1.introduction.md b/apps/docs/content/1.getting-started/1.introduction.md index 30c268d..b075a61 100644 --- a/apps/docs/content/1.getting-started/1.introduction.md +++ b/apps/docs/content/1.getting-started/1.introduction.md @@ -97,6 +97,8 @@ Structured errors provide actionable context: ::code-group ```typescript [Code] // server/api/checkout.post.ts +import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3 + throw createError({ message: 'Payment failed', status: 402, diff --git a/apps/docs/content/1.getting-started/2.installation.md b/apps/docs/content/1.getting-started/2.installation.md index 1186432..757a451 100644 --- a/apps/docs/content/1.getting-started/2.installation.md +++ b/apps/docs/content/1.getting-started/2.installation.md @@ -62,7 +62,7 @@ export default defineNitroConfig({ ``` ::callout{icon="i-lucide-info" color="info"} -For early Nitro v3 support, use `evlog/nitro/v3` instead of `evlog/nitro`. +For early Nitro v3 support, use `evlog/nitro/v3` instead of `evlog/nitro`. When using Nitro v3, import `createError` from `evlog/nitro/v3` instead of `evlog`. :: ## Standalone TypeScript diff --git a/apps/docs/content/1.getting-started/3.quick-start.md b/apps/docs/content/1.getting-started/3.quick-start.md index 4885af0..9b7e5bb 100644 --- a/apps/docs/content/1.getting-started/3.quick-start.md +++ b/apps/docs/content/1.getting-started/3.quick-start.md @@ -37,10 +37,14 @@ The logger automatically emits when the request ends. No manual `emit()` call ne Use `createError()` to throw errors with actionable context: +::callout{icon="i-lucide-info" color="info"} +For Nitro v3, import from `evlog/nitro/v3` instead of `evlog`. +:: + ::code-group ```typescript [Code] // server/api/checkout.post.ts -import { createError } from 'evlog' +import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3 throw createError({ message: 'Payment failed', diff --git a/apps/docs/content/2.core-concepts/2.structured-errors.md b/apps/docs/content/2.core-concepts/2.structured-errors.md index 33812a4..4cd0e17 100644 --- a/apps/docs/content/2.core-concepts/2.structured-errors.md +++ b/apps/docs/content/2.core-concepts/2.structured-errors.md @@ -5,6 +5,10 @@ description: Create errors that explain why they occurred and how to fix them. evlog provides a `createError()` function that creates errors with rich, actionable context. +::callout{icon="i-lucide-info" color="info"} +For Nitro v3, import `createError` from `evlog/nitro/v3` instead of `evlog`. +:: + ## Why Structured Errors? Traditional errors are often unhelpful: @@ -60,7 +64,7 @@ throw createError({ ::code-group ```typescript [Code] // server/api/users/[id].get.ts -import { createError } from 'evlog' +import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3 throw createError({ message: 'User not found', diff --git a/packages/evlog/src/nitro-v3/error.ts b/packages/evlog/src/nitro-v3/error.ts new file mode 100644 index 0000000..65f1dbe --- /dev/null +++ b/packages/evlog/src/nitro-v3/error.ts @@ -0,0 +1,116 @@ +import { HTTPError } from 'nitro/h3' +import type { ErrorOptions } from '../types' +import { colors, isServer } from '../utils' + +/** + * Structured error with context for better debugging + * + * @example + * ```ts + * throw new EvlogError({ + * message: 'Failed to sync repository', + * status: 503, + * why: 'GitHub API rate limit exceeded', + * fix: 'Wait 1 hour or use a different token', + * link: 'https://docs.github.com/en/rest/rate-limit', + * cause: originalError, + * }) + * ``` + */ +export class EvlogError extends HTTPError { + + readonly status: number + readonly why?: string + readonly fix?: string + readonly link?: string + + override get name(): string { + return 'EvlogError' + } + + constructor(options: ErrorOptions | string) { + const opts = typeof options === 'string' ? { message: options } : options + + const body = opts.why || opts.fix || opts.link + ? { why: opts.why, fix: opts.fix, link: opts.link } + : undefined + + super(opts.message, { cause: opts.cause, body }) + + this.status = opts.status ?? 500 + this.why = opts.why + this.fix = opts.fix + this.link = opts.link + + // Maintain proper stack trace in V8 + if (Error.captureStackTrace) { + Error.captureStackTrace(this, EvlogError) + } + } + + get statusCode(): number { + return this.status + } + + override toString(): string { + // Use colors only on server (terminal) + const useColors = isServer() + + const red = useColors ? colors.red : '' + const yellow = useColors ? colors.yellow : '' + const cyan = useColors ? colors.cyan : '' + const dim = useColors ? colors.dim : '' + const reset = useColors ? colors.reset : '' + const bold = useColors ? colors.bold : '' + + const lines: string[] = [] + + lines.push(`${red}${bold}Error:${reset} ${this.message}`) + + if (this.why) { + lines.push(`${yellow}Why:${reset} ${this.why}`) + } + + if (this.fix) { + lines.push(`${cyan}Fix:${reset} ${this.fix}`) + } + + if (this.link) { + lines.push(`${dim}More info:${reset} ${this.link}`) + } + + if (this.cause) { + lines.push(`${dim}Caused by:${reset} ${(this.cause as Error).message}`) + } + + return lines.join('\n') + } + +} + +/** + * Create a structured error with context for debugging and user-facing messages. + * + * @param options - Error message string or full options object + * @returns EvlogError instance compatible with Nitro's error handling + * + * @example + * ```ts + * // Simple error + * throw createError('Something went wrong') + * + * // Structured error with context + * throw createError({ + * message: 'Payment failed', + * status: 402, + * why: 'Card declined by issuer', + * fix: 'Try a different payment method', + * link: 'https://docs.example.com/payments', + * }) + * ``` + */ +export function createError(options: ErrorOptions | string): EvlogError { + return new EvlogError(options) +} + +export const createEvlogError = createError diff --git a/packages/evlog/src/nitro-v3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts index 4e896a6..0b5d63f 100644 --- a/packages/evlog/src/nitro-v3/plugin.ts +++ b/packages/evlog/src/nitro-v3/plugin.ts @@ -7,6 +7,8 @@ import { createRequestLogger, initLogger } from '../logger' import { shouldLog } from '../nitro' import type { RequestLogger } from '../types' +export * from './error' + interface EvlogConfig { env?: Record pretty?: boolean From 23c32cde26df882ae3b5486806fa288bcd3b71e3 Mon Sep 17 00:00:00 2001 From: schplitt Date: Sat, 31 Jan 2026 14:29:23 +0100 Subject: [PATCH 13/26] nitro/v3 feature parity --- packages/evlog/src/nitro-v3/plugin.ts | 87 ++++++++++++++++++++++++--- packages/evlog/src/nitro.ts | 13 +--- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/packages/evlog/src/nitro-v3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts index 0b5d63f..93327bd 100644 --- a/packages/evlog/src/nitro-v3/plugin.ts +++ b/packages/evlog/src/nitro-v3/plugin.ts @@ -5,7 +5,7 @@ import type { HTTPEvent } from 'nitro/h3' import { parseURL } from 'ufo' import { createRequestLogger, initLogger } from '../logger' import { shouldLog } from '../nitro' -import type { RequestLogger } from '../types' +import type { RequestLogger, SamplingConfig, TailSamplingContext, WideEvent } from '../types' export * from './error' @@ -13,6 +13,7 @@ interface EvlogConfig { env?: Record pretty?: boolean include?: string[] + sampling?: SamplingConfig } // currently nitro/v3 doesnt export hook types correctly @@ -22,6 +23,8 @@ interface NitroRuntimeHooks { error: CaptureError; request: (event: HTTPEvent) => void | Promise; response: (res: Response, event: HTTPEvent) => void | Promise; + 'evlog:emit:keep': (ctx: TailSamplingContext) => void | Promise; + 'evlog:drain': (ctx: { event: WideEvent; request?: { method?: string; path: string; requestId?: string } }) => void | Promise; } // Hookable core type not available so we build it our self type Hooks = { @@ -38,6 +41,7 @@ export default definePlugin((nitroApp) => { initLogger({ env: evlogConfig?.env, pretty: evlogConfig?.pretty, + sampling: evlogConfig?.sampling, }) const hooks = nitroApp.hooks as Hooks @@ -67,22 +71,89 @@ export default definePlugin((nitroApp) => { e.req.context = {} } e.req.context.log = log + // Store start time for duration calculation in tail sampling + e.req.context._evlogStartTime = Date.now() }) - hooks.hook('response', (res, event) => { + hooks.hook('response', async (res, event) => { const e = event + // Skip if already emitted by error hook + if (e.req.context?._evlogEmitted) return + const log = e.req.context?.log as RequestLogger | undefined - if (log) { - log.set({ status: res.status }) - log.emit() + if (log && e.req.context) { + const { status } = res + log.set({ status }) + + const { pathname } = parseURL(e.req.url) + const startTime = e.req.context._evlogStartTime as number | undefined + const durationMs = startTime ? Date.now() - startTime : undefined + + const tailCtx: TailSamplingContext = { + status, + duration: durationMs, + path: pathname, + method: e.req.method, + context: log.getContext(), + shouldKeep: false, + } + + await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx) + + const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep }) + + // Drain hook integration + if (emittedEvent) { + (nitroApp.hooks as any).callHook('evlog:drain', { + event: emittedEvent, + request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, + }).catch((err: Error) => { + console.error('[evlog] drain failed:', err) + }) + } } }) - hooks.hook('error', (error, { event }) => { + hooks.hook('error', async (error, { event }) => { const e = event - const log = e?.req.context?.log as RequestLogger | undefined - if (log) { + if (!e) return + + const log = e.req.context?.log as RequestLogger | undefined + if (log && e.req.context) { log.error(error as Error) + + // Get the actual error status code + const errorStatus = (error as { statusCode?: number }).statusCode ?? 500 + log.set({ status: errorStatus }) + + const { pathname } = parseURL(e.req.url) + const startTime = e.req.context._evlogStartTime as number | undefined + const durationMs = startTime ? Date.now() - startTime : undefined + + const tailCtx: TailSamplingContext = { + status: errorStatus, + duration: durationMs, + path: pathname, + method: e.req.method, + context: log.getContext(), + shouldKeep: false, + } + + await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx) + + e.req.context._evlogEmitted = true + + const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep }) + + // Drain hook integration + if (emittedEvent) { + await nitroApp.hooks.callHook('evlog:drain', { + event: emittedEvent, + request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, + }).catch((err: Error) => { + console.error('[evlog] drain failed:', err) + }) + } } }) }) diff --git a/packages/evlog/src/nitro.ts b/packages/evlog/src/nitro.ts index 9322d74..cb985c9 100644 --- a/packages/evlog/src/nitro.ts +++ b/packages/evlog/src/nitro.ts @@ -1,15 +1,4 @@ -function matchesPattern(path: string, pattern: string): boolean { - // Convert glob pattern to regex - const regexPattern = pattern - .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special regex chars except * and ? - .replace(/\*\*/g, '{{GLOBSTAR}}') // Temp placeholder for ** - .replace(/\*/g, '[^/]*') // * matches anything except / - .replace(/{{GLOBSTAR}}/g, '.*') // ** matches anything including / - .replace(/\?/g, '[^/]') // ? matches single char except / - - const regex = new RegExp(`^${regexPattern}$`) - return regex.test(path) -} +import { matchesPattern } from './utils' export function shouldLog(path: string, include?: string[]): boolean { // If no include patterns, log everything From 2bd17f62c794ee3cf433a33393f248597421df5d Mon Sep 17 00:00:00 2001 From: schplitt Date: Sat, 31 Jan 2026 17:43:47 +0100 Subject: [PATCH 14/26] fix: error handling/logging --- .../routes/api/test/update.put.ts | 3 ++- packages/evlog/src/nitro-v3/error.ts | 10 ++++---- packages/evlog/src/nitro-v3/plugin.ts | 24 +++++++++++-------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/nitro-v3-playground/routes/api/test/update.put.ts b/apps/nitro-v3-playground/routes/api/test/update.put.ts index c40f5f3..52bd014 100644 --- a/apps/nitro-v3-playground/routes/api/test/update.put.ts +++ b/apps/nitro-v3-playground/routes/api/test/update.put.ts @@ -1,5 +1,6 @@ import { defineHandler, readBody } from 'nitro/h3' -import { useLogger, createError } from 'evlog' +import { useLogger } from 'evlog' +import { createError } from 'evlog/nitro/v3' export default defineHandler(async (event) => { const log = useLogger(event) diff --git a/packages/evlog/src/nitro-v3/error.ts b/packages/evlog/src/nitro-v3/error.ts index 65f1dbe..1cfc6dc 100644 --- a/packages/evlog/src/nitro-v3/error.ts +++ b/packages/evlog/src/nitro-v3/error.ts @@ -24,10 +24,6 @@ export class EvlogError extends HTTPError { readonly fix?: string readonly link?: string - override get name(): string { - return 'EvlogError' - } - constructor(options: ErrorOptions | string) { const opts = typeof options === 'string' ? { message: options } : options @@ -35,9 +31,11 @@ export class EvlogError extends HTTPError { ? { why: opts.why, fix: opts.fix, link: opts.link } : undefined - super(opts.message, { cause: opts.cause, body }) + const statusCode = opts.status ?? 500 + + super(opts.message, { cause: opts.cause, body, statusCode }) - this.status = opts.status ?? 500 + this.status = statusCode this.why = opts.why this.fix = opts.fix this.link = opts.link diff --git a/packages/evlog/src/nitro-v3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts index 93327bd..53f14ed 100644 --- a/packages/evlog/src/nitro-v3/plugin.ts +++ b/packages/evlog/src/nitro-v3/plugin.ts @@ -104,12 +104,14 @@ export default definePlugin((nitroApp) => { // Drain hook integration if (emittedEvent) { - (nitroApp.hooks as any).callHook('evlog:drain', { - event: emittedEvent, - request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, - }).catch((err: Error) => { + try { + await nitroApp.hooks.callHook('evlog:drain', { + event: emittedEvent, + request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, + }) + } catch (err) { console.error('[evlog] drain failed:', err) - }) + } } } }) @@ -147,12 +149,14 @@ export default definePlugin((nitroApp) => { // Drain hook integration if (emittedEvent) { - await nitroApp.hooks.callHook('evlog:drain', { - event: emittedEvent, - request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, - }).catch((err: Error) => { + try { + await nitroApp.hooks.callHook('evlog:drain', { + event: emittedEvent, + request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, + }) + } catch (err) { console.error('[evlog] drain failed:', err) - }) + } } } }) From 4d7b5e41b54615d5e8298858ca96052459aa5f63 Mon Sep 17 00:00:00 2001 From: schplitt Date: Sat, 31 Jan 2026 17:50:36 +0100 Subject: [PATCH 15/26] nitrov3 respect exclude config --- packages/evlog/src/nitro-v3/plugin.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/evlog/src/nitro-v3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts index 53f14ed..7272044 100644 --- a/packages/evlog/src/nitro-v3/plugin.ts +++ b/packages/evlog/src/nitro-v3/plugin.ts @@ -13,6 +13,7 @@ interface EvlogConfig { env?: Record pretty?: boolean include?: string[] + exclude?: string[] sampling?: SamplingConfig } @@ -57,8 +58,8 @@ export default definePlugin((nitroApp) => { pathname } = parseURL(e.req.url) - // Skip logging for routes not matching include patterns - if (!shouldLog(pathname, evlogConfig?.include)) { + // Skip logging for routes not matching include/exclude patterns + if (!shouldLog(pathname, evlogConfig?.include, evlogConfig?.exclude)) { return } From 3fe2419575d37e2e1eb66d383634599f71f21784 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 20:49:11 +0100 Subject: [PATCH 16/26] feat: nitro v3 feature parity --- packages/evlog/src/nitro-v3/error.ts | 114 -------- packages/evlog/src/nitro-v3/errorHandler.ts | 75 +++++ packages/evlog/src/nitro-v3/plugin.ts | 305 ++++++++++++-------- packages/evlog/src/nitro.ts | 34 +++ packages/evlog/src/nitro/plugin.ts | 53 +--- packages/evlog/src/types.ts | 10 +- 6 files changed, 311 insertions(+), 280 deletions(-) delete mode 100644 packages/evlog/src/nitro-v3/error.ts create mode 100644 packages/evlog/src/nitro-v3/errorHandler.ts diff --git a/packages/evlog/src/nitro-v3/error.ts b/packages/evlog/src/nitro-v3/error.ts deleted file mode 100644 index 1cfc6dc..0000000 --- a/packages/evlog/src/nitro-v3/error.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { HTTPError } from 'nitro/h3' -import type { ErrorOptions } from '../types' -import { colors, isServer } from '../utils' - -/** - * Structured error with context for better debugging - * - * @example - * ```ts - * throw new EvlogError({ - * message: 'Failed to sync repository', - * status: 503, - * why: 'GitHub API rate limit exceeded', - * fix: 'Wait 1 hour or use a different token', - * link: 'https://docs.github.com/en/rest/rate-limit', - * cause: originalError, - * }) - * ``` - */ -export class EvlogError extends HTTPError { - - readonly status: number - readonly why?: string - readonly fix?: string - readonly link?: string - - constructor(options: ErrorOptions | string) { - const opts = typeof options === 'string' ? { message: options } : options - - const body = opts.why || opts.fix || opts.link - ? { why: opts.why, fix: opts.fix, link: opts.link } - : undefined - - const statusCode = opts.status ?? 500 - - super(opts.message, { cause: opts.cause, body, statusCode }) - - this.status = statusCode - this.why = opts.why - this.fix = opts.fix - this.link = opts.link - - // Maintain proper stack trace in V8 - if (Error.captureStackTrace) { - Error.captureStackTrace(this, EvlogError) - } - } - - get statusCode(): number { - return this.status - } - - override toString(): string { - // Use colors only on server (terminal) - const useColors = isServer() - - const red = useColors ? colors.red : '' - const yellow = useColors ? colors.yellow : '' - const cyan = useColors ? colors.cyan : '' - const dim = useColors ? colors.dim : '' - const reset = useColors ? colors.reset : '' - const bold = useColors ? colors.bold : '' - - const lines: string[] = [] - - lines.push(`${red}${bold}Error:${reset} ${this.message}`) - - if (this.why) { - lines.push(`${yellow}Why:${reset} ${this.why}`) - } - - if (this.fix) { - lines.push(`${cyan}Fix:${reset} ${this.fix}`) - } - - if (this.link) { - lines.push(`${dim}More info:${reset} ${this.link}`) - } - - if (this.cause) { - lines.push(`${dim}Caused by:${reset} ${(this.cause as Error).message}`) - } - - return lines.join('\n') - } - -} - -/** - * Create a structured error with context for debugging and user-facing messages. - * - * @param options - Error message string or full options object - * @returns EvlogError instance compatible with Nitro's error handling - * - * @example - * ```ts - * // Simple error - * throw createError('Something went wrong') - * - * // Structured error with context - * throw createError({ - * message: 'Payment failed', - * status: 402, - * why: 'Card declined by issuer', - * fix: 'Try a different payment method', - * link: 'https://docs.example.com/payments', - * }) - * ``` - */ -export function createError(options: ErrorOptions | string): EvlogError { - return new EvlogError(options) -} - -export const createEvlogError = createError diff --git a/packages/evlog/src/nitro-v3/errorHandler.ts b/packages/evlog/src/nitro-v3/errorHandler.ts new file mode 100644 index 0000000..9f50d13 --- /dev/null +++ b/packages/evlog/src/nitro-v3/errorHandler.ts @@ -0,0 +1,75 @@ +import type { HTTPEvent } from 'nitro/h3' +import { parseURL } from 'ufo' +import { defineErrorHandler } from 'nitro' +import { EvlogError } from '../error' + +/** + * Custom Nitro v3 error handler that properly serializes EvlogError. + * This ensures that 'data' (containing 'why', 'fix', 'link') is preserved + * in the JSON response regardless of the underlying HTTP framework. + * + * For non-EvlogError, it preserves Nitro's default response shape while + * sanitizing internal error details in production for 5xx errors. + * + * Usage in nitro.config.ts: + * ```ts + * import { defineConfig } from 'nitro' + * import evlogErrorHandler from 'evlog/nitro/v3/errorHandler' + * + * export default defineConfig({ + * errorHandler: evlogErrorHandler, + * }) + * ``` + */ +export const evlogErrorHandler = defineErrorHandler(async (error, event, { defaultHandler }): Promise => { + // Check if this is an EvlogError (by name or by checking cause) + + const evlogError = error.name === 'EvlogError' + ? error + : (error.cause as Error)?.name === 'EvlogError' + ? error.cause as Error + : error.cause instanceof EvlogError + ? error.cause + : null + + + const isDev = process.env.NODE_ENV === 'development' + const url = parseURL(event.req.url).pathname + + // For non-EvlogError, preserve Nitro's default response shape + if (!evlogError) { + const res = await defaultHandler(error, event, { json: true }) + const body = typeof res.body === 'string' ? res.body : JSON.stringify(res.body) + return new Response(body, { + status: res.status, + statusText: res.statusText, + headers: res.headers, + }) + } + + + // Derive status from evlogError to ensure consistency between + // HTTP response status and response body + const status = (evlogError as { status?: number }).status + ?? (evlogError as { statusCode?: number }).statusCode + ?? 500 + + // Serialize EvlogError with all its data, preserving Nitro's response shape + const { data } = evlogError as { data?: unknown } + const statusMessage = (evlogError as { statusMessage?: string }).statusMessage || evlogError.message + return new Response(JSON.stringify({ + url, + status, + statusCode: status, + statusText: statusMessage, + statusMessage, + message: evlogError.message, + error: true, + ...(data !== undefined && { data }), + }), { + status, + headers: { 'Content-Type': 'application/json' }, + }) +}) + +export default evlogErrorHandler diff --git a/packages/evlog/src/nitro-v3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts index 7272044..68c853d 100644 --- a/packages/evlog/src/nitro-v3/plugin.ts +++ b/packages/evlog/src/nitro-v3/plugin.ts @@ -4,35 +4,119 @@ import type { CaptureError } from 'nitro/types' import type { HTTPEvent } from 'nitro/h3' import { parseURL } from 'ufo' import { createRequestLogger, initLogger } from '../logger' -import { shouldLog } from '../nitro' -import type { RequestLogger, SamplingConfig, TailSamplingContext, WideEvent } from '../types' - -export * from './error' +import { shouldLog, getServiceForPath } from '../nitro' +import type { EnrichContext, RequestLogger, RouteConfig, SamplingConfig, TailSamplingContext, WideEvent } from '../types' +import { filterSafeHeaders } from '../utils' interface EvlogConfig { env?: Record pretty?: boolean include?: string[] exclude?: string[] + routes?: Record sampling?: SamplingConfig } -// currently nitro/v3 doesnt export hook types correctly +// Nitro v3 doesn't fully export hook types yet // https://github.com/nitrojs/nitro/blob/8882bc9e1dbf2d342e73097f22a2156f70f50575/src/types/runtime/nitro.ts#L48-L53 -interface NitroRuntimeHooks { - close: () => void; - error: CaptureError; - request: (event: HTTPEvent) => void | Promise; - response: (res: Response, event: HTTPEvent) => void | Promise; - 'evlog:emit:keep': (ctx: TailSamplingContext) => void | Promise; - 'evlog:drain': (ctx: { event: WideEvent; request?: { method?: string; path: string; requestId?: string } }) => void | Promise; +interface NitroV3Hooks { + close: () => void + error: CaptureError + request: (event: HTTPEvent) => void | Promise + response: (res: Response, event: HTTPEvent) => void | Promise + 'evlog:emit:keep': (ctx: TailSamplingContext) => void | Promise + 'evlog:enrich': (ctx: EnrichContext) => void | Promise + 'evlog:drain': (ctx: { event: WideEvent; request?: { method?: string; path: string; requestId?: string }; headers?: Record }) => void | Promise } -// Hookable core type not available so we build it our self + type Hooks = { - hook: ( - name: THookName, - listener: NitroRuntimeHooks[THookName] - ) => void; + hook: (name: T, listener: NitroV3Hooks[T]) => void + callHook: (name: T, ...args: Parameters) => Promise +} + +function getContext(event: HTTPEvent): Record { + if (!event.req.context) { + event.req.context = {} + } + return event.req.context +} + +function getSafeRequestHeaders(event: HTTPEvent): Record { + const headers: Record = {} + event.req.headers.forEach((value, key) => { + headers[key] = value + }) + return filterSafeHeaders(headers) +} + +function getSafeResponseHeaders(res: Response): Record | undefined { + const headers: Record = {} + res.headers.forEach((value, key) => { + headers[key] = value + }) + if (Object.keys(headers).length === 0) return undefined + return filterSafeHeaders(headers) +} + +function buildHookContext( + event: HTTPEvent, + res?: Response, +): Omit { + const { pathname } = parseURL(event.req.url) + const responseHeaders = res ? getSafeResponseHeaders(res) : undefined + return { + request: { method: event.req.method, path: pathname }, + headers: getSafeRequestHeaders(event), + response: { + status: res?.status ?? 200, + headers: responseHeaders, + }, + } +} + +function callDrainHook( + hooks: Hooks, + emittedEvent: WideEvent | null, + event: HTTPEvent, + request: EnrichContext['request'], + headers: EnrichContext['headers'], +): void { + if (!emittedEvent) return + let drainPromise: Promise | undefined + try { + drainPromise = hooks.callHook('evlog:drain', { + event: emittedEvent, + request, + headers, + }) + } catch (err) { + console.error('[evlog] drain failed:', err) + } + + // Use waitUntil if available (srvx native — Cloudflare Workers, Vercel Edge, etc.) + // This ensures drains complete before the runtime terminates + if (drainPromise && typeof event.req.waitUntil === 'function') { + event.req.waitUntil(drainPromise) + } +} + +async function callEnrichAndDrain( + hooks: Hooks, + emittedEvent: WideEvent | null, + event: HTTPEvent, + res?: Response, +): Promise { + if (!emittedEvent) return + + const hookContext = buildHookContext(event, res) + + try { + await hooks.callHook('evlog:enrich', { event: emittedEvent, ...hookContext }) + } catch (err) { + console.error('[evlog] enrich failed:', err) + } + + callDrainHook(hooks, emittedEvent, event, hookContext.request, hookContext.headers) } export default definePlugin((nitroApp) => { @@ -45,120 +129,113 @@ export default definePlugin((nitroApp) => { sampling: evlogConfig?.sampling, }) - const hooks = nitroApp.hooks as Hooks - + const hooks = nitroApp.hooks as unknown as Hooks hooks.hook('request', (event) => { - const e = event + const { pathname } = parseURL(event.req.url) - const { method } = e.req - const requestId = e.req.context?.requestId as string | undefined ?? crypto.randomUUID() - - const { - pathname - } = parseURL(e.req.url) - // Skip logging for routes not matching include/exclude patterns if (!shouldLog(pathname, evlogConfig?.include, evlogConfig?.exclude)) { return } - + + const ctx = getContext(event) + + // Store start time for duration calculation in tail sampling + ctx._evlogStartTime = Date.now() + + let requestIdOverride: string | undefined = undefined + if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') { + const cfRay = event.req.headers.get('cf-ray') + if (cfRay) requestIdOverride = cfRay + } + const log = createRequestLogger({ - method: method, + method: event.req.method, path: pathname, - requestId, + requestId: requestIdOverride || ctx.requestId as string | undefined || crypto.randomUUID(), }) - if (!e.req.context) { - e.req.context = {} + + // Apply route-based service configuration if a matching route is found + const routeService = getServiceForPath(pathname, evlogConfig?.routes) + if (routeService) { + log.set({ service: routeService }) } - e.req.context.log = log - // Store start time for duration calculation in tail sampling - e.req.context._evlogStartTime = Date.now() + + ctx.log = log }) - + hooks.hook('response', async (res, event) => { - const e = event + const ctx = event.req.context // Skip if already emitted by error hook - if (e.req.context?._evlogEmitted) return - - const log = e.req.context?.log as RequestLogger | undefined - if (log && e.req.context) { - const { status } = res - log.set({ status }) - - const { pathname } = parseURL(e.req.url) - const startTime = e.req.context._evlogStartTime as number | undefined - const durationMs = startTime ? Date.now() - startTime : undefined - - const tailCtx: TailSamplingContext = { - status, - duration: durationMs, - path: pathname, - method: e.req.method, - context: log.getContext(), - shouldKeep: false, - } - - await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx) - - const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep }) - - // Drain hook integration - if (emittedEvent) { - try { - await nitroApp.hooks.callHook('evlog:drain', { - event: emittedEvent, - request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, - }) - } catch (err) { - console.error('[evlog] drain failed:', err) - } - } + if (ctx?._evlogEmitted) return + + const log = ctx?.log as RequestLogger | undefined + if (!log || !ctx) return + + const { status } = res + log.set({ status }) + + const startTime = ctx._evlogStartTime as number | undefined + const durationMs = startTime ? Date.now() - startTime : undefined + + const { pathname } = parseURL(event.req.url) + + const tailCtx: TailSamplingContext = { + status, + duration: durationMs, + path: pathname, + method: event.req.method, + context: log.getContext(), + shouldKeep: false, } + + await hooks.callHook('evlog:emit:keep', tailCtx) + + const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep }) + await callEnrichAndDrain(hooks, emittedEvent, event, res) }) - + hooks.hook('error', async (error, { event }) => { - const e = event - if (!e) return - - const log = e.req.context?.log as RequestLogger | undefined - if (log && e.req.context) { - log.error(error as Error) - - // Get the actual error status code - const errorStatus = (error as { statusCode?: number }).statusCode ?? 500 - log.set({ status: errorStatus }) - - const { pathname } = parseURL(e.req.url) - const startTime = e.req.context._evlogStartTime as number | undefined - const durationMs = startTime ? Date.now() - startTime : undefined - - const tailCtx: TailSamplingContext = { - status: errorStatus, - duration: durationMs, - path: pathname, - method: e.req.method, - context: log.getContext(), - shouldKeep: false, - } - - await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx) - - e.req.context._evlogEmitted = true - - const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep }) - - // Drain hook integration - if (emittedEvent) { - try { - await nitroApp.hooks.callHook('evlog:drain', { - event: emittedEvent, - request: { method: e.req.method, path: pathname, requestId: e.req.context.requestId as string | undefined }, - }) - } catch (err) { - console.error('[evlog] drain failed:', err) - } - } + if (!event) return + const e = event as HTTPEvent + + const ctx = e.req.context + const log = ctx?.log as RequestLogger | undefined + if (!log || !ctx) return + + // Check if error.cause is an EvlogError (thrown errors get wrapped in HTTPError by nitro) + const actualError = (error.cause as Error)?.name === 'EvlogError' + ? error.cause as Error + : error as Error + + log.error(actualError) + + // Get the actual error status code (from EvlogError if available) + const errorStatus = (actualError as { status?: number }).status + ?? (actualError as { statusCode?: number }).statusCode + ?? (error as { statusCode?: number }).statusCode + ?? 500 + log.set({ status: errorStatus }) + + const { pathname } = parseURL(e.req.url) + const startTime = ctx._evlogStartTime as number | undefined + const durationMs = startTime ? Date.now() - startTime : undefined + + const tailCtx: TailSamplingContext = { + status: errorStatus, + duration: durationMs, + path: pathname, + method: e.req.method, + context: log.getContext(), + shouldKeep: false, } + + await hooks.callHook('evlog:emit:keep', tailCtx) + + ctx._evlogEmitted = true + + const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep }) + await callEnrichAndDrain(hooks, emittedEvent, e) }) }) diff --git a/packages/evlog/src/nitro.ts b/packages/evlog/src/nitro.ts index 29576ba..6a2383f 100644 --- a/packages/evlog/src/nitro.ts +++ b/packages/evlog/src/nitro.ts @@ -1,3 +1,4 @@ +import type { RouteConfig } from './types' import { matchesPattern } from './utils' export function shouldLog(path: string, include?: string[], exclude?: string[]): boolean { @@ -16,3 +17,36 @@ export function shouldLog(path: string, include?: string[], exclude?: string[]): // Log only if path matches at least one include pattern return include.some(pattern => matchesPattern(path, pattern)) } + +/** + * Find the service name for a given path based on route patterns. + * + * When multiple patterns match the same path, the first matching pattern wins + * based on object iteration order. To ensure predictable behavior, order your + * route patterns from most specific to most general. + * + * @param path - The request path to match + * @param routes - Route configuration mapping patterns to service names + * @returns The service name for the matching route, or undefined if no match + * + * @example + * ```ts + * // Good: specific patterns first, general patterns last + * routes: { + * '/api/auth/admin/**': { service: 'admin-service' }, + * '/api/auth/**': { service: 'auth-service' }, + * '/api/**': { service: 'api-service' }, + * } + * ``` + */ +export function getServiceForPath(path: string, routes?: Record): string | undefined { + if (!routes) return undefined + + for (const [pattern, config] of Object.entries(routes)) { + if (matchesPattern(path, pattern)) { + return config.service + } + } + + return undefined +} diff --git a/packages/evlog/src/nitro/plugin.ts b/packages/evlog/src/nitro/plugin.ts index 8669d85..e6ce13f 100644 --- a/packages/evlog/src/nitro/plugin.ts +++ b/packages/evlog/src/nitro/plugin.ts @@ -2,8 +2,9 @@ import type { NitroApp } from 'nitropack/types' import { defineNitroPlugin, useRuntimeConfig } from 'nitropack/runtime' import { getHeaders } from 'h3' import { createRequestLogger, initLogger } from '../logger' +import { shouldLog, getServiceForPath } from '../nitro' import type { EnrichContext, RequestLogger, RouteConfig, SamplingConfig, ServerEvent, TailSamplingContext, WideEvent } from '../types' -import { filterSafeHeaders, matchesPattern } from '../utils' +import { filterSafeHeaders } from '../utils' interface EvlogConfig { env?: Record @@ -14,56 +15,6 @@ interface EvlogConfig { sampling?: SamplingConfig } -function shouldLog(path: string, include?: string[], exclude?: string[]): boolean { - // Check exclusions first (they take precedence) - if (exclude && exclude.length > 0) { - if (exclude.some(pattern => matchesPattern(path, pattern))) { - return false - } - } - - // If no include patterns, log everything (that wasn't excluded) - if (!include || include.length === 0) { - return true - } - - // Log only if path matches at least one include pattern - return include.some(pattern => matchesPattern(path, pattern)) -} - -/** - * Find the service name for a given path based on route patterns. - * - * When multiple patterns match the same path, the first matching pattern wins - * based on object iteration order. To ensure predictable behavior, order your - * route patterns from most specific to most general. - * - * @param path - The request path to match - * @param routes - Route configuration mapping patterns to service names - * @returns The service name for the matching route, or undefined if no match - * - * @example - * ```ts - * // Good: specific patterns first, general patterns last - * routes: { - * '/api/auth/admin/**': { service: 'admin-service' }, - * '/api/auth/**': { service: 'auth-service' }, - * '/api/**': { service: 'api-service' }, - * } - * ``` - */ -function getServiceForPath(path: string, routes?: Record): string | undefined { - if (!routes) return undefined - - for (const [pattern, config] of Object.entries(routes)) { - if (matchesPattern(path, pattern)) { - return config.service - } - } - - return undefined -} - function getSafeHeaders(event: ServerEvent): Record { const allHeaders = getHeaders(event as Parameters[0]) return filterSafeHeaders(allHeaders) diff --git a/packages/evlog/src/types.ts b/packages/evlog/src/types.ts index d599951..1297d3a 100644 --- a/packages/evlog/src/types.ts +++ b/packages/evlog/src/types.ts @@ -50,6 +50,14 @@ declare module 'nitropack/types' { } } +declare module 'nitro/types' { + interface NitroRuntimeHooks { + 'evlog:emit:keep': (ctx: TailSamplingContext) => void | Promise + 'evlog:enrich': (ctx: EnrichContext) => void | Promise + 'evlog:drain': (ctx: DrainContext) => void | Promise + } +} + /** * Transport configuration for sending client logs to the server */ @@ -135,7 +143,7 @@ export interface EnrichContext { /** Request metadata (if available) */ request?: { method?: string - path?: string + path: string requestId?: string } /** Safe HTTP request headers (sensitive headers filtered out) */ From 5e2e51d797361cc7e8235107d61e90f0ece6162b Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 20:49:53 +0100 Subject: [PATCH 17/26] chore: deps --- bun.lock | 329 ++++++++++++++++++++++++------------ packages/evlog/package.json | 12 +- 2 files changed, 227 insertions(+), 114 deletions(-) diff --git a/bun.lock b/bun.lock index f00702c..68ff28a 100644 --- a/bun.lock +++ b/bun.lock @@ -61,11 +61,16 @@ "packages/evlog": { "name": "evlog", "version": "1.7.0", + "dependencies": { + "@nuxt/kit": "^4.3.0", + "ufo": "^1.6.3", + }, "devDependencies": { "@nuxt/devtools": "^3.1.1", "@nuxt/schema": "^4.3.1", "@nuxt/test-utils": "^3.23.0", "changelogen": "^0.6.2", + "consola": "^3.4.2", "h3": "^1.15.5", "nitro": "^3.0.1-alpha.2", "nitropack": "^2.13.1", @@ -436,7 +441,7 @@ "@nuxt/image": ["@nuxt/image@2.0.0", "", { "dependencies": { "@nuxt/kit": "^4.2.0", "consola": "^3.4.2", "defu": "^6.1.4", "h3": "^1.15.4", "image-meta": "^0.2.2", "knitwork": "^1.2.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "std-env": "^3.10.0", "ufo": "^1.6.1" }, "optionalDependencies": { "ipx": "^3.1.1" } }, "sha512-otHi6gAoYXKLrp8m27ZjX1PjxOPaltQ4OiUs/BhkW995mF/vXf8SWQTw68fww+Uric0v+XgoVrP9icDi+yT6zw=="], - "@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@nuxt/kit": ["@nuxt/kit@4.3.1", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^3.0.0", "scule": "^1.3.0", "semver": "^7.7.4", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-UjBFt72dnpc+83BV3OIbCT0YHLevJtgJCHpxMX0YRKWLDhhbcDdUse87GtsQBrjvOzK7WUNUYLDS/hQLYev5rA=="], "@nuxt/nitro-server": ["@nuxt/nitro-server@4.3.1", "", { "dependencies": { "@nuxt/devalue": "^2.0.2", "@nuxt/kit": "4.3.1", "@unhead/vue": "^2.1.3", "@vue/shared": "^3.5.27", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "devalue": "^5.6.2", "errx": "^0.1.0", "escape-string-regexp": "^5.0.0", "exsolve": "^1.0.8", "h3": "^1.15.5", "impound": "^1.0.0", "klona": "^2.0.6", "mocked-exports": "^0.1.1", "nitropack": "^2.13.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rou3": "^0.7.12", "std-env": "^3.10.0", "ufo": "^1.6.3", "unctx": "^2.5.0", "unstorage": "^1.17.4", "vue": "^3.5.27", "vue-bundle-renderer": "^2.2.0", "vue-devtools-stub": "^0.1.0" }, "peerDependencies": { "nuxt": "^4.3.1" } }, "sha512-4aNiM69Re02gI1ywnDND0m6QdVKXhWzDdtvl/16veytdHZj3FSq57ZCwOClNJ7HQkEMqXgS+bi6S2HmJX+et+g=="], @@ -462,45 +467,45 @@ "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], - "@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.112.0", "", { "os": "android", "cpu": "arm" }, "sha512-m7TGBR2hjsBJIN9UJ909KBoKsuogo6CuLsHKvUIBXdjI0JVHP8g4ZHeB+BJpGn5LJdeSGDfz9MWiuXrZDRzunw=="], + "@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.110.0", "", { "os": "android", "cpu": "arm" }, "sha512-43fMTO8/5bMlqfOiNSZNKUzIqeLIYuB9Hr1Ohyf58B1wU11S2dPGibTXOGNaWsfgHy99eeZ1bSgeIHy/fEYqbw=="], - "@oxc-minify/binding-android-arm64": ["@oxc-minify/binding-android-arm64@0.112.0", "", { "os": "android", "cpu": "arm64" }, "sha512-RvxOOkzvP5NeeoraBtgNJSBqO+XzlS7DooxST/drAXCfO52GsmxVB1N7QmifrsTYtH8GC2z3DTFjZQ1w/AJOWg=="], + "@oxc-minify/binding-android-arm64": ["@oxc-minify/binding-android-arm64@0.110.0", "", { "os": "android", "cpu": "arm64" }, "sha512-5oQrnn9eK/ccOp80PTrNj0Vq893NPNNRryjGpOIVsYNgWFuoGCfpnKg68oEFcN8bArizYAqw4nvgHljEnar69w=="], - "@oxc-minify/binding-darwin-arm64": ["@oxc-minify/binding-darwin-arm64@0.112.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-hDslO3uVHza3kB9zkcsi25JzN65Gj5ZYty0OvylS11Mhg9ydCYxAzfQ/tISHW/YmV1NRUJX8+GGqM1cKmrHaTA=="], + "@oxc-minify/binding-darwin-arm64": ["@oxc-minify/binding-darwin-arm64@0.110.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dqBDgTG9tF2z2lrZp9E8wU+Godz1i8gCGSei2eFKS2hRploBOD5dmOLp1j4IMornkPvSQmbwB3uSjPq7fjx4EA=="], - "@oxc-minify/binding-darwin-x64": ["@oxc-minify/binding-darwin-x64@0.112.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-mWA2Y5bUyNoGM+gSGGHesgtQ3LDWgpRe4zDGkBDovxNIiDLBXqu/7QcuS+G918w8oG9VYm1q1iinILer/2pD1Q=="], + "@oxc-minify/binding-darwin-x64": ["@oxc-minify/binding-darwin-x64@0.110.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U0AqabqaooDOpYmeeOye8wClv8PSScELXgOfYqyqgrwH9J9KrpCE1jL8Rlqgz68QbL4mPw3V6sKiiHssI4CLeQ=="], - "@oxc-minify/binding-freebsd-x64": ["@oxc-minify/binding-freebsd-x64@0.112.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-T7fsegxcy82xS0jWPXkz/BMhrkb3D7YOCiV0R9pDksjaov+iIFoNEWAoBsaC5NtpdzkX+bmffwDpu336EIfEeg=="], + "@oxc-minify/binding-freebsd-x64": ["@oxc-minify/binding-freebsd-x64@0.110.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-H0w8o/Wo1072WSdLfhwwrpFpwZnPpjQODlHuRYkTfsSSSJbTxQtjJd4uxk7YJsRv5RQp69y0I7zvdH6f8Xueyw=="], - "@oxc-minify/binding-linux-arm-gnueabihf": ["@oxc-minify/binding-linux-arm-gnueabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-yePavbIilAcpVYc8vRsDCn3xJxHMXDZIiamyH9fuLosAHNELcLib4/JR4fhDk4NmHVagQH3kRhsnm5Q9cm3pAw=="], + "@oxc-minify/binding-linux-arm-gnueabihf": ["@oxc-minify/binding-linux-arm-gnueabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-qd6sW0AvEVYZhbVVMGtmKZw3b1zDYGIW+54Uh42moWRAj6i4Jhk/LGr6r9YNZpOINeuvZfkFuEeDD/jbu7xPUA=="], - "@oxc-minify/binding-linux-arm-musleabihf": ["@oxc-minify/binding-linux-arm-musleabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-lmPWLXtW6FspERhy97iP0hwbmLtL66xI29QQ9GpHmTiE4k+zv/FaefuV/Qw+LuHnmFSYzUNrLcxh4ulOZTIP2g=="], + "@oxc-minify/binding-linux-arm-musleabihf": ["@oxc-minify/binding-linux-arm-musleabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7WXP0aXMrWSn0ScppUBi3jf68ebfBG0eri8kxLmBOVSBj6jw1repzkHMITJMBeLr5d0tT/51qFEptiAk2EP2iA=="], - "@oxc-minify/binding-linux-arm64-gnu": ["@oxc-minify/binding-linux-arm64-gnu@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gySS5XqU5MKs/oCjsTlVm8zb8lqcNKHEANsaRmhW2qvGKJoeGwFb6Fbq6TLCZMRuk143mLbncbverBCa1c3dog=="], + "@oxc-minify/binding-linux-arm64-gnu": ["@oxc-minify/binding-linux-arm64-gnu@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-LYfADrq5x1W5gs+u9OIbMbDQNYkAECTXX0ufnAuf3oGmO51rF98kGFR5qJqC/6/csokDyT3wwTpxhE0TkcF/Og=="], - "@oxc-minify/binding-linux-arm64-musl": ["@oxc-minify/binding-linux-arm64-musl@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IRFMZX589lr3rjG0jc8N261/7wqFq2Vl0OMrJWeFls5BF8HiB+fRYuf0Zy2CyRH6NCY2vbdDdp+QCAavQGVsGw=="], + "@oxc-minify/binding-linux-arm64-musl": ["@oxc-minify/binding-linux-arm64-musl@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-53GjCVY8kvymk9P6qNDh6zyblcehF5QHstq9QgCjv13ONGRnSHjeds0PxIwiihD7h295bxsWs84DN39syLPH4Q=="], - "@oxc-minify/binding-linux-ppc64-gnu": ["@oxc-minify/binding-linux-ppc64-gnu@0.112.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-V/69XqIW9hCUceDpcZh79oDg+F4ptEgIfKRENzYs41LRbSoJ7sNjjcW4zifqyviTvzcnXLgK4uoTyoymmNZBMQ=="], + "@oxc-minify/binding-linux-ppc64-gnu": ["@oxc-minify/binding-linux-ppc64-gnu@0.110.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-li8XcN81dxbJDMBESnTgGhoiAQ+CNIdM0QGscZ4duVPjCry1RpX+5FJySFbGqG3pk4s9ZzlL/vtQtbRzZIZOzg=="], - "@oxc-minify/binding-linux-riscv64-gnu": ["@oxc-minify/binding-linux-riscv64-gnu@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-zghvexySyGXGNW+MutjZN7UGTyOQl56RWMlPe1gb+knBm/+0hf9qjk7Q6ofm2tSte+vQolPfQttifGl0dP9uvQ=="], + "@oxc-minify/binding-linux-riscv64-gnu": ["@oxc-minify/binding-linux-riscv64-gnu@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-SweKfsnLKShu6UFV8mwuj1d1wmlNoL/FlAxPUzwjEBgwiT2HQkY24KnjBH+TIA+//1O83kzmWKvvs4OuEhdIEQ=="], - "@oxc-minify/binding-linux-riscv64-musl": ["@oxc-minify/binding-linux-riscv64-musl@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-E4a8VUFDJPb2mPcc7J4NQQPi1ssHKF7/g4r6KD2+SBVERIaEEd3cGNqR7SG3g82/BLGV2UDoQe/WvZCkt5M/bQ=="], + "@oxc-minify/binding-linux-riscv64-musl": ["@oxc-minify/binding-linux-riscv64-musl@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-oH8G4aFMP8XyTsEpdANC5PQyHgSeGlopHZuW1rpyYcaErg5YaK0vXjQ4EM5HVvPm+feBV24JjxgakTnZoF3aOQ=="], - "@oxc-minify/binding-linux-s390x-gnu": ["@oxc-minify/binding-linux-s390x-gnu@0.112.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-2Hx87sK3y6jBV364Mvv0zyxiITIuy26Ixenv6pK7e+4an3HgNdhAj8nk3aLoLTTSvLik5/MaGhcZGEu9tYV1aA=="], + "@oxc-minify/binding-linux-s390x-gnu": ["@oxc-minify/binding-linux-s390x-gnu@0.110.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-W9na+Vza7XVUlpf8wMt4QBfH35KeTENEmnpPUq3NSlbQHz8lSlSvhAafvo43NcKvHAXV3ckD/mUf2VkqSdbklg=="], - "@oxc-minify/binding-linux-x64-gnu": ["@oxc-minify/binding-linux-x64-gnu@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2MSCnEPLk9ddSouMhJo78Xy2/JbYC80OYzWdR4yWTGSULsgH3d1VXg73DSwFL8vU7Ad9oK10DioBY2ww7sQTEg=="], + "@oxc-minify/binding-linux-x64-gnu": ["@oxc-minify/binding-linux-x64-gnu@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XJdA4mmmXOjJxSRgNJXsDP7Xe8h3gQhmb56hUcCrvq5d+h5UcEi2pR8rxsdIrS8QmkLuBA3eHkGK8E27D7DTgQ=="], - "@oxc-minify/binding-linux-x64-musl": ["@oxc-minify/binding-linux-x64-musl@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-HAPfmQKlkVi97/zRonVE9t/kKUG3ni+mOuU1Euw+3s37KwUuOJjmcwXdclVgXKBlTkCGO0FajPwW5dAJeIXCCw=="], + "@oxc-minify/binding-linux-x64-musl": ["@oxc-minify/binding-linux-x64-musl@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QqzvALuOTtSckI8x467R4GNArzYDb/yEh6aNzLoeaY1O7vfT7SPDwlOEcchaTznutpeS9Dy8gUS/AfqtUHaufw=="], - "@oxc-minify/binding-openharmony-arm64": ["@oxc-minify/binding-openharmony-arm64@0.112.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bLnMojcPadYzMNpB6IAqMiTOag4etc0zbs8On73JsotO1W5c5/j/ncplpSokpEpNasKRUpHVRXpmq0KRXprNhw=="], + "@oxc-minify/binding-openharmony-arm64": ["@oxc-minify/binding-openharmony-arm64@0.110.0", "", { "os": "none", "cpu": "arm64" }, "sha512-gAMssLs2Q3+uhLZxanh1DF+27Kaug3cf4PXb9AB7XK81DR+LVcKySXaoGYoOs20Co0fFSphd6rRzKge2qDK3dA=="], - "@oxc-minify/binding-wasm32-wasi": ["@oxc-minify/binding-wasm32-wasi@0.112.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-tv7PmHYq/8QBlqMaDjsy51GF5KQkG17Yc/PsgB5OVndU34kwbQuebBIic7UfK9ygzidI8moYq3ztnu3za/rqHw=="], + "@oxc-minify/binding-wasm32-wasi": ["@oxc-minify/binding-wasm32-wasi@0.110.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-7Wqi5Zjl022bs2zXq+ICdalDPeDuCH/Nhbi8q2isLihAonMVIT0YH2hqqnNEylRNGYck+FJ6gRZwMpGCgrNxPg=="], - "@oxc-minify/binding-win32-arm64-msvc": ["@oxc-minify/binding-win32-arm64-msvc@0.112.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-d+jes2jwRkcBSpcaZC6cL8GBi56Br6uAorn9dfquhWLczWL+hHSvvVrRgT1i5/6dkf5UWx2zdoEsAMiJ11w78A=="], + "@oxc-minify/binding-win32-arm64-msvc": ["@oxc-minify/binding-win32-arm64-msvc@0.110.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZPx+0Tj4dqn41ecyoGotlvekQKy6JxJCixn9Rw7h/dafZ3eDuBcEVh3c2ZoldXXsyMIt5ywI8IWzFZsjNedd5Q=="], - "@oxc-minify/binding-win32-ia32-msvc": ["@oxc-minify/binding-win32-ia32-msvc@0.112.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-TV1C3qDwj7//jNIi5tnNRhReSUgtaRQKi5KobDE6zVAc5gjeuBA8G2qizS9ziXlf/I0dlelrGmGMMDJmH9ekWg=="], + "@oxc-minify/binding-win32-ia32-msvc": ["@oxc-minify/binding-win32-ia32-msvc@0.110.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-H0Oyd3RWBfpEyvJIrFK94RYiY7KKSQl11Ym7LMDwLEagelIAfRCkt1amHZhFa/S3ZRoaOJFXzEw4YKeSsjVFsg=="], - "@oxc-minify/binding-win32-x64-msvc": ["@oxc-minify/binding-win32-x64-msvc@0.112.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LML2Gld6VY8/+7a3VH4k1qngsBXvTkXgbmYgSYwaElqtiQiYaAcXfi0XKOUGe3k3GbBK4juAGixC31CrdFHAQw=="], + "@oxc-minify/binding-win32-x64-msvc": ["@oxc-minify/binding-win32-x64-msvc@0.110.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Hr3nK90+qXKJ2kepXwFIcNfQQIOBecB4FFCyaMMypthoEEhVP08heRynj4eSXZ8NL9hLjs3fQzH8PJXfpznRnQ=="], "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.112.0", "", { "os": "android", "cpu": "arm" }, "sha512-retxBzJ39Da7Lh/eZTn9+HJgTeDUxZIpuI0urOsmcFsBKXAth3lc1jIvwseQ9qbAI/VrsoFOXiGIzgclARbAHg=="], @@ -544,45 +549,45 @@ "@oxc-project/types": ["@oxc-project/types@0.111.0", "", {}, "sha512-bh54LJMafgRGl2cPQ/QM+tI5rWaShm/wK9KywEj/w36MhiPKXYM67H2y3q+9pr4YO7ufwg2AKdBAZkhHBD8ClA=="], - "@oxc-transform/binding-android-arm-eabi": ["@oxc-transform/binding-android-arm-eabi@0.112.0", "", { "os": "android", "cpu": "arm" }, "sha512-r4LuBaPnOAi0eUOBNi880Fm2tO2omH7N1FRrL6+nyz/AjQ+QPPLtoyZJva0O+sKi1buyN/7IzM5p9m+5ANSDbg=="], + "@oxc-transform/binding-android-arm-eabi": ["@oxc-transform/binding-android-arm-eabi@0.110.0", "", { "os": "android", "cpu": "arm" }, "sha512-sE9dxvqqAax1YYJ3t7j+h5ZSI9jl6dYuDfngl6ieZUrIy5P89/8JKVgAzgp8o3wQSo7ndpJvYsi1K4ZqrmbP7w=="], - "@oxc-transform/binding-android-arm64": ["@oxc-transform/binding-android-arm64@0.112.0", "", { "os": "android", "cpu": "arm64" }, "sha512-ve46vQcQrY8eGe8990VSlS9gkD+AogJqbtfOkeua+5sQGQTDgeIRRxOm7ktCo19uZc2bEBwXRJITgosd+NRVmQ=="], + "@oxc-transform/binding-android-arm64": ["@oxc-transform/binding-android-arm64@0.110.0", "", { "os": "android", "cpu": "arm64" }, "sha512-nqtbP4aMCtsCZ6qpHlHaQoWVHSBtlKzwaAgwEOvR+9DWqHjk31BHvpGiDXlMeed6CVNpl3lCbWgygb3RcSjcfw=="], - "@oxc-transform/binding-darwin-arm64": ["@oxc-transform/binding-darwin-arm64@0.112.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ddbmLU3Tr+i7MOynfwAXxUXud3SjJKlv7XNjaq08qiI8Av/QvhXVGc2bMhXkWQSMSBUeTDoiughKjK+Zsb6y/A=="], + "@oxc-transform/binding-darwin-arm64": ["@oxc-transform/binding-darwin-arm64@0.110.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oeSeHnL4Z4cMXtc8V0/rwoVn0dgwlS9q0j6LcHn9dIhtFEdp3W0iSBF8YmMQA+E7sILeLDjsHmHE4Kp0sOScXw=="], - "@oxc-transform/binding-darwin-x64": ["@oxc-transform/binding-darwin-x64@0.112.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-TKvmNw96jQZPqYb4pRrzLFDailNB3YS14KNn+x2hwRbqc6CqY96S9PYwyOpVpYdxfoRjYO9WgX9SoS+62a1DPA=="], + "@oxc-transform/binding-darwin-x64": ["@oxc-transform/binding-darwin-x64@0.110.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-nL9K5x7OuZydobAGPylsEW9d4APs2qEkIBLMgQPA+kY8dtVD3IR87QsTbs4l4DBQYyun/+ay6qVCDlxqxdX2Jg=="], - "@oxc-transform/binding-freebsd-x64": ["@oxc-transform/binding-freebsd-x64@0.112.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YPMkSCDaelO8HHYRMYjm+Q+IfkfIbdtQzwPuasItYkq8UUkNeHNPheNh2JkvQa3c+io3E9ePOgHQ2yihpk7o/Q=="], + "@oxc-transform/binding-freebsd-x64": ["@oxc-transform/binding-freebsd-x64@0.110.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GS29zXXirDQhZEUq8xKJ1azAWMuUy3Ih3W5Bc5ddk12LRthO5wRLFcKIyeHpAXCoXymQ+LmxbMtbPf84GPxouw=="], - "@oxc-transform/binding-linux-arm-gnueabihf": ["@oxc-transform/binding-linux-arm-gnueabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-nA7kzQGNEpuTRknst/IJ3l8hqmDmEda3aun6jkXgp7gKxESjuHeaNH04mKISxvJ7fIacvP2g/wtTSnm4u5jL8Q=="], + "@oxc-transform/binding-linux-arm-gnueabihf": ["@oxc-transform/binding-linux-arm-gnueabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-glzDHak8ISyZJemCUi7RCvzNSl+MQ1ly9RceT2qRufhUsvNZ4C/2QLJ1HJwd2N6E88bO4laYn+RofdRzNnGGEA=="], - "@oxc-transform/binding-linux-arm-musleabihf": ["@oxc-transform/binding-linux-arm-musleabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-w8GuLmckKlGc3YujaZKhtbFxziCcosvM2l9GnQjCb/yENWLGDiyQOy0BTAgPGdJwpYTiOeJblEXSuXYvlE1Ong=="], + "@oxc-transform/binding-linux-arm-musleabihf": ["@oxc-transform/binding-linux-arm-musleabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-8JThvgJ2FRoTVfbp7e4wqeZqCZbtudM06SfZmNzND9kPNu/LVYygIR+72RWs+xm4bWkuYHg/islo/boNPtMT5Q=="], - "@oxc-transform/binding-linux-arm64-gnu": ["@oxc-transform/binding-linux-arm64-gnu@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-9LwwGnJ8+WT0rXcrI8M0RJtDNt91eMqcDPPEvJxhRFHIMcHTy5D5xT+fOl3Us0yMqKo3HUWkbfUYqAp4GoZ3Jw=="], + "@oxc-transform/binding-linux-arm64-gnu": ["@oxc-transform/binding-linux-arm64-gnu@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IRh21Ub/g4bkHoErZ0AUWMlWfoZaS0A6EaOVtbcY70RSYIMlrsbjiFwJCzM+b/1DD1rXbH5tsGcH7GweTbfRqg=="], - "@oxc-transform/binding-linux-arm64-musl": ["@oxc-transform/binding-linux-arm64-musl@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Lg6VOuSd3oXv7J0eGywgqh/086h+qQzIBOD+47pYKMTTJcbDe+f3h/RgGoMKJE5HhiwT5sH1aGEJfIfaYUiVSw=="], + "@oxc-transform/binding-linux-arm64-musl": ["@oxc-transform/binding-linux-arm64-musl@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-e5JN94/oy+wevk76q+LMr+2klTTcO60uXa+Wkq558Ms7mdF2TvkKFI++d/JeiuIwJLTi/BxQ4qdT5FWcsHM/ug=="], - "@oxc-transform/binding-linux-ppc64-gnu": ["@oxc-transform/binding-linux-ppc64-gnu@0.112.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-PXzmj82o1moA4IGphYImTRgc2youTi4VRfyFX3CHwLjxPcQ5JtcsgbDt4QUdOzXZ+zC07s5jf2ZzhRapEOlj2w=="], + "@oxc-transform/binding-linux-ppc64-gnu": ["@oxc-transform/binding-linux-ppc64-gnu@0.110.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y3/Tnnz1GvDpmv8FXBIKtdZPsdZklOEPdrL6NHrN5i2u54BOkybFaDSptgWF53wOrJlTrcmAVSE6fRKK9XCM2Q=="], - "@oxc-transform/binding-linux-riscv64-gnu": ["@oxc-transform/binding-linux-riscv64-gnu@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-vhJsMsVH/6xwa3bt1LGts33FXUkGjaEGDwsRyp4lIfOjSfQVWMtCmWMFNaA0dW9FVWdD2Gt2fSFBSZ+azDxlpg=="], + "@oxc-transform/binding-linux-riscv64-gnu": ["@oxc-transform/binding-linux-riscv64-gnu@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-Y0E35iA9/v9jlkNcP6tMJ+ZFOS0rLsWDqG6rU9z+X2R3fBFJBO9UARIK6ngx8upxk81y1TFR2CmBFhupfYdH6Q=="], - "@oxc-transform/binding-linux-riscv64-musl": ["@oxc-transform/binding-linux-riscv64-musl@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-cXWFb7z+2IjFUEcXtRwluq9oEG5qnyFCjiu3SWrgYNcWwPdHusv3I/7K5/CTbbi4StoZ5txbi7/iSfDHNyWuRw=="], + "@oxc-transform/binding-linux-riscv64-musl": ["@oxc-transform/binding-linux-riscv64-musl@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-JOUSYFfHjBUs7xp2FHmZHb8eTYD/oEu0NklS6JgUauqnoXZHiTLPLVW2o2uVCqldnabYHcomuwI2iqVFYJNhTw=="], - "@oxc-transform/binding-linux-s390x-gnu": ["@oxc-transform/binding-linux-s390x-gnu@0.112.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-eEFu4SRqJTJ20/88KRWmp+jpHKAw0Y1DsnSgpEeXyBIIcsOaLIUMU/TfYWUmqRbvbMV9rmOmI3kp5xWYUq6kSQ=="], + "@oxc-transform/binding-linux-s390x-gnu": ["@oxc-transform/binding-linux-s390x-gnu@0.110.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-7blgoXF9D3Ngzb7eun23pNrHJpoV/TtE6LObwlZ3Nmb4oZ6Z+yMvBVaoW68NarbmvNGfZ95zrOjgm6cVETLYBA=="], - "@oxc-transform/binding-linux-x64-gnu": ["@oxc-transform/binding-linux-x64-gnu@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ST1MDT+TlOyZ1c5btrGinRSUW2Jf4Pa+0gdKwsyjDSOC3dxy2ZNkN3mosTf4ywc3J+mxfYKqtjs7zSwHz03ILA=="], + "@oxc-transform/binding-linux-x64-gnu": ["@oxc-transform/binding-linux-x64-gnu@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-YQ2joGWCVDZVEU2cD/r/w49hVjDm/Qu1BvC/7zs8LvprzdLS/HyMXGF2oA0puw0b+AqgYaz3bhwKB2xexHyITQ=="], - "@oxc-transform/binding-linux-x64-musl": ["@oxc-transform/binding-linux-x64-musl@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ISQoA3pD4cyTGpf9sXXeerH6pL2L6EIpdy6oAy2ttkswyVFDyQNVOVIGIdLZDgbpmqGljxZnWqt/J/N68pQaig=="], + "@oxc-transform/binding-linux-x64-musl": ["@oxc-transform/binding-linux-x64-musl@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-fkjr5qE632ULmNgvFXWDR/8668WxERz3tU7TQFp6JebPBneColitjSkdx6VKNVXEoMmQnOvBIGeP5tUNT384oA=="], - "@oxc-transform/binding-openharmony-arm64": ["@oxc-transform/binding-openharmony-arm64@0.112.0", "", { "os": "none", "cpu": "arm64" }, "sha512-UOGVrGIv7yLJovyEXEyUTADuLq98vd/cbMHFLJweRXD+11I8Tn4jASi4WzdsN8C3BVYGRHrXH2NlSBmhz33a4g=="], + "@oxc-transform/binding-openharmony-arm64": ["@oxc-transform/binding-openharmony-arm64@0.110.0", "", { "os": "none", "cpu": "arm64" }, "sha512-HWH9Zj+lMrdSTqFRCZsvDWMz7OnMjbdGsm3xURXWfRZpuaz0bVvyuZNDQXc4FyyhRDsemICaJbU1bgeIpUJDGw=="], - "@oxc-transform/binding-wasm32-wasi": ["@oxc-transform/binding-wasm32-wasi@0.112.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-XIX7Gpq9koAvzBVHDlVFHM79r5uOVK6kTEsdsN4qaajpjkgtv4tdsAOKIYK6l7fUbsbE6xS+6w1+yRFrDeC1kg=="], + "@oxc-transform/binding-wasm32-wasi": ["@oxc-transform/binding-wasm32-wasi@0.110.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ejdxHmYfIcHDPhZUe3WklViLt9mDEJE5BzcW7+R1vc5i/5JFA8D0l7NUSsHBJ7FB8Bu9gF+5iMDm6cXGAgaghw=="], - "@oxc-transform/binding-win32-arm64-msvc": ["@oxc-transform/binding-win32-arm64-msvc@0.112.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-EgXef9kOne9BNsbYBbuRqxk2hteT0xsAGcx/VbtCBMJYNj8fANFhT271DUSOgfa4DAgrQQmsyt/Kr1aV9mpU9w=="], + "@oxc-transform/binding-win32-arm64-msvc": ["@oxc-transform/binding-win32-arm64-msvc@0.110.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-9VTwpXCZs7xkV+mKhQ62dVk7KLnLXtEUxNS2T4nLz3iMl1IJbA4h5oltK0JoobtiUAnbkV53QmMVGW8+Nh3bDQ=="], - "@oxc-transform/binding-win32-ia32-msvc": ["@oxc-transform/binding-win32-ia32-msvc@0.112.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-6QaB0qjNaou2YR+blncHdw7j0e26IOwOIjLbhVGDeuf9+4rjJeiqRXJ2hOtCcS4zblnao/MjdgQuZ3fM0nl+Kw=="], + "@oxc-transform/binding-win32-ia32-msvc": ["@oxc-transform/binding-win32-ia32-msvc@0.110.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-5y0fzuNON7/F2hh2P94vANFaRPJ/3DI1hVl5rseCT8VUVqOGIjWaza0YS/D1g6t1WwycW2LWDMi2raOKoWU5GQ=="], - "@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.112.0", "", { "os": "win32", "cpu": "x64" }, "sha512-FRKYlY959QeqRPx9kXs0HjU2xuXPT1cdF+vvA200D9uAX/KLcC34MwRqUKTYml4kCc2Vf/P2pBR9cQuBm3zECQ=="], + "@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.110.0", "", { "os": "win32", "cpu": "x64" }, "sha512-QROrowwlrApI1fEScMknGWKM6GTM/Z2xwMnDqvSaEmzNazBsDUlE08Jasw610hFEsYAVU2K5sp/YaCa9ORdP4A=="], "@parcel/watcher": ["@parcel/watcher@2.5.6", "", { "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", "node-addon-api": "^7.0.0", "picomatch": "^4.0.3" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.6", "@parcel/watcher-darwin-arm64": "2.5.6", "@parcel/watcher-darwin-x64": "2.5.6", "@parcel/watcher-freebsd-x64": "2.5.6", "@parcel/watcher-linux-arm-glibc": "2.5.6", "@parcel/watcher-linux-arm-musl": "2.5.6", "@parcel/watcher-linux-arm64-glibc": "2.5.6", "@parcel/watcher-linux-arm64-musl": "2.5.6", "@parcel/watcher-linux-x64-glibc": "2.5.6", "@parcel/watcher-linux-x64-musl": "2.5.6", "@parcel/watcher-win32-arm64": "2.5.6", "@parcel/watcher-win32-ia32": "2.5.6", "@parcel/watcher-win32-x64": "2.5.6" } }, "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ=="], @@ -2186,11 +2191,11 @@ "orderedmap": ["orderedmap@2.1.1", "", {}, "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g=="], - "oxc-minify": ["oxc-minify@0.112.0", "", { "optionalDependencies": { "@oxc-minify/binding-android-arm-eabi": "0.112.0", "@oxc-minify/binding-android-arm64": "0.112.0", "@oxc-minify/binding-darwin-arm64": "0.112.0", "@oxc-minify/binding-darwin-x64": "0.112.0", "@oxc-minify/binding-freebsd-x64": "0.112.0", "@oxc-minify/binding-linux-arm-gnueabihf": "0.112.0", "@oxc-minify/binding-linux-arm-musleabihf": "0.112.0", "@oxc-minify/binding-linux-arm64-gnu": "0.112.0", "@oxc-minify/binding-linux-arm64-musl": "0.112.0", "@oxc-minify/binding-linux-ppc64-gnu": "0.112.0", "@oxc-minify/binding-linux-riscv64-gnu": "0.112.0", "@oxc-minify/binding-linux-riscv64-musl": "0.112.0", "@oxc-minify/binding-linux-s390x-gnu": "0.112.0", "@oxc-minify/binding-linux-x64-gnu": "0.112.0", "@oxc-minify/binding-linux-x64-musl": "0.112.0", "@oxc-minify/binding-openharmony-arm64": "0.112.0", "@oxc-minify/binding-wasm32-wasi": "0.112.0", "@oxc-minify/binding-win32-arm64-msvc": "0.112.0", "@oxc-minify/binding-win32-ia32-msvc": "0.112.0", "@oxc-minify/binding-win32-x64-msvc": "0.112.0" } }, "sha512-rkVSeeIRSt+RYI9uX6xonBpLUpvZyegxIg0UL87ev7YAfUqp7IIZlRjkgQN5Us1lyXD//TOo0Dcuuro/TYOWoQ=="], + "oxc-minify": ["oxc-minify@0.110.0", "", { "optionalDependencies": { "@oxc-minify/binding-android-arm-eabi": "0.110.0", "@oxc-minify/binding-android-arm64": "0.110.0", "@oxc-minify/binding-darwin-arm64": "0.110.0", "@oxc-minify/binding-darwin-x64": "0.110.0", "@oxc-minify/binding-freebsd-x64": "0.110.0", "@oxc-minify/binding-linux-arm-gnueabihf": "0.110.0", "@oxc-minify/binding-linux-arm-musleabihf": "0.110.0", "@oxc-minify/binding-linux-arm64-gnu": "0.110.0", "@oxc-minify/binding-linux-arm64-musl": "0.110.0", "@oxc-minify/binding-linux-ppc64-gnu": "0.110.0", "@oxc-minify/binding-linux-riscv64-gnu": "0.110.0", "@oxc-minify/binding-linux-riscv64-musl": "0.110.0", "@oxc-minify/binding-linux-s390x-gnu": "0.110.0", "@oxc-minify/binding-linux-x64-gnu": "0.110.0", "@oxc-minify/binding-linux-x64-musl": "0.110.0", "@oxc-minify/binding-openharmony-arm64": "0.110.0", "@oxc-minify/binding-wasm32-wasi": "0.110.0", "@oxc-minify/binding-win32-arm64-msvc": "0.110.0", "@oxc-minify/binding-win32-ia32-msvc": "0.110.0", "@oxc-minify/binding-win32-x64-msvc": "0.110.0" } }, "sha512-KWGTzPo83QmGrXC4ml83PM9HDwUPtZFfasiclUvTV4i3/0j7xRRqINVkrL77CbQnoWura3CMxkRofjQKVDuhBw=="], "oxc-parser": ["oxc-parser@0.112.0", "", { "dependencies": { "@oxc-project/types": "^0.112.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.112.0", "@oxc-parser/binding-android-arm64": "0.112.0", "@oxc-parser/binding-darwin-arm64": "0.112.0", "@oxc-parser/binding-darwin-x64": "0.112.0", "@oxc-parser/binding-freebsd-x64": "0.112.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.112.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.112.0", "@oxc-parser/binding-linux-arm64-gnu": "0.112.0", "@oxc-parser/binding-linux-arm64-musl": "0.112.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.112.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.112.0", "@oxc-parser/binding-linux-riscv64-musl": "0.112.0", "@oxc-parser/binding-linux-s390x-gnu": "0.112.0", "@oxc-parser/binding-linux-x64-gnu": "0.112.0", "@oxc-parser/binding-linux-x64-musl": "0.112.0", "@oxc-parser/binding-openharmony-arm64": "0.112.0", "@oxc-parser/binding-wasm32-wasi": "0.112.0", "@oxc-parser/binding-win32-arm64-msvc": "0.112.0", "@oxc-parser/binding-win32-ia32-msvc": "0.112.0", "@oxc-parser/binding-win32-x64-msvc": "0.112.0" } }, "sha512-7rQ3QdJwobMQLMZwQaPuPYMEF2fDRZwf51lZ//V+bA37nejjKW5ifMHbbCwvA889Y4RLhT+/wLJpPRhAoBaZYw=="], - "oxc-transform": ["oxc-transform@0.112.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm-eabi": "0.112.0", "@oxc-transform/binding-android-arm64": "0.112.0", "@oxc-transform/binding-darwin-arm64": "0.112.0", "@oxc-transform/binding-darwin-x64": "0.112.0", "@oxc-transform/binding-freebsd-x64": "0.112.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.112.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.112.0", "@oxc-transform/binding-linux-arm64-gnu": "0.112.0", "@oxc-transform/binding-linux-arm64-musl": "0.112.0", "@oxc-transform/binding-linux-ppc64-gnu": "0.112.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.112.0", "@oxc-transform/binding-linux-riscv64-musl": "0.112.0", "@oxc-transform/binding-linux-s390x-gnu": "0.112.0", "@oxc-transform/binding-linux-x64-gnu": "0.112.0", "@oxc-transform/binding-linux-x64-musl": "0.112.0", "@oxc-transform/binding-openharmony-arm64": "0.112.0", "@oxc-transform/binding-wasm32-wasi": "0.112.0", "@oxc-transform/binding-win32-arm64-msvc": "0.112.0", "@oxc-transform/binding-win32-ia32-msvc": "0.112.0", "@oxc-transform/binding-win32-x64-msvc": "0.112.0" } }, "sha512-cIRRvZgrHfsAHrkt8LWdAX4+Do8R0MzQSfeo9yzErzHeYiuyNiP4PCTPbOy/wBXL4MYzt3ebrBa5jt3akQkKAg=="], + "oxc-transform": ["oxc-transform@0.110.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm-eabi": "0.110.0", "@oxc-transform/binding-android-arm64": "0.110.0", "@oxc-transform/binding-darwin-arm64": "0.110.0", "@oxc-transform/binding-darwin-x64": "0.110.0", "@oxc-transform/binding-freebsd-x64": "0.110.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.110.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.110.0", "@oxc-transform/binding-linux-arm64-gnu": "0.110.0", "@oxc-transform/binding-linux-arm64-musl": "0.110.0", "@oxc-transform/binding-linux-ppc64-gnu": "0.110.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.110.0", "@oxc-transform/binding-linux-riscv64-musl": "0.110.0", "@oxc-transform/binding-linux-s390x-gnu": "0.110.0", "@oxc-transform/binding-linux-x64-gnu": "0.110.0", "@oxc-transform/binding-linux-x64-musl": "0.110.0", "@oxc-transform/binding-openharmony-arm64": "0.110.0", "@oxc-transform/binding-wasm32-wasi": "0.110.0", "@oxc-transform/binding-win32-arm64-msvc": "0.110.0", "@oxc-transform/binding-win32-ia32-msvc": "0.110.0", "@oxc-transform/binding-win32-x64-msvc": "0.110.0" } }, "sha512-/fymQNzzUoKZweH0nC5yvbI2eR0yWYusT9TEKDYVgOgYrf9Qmdez9lUFyvxKR9ycx+PTHi/reIOzqf3wkShQsw=="], "oxc-walker": ["oxc-walker@0.7.0", "", { "dependencies": { "magic-regexp": "^0.10.0" }, "peerDependencies": { "oxc-parser": ">=0.98.0" } }, "sha512-54B4KUhrzbzc4sKvKwVYm7E2PgeROpGba0/2nlNZMqfDyca+yOor5IMb4WLGBatGDT0nkzYdYuzylg7n3YfB7A=="], @@ -2398,7 +2403,7 @@ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], - "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "rc9": ["rc9@3.0.0", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.5" } }, "sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA=="], "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], @@ -2778,7 +2783,7 @@ "unrun": ["unrun@0.2.27", "", { "dependencies": { "rolldown": "1.0.0-rc.3" }, "peerDependencies": { "synckit": "^0.11.11" }, "optionalPeers": ["synckit"], "bin": { "unrun": "dist/cli.mjs" } }, "sha512-Mmur1UJpIbfxasLOhPRvox/QS4xBiDii71hMP7smfRthGcwFL2OAmYRgduLANOAU4LUkvVamuP+02U+c90jlrw=="], - "unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "unstorage": ["unstorage@2.0.0-alpha.5", "", { "peerDependencies": { "@azure/app-configuration": "^1.9.0", "@azure/cosmos": "^4.7.0", "@azure/data-tables": "^13.3.1", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.29.1", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.12.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.35.6", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.8.2", "lru-cache": "^11.2.2", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-Sj8btci21Twnd6M+N+MHhjg3fVn6lAPElPmvFTe0Y/wR0WImErUdA1PzlAaUavHylJ7uDiFwlZDQKm0elG4b7g=="], "untun": ["untun@0.1.3", "", { "dependencies": { "citty": "^0.1.5", "consola": "^3.2.3", "pathe": "^1.1.1" }, "bin": { "untun": "bin/untun.mjs" } }, "sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ=="], @@ -2934,6 +2939,8 @@ "@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + "@dxup/nuxt/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], @@ -2962,32 +2969,44 @@ "@nuxt/cli/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "@nuxt/content/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@nuxt/content/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], "@nuxt/content/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@nuxt/devtools/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "@nuxt/devtools-kit/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "@nuxt/fonts/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@nuxt/fonts/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], "@nuxt/fonts/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "@nuxt/icon/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "@nuxt/image/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@nuxt/nitro-server/@nuxt/kit": ["@nuxt/kit@4.3.1", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^3.0.0", "scule": "^1.3.0", "semver": "^7.7.4", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-UjBFt72dnpc+83BV3OIbCT0YHLevJtgJCHpxMX0YRKWLDhhbcDdUse87GtsQBrjvOzK7WUNUYLDS/hQLYev5rA=="], + "@nuxt/kit/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "@nuxt/nitro-server/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], - "@nuxt/telemetry/ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="], + "@nuxt/nitro-server/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], - "@nuxt/telemetry/rc9": ["rc9@3.0.0", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.5" } }, "sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA=="], + "@nuxt/telemetry/ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="], "@nuxt/test-utils/@nuxt/kit": ["@nuxt/kit@3.21.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "knitwork": "^1.3.0", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-KMTLK/dsGaQioZzkYUvgfN9le4grNW54aNcA1jqzgVZLcFVy4jJfrJr5WZio9NT2EMfajdoZ+V28aD7BRr4Zfw=="], + "@nuxt/ui/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@nuxt/ui/@nuxt/schema": ["@nuxt/schema@4.3.0", "", { "dependencies": { "@vue/shared": "^3.5.27", "defu": "^6.1.4", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "std-env": "^3.10.0" } }, "sha512-+Ps3exseMFH3MOapbBmDdpaHpPV7wqcB6+Ir9w8h91771HwMOWrQomAZpqDvw7FtFraoD5Xw7dhSKDhkwJRSmQ=="], "@nuxt/ui/@unhead/vue": ["@unhead/vue@2.1.2", "", { "dependencies": { "hookable": "^6.0.1", "unhead": "2.1.2" }, "peerDependencies": { "vue": ">=3.5.18" } }, "sha512-w5yxH/fkkLWAFAOnMSIbvAikNHYn6pgC7zGF/BasXf+K3CO1cYIPFehYAk5jpcsbiNPMc3goyyw1prGLoyD14g=="], - "@nuxt/vite-builder/@nuxt/kit": ["@nuxt/kit@4.3.1", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^3.0.0", "scule": "^1.3.0", "semver": "^7.7.4", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-UjBFt72dnpc+83BV3OIbCT0YHLevJtgJCHpxMX0YRKWLDhhbcDdUse87GtsQBrjvOzK7WUNUYLDS/hQLYev5rA=="], - "@nuxt/vite-builder/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], "@nuxt/vite-builder/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -2998,6 +3017,8 @@ "@nuxtjs/color-mode/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "@nuxtjs/i18n/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@nuxtjs/i18n/oxc-parser": ["oxc-parser@0.95.0", "", { "dependencies": { "@oxc-project/types": "^0.95.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm64": "0.95.0", "@oxc-parser/binding-darwin-arm64": "0.95.0", "@oxc-parser/binding-darwin-x64": "0.95.0", "@oxc-parser/binding-freebsd-x64": "0.95.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.95.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.95.0", "@oxc-parser/binding-linux-arm64-gnu": "0.95.0", "@oxc-parser/binding-linux-arm64-musl": "0.95.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.95.0", "@oxc-parser/binding-linux-s390x-gnu": "0.95.0", "@oxc-parser/binding-linux-x64-gnu": "0.95.0", "@oxc-parser/binding-linux-x64-musl": "0.95.0", "@oxc-parser/binding-wasm32-wasi": "0.95.0", "@oxc-parser/binding-win32-arm64-msvc": "0.95.0", "@oxc-parser/binding-win32-x64-msvc": "0.95.0" } }, "sha512-Te8fE/SmiiKWIrwBwxz5Dod87uYvsbcZ9JAL5ylPg1DevyKgTkxCXnPEaewk1Su2qpfNmry5RHoN+NywWFCG+A=="], "@nuxtjs/i18n/oxc-transform": ["oxc-transform@0.95.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm64": "0.95.0", "@oxc-transform/binding-darwin-arm64": "0.95.0", "@oxc-transform/binding-darwin-x64": "0.95.0", "@oxc-transform/binding-freebsd-x64": "0.95.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.95.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.95.0", "@oxc-transform/binding-linux-arm64-gnu": "0.95.0", "@oxc-transform/binding-linux-arm64-musl": "0.95.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.95.0", "@oxc-transform/binding-linux-s390x-gnu": "0.95.0", "@oxc-transform/binding-linux-x64-gnu": "0.95.0", "@oxc-transform/binding-linux-x64-musl": "0.95.0", "@oxc-transform/binding-wasm32-wasi": "0.95.0", "@oxc-transform/binding-win32-arm64-msvc": "0.95.0", "@oxc-transform/binding-win32-x64-msvc": "0.95.0" } }, "sha512-SmS5aThb5K0SoUZgzGbikNBjrGHfOY4X5TEqBlaZb1uy5YgXbUSbpakpZJ13yW36LNqy8Im5+y+sIk5dlzpZ/w=="], @@ -3010,6 +3031,12 @@ "@nuxtjs/mcp-toolkit/@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="], + "@nuxtjs/mcp-toolkit/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "@nuxtjs/mdc/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "@nuxtjs/robots/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "@parcel/watcher-wasm/napi-wasm": ["napi-wasm@1.1.3", "", { "bundled": true }, "sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg=="], "@poppinss/colors/kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], @@ -3070,6 +3097,8 @@ "body-parser/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + "c12/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "chrome-launcher/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], "compress-commons/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], @@ -3078,6 +3107,8 @@ "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], + "docus/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "engine.io-client/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], @@ -3092,6 +3123,8 @@ "fontless/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "fontless/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "giget/citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], @@ -3110,6 +3143,8 @@ "ipx/citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], + "ipx/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + "jsonc-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "jsonc-eslint-parser/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], @@ -3136,12 +3171,6 @@ "nitro/ofetch": ["ofetch@2.0.0-alpha.3", "", {}, "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA=="], - "nitro/oxc-minify": ["oxc-minify@0.110.0", "", { "optionalDependencies": { "@oxc-minify/binding-android-arm-eabi": "0.110.0", "@oxc-minify/binding-android-arm64": "0.110.0", "@oxc-minify/binding-darwin-arm64": "0.110.0", "@oxc-minify/binding-darwin-x64": "0.110.0", "@oxc-minify/binding-freebsd-x64": "0.110.0", "@oxc-minify/binding-linux-arm-gnueabihf": "0.110.0", "@oxc-minify/binding-linux-arm-musleabihf": "0.110.0", "@oxc-minify/binding-linux-arm64-gnu": "0.110.0", "@oxc-minify/binding-linux-arm64-musl": "0.110.0", "@oxc-minify/binding-linux-ppc64-gnu": "0.110.0", "@oxc-minify/binding-linux-riscv64-gnu": "0.110.0", "@oxc-minify/binding-linux-riscv64-musl": "0.110.0", "@oxc-minify/binding-linux-s390x-gnu": "0.110.0", "@oxc-minify/binding-linux-x64-gnu": "0.110.0", "@oxc-minify/binding-linux-x64-musl": "0.110.0", "@oxc-minify/binding-openharmony-arm64": "0.110.0", "@oxc-minify/binding-wasm32-wasi": "0.110.0", "@oxc-minify/binding-win32-arm64-msvc": "0.110.0", "@oxc-minify/binding-win32-ia32-msvc": "0.110.0", "@oxc-minify/binding-win32-x64-msvc": "0.110.0" } }, "sha512-KWGTzPo83QmGrXC4ml83PM9HDwUPtZFfasiclUvTV4i3/0j7xRRqINVkrL77CbQnoWura3CMxkRofjQKVDuhBw=="], - - "nitro/oxc-transform": ["oxc-transform@0.110.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm-eabi": "0.110.0", "@oxc-transform/binding-android-arm64": "0.110.0", "@oxc-transform/binding-darwin-arm64": "0.110.0", "@oxc-transform/binding-darwin-x64": "0.110.0", "@oxc-transform/binding-freebsd-x64": "0.110.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.110.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.110.0", "@oxc-transform/binding-linux-arm64-gnu": "0.110.0", "@oxc-transform/binding-linux-arm64-musl": "0.110.0", "@oxc-transform/binding-linux-ppc64-gnu": "0.110.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.110.0", "@oxc-transform/binding-linux-riscv64-musl": "0.110.0", "@oxc-transform/binding-linux-s390x-gnu": "0.110.0", "@oxc-transform/binding-linux-x64-gnu": "0.110.0", "@oxc-transform/binding-linux-x64-musl": "0.110.0", "@oxc-transform/binding-openharmony-arm64": "0.110.0", "@oxc-transform/binding-wasm32-wasi": "0.110.0", "@oxc-transform/binding-win32-arm64-msvc": "0.110.0", "@oxc-transform/binding-win32-ia32-msvc": "0.110.0", "@oxc-transform/binding-win32-x64-msvc": "0.110.0" } }, "sha512-/fymQNzzUoKZweH0nC5yvbI2eR0yWYusT9TEKDYVgOgYrf9Qmdez9lUFyvxKR9ycx+PTHi/reIOzqf3wkShQsw=="], - - "nitro/unstorage": ["unstorage@2.0.0-alpha.5", "", { "peerDependencies": { "@azure/app-configuration": "^1.9.0", "@azure/cosmos": "^4.7.0", "@azure/data-tables": "^13.3.1", "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", "@azure/storage-blob": "^12.29.1", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.12.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.35.6", "@vercel/blob": ">=0.27.3", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "chokidar": "^4 || ^5", "db0": ">=0.3.4", "idb-keyval": "^6.2.2", "ioredis": "^5.8.2", "lru-cache": "^11.2.2", "mongodb": "^6 || ^7", "ofetch": "*", "uploadthing": "^7.7.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "chokidar", "db0", "idb-keyval", "ioredis", "lru-cache", "mongodb", "ofetch", "uploadthing"] }, "sha512-Sj8btci21Twnd6M+N+MHhjg3fVn6lAPElPmvFTe0Y/wR0WImErUdA1PzlAaUavHylJ7uDiFwlZDQKm0elG4b7g=="], - "nitropack/citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], "nitropack/cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], @@ -3154,8 +3183,6 @@ "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - "nuxt/@nuxt/kit": ["@nuxt/kit@4.3.1", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^3.0.0", "scule": "^1.3.0", "semver": "^7.7.4", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-UjBFt72dnpc+83BV3OIbCT0YHLevJtgJCHpxMX0YRKWLDhhbcDdUse87GtsQBrjvOzK7WUNUYLDS/hQLYev5rA=="], - "nuxt/cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], "nuxt/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -3164,14 +3191,30 @@ "nuxt/nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="], + "nuxt/oxc-minify": ["oxc-minify@0.112.0", "", { "optionalDependencies": { "@oxc-minify/binding-android-arm-eabi": "0.112.0", "@oxc-minify/binding-android-arm64": "0.112.0", "@oxc-minify/binding-darwin-arm64": "0.112.0", "@oxc-minify/binding-darwin-x64": "0.112.0", "@oxc-minify/binding-freebsd-x64": "0.112.0", "@oxc-minify/binding-linux-arm-gnueabihf": "0.112.0", "@oxc-minify/binding-linux-arm-musleabihf": "0.112.0", "@oxc-minify/binding-linux-arm64-gnu": "0.112.0", "@oxc-minify/binding-linux-arm64-musl": "0.112.0", "@oxc-minify/binding-linux-ppc64-gnu": "0.112.0", "@oxc-minify/binding-linux-riscv64-gnu": "0.112.0", "@oxc-minify/binding-linux-riscv64-musl": "0.112.0", "@oxc-minify/binding-linux-s390x-gnu": "0.112.0", "@oxc-minify/binding-linux-x64-gnu": "0.112.0", "@oxc-minify/binding-linux-x64-musl": "0.112.0", "@oxc-minify/binding-openharmony-arm64": "0.112.0", "@oxc-minify/binding-wasm32-wasi": "0.112.0", "@oxc-minify/binding-win32-arm64-msvc": "0.112.0", "@oxc-minify/binding-win32-ia32-msvc": "0.112.0", "@oxc-minify/binding-win32-x64-msvc": "0.112.0" } }, "sha512-rkVSeeIRSt+RYI9uX6xonBpLUpvZyegxIg0UL87ev7YAfUqp7IIZlRjkgQN5Us1lyXD//TOo0Dcuuro/TYOWoQ=="], + + "nuxt/oxc-transform": ["oxc-transform@0.112.0", "", { "optionalDependencies": { "@oxc-transform/binding-android-arm-eabi": "0.112.0", "@oxc-transform/binding-android-arm64": "0.112.0", "@oxc-transform/binding-darwin-arm64": "0.112.0", "@oxc-transform/binding-darwin-x64": "0.112.0", "@oxc-transform/binding-freebsd-x64": "0.112.0", "@oxc-transform/binding-linux-arm-gnueabihf": "0.112.0", "@oxc-transform/binding-linux-arm-musleabihf": "0.112.0", "@oxc-transform/binding-linux-arm64-gnu": "0.112.0", "@oxc-transform/binding-linux-arm64-musl": "0.112.0", "@oxc-transform/binding-linux-ppc64-gnu": "0.112.0", "@oxc-transform/binding-linux-riscv64-gnu": "0.112.0", "@oxc-transform/binding-linux-riscv64-musl": "0.112.0", "@oxc-transform/binding-linux-s390x-gnu": "0.112.0", "@oxc-transform/binding-linux-x64-gnu": "0.112.0", "@oxc-transform/binding-linux-x64-musl": "0.112.0", "@oxc-transform/binding-openharmony-arm64": "0.112.0", "@oxc-transform/binding-wasm32-wasi": "0.112.0", "@oxc-transform/binding-win32-arm64-msvc": "0.112.0", "@oxc-transform/binding-win32-ia32-msvc": "0.112.0", "@oxc-transform/binding-win32-x64-msvc": "0.112.0" } }, "sha512-cIRRvZgrHfsAHrkt8LWdAX4+Do8R0MzQSfeo9yzErzHeYiuyNiP4PCTPbOy/wBXL4MYzt3ebrBa5jt3akQkKAg=="], + "nuxt/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "nuxt/unplugin": ["unplugin@3.0.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg=="], + "nuxt-component-meta/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "nuxt-component-meta/citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], + "nuxt-llms/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "nuxt-og-image/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "nuxt-og-image/execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="], + "nuxt-og-image/unstorage": ["unstorage@1.17.4", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.5", "lru-cache": "^11.2.0", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw=="], + + "nuxt-site-config/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + + "nuxt-site-config-kit/@nuxt/kit": ["@nuxt/kit@4.3.0", "", { "dependencies": { "c12": "^3.3.3", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.3", "unctx": "^2.5.0", "untyped": "^2.0.0" } }, "sha512-cD/0UU9RQmlnTbmyJTDyzN8f6CzpziDLv3tFQCnwl0Aoxt3KmFu4k/XA4Sogxqj7jJ/3cdX1kL+Lnsh34sxcQQ=="], + "oxc-parser/@oxc-project/types": ["@oxc-project/types@0.112.0", "", {}, "sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], @@ -3274,6 +3317,10 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "@dxup/nuxt/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@dxup/nuxt/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "@intlify/bundle-utils/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], "@intlify/bundle-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], @@ -3338,6 +3385,22 @@ "@nuxt/cli/@clack/prompts/@clack/core": ["@clack/core@1.0.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-Orf9Ltr5NeiEuVJS8Rk2XTw3IxNC2Bic3ash7GgYeA8LJ/zmSNpSQ/m5UAhe03lA6KFgklzZ5KTHs4OAMA/SAQ=="], + "@nuxt/content/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxt/content/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + + "@nuxt/devtools-kit/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxt/devtools-kit/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + + "@nuxt/devtools/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxt/devtools/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + + "@nuxt/fonts/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxt/fonts/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "@nuxt/fonts/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], "@nuxt/fonts/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], @@ -3390,23 +3453,25 @@ "@nuxt/fonts/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], - "@nuxt/nitro-server/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + "@nuxt/icon/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxt/icon/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "@nuxt/nitro-server/@nuxt/kit/rc9": ["rc9@3.0.0", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.5" } }, "sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA=="], + "@nuxt/image/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@nuxt/nitro-server/@nuxt/kit/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "@nuxt/image/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], "@nuxt/test-utils/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@nuxt/ui/@unhead/vue/hookable": ["hookable@6.0.1", "", {}, "sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw=="], + "@nuxt/test-utils/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "@nuxt/ui/@unhead/vue/unhead": ["unhead@2.1.2", "", { "dependencies": { "hookable": "^6.0.1" } }, "sha512-vSihrxyb+zsEUfEbraZBCjdE0p/WSoc2NGDrpwwSNAwuPxhYK1nH3eegf02IENLpn1sUhL8IoO84JWmRQ6tILA=="], + "@nuxt/ui/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@nuxt/vite-builder/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + "@nuxt/ui/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "@nuxt/vite-builder/@nuxt/kit/rc9": ["rc9@3.0.0", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.5" } }, "sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA=="], + "@nuxt/ui/@unhead/vue/hookable": ["hookable@6.0.1", "", {}, "sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw=="], - "@nuxt/vite-builder/@nuxt/kit/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "@nuxt/ui/@unhead/vue/unhead": ["unhead@2.1.2", "", { "dependencies": { "hookable": "^6.0.1" } }, "sha512-vSihrxyb+zsEUfEbraZBCjdE0p/WSoc2NGDrpwwSNAwuPxhYK1nH3eegf02IENLpn1sUhL8IoO84JWmRQ6tILA=="], "@nuxt/vite-builder/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], @@ -3466,10 +3531,16 @@ "@nuxtjs/color-mode/@nuxt/kit/pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], + "@nuxtjs/color-mode/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "@nuxtjs/color-mode/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], "@nuxtjs/color-mode/pkg-types/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "@nuxtjs/i18n/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxtjs/i18n/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "@nuxtjs/i18n/oxc-parser/@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.95.0", "", { "os": "android", "cpu": "arm64" }, "sha512-dZyxhhvJigwWL1wgnLlqyEiSeuqO0WdDH9H+if0dPcBM4fKa5fjVkaUcJT1jBMcBTnkjxMwTXYZy5TK60N0fjg=="], "@nuxtjs/i18n/oxc-parser/@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.95.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zun9+V33kyCtNec9oUSWwb0qi3fB8pXwum1yGFECPEr55g/CrWju6/Jv4hwwNBeW2tK9Ch/PRstEtYmOLMhHpg=="], @@ -3536,6 +3607,18 @@ "@nuxtjs/mcp-toolkit/@clack/prompts/@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="], + "@nuxtjs/mcp-toolkit/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxtjs/mcp-toolkit/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + + "@nuxtjs/mdc/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxtjs/mdc/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + + "@nuxtjs/robots/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@nuxtjs/robots/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], @@ -3552,6 +3635,10 @@ "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], + "docus/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "docus/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + "fontless/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], "fontless/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], @@ -3612,97 +3699,115 @@ "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - "nitro/oxc-minify/@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.110.0", "", { "os": "android", "cpu": "arm" }, "sha512-43fMTO8/5bMlqfOiNSZNKUzIqeLIYuB9Hr1Ohyf58B1wU11S2dPGibTXOGNaWsfgHy99eeZ1bSgeIHy/fEYqbw=="], + "nuxt-component-meta/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "nitro/oxc-minify/@oxc-minify/binding-android-arm64": ["@oxc-minify/binding-android-arm64@0.110.0", "", { "os": "android", "cpu": "arm64" }, "sha512-5oQrnn9eK/ccOp80PTrNj0Vq893NPNNRryjGpOIVsYNgWFuoGCfpnKg68oEFcN8bArizYAqw4nvgHljEnar69w=="], + "nuxt-component-meta/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "nitro/oxc-minify/@oxc-minify/binding-darwin-arm64": ["@oxc-minify/binding-darwin-arm64@0.110.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dqBDgTG9tF2z2lrZp9E8wU+Godz1i8gCGSei2eFKS2hRploBOD5dmOLp1j4IMornkPvSQmbwB3uSjPq7fjx4EA=="], + "nuxt-llms/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "nitro/oxc-minify/@oxc-minify/binding-darwin-x64": ["@oxc-minify/binding-darwin-x64@0.110.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U0AqabqaooDOpYmeeOye8wClv8PSScELXgOfYqyqgrwH9J9KrpCE1jL8Rlqgz68QbL4mPw3V6sKiiHssI4CLeQ=="], + "nuxt-llms/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "nitro/oxc-minify/@oxc-minify/binding-freebsd-x64": ["@oxc-minify/binding-freebsd-x64@0.110.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-H0w8o/Wo1072WSdLfhwwrpFpwZnPpjQODlHuRYkTfsSSSJbTxQtjJd4uxk7YJsRv5RQp69y0I7zvdH6f8Xueyw=="], + "nuxt-og-image/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-arm-gnueabihf": ["@oxc-minify/binding-linux-arm-gnueabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-qd6sW0AvEVYZhbVVMGtmKZw3b1zDYGIW+54Uh42moWRAj6i4Jhk/LGr6r9YNZpOINeuvZfkFuEeDD/jbu7xPUA=="], + "nuxt-og-image/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-arm-musleabihf": ["@oxc-minify/binding-linux-arm-musleabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7WXP0aXMrWSn0ScppUBi3jf68ebfBG0eri8kxLmBOVSBj6jw1repzkHMITJMBeLr5d0tT/51qFEptiAk2EP2iA=="], + "nuxt-og-image/execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-arm64-gnu": ["@oxc-minify/binding-linux-arm64-gnu@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-LYfADrq5x1W5gs+u9OIbMbDQNYkAECTXX0ufnAuf3oGmO51rF98kGFR5qJqC/6/csokDyT3wwTpxhE0TkcF/Og=="], + "nuxt-og-image/execa/human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-arm64-musl": ["@oxc-minify/binding-linux-arm64-musl@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-53GjCVY8kvymk9P6qNDh6zyblcehF5QHstq9QgCjv13ONGRnSHjeds0PxIwiihD7h295bxsWs84DN39syLPH4Q=="], + "nuxt-og-image/execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-ppc64-gnu": ["@oxc-minify/binding-linux-ppc64-gnu@0.110.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-li8XcN81dxbJDMBESnTgGhoiAQ+CNIdM0QGscZ4duVPjCry1RpX+5FJySFbGqG3pk4s9ZzlL/vtQtbRzZIZOzg=="], + "nuxt-og-image/execa/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-riscv64-gnu": ["@oxc-minify/binding-linux-riscv64-gnu@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-SweKfsnLKShu6UFV8mwuj1d1wmlNoL/FlAxPUzwjEBgwiT2HQkY24KnjBH+TIA+//1O83kzmWKvvs4OuEhdIEQ=="], + "nuxt-og-image/execa/strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-riscv64-musl": ["@oxc-minify/binding-linux-riscv64-musl@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-oH8G4aFMP8XyTsEpdANC5PQyHgSeGlopHZuW1rpyYcaErg5YaK0vXjQ4EM5HVvPm+feBV24JjxgakTnZoF3aOQ=="], + "nuxt-site-config-kit/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-s390x-gnu": ["@oxc-minify/binding-linux-s390x-gnu@0.110.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-W9na+Vza7XVUlpf8wMt4QBfH35KeTENEmnpPUq3NSlbQHz8lSlSvhAafvo43NcKvHAXV3ckD/mUf2VkqSdbklg=="], + "nuxt-site-config-kit/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-x64-gnu": ["@oxc-minify/binding-linux-x64-gnu@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XJdA4mmmXOjJxSRgNJXsDP7Xe8h3gQhmb56hUcCrvq5d+h5UcEi2pR8rxsdIrS8QmkLuBA3eHkGK8E27D7DTgQ=="], + "nuxt-site-config/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "nitro/oxc-minify/@oxc-minify/binding-linux-x64-musl": ["@oxc-minify/binding-linux-x64-musl@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-QqzvALuOTtSckI8x467R4GNArzYDb/yEh6aNzLoeaY1O7vfT7SPDwlOEcchaTznutpeS9Dy8gUS/AfqtUHaufw=="], + "nuxt-site-config/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "nitro/oxc-minify/@oxc-minify/binding-openharmony-arm64": ["@oxc-minify/binding-openharmony-arm64@0.110.0", "", { "os": "none", "cpu": "arm64" }, "sha512-gAMssLs2Q3+uhLZxanh1DF+27Kaug3cf4PXb9AB7XK81DR+LVcKySXaoGYoOs20Co0fFSphd6rRzKge2qDK3dA=="], + "nuxt/oxc-minify/@oxc-minify/binding-android-arm-eabi": ["@oxc-minify/binding-android-arm-eabi@0.112.0", "", { "os": "android", "cpu": "arm" }, "sha512-m7TGBR2hjsBJIN9UJ909KBoKsuogo6CuLsHKvUIBXdjI0JVHP8g4ZHeB+BJpGn5LJdeSGDfz9MWiuXrZDRzunw=="], - "nitro/oxc-minify/@oxc-minify/binding-wasm32-wasi": ["@oxc-minify/binding-wasm32-wasi@0.110.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-7Wqi5Zjl022bs2zXq+ICdalDPeDuCH/Nhbi8q2isLihAonMVIT0YH2hqqnNEylRNGYck+FJ6gRZwMpGCgrNxPg=="], + "nuxt/oxc-minify/@oxc-minify/binding-android-arm64": ["@oxc-minify/binding-android-arm64@0.112.0", "", { "os": "android", "cpu": "arm64" }, "sha512-RvxOOkzvP5NeeoraBtgNJSBqO+XzlS7DooxST/drAXCfO52GsmxVB1N7QmifrsTYtH8GC2z3DTFjZQ1w/AJOWg=="], - "nitro/oxc-minify/@oxc-minify/binding-win32-arm64-msvc": ["@oxc-minify/binding-win32-arm64-msvc@0.110.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-ZPx+0Tj4dqn41ecyoGotlvekQKy6JxJCixn9Rw7h/dafZ3eDuBcEVh3c2ZoldXXsyMIt5ywI8IWzFZsjNedd5Q=="], + "nuxt/oxc-minify/@oxc-minify/binding-darwin-arm64": ["@oxc-minify/binding-darwin-arm64@0.112.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-hDslO3uVHza3kB9zkcsi25JzN65Gj5ZYty0OvylS11Mhg9ydCYxAzfQ/tISHW/YmV1NRUJX8+GGqM1cKmrHaTA=="], - "nitro/oxc-minify/@oxc-minify/binding-win32-ia32-msvc": ["@oxc-minify/binding-win32-ia32-msvc@0.110.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-H0Oyd3RWBfpEyvJIrFK94RYiY7KKSQl11Ym7LMDwLEagelIAfRCkt1amHZhFa/S3ZRoaOJFXzEw4YKeSsjVFsg=="], + "nuxt/oxc-minify/@oxc-minify/binding-darwin-x64": ["@oxc-minify/binding-darwin-x64@0.112.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-mWA2Y5bUyNoGM+gSGGHesgtQ3LDWgpRe4zDGkBDovxNIiDLBXqu/7QcuS+G918w8oG9VYm1q1iinILer/2pD1Q=="], - "nitro/oxc-minify/@oxc-minify/binding-win32-x64-msvc": ["@oxc-minify/binding-win32-x64-msvc@0.110.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Hr3nK90+qXKJ2kepXwFIcNfQQIOBecB4FFCyaMMypthoEEhVP08heRynj4eSXZ8NL9hLjs3fQzH8PJXfpznRnQ=="], + "nuxt/oxc-minify/@oxc-minify/binding-freebsd-x64": ["@oxc-minify/binding-freebsd-x64@0.112.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-T7fsegxcy82xS0jWPXkz/BMhrkb3D7YOCiV0R9pDksjaov+iIFoNEWAoBsaC5NtpdzkX+bmffwDpu336EIfEeg=="], - "nitro/oxc-transform/@oxc-transform/binding-android-arm-eabi": ["@oxc-transform/binding-android-arm-eabi@0.110.0", "", { "os": "android", "cpu": "arm" }, "sha512-sE9dxvqqAax1YYJ3t7j+h5ZSI9jl6dYuDfngl6ieZUrIy5P89/8JKVgAzgp8o3wQSo7ndpJvYsi1K4ZqrmbP7w=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-arm-gnueabihf": ["@oxc-minify/binding-linux-arm-gnueabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-yePavbIilAcpVYc8vRsDCn3xJxHMXDZIiamyH9fuLosAHNELcLib4/JR4fhDk4NmHVagQH3kRhsnm5Q9cm3pAw=="], - "nitro/oxc-transform/@oxc-transform/binding-android-arm64": ["@oxc-transform/binding-android-arm64@0.110.0", "", { "os": "android", "cpu": "arm64" }, "sha512-nqtbP4aMCtsCZ6qpHlHaQoWVHSBtlKzwaAgwEOvR+9DWqHjk31BHvpGiDXlMeed6CVNpl3lCbWgygb3RcSjcfw=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-arm-musleabihf": ["@oxc-minify/binding-linux-arm-musleabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-lmPWLXtW6FspERhy97iP0hwbmLtL66xI29QQ9GpHmTiE4k+zv/FaefuV/Qw+LuHnmFSYzUNrLcxh4ulOZTIP2g=="], - "nitro/oxc-transform/@oxc-transform/binding-darwin-arm64": ["@oxc-transform/binding-darwin-arm64@0.110.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oeSeHnL4Z4cMXtc8V0/rwoVn0dgwlS9q0j6LcHn9dIhtFEdp3W0iSBF8YmMQA+E7sILeLDjsHmHE4Kp0sOScXw=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-arm64-gnu": ["@oxc-minify/binding-linux-arm64-gnu@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gySS5XqU5MKs/oCjsTlVm8zb8lqcNKHEANsaRmhW2qvGKJoeGwFb6Fbq6TLCZMRuk143mLbncbverBCa1c3dog=="], - "nitro/oxc-transform/@oxc-transform/binding-darwin-x64": ["@oxc-transform/binding-darwin-x64@0.110.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-nL9K5x7OuZydobAGPylsEW9d4APs2qEkIBLMgQPA+kY8dtVD3IR87QsTbs4l4DBQYyun/+ay6qVCDlxqxdX2Jg=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-arm64-musl": ["@oxc-minify/binding-linux-arm64-musl@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IRFMZX589lr3rjG0jc8N261/7wqFq2Vl0OMrJWeFls5BF8HiB+fRYuf0Zy2CyRH6NCY2vbdDdp+QCAavQGVsGw=="], - "nitro/oxc-transform/@oxc-transform/binding-freebsd-x64": ["@oxc-transform/binding-freebsd-x64@0.110.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GS29zXXirDQhZEUq8xKJ1azAWMuUy3Ih3W5Bc5ddk12LRthO5wRLFcKIyeHpAXCoXymQ+LmxbMtbPf84GPxouw=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-ppc64-gnu": ["@oxc-minify/binding-linux-ppc64-gnu@0.112.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-V/69XqIW9hCUceDpcZh79oDg+F4ptEgIfKRENzYs41LRbSoJ7sNjjcW4zifqyviTvzcnXLgK4uoTyoymmNZBMQ=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-arm-gnueabihf": ["@oxc-transform/binding-linux-arm-gnueabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-glzDHak8ISyZJemCUi7RCvzNSl+MQ1ly9RceT2qRufhUsvNZ4C/2QLJ1HJwd2N6E88bO4laYn+RofdRzNnGGEA=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-riscv64-gnu": ["@oxc-minify/binding-linux-riscv64-gnu@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-zghvexySyGXGNW+MutjZN7UGTyOQl56RWMlPe1gb+knBm/+0hf9qjk7Q6ofm2tSte+vQolPfQttifGl0dP9uvQ=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-arm-musleabihf": ["@oxc-transform/binding-linux-arm-musleabihf@0.110.0", "", { "os": "linux", "cpu": "arm" }, "sha512-8JThvgJ2FRoTVfbp7e4wqeZqCZbtudM06SfZmNzND9kPNu/LVYygIR+72RWs+xm4bWkuYHg/islo/boNPtMT5Q=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-riscv64-musl": ["@oxc-minify/binding-linux-riscv64-musl@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-E4a8VUFDJPb2mPcc7J4NQQPi1ssHKF7/g4r6KD2+SBVERIaEEd3cGNqR7SG3g82/BLGV2UDoQe/WvZCkt5M/bQ=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-arm64-gnu": ["@oxc-transform/binding-linux-arm64-gnu@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IRh21Ub/g4bkHoErZ0AUWMlWfoZaS0A6EaOVtbcY70RSYIMlrsbjiFwJCzM+b/1DD1rXbH5tsGcH7GweTbfRqg=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-s390x-gnu": ["@oxc-minify/binding-linux-s390x-gnu@0.112.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-2Hx87sK3y6jBV364Mvv0zyxiITIuy26Ixenv6pK7e+4an3HgNdhAj8nk3aLoLTTSvLik5/MaGhcZGEu9tYV1aA=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-arm64-musl": ["@oxc-transform/binding-linux-arm64-musl@0.110.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-e5JN94/oy+wevk76q+LMr+2klTTcO60uXa+Wkq558Ms7mdF2TvkKFI++d/JeiuIwJLTi/BxQ4qdT5FWcsHM/ug=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-x64-gnu": ["@oxc-minify/binding-linux-x64-gnu@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2MSCnEPLk9ddSouMhJo78Xy2/JbYC80OYzWdR4yWTGSULsgH3d1VXg73DSwFL8vU7Ad9oK10DioBY2ww7sQTEg=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-ppc64-gnu": ["@oxc-transform/binding-linux-ppc64-gnu@0.110.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y3/Tnnz1GvDpmv8FXBIKtdZPsdZklOEPdrL6NHrN5i2u54BOkybFaDSptgWF53wOrJlTrcmAVSE6fRKK9XCM2Q=="], + "nuxt/oxc-minify/@oxc-minify/binding-linux-x64-musl": ["@oxc-minify/binding-linux-x64-musl@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-HAPfmQKlkVi97/zRonVE9t/kKUG3ni+mOuU1Euw+3s37KwUuOJjmcwXdclVgXKBlTkCGO0FajPwW5dAJeIXCCw=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-riscv64-gnu": ["@oxc-transform/binding-linux-riscv64-gnu@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-Y0E35iA9/v9jlkNcP6tMJ+ZFOS0rLsWDqG6rU9z+X2R3fBFJBO9UARIK6ngx8upxk81y1TFR2CmBFhupfYdH6Q=="], + "nuxt/oxc-minify/@oxc-minify/binding-openharmony-arm64": ["@oxc-minify/binding-openharmony-arm64@0.112.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bLnMojcPadYzMNpB6IAqMiTOag4etc0zbs8On73JsotO1W5c5/j/ncplpSokpEpNasKRUpHVRXpmq0KRXprNhw=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-riscv64-musl": ["@oxc-transform/binding-linux-riscv64-musl@0.110.0", "", { "os": "linux", "cpu": "none" }, "sha512-JOUSYFfHjBUs7xp2FHmZHb8eTYD/oEu0NklS6JgUauqnoXZHiTLPLVW2o2uVCqldnabYHcomuwI2iqVFYJNhTw=="], + "nuxt/oxc-minify/@oxc-minify/binding-wasm32-wasi": ["@oxc-minify/binding-wasm32-wasi@0.112.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-tv7PmHYq/8QBlqMaDjsy51GF5KQkG17Yc/PsgB5OVndU34kwbQuebBIic7UfK9ygzidI8moYq3ztnu3za/rqHw=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-s390x-gnu": ["@oxc-transform/binding-linux-s390x-gnu@0.110.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-7blgoXF9D3Ngzb7eun23pNrHJpoV/TtE6LObwlZ3Nmb4oZ6Z+yMvBVaoW68NarbmvNGfZ95zrOjgm6cVETLYBA=="], + "nuxt/oxc-minify/@oxc-minify/binding-win32-arm64-msvc": ["@oxc-minify/binding-win32-arm64-msvc@0.112.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-d+jes2jwRkcBSpcaZC6cL8GBi56Br6uAorn9dfquhWLczWL+hHSvvVrRgT1i5/6dkf5UWx2zdoEsAMiJ11w78A=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-x64-gnu": ["@oxc-transform/binding-linux-x64-gnu@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-YQ2joGWCVDZVEU2cD/r/w49hVjDm/Qu1BvC/7zs8LvprzdLS/HyMXGF2oA0puw0b+AqgYaz3bhwKB2xexHyITQ=="], + "nuxt/oxc-minify/@oxc-minify/binding-win32-ia32-msvc": ["@oxc-minify/binding-win32-ia32-msvc@0.112.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-TV1C3qDwj7//jNIi5tnNRhReSUgtaRQKi5KobDE6zVAc5gjeuBA8G2qizS9ziXlf/I0dlelrGmGMMDJmH9ekWg=="], - "nitro/oxc-transform/@oxc-transform/binding-linux-x64-musl": ["@oxc-transform/binding-linux-x64-musl@0.110.0", "", { "os": "linux", "cpu": "x64" }, "sha512-fkjr5qE632ULmNgvFXWDR/8668WxERz3tU7TQFp6JebPBneColitjSkdx6VKNVXEoMmQnOvBIGeP5tUNT384oA=="], + "nuxt/oxc-minify/@oxc-minify/binding-win32-x64-msvc": ["@oxc-minify/binding-win32-x64-msvc@0.112.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LML2Gld6VY8/+7a3VH4k1qngsBXvTkXgbmYgSYwaElqtiQiYaAcXfi0XKOUGe3k3GbBK4juAGixC31CrdFHAQw=="], - "nitro/oxc-transform/@oxc-transform/binding-openharmony-arm64": ["@oxc-transform/binding-openharmony-arm64@0.110.0", "", { "os": "none", "cpu": "arm64" }, "sha512-HWH9Zj+lMrdSTqFRCZsvDWMz7OnMjbdGsm3xURXWfRZpuaz0bVvyuZNDQXc4FyyhRDsemICaJbU1bgeIpUJDGw=="], + "nuxt/oxc-transform/@oxc-transform/binding-android-arm-eabi": ["@oxc-transform/binding-android-arm-eabi@0.112.0", "", { "os": "android", "cpu": "arm" }, "sha512-r4LuBaPnOAi0eUOBNi880Fm2tO2omH7N1FRrL6+nyz/AjQ+QPPLtoyZJva0O+sKi1buyN/7IzM5p9m+5ANSDbg=="], - "nitro/oxc-transform/@oxc-transform/binding-wasm32-wasi": ["@oxc-transform/binding-wasm32-wasi@0.110.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ejdxHmYfIcHDPhZUe3WklViLt9mDEJE5BzcW7+R1vc5i/5JFA8D0l7NUSsHBJ7FB8Bu9gF+5iMDm6cXGAgaghw=="], + "nuxt/oxc-transform/@oxc-transform/binding-android-arm64": ["@oxc-transform/binding-android-arm64@0.112.0", "", { "os": "android", "cpu": "arm64" }, "sha512-ve46vQcQrY8eGe8990VSlS9gkD+AogJqbtfOkeua+5sQGQTDgeIRRxOm7ktCo19uZc2bEBwXRJITgosd+NRVmQ=="], - "nitro/oxc-transform/@oxc-transform/binding-win32-arm64-msvc": ["@oxc-transform/binding-win32-arm64-msvc@0.110.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-9VTwpXCZs7xkV+mKhQ62dVk7KLnLXtEUxNS2T4nLz3iMl1IJbA4h5oltK0JoobtiUAnbkV53QmMVGW8+Nh3bDQ=="], + "nuxt/oxc-transform/@oxc-transform/binding-darwin-arm64": ["@oxc-transform/binding-darwin-arm64@0.112.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ddbmLU3Tr+i7MOynfwAXxUXud3SjJKlv7XNjaq08qiI8Av/QvhXVGc2bMhXkWQSMSBUeTDoiughKjK+Zsb6y/A=="], - "nitro/oxc-transform/@oxc-transform/binding-win32-ia32-msvc": ["@oxc-transform/binding-win32-ia32-msvc@0.110.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-5y0fzuNON7/F2hh2P94vANFaRPJ/3DI1hVl5rseCT8VUVqOGIjWaza0YS/D1g6t1WwycW2LWDMi2raOKoWU5GQ=="], + "nuxt/oxc-transform/@oxc-transform/binding-darwin-x64": ["@oxc-transform/binding-darwin-x64@0.112.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-TKvmNw96jQZPqYb4pRrzLFDailNB3YS14KNn+x2hwRbqc6CqY96S9PYwyOpVpYdxfoRjYO9WgX9SoS+62a1DPA=="], - "nitro/oxc-transform/@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.110.0", "", { "os": "win32", "cpu": "x64" }, "sha512-QROrowwlrApI1fEScMknGWKM6GTM/Z2xwMnDqvSaEmzNazBsDUlE08Jasw610hFEsYAVU2K5sp/YaCa9ORdP4A=="], + "nuxt/oxc-transform/@oxc-transform/binding-freebsd-x64": ["@oxc-transform/binding-freebsd-x64@0.112.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YPMkSCDaelO8HHYRMYjm+Q+IfkfIbdtQzwPuasItYkq8UUkNeHNPheNh2JkvQa3c+io3E9ePOgHQ2yihpk7o/Q=="], - "nuxt-og-image/execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], + "nuxt/oxc-transform/@oxc-transform/binding-linux-arm-gnueabihf": ["@oxc-transform/binding-linux-arm-gnueabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-nA7kzQGNEpuTRknst/IJ3l8hqmDmEda3aun6jkXgp7gKxESjuHeaNH04mKISxvJ7fIacvP2g/wtTSnm4u5jL8Q=="], - "nuxt-og-image/execa/human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], + "nuxt/oxc-transform/@oxc-transform/binding-linux-arm-musleabihf": ["@oxc-transform/binding-linux-arm-musleabihf@0.112.0", "", { "os": "linux", "cpu": "arm" }, "sha512-w8GuLmckKlGc3YujaZKhtbFxziCcosvM2l9GnQjCb/yENWLGDiyQOy0BTAgPGdJwpYTiOeJblEXSuXYvlE1Ong=="], - "nuxt-og-image/execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], + "nuxt/oxc-transform/@oxc-transform/binding-linux-arm64-gnu": ["@oxc-transform/binding-linux-arm64-gnu@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-9LwwGnJ8+WT0rXcrI8M0RJtDNt91eMqcDPPEvJxhRFHIMcHTy5D5xT+fOl3Us0yMqKo3HUWkbfUYqAp4GoZ3Jw=="], - "nuxt-og-image/execa/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], + "nuxt/oxc-transform/@oxc-transform/binding-linux-arm64-musl": ["@oxc-transform/binding-linux-arm64-musl@0.112.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Lg6VOuSd3oXv7J0eGywgqh/086h+qQzIBOD+47pYKMTTJcbDe+f3h/RgGoMKJE5HhiwT5sH1aGEJfIfaYUiVSw=="], - "nuxt-og-image/execa/strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], + "nuxt/oxc-transform/@oxc-transform/binding-linux-ppc64-gnu": ["@oxc-transform/binding-linux-ppc64-gnu@0.112.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-PXzmj82o1moA4IGphYImTRgc2youTi4VRfyFX3CHwLjxPcQ5JtcsgbDt4QUdOzXZ+zC07s5jf2ZzhRapEOlj2w=="], + + "nuxt/oxc-transform/@oxc-transform/binding-linux-riscv64-gnu": ["@oxc-transform/binding-linux-riscv64-gnu@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-vhJsMsVH/6xwa3bt1LGts33FXUkGjaEGDwsRyp4lIfOjSfQVWMtCmWMFNaA0dW9FVWdD2Gt2fSFBSZ+azDxlpg=="], + + "nuxt/oxc-transform/@oxc-transform/binding-linux-riscv64-musl": ["@oxc-transform/binding-linux-riscv64-musl@0.112.0", "", { "os": "linux", "cpu": "none" }, "sha512-cXWFb7z+2IjFUEcXtRwluq9oEG5qnyFCjiu3SWrgYNcWwPdHusv3I/7K5/CTbbi4StoZ5txbi7/iSfDHNyWuRw=="], + + "nuxt/oxc-transform/@oxc-transform/binding-linux-s390x-gnu": ["@oxc-transform/binding-linux-s390x-gnu@0.112.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-eEFu4SRqJTJ20/88KRWmp+jpHKAw0Y1DsnSgpEeXyBIIcsOaLIUMU/TfYWUmqRbvbMV9rmOmI3kp5xWYUq6kSQ=="], + + "nuxt/oxc-transform/@oxc-transform/binding-linux-x64-gnu": ["@oxc-transform/binding-linux-x64-gnu@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ST1MDT+TlOyZ1c5btrGinRSUW2Jf4Pa+0gdKwsyjDSOC3dxy2ZNkN3mosTf4ywc3J+mxfYKqtjs7zSwHz03ILA=="], + + "nuxt/oxc-transform/@oxc-transform/binding-linux-x64-musl": ["@oxc-transform/binding-linux-x64-musl@0.112.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ISQoA3pD4cyTGpf9sXXeerH6pL2L6EIpdy6oAy2ttkswyVFDyQNVOVIGIdLZDgbpmqGljxZnWqt/J/N68pQaig=="], + + "nuxt/oxc-transform/@oxc-transform/binding-openharmony-arm64": ["@oxc-transform/binding-openharmony-arm64@0.112.0", "", { "os": "none", "cpu": "arm64" }, "sha512-UOGVrGIv7yLJovyEXEyUTADuLq98vd/cbMHFLJweRXD+11I8Tn4jASi4WzdsN8C3BVYGRHrXH2NlSBmhz33a4g=="], + + "nuxt/oxc-transform/@oxc-transform/binding-wasm32-wasi": ["@oxc-transform/binding-wasm32-wasi@0.112.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-XIX7Gpq9koAvzBVHDlVFHM79r5uOVK6kTEsdsN4qaajpjkgtv4tdsAOKIYK6l7fUbsbE6xS+6w1+yRFrDeC1kg=="], + + "nuxt/oxc-transform/@oxc-transform/binding-win32-arm64-msvc": ["@oxc-transform/binding-win32-arm64-msvc@0.112.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-EgXef9kOne9BNsbYBbuRqxk2hteT0xsAGcx/VbtCBMJYNj8fANFhT271DUSOgfa4DAgrQQmsyt/Kr1aV9mpU9w=="], + + "nuxt/oxc-transform/@oxc-transform/binding-win32-ia32-msvc": ["@oxc-transform/binding-win32-ia32-msvc@0.112.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-6QaB0qjNaou2YR+blncHdw7j0e26IOwOIjLbhVGDeuf9+4rjJeiqRXJ2hOtCcS4zblnao/MjdgQuZ3fM0nl+Kw=="], - "nuxt/@nuxt/kit/rc9": ["rc9@3.0.0", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.5" } }, "sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA=="], + "nuxt/oxc-transform/@oxc-transform/binding-win32-x64-msvc": ["@oxc-transform/binding-win32-x64-msvc@0.112.0", "", { "os": "win32", "cpu": "x64" }, "sha512-FRKYlY959QeqRPx9kXs0HjU2xuXPT1cdF+vvA200D9uAX/KLcC34MwRqUKTYml4kCc2Vf/P2pBR9cQuBm3zECQ=="], "readdir-glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], diff --git a/packages/evlog/package.json b/packages/evlog/package.json index 7d592b2..baf672b 100644 --- a/packages/evlog/package.json +++ b/packages/evlog/package.json @@ -39,6 +39,10 @@ "types": "./dist/nitro/v3/plugin.d.mts", "import": "./dist/nitro/v3/plugin.mjs" }, + "./nitro/v3/errorHandler": { + "types": "./dist/nitro/v3/errorHandler.d.mts", + "import": "./dist/nitro/v3/errorHandler.mjs" + }, "./workers": { "types": "./dist/workers.d.mts", "import": "./dist/workers.mjs" @@ -84,6 +88,9 @@ "nitro/v3": [ "./dist/nitro/v3/plugin.d.mts" ], + "nitro/v3/errorHandler": [ + "./dist/nitro/v3/errorHandler.d.mts" + ], "workers": [ "./dist/workers.d.mts" ], @@ -131,12 +138,13 @@ "@nuxt/schema": "^4.3.1", "@nuxt/test-utils": "^3.23.0", "changelogen": "^0.6.2", + "consola": "^3.4.2", "h3": "^1.15.5", + "nitro": "^3.0.1-alpha.2", "nitropack": "^2.13.1", "nuxt": "^4.3.1", "tsdown": "^0.20.3", - "typescript": "^5.9.3", - "nitro": "^3.0.1-alpha.2" + "typescript": "^5.9.3" }, "peerDependencies": { "@nuxt/kit": "^4.3.1", From da5ff3a8d9c8af63c45047f6cb443c1be362fc6b Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 20:50:10 +0100 Subject: [PATCH 18/26] build: add nitro v3 plugin and error handler entries to tsdown config --- packages/evlog/tsdown.config.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/evlog/tsdown.config.ts b/packages/evlog/tsdown.config.ts index d57bc47..0f2b359 100644 --- a/packages/evlog/tsdown.config.ts +++ b/packages/evlog/tsdown.config.ts @@ -6,6 +6,8 @@ export default defineConfig({ 'nuxt/module': 'src/nuxt/module.ts', 'nitro/plugin': 'src/nitro/plugin.ts', 'nitro/errorHandler': 'src/nitro/errorHandler.ts', + 'nitro/v3/plugin': 'src/nitro-v3/plugin.ts', + 'nitro/v3/errorHandler': 'src/nitro-v3/errorHandler.ts', 'runtime/client/log': 'src/runtime/client/log.ts', 'runtime/client/plugin': 'src/runtime/client/plugin.ts', 'runtime/server/useLogger': 'src/runtime/server/useLogger.ts', @@ -36,6 +38,11 @@ export default defineConfig({ '@nuxt/schema', 'nitropack', 'nitropack/runtime', + 'nitro', + 'nitro/h3', + 'nitro/runtime-config', + 'nitro/types', + 'ufo', 'ofetch', 'h3', ], From 3be516a5bc716c87dca7a02bec9e77d761a08887 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 20:50:20 +0100 Subject: [PATCH 19/26] test: nitro v3 tests --- .../test/nitro-v3/fixture/nitro.config.ts | 30 ++ .../nitro-v3/fixture/plugins/test-drain.ts | 19 ++ .../nitro-v3/fixture/plugins/test-enrich.ts | 16 + .../nitro-v3/fixture/plugins/test-sampling.ts | 20 ++ .../test/nitro-v3/fixture/routes/throws.ts | 18 ++ .../test/nitro-v3/fixture/routes/works.ts | 12 + packages/evlog/test/nitro-v3/nitro-v3.test.ts | 278 ++++++++++++++++++ packages/evlog/vitest.config.ts | 1 + 8 files changed, 394 insertions(+) create mode 100644 packages/evlog/test/nitro-v3/fixture/nitro.config.ts create mode 100644 packages/evlog/test/nitro-v3/fixture/plugins/test-drain.ts create mode 100644 packages/evlog/test/nitro-v3/fixture/plugins/test-enrich.ts create mode 100644 packages/evlog/test/nitro-v3/fixture/plugins/test-sampling.ts create mode 100644 packages/evlog/test/nitro-v3/fixture/routes/throws.ts create mode 100644 packages/evlog/test/nitro-v3/fixture/routes/works.ts create mode 100644 packages/evlog/test/nitro-v3/nitro-v3.test.ts diff --git a/packages/evlog/test/nitro-v3/fixture/nitro.config.ts b/packages/evlog/test/nitro-v3/fixture/nitro.config.ts new file mode 100644 index 0000000..0623f32 --- /dev/null +++ b/packages/evlog/test/nitro-v3/fixture/nitro.config.ts @@ -0,0 +1,30 @@ +import { + defineConfig +} from 'nitro' +import { resolve } from 'pathe' + +const evlogRoot = resolve(__dirname, '../../../src') + +export default defineConfig({ + serverDir: './', + errorHandler: resolve(evlogRoot, 'nitro-v3/errorHandler.ts'), + plugins: [resolve(evlogRoot, 'nitro-v3/plugin.ts')], + alias: { + 'evlog': resolve(evlogRoot, 'index.ts'), + }, + builder: 'rollup', + watchOptions: { + ignored: ['**/*'], + ignoreInitial: true, + usePolling: false, + }, + rollupConfig: { + watch: { + exclude: ['**/*'], + chokidar: { + ignoreInitial: true, + usePolling: false, + } + } + } +}) diff --git a/packages/evlog/test/nitro-v3/fixture/plugins/test-drain.ts b/packages/evlog/test/nitro-v3/fixture/plugins/test-drain.ts new file mode 100644 index 0000000..28c6c7f --- /dev/null +++ b/packages/evlog/test/nitro-v3/fixture/plugins/test-drain.ts @@ -0,0 +1,19 @@ +import { definePlugin } from 'nitro' +import type { DrainContext } from '../../../../src/types' + +export default definePlugin((nitroApp) => { + nitroApp.hooks.hook('evlog:drain', (ctx: DrainContext) => { + console.log('[TEST:DRAIN]', JSON.stringify({ + eventLevel: ctx.event.level, + hasHeaders: !!ctx.headers, + headerKeys: ctx.headers ? Object.keys(ctx.headers).sort() : [], + hasAuthHeader: ctx.headers ? 'authorization' in ctx.headers : false, + hasCookieHeader: ctx.headers ? 'cookie' in ctx.headers : false, + hasUserAgent: ctx.headers ? 'user-agent' in ctx.headers : false, + requestPath: ctx.request?.path, + requestMethod: ctx.request?.method, + hasEnrichment: 'customEnrichment' in ctx.event, + enrichmentValue: (ctx.event as any).customEnrichment, + })) + }) +}) diff --git a/packages/evlog/test/nitro-v3/fixture/plugins/test-enrich.ts b/packages/evlog/test/nitro-v3/fixture/plugins/test-enrich.ts new file mode 100644 index 0000000..bb7d33c --- /dev/null +++ b/packages/evlog/test/nitro-v3/fixture/plugins/test-enrich.ts @@ -0,0 +1,16 @@ +import { definePlugin } from 'nitro' +import type { EnrichContext } from '../../../../src/types' + +export default definePlugin((nitroApp) => { + nitroApp.hooks.hook('evlog:enrich', (ctx: EnrichContext) => { + console.log('[TEST:ENRICH]', JSON.stringify({ + eventLevel: ctx.event.level, + hasCustomField: 'customEnrichment' in ctx.event, + requestPath: ctx.request?.path, + headerKeys: ctx.headers ? Object.keys(ctx.headers).sort() : [], + })) + + // Add custom enrichment for testing + ctx.event.customEnrichment = 'enriched' + }) +}) diff --git a/packages/evlog/test/nitro-v3/fixture/plugins/test-sampling.ts b/packages/evlog/test/nitro-v3/fixture/plugins/test-sampling.ts new file mode 100644 index 0000000..a39d827 --- /dev/null +++ b/packages/evlog/test/nitro-v3/fixture/plugins/test-sampling.ts @@ -0,0 +1,20 @@ +import { definePlugin } from 'nitro' + +export default definePlugin((nitroApp) => { + nitroApp.hooks.hook('evlog:emit:keep', (ctx) => { + console.log('[TEST:SAMPLING]', JSON.stringify({ + initialShouldKeep: ctx.shouldKeep, + contextKeys: Object.keys(ctx.context), + hasUserInContext: 'user' in ctx.context, + requestPath: ctx.path, + requestMethod: ctx.method, + status: ctx.status, + duration: ctx.duration, + })) + + // Custom tail sampling logic for testing + if (ctx.context.user && (ctx.context.user as any).premium) { + ctx.shouldKeep = true + } + }) +}) diff --git a/packages/evlog/test/nitro-v3/fixture/routes/throws.ts b/packages/evlog/test/nitro-v3/fixture/routes/throws.ts new file mode 100644 index 0000000..ea56fc8 --- /dev/null +++ b/packages/evlog/test/nitro-v3/fixture/routes/throws.ts @@ -0,0 +1,18 @@ +import { defineHandler } from 'nitro/h3' +import { createError, useLogger } from 'evlog' + +export default defineHandler((event) => { + const log = useLogger(event) + + log.set({ user: { id: 42, plan: 'enterprise' } }) + log.set({ transaction: { id: 'txn_123', amount: 5000 } }) + log.set({ attempt: { count: 3, method: 'credit_card' } }) + + throw createError({ + message: 'Payment failed', + status: 402, + why: 'Card declined by issuer (insufficient funds)', + fix: 'Try a different payment method or contact your bank', + link: 'https://docs.example.com/payments/declined', + }) +}) diff --git a/packages/evlog/test/nitro-v3/fixture/routes/works.ts b/packages/evlog/test/nitro-v3/fixture/routes/works.ts new file mode 100644 index 0000000..baa19d5 --- /dev/null +++ b/packages/evlog/test/nitro-v3/fixture/routes/works.ts @@ -0,0 +1,12 @@ +import { defineHandler } from 'nitro/h3' +import { useLogger } from 'evlog' + +export default defineHandler((event) => { + const log = useLogger(event) + + log.set({ user: { id: 1, plan: 'pro' } }) + log.set({ cart: { id: 42, items: 3, total: 9999 } }) + log.set({ payment: { method: 'card', status: 'success' } }) + + return { success: true } +}) diff --git a/packages/evlog/test/nitro-v3/nitro-v3.test.ts b/packages/evlog/test/nitro-v3/nitro-v3.test.ts new file mode 100644 index 0000000..b5226bf --- /dev/null +++ b/packages/evlog/test/nitro-v3/nitro-v3.test.ts @@ -0,0 +1,278 @@ +import { + afterAll, + beforeAll, + describe, + expect, + it, + vi, +} from 'vitest' +import { + build, + createDevServer, + createNitro, + prepare, +} from 'nitro/builder' +import { resolve } from 'pathe' +import { consola } from 'consola' +import { parseError } from '../../src/runtime/utils/parseError' + +const rootDir = resolve(__dirname, './fixture') + +describe.sequential('Nitro v3 Server with evlog', () => { + let nitro: Awaited> + let devServer: ReturnType + let server: Awaited['listen']>> + + beforeAll(async () => { + nitro = await createNitro({ + dev: true, + rootDir, + }) + devServer = createDevServer(nitro) + server = devServer.listen({}) + await prepare(nitro) + const ready = new Promise((resolve) => { + nitro.hooks.hook('dev:reload', () => resolve()) + }) + await build(nitro) + await ready + }) + + afterAll(async () => { + await devServer?.close() + await nitro?.close() + }) + + it('should be able to get the correct result', async () => { + const res = await server.fetch(new Request(new URL('/works', server.url))) + const json = await res.json() + + expect(json).toEqual({ success: true }) + }) + + it.sequential('should have displayed the correct log message', async () => { + const logs: any[] = [] + const mockFn = vi.fn((context) => { + logs.push(String(context)) + }) + + consola.mockTypes((typeName, type) => mockFn) + consola.wrapAll() + + try { + await server.fetch(new Request(new URL('/works', server.url))) + + // Wait for async logs to be written + await new Promise(resolve => setTimeout(resolve, 100)) + + expect(mockFn).toHaveBeenCalled() + const logOutput = logs.join('\n') + + expect(logOutput).toMatch(/INFO.*GET \/works.*200/) + expect(logOutput).toContain('payment:') + expect(logOutput).toContain('method=card') + expect(logOutput).toContain('status=success') + expect(logOutput).toContain('cart:') + expect(logOutput).toContain('id=42') + expect(logOutput).toContain('items=3') + expect(logOutput).toContain('total=9999') + expect(logOutput).toContain('user:') + expect(logOutput).toContain('id=1') + expect(logOutput).toContain('plan=pro') + expect(logOutput).toContain('requestId:') + } finally { + consola.restoreAll() + } + }) + + it.sequential('should handle structured errors correctly', async () => { + const logs: any[] = [] + const mockFn = vi.fn((context) => { + logs.push(String(context)) + }) + + consola.mockTypes((typeName, type) => mockFn) + consola.wrapAll() + + try { + const res = await server.fetch(new Request(new URL('/throws', server.url))) + + expect(res.status).toBe(402) + + const json = await res.json() + const error = parseError(json) + + // Verify all error fields are accessible at top level + expect(error.message).toBe('Payment failed') + expect(error.status).toBe(402) + expect(error.why).toBe('Card declined by issuer (insufficient funds)') + expect(error.fix).toBe('Try a different payment method or contact your bank') + expect(error.link).toBe('https://docs.example.com/payments/declined') + + // Wait for async logs to be written + await new Promise(resolve => setTimeout(resolve, 100)) + + // Verify error logs include wide context + expect(mockFn).toHaveBeenCalled() + const logOutput = logs.join('\\n') + + expect(logOutput).toMatch(/ERROR.*GET \/throws.*402/) + expect(logOutput).toContain('user:') + expect(logOutput).toContain('id=42') + expect(logOutput).toContain('plan=enterprise') + expect(logOutput).toContain('transaction:') + expect(logOutput).toContain('id=txn_123') + expect(logOutput).toContain('amount=5000') + expect(logOutput).toContain('attempt:') + expect(logOutput).toContain('count=3') + expect(logOutput).toContain('method=credit_card') + expect(logOutput).toContain('error:') + expect(logOutput).toContain('Payment failed') + } finally { + consola.restoreAll() + } + }) + + it.sequential('should call evlog:drain hook with safe headers', async () => { + const logs: any[] = [] + const mockFn = vi.fn((context) => { + logs.push(String(context)) + }) + + consola.mockTypes((typeName, type) => mockFn) + consola.wrapAll() + + try { + await server.fetch(new Request(new URL('/works', server.url), { + headers: { + 'Authorization': 'Bearer secret-token', + 'Cookie': 'session=abc123', + 'User-Agent': 'Test Browser', + 'X-Custom-Header': 'custom-value', + }, + })) + + // Wait for async logs and hooks to be called + await new Promise(resolve => setTimeout(resolve, 100)) + + expect(mockFn).toHaveBeenCalled() + const logOutput = logs.join('\n') + + // Find the drain hook log + const drainLogMatch = logOutput.match(/\[TEST:DRAIN\] (.+)/) + expect(drainLogMatch).toBeTruthy() + + const drainData = JSON.parse(drainLogMatch![1]) + + // Verify sensitive headers are filtered out + expect(drainData.hasAuthHeader).toBe(false) + expect(drainData.hasCookieHeader).toBe(false) + + // Verify safe headers are included + expect(drainData.hasUserAgent).toBe(true) + expect(drainData.headerKeys).toContain('user-agent') + expect(drainData.headerKeys).toContain('x-custom-header') + + // Verify sensitive headers are not in the keys + expect(drainData.headerKeys).not.toContain('authorization') + expect(drainData.headerKeys).not.toContain('cookie') + + // Verify request metadata + expect(drainData.requestPath).toBe('/works') + expect(drainData.requestMethod).toBe('GET') + expect(drainData.eventLevel).toBe('info') + } finally { + consola.restoreAll() + } + }) + + it.sequential('should call evlog:enrich hook with correct context', async () => { + const logs: any[] = [] + const mockFn = vi.fn((context) => { + logs.push(String(context)) + }) + + consola.mockTypes((typeName, type) => mockFn) + consola.wrapAll() + + try { + await server.fetch(new Request(new URL('/works', server.url))) + + // Wait for async logs and hooks to be called + await new Promise(resolve => setTimeout(resolve, 100)) + + expect(mockFn).toHaveBeenCalled() + const logOutput = logs.join('\n') + + // Find the enrich hook log + const enrichLogMatch = logOutput.match(/\[TEST:ENRICH\] (.+)/) + expect(enrichLogMatch).toBeTruthy() + + const enrichData = JSON.parse(enrichLogMatch![1]) + + // Verify enrich hook received the event before enrichment + expect(enrichData.hasCustomField).toBe(false) + expect(enrichData.requestPath).toBe('/works') + expect(enrichData.eventLevel).toBe('info') + + // Verify headers were passed to enrich hook + expect(enrichData.headerKeys).toBeTruthy() + expect(enrichData.headerKeys.length).toBeGreaterThan(0) + + // Verify drain hook received the enriched event + const drainLogMatch = logOutput.match(/\[TEST:DRAIN\] (.+)/) + expect(drainLogMatch).toBeTruthy() + + const drainData = JSON.parse(drainLogMatch![1]) + + // Enrichment should be present in drain hook (runs after enrich) + expect(drainData.hasEnrichment).toBe(true) + expect(drainData.enrichmentValue).toBe('enriched') + } finally { + consola.restoreAll() + } + }) + + it.sequential('should call evlog:emit:keep hook for tail sampling', async () => { + const logs: any[] = [] + const mockFn = vi.fn((context) => { + logs.push(String(context)) + }) + + consola.mockTypes((typeName, type) => mockFn) + consola.wrapAll() + + try { + await server.fetch(new Request(new URL('/works', server.url))) + + // Wait for async logs and hooks to be called + await new Promise(resolve => setTimeout(resolve, 100)) + + expect(mockFn).toHaveBeenCalled() + const logOutput = logs.join('\n') + + // Find the sampling hook log + const samplingLogMatch = logOutput.match(/\[TEST:SAMPLING\] (.+)/) + expect(samplingLogMatch).toBeTruthy() + + const samplingData = JSON.parse(samplingLogMatch![1]) + + // Verify context is available + expect(samplingData.contextKeys).toContain('payment') + expect(samplingData.contextKeys).toContain('cart') + expect(samplingData.contextKeys).toContain('user') + expect(samplingData.hasUserInContext).toBe(true) + + // Verify request metadata + expect(samplingData.requestPath).toBe('/works') + expect(samplingData.requestMethod).toBe('GET') + expect(samplingData.status).toBe(200) + expect(samplingData.duration).toBeGreaterThanOrEqual(0) + + // Verify sampling decision + expect(samplingData.initialShouldKeep).toBe(false) + } finally { + consola.restoreAll() + } + }) +}) diff --git a/packages/evlog/vitest.config.ts b/packages/evlog/vitest.config.ts index 933233d..e8b0979 100644 --- a/packages/evlog/vitest.config.ts +++ b/packages/evlog/vitest.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { + hookTimeout: 30_000, include: ['test/**/*.test.ts'], environment: 'node', coverage: { From 83ecf184602da3d57f92fd91227e7140422a499e Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 21:00:36 +0100 Subject: [PATCH 20/26] chore: clean up nitro v3 playground --- apps/nitro-v3-playground/index.html | 113 -------- apps/nitro-v3-playground/nitro.config.ts | 3 +- apps/nitro-v3-playground/public/styles.css | 253 ------------------ .../routes/api/test/update.put.ts | 3 +- .../routes/{api => }/index.ts | 0 apps/nitro-v3-playground/tsconfig.json | 5 +- 6 files changed, 7 insertions(+), 370 deletions(-) delete mode 100644 apps/nitro-v3-playground/index.html delete mode 100644 apps/nitro-v3-playground/public/styles.css rename apps/nitro-v3-playground/routes/{api => }/index.ts (100%) diff --git a/apps/nitro-v3-playground/index.html b/apps/nitro-v3-playground/index.html deleted file mode 100644 index 5485925..0000000 --- a/apps/nitro-v3-playground/index.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - evlog Nitro v3 Playground - - - - - - -
-

evlog Nitro v3 Playground 🚀

-

Test the evlog integration with different HTTP methods. Check your terminal for wide event logs!

-
-
-

Test API Endpoints

- -
- - -
- -
- - - - -
- -
- -
- -
-
- -
- - - - diff --git a/apps/nitro-v3-playground/nitro.config.ts b/apps/nitro-v3-playground/nitro.config.ts index 7e29717..ed86ede 100644 --- a/apps/nitro-v3-playground/nitro.config.ts +++ b/apps/nitro-v3-playground/nitro.config.ts @@ -3,5 +3,6 @@ import { defineConfig } from 'nitro' export default defineConfig({ serverDir: './', // TODO: make playground work with evlog/nitro/v3 - plugins: ['../../packages/evlog/src/nitro-v3/plugin.ts'] + plugins: ['../../packages/evlog/src/nitro-v3/plugin.ts'], + errorHandler: "../../packages/evlog/src/nitro-v3/errorHandler.ts" }) diff --git a/apps/nitro-v3-playground/public/styles.css b/apps/nitro-v3-playground/public/styles.css deleted file mode 100644 index 61fb186..0000000 --- a/apps/nitro-v3-playground/public/styles.css +++ /dev/null @@ -1,253 +0,0 @@ -:root { - --bg: #020202; - --card: #0a0a0a; - --text: #fafafa; - --muted: #94a3b8; - --border: #27272a; - --primary: #2853FF; - --primary-hover: #3d65ff; - --success: #0ea5a4; - --warning: #f59e0b; - --danger: #ef4444; - --purple: #8b5cf6; - --code-bg: #000000; - --code-text: #e6eef8; - --radius: 8px; - --section-bg: #0f0f0f; -} - -* { - box-sizing: border-box; -} - -html, -body { - height: 100%; - overflow: hidden; - margin: 0; - padding: 0; -} - -body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif; - background: var(--bg); - color: var(--text); - display: flex; - align-items: center; - justify-content: center; - padding: 24px; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - line-height: 1.5; -} - -.card { - background: var(--card); - padding: 48px; - border-radius: 12px; - max-width: 920px; - width: 100%; - max-height: calc(100vh - 48px); - overflow-y: auto; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 20px 40px rgba(0, 0, 0, 0.5); - border: 1px solid var(--border); -} - -h1 { - margin: 0 0 8px 0; - font-weight: 700; - font-size: 2rem; - color: var(--text); - letter-spacing: -0.02em; - line-height: 1.2; -} - -p { - margin: 0 0 24px 0; - color: var(--muted); - font-size: 1rem; -} - -a { - color: var(--primary); - text-decoration: none; - font-weight: 500; -} - -a:hover { - text-decoration: underline; -} - -code, -pre { - font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; - font-size: 0.875rem; -} - -pre.api { - margin-top: 24px; - background: var(--code-bg); - color: var(--code-text); - padding: 16px 20px; - border-radius: var(--radius); - overflow: auto; - white-space: pre-wrap; - word-break: break-word; - font-size: 0.8125rem; - line-height: 1.6; -} - -.demo-section { - margin-top: 40px; - padding: 32px; - background: var(--section-bg); - border-radius: var(--radius); - border: 1px solid var(--border); -} - -.demo-section h2 { - margin: 0 0 24px 0; - font-size: 1.25rem; - font-weight: 700; - color: var(--text); - letter-spacing: -0.01em; -} - -.buttons { - display: flex; - gap: 12px; - margin-bottom: 16px; - flex-wrap: wrap; -} - -button { - padding: 12px 24px; - border: none; - border-radius: 6px; - font-family: inherit; - font-size: 0.9375rem; - font-weight: 600; - cursor: pointer; - transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1); - flex: 1; - min-width: fit-content; -} - -button:hover { - transform: translateY(-1px); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); -} - -button:active { - transform: translateY(0); -} - -.btn-get { - background: var(--success); - color: white; -} - -.btn-get:hover { - background: #0d9488; -} - -.btn-post { - background: var(--purple); - color: white; -} - -.btn-post:hover { - background: #7c3aed; -} - -.btn-delete { - background: var(--danger); - color: white; -} - -.btn-delete:hover { - background: #dc2626; -} - -.btn-wide { - background: var(--primary); - color: white; - flex: 1 1 100%; -} - -.btn-wide:hover { - background: var(--primary-hover); -} - -#result { - margin-top: 20px; - padding: 20px 24px; - background: var(--code-bg); - color: var(--code-text); - border-radius: var(--radius); - font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; - font-size: 0.8125rem; - line-height: 1.7; - white-space: pre-wrap; - word-break: break-word; - min-height: 80px; - display: none; - border: 1px solid #18181b; -} - -#result.show { - display: block; - animation: fadeIn 0.2s ease-in; -} - -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(4px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - -.input-group { - margin-bottom: 24px; -} - -.input-group label { - display: block; - margin-bottom: 8px; - font-size: 0.875rem; - font-weight: 600; - color: var(--text); -} - -.input-group input { - width: 100%; - padding: 12px 16px; - border: 1px solid var(--border); - border-radius: 6px; - font-family: inherit; - font-size: 0.9375rem; - background: var(--code-bg); - color: var(--text); - transition: border-color 0.15s, box-shadow 0.15s; -} - -.input-group input:focus { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 3px rgba(40, 83, 255, 0.1); -} - -.input-group input::placeholder { - color: #94a3b8; -} - -/* Subtle separator */ -.separator { - height: 1px; - background: linear-gradient(to right, transparent, var(--border), transparent); - margin: 32px 0; -} diff --git a/apps/nitro-v3-playground/routes/api/test/update.put.ts b/apps/nitro-v3-playground/routes/api/test/update.put.ts index 52bd014..c40f5f3 100644 --- a/apps/nitro-v3-playground/routes/api/test/update.put.ts +++ b/apps/nitro-v3-playground/routes/api/test/update.put.ts @@ -1,6 +1,5 @@ import { defineHandler, readBody } from 'nitro/h3' -import { useLogger } from 'evlog' -import { createError } from 'evlog/nitro/v3' +import { useLogger, createError } from 'evlog' export default defineHandler(async (event) => { const log = useLogger(event) diff --git a/apps/nitro-v3-playground/routes/api/index.ts b/apps/nitro-v3-playground/routes/index.ts similarity index 100% rename from apps/nitro-v3-playground/routes/api/index.ts rename to apps/nitro-v3-playground/routes/index.ts diff --git a/apps/nitro-v3-playground/tsconfig.json b/apps/nitro-v3-playground/tsconfig.json index 1099389..57d38c4 100644 --- a/apps/nitro-v3-playground/tsconfig.json +++ b/apps/nitro-v3-playground/tsconfig.json @@ -1,8 +1,11 @@ { "extends": ["nitro/tsconfig"], "compilerOptions": { + "moduleResolution": "bundler", "paths": { - "~/*": ["./*"] + "~/*": ["./*"], + "evlog": ["../../packages/evlog/src/index.ts"], + "evlog/*": ["../../packages/evlog/src/*"] } } } From cd2f9fb4d695963d210623f861afcb16f3826cc6 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 21:10:43 +0100 Subject: [PATCH 21/26] docs: update nitro v3 usage --- .../1.getting-started/1.introduction.md | 2 +- .../1.getting-started/2.installation.md | 40 ++++++++++++++++++- .../1.getting-started/3.quick-start.md | 6 +-- .../2.core-concepts/2.structured-errors.md | 6 +-- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/apps/docs/content/1.getting-started/1.introduction.md b/apps/docs/content/1.getting-started/1.introduction.md index 76e88c8..a5a1266 100644 --- a/apps/docs/content/1.getting-started/1.introduction.md +++ b/apps/docs/content/1.getting-started/1.introduction.md @@ -111,7 +111,7 @@ Structured errors provide actionable context: ::code-group ```typescript [Code] // server/api/checkout.post.ts -import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3 +import { createError } from 'evlog' throw createError({ message: 'Payment failed', diff --git a/apps/docs/content/1.getting-started/2.installation.md b/apps/docs/content/1.getting-started/2.installation.md index accc4fb..cd8d645 100644 --- a/apps/docs/content/1.getting-started/2.installation.md +++ b/apps/docs/content/1.getting-started/2.installation.md @@ -372,16 +372,52 @@ bun add evlog ``` :: -Then, add evlog as a Nitro plugin (without Nuxt) using the `evlog/nitro` plugin: +### Plugin Setup +Add evlog as a Nitro plugin. The plugin path differs between Nitro v2 and v3: + +::code-group ```typescript [nitro.config.ts] +// nitro export default defineNitroConfig({ plugins: ['evlog/nitro'], }) ``` +```typescript [nitro.config.ts] +// nitro v3 +import { defineConfig } from 'nitro' + +export default defineConfig({ + plugins: ['evlog/nitro/v3'], +}) +``` +:: + +### Error Handler + +Use the evlog error handler to properly serialize structured errors with all fields (`why`, `fix`, `link`) in the HTTP response: + +::code-group +```typescript [nitro.config.ts] +// nitro +export default defineNitroConfig({ + plugins: ['evlog/nitro'], + errorHandler: ['evlog/nitro'], +}) +``` +```typescript [nitro.config.ts] +// nitro v3 +import { defineConfig } from 'nitro' + +export default defineConfig({ + plugins: ['evlog/nitro/v3'], + errorHandler: ['evlog/nitro/v3'], +}) +``` +:: ::callout{icon="i-lucide-info" color="info"} -For early Nitro v3 support, use `evlog/nitro/v3` instead of `evlog/nitro`. When using Nitro v3, import `createError` from `evlog/nitro/v3` instead of `evlog`. +**Note:** The `createError` function is available from `evlog` for all Nitro versions. Only the plugin and error handler paths differ between v2 and v3. :: ## Cloudflare Workers diff --git a/apps/docs/content/1.getting-started/3.quick-start.md b/apps/docs/content/1.getting-started/3.quick-start.md index 90e0a1e..11e10d7 100644 --- a/apps/docs/content/1.getting-started/3.quick-start.md +++ b/apps/docs/content/1.getting-started/3.quick-start.md @@ -121,14 +121,10 @@ export default defineEventHandler((event) => { Use `createError()` to throw errors with actionable context: -::callout{icon="i-lucide-info" color="info"} -For Nitro v3, import from `evlog/nitro/v3` instead of `evlog`. -:: - ::code-group ```typescript [Code] // server/api/checkout.post.ts -import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3 +import { createError } from 'evlog' throw createError({ message: 'Payment failed', diff --git a/apps/docs/content/2.core-concepts/2.structured-errors.md b/apps/docs/content/2.core-concepts/2.structured-errors.md index 378c6de..061f761 100644 --- a/apps/docs/content/2.core-concepts/2.structured-errors.md +++ b/apps/docs/content/2.core-concepts/2.structured-errors.md @@ -18,10 +18,6 @@ links: evlog provides a `createError()` function that creates errors with rich, actionable context. -::callout{icon="i-lucide-info" color="info"} -For Nitro v3, import `createError` from `evlog/nitro/v3` instead of `evlog`. -:: - ## Why Structured Errors? Traditional errors are often unhelpful: @@ -77,7 +73,7 @@ throw createError({ ::code-group ```typescript [Code] // server/api/users/[id].get.ts -import { createError } from 'evlog' // Use 'evlog/nitro/v3' for Nitro v3 +import { createError } from 'evlog' throw createError({ message: 'User not found', From 8b1339fcc726f2923101fa804b6175b919833e68 Mon Sep 17 00:00:00 2001 From: schplitt Date: Tue, 10 Feb 2026 21:34:57 +0100 Subject: [PATCH 22/26] docs: update README for Nitro v3 playground --- apps/nitro-v3-playground/README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/apps/nitro-v3-playground/README.md b/apps/nitro-v3-playground/README.md index ce15a30..0d5b3ff 100644 --- a/apps/nitro-v3-playground/README.md +++ b/apps/nitro-v3-playground/README.md @@ -1,18 +1,14 @@ -# Nitro starter - -Create your API and deploy it anywhere with this Nitro starter. +# Nitro v3 evlog playground ## Getting started ```bash -npm install -npm run dev +bun install +bun run dev ``` ## Deploying ```bash -npm run build +bun run build ``` - -Then checkout the [Nitro documentation](https://v3.nitro.build/deploy) to learn more about the different deployment presets. From fa5f1756e5aacee72429a6fb3878706da4d8ff82 Mon Sep 17 00:00:00 2001 From: schplitt Date: Wed, 11 Feb 2026 19:34:07 +0100 Subject: [PATCH 23/26] build: explicitly inline `ufo` --- bun.lock | 7 ++----- packages/evlog/package.json | 4 ++-- packages/evlog/tsdown.config.ts | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/bun.lock b/bun.lock index 8c0bed2..90f7653 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "evlog-monorepo", @@ -88,7 +89,6 @@ "version": "1.7.0", "dependencies": { "@nuxt/kit": "^4.3.0", - "ufo": "^1.6.3", }, "devDependencies": { "@nuxt/devtools": "^3.1.1", @@ -102,6 +102,7 @@ "nuxt": "^4.3.1", "tsdown": "^0.20.3", "typescript": "^5.9.3", + "ufo": "^1.6.3", }, "peerDependencies": { "@nuxt/kit": "^4.3.1", @@ -3444,10 +3445,6 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "@dxup/nuxt/@nuxt/kit/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - - "@dxup/nuxt/@nuxt/kit/rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], - "@intlify/bundle-utils/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], "@intlify/bundle-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], diff --git a/packages/evlog/package.json b/packages/evlog/package.json index 3a5de83..330624e 100644 --- a/packages/evlog/package.json +++ b/packages/evlog/package.json @@ -137,10 +137,10 @@ "typecheck": "echo 'Typecheck handled by build'" }, "dependencies": { - "@nuxt/kit": "^4.3.0", - "ufo": "^1.6.3" + "@nuxt/kit": "^4.3.0" }, "devDependencies": { + "ufo": "^1.6.3", "@nuxt/devtools": "^3.1.1", "@nuxt/schema": "^4.3.1", "@nuxt/test-utils": "^3.23.0", diff --git a/packages/evlog/tsdown.config.ts b/packages/evlog/tsdown.config.ts index 8eca694..6c6ded6 100644 --- a/packages/evlog/tsdown.config.ts +++ b/packages/evlog/tsdown.config.ts @@ -43,7 +43,6 @@ export default defineConfig({ 'nitro/h3', 'nitro/runtime-config', 'nitro/types', - 'ufo', 'ofetch', 'h3', ], From 0534fc126373a438ee6b03f42c55f2f19fafcae6 Mon Sep 17 00:00:00 2001 From: schplitt Date: Wed, 11 Feb 2026 19:52:07 +0100 Subject: [PATCH 24/26] refactor: remove evlog path mappings from playground tsconfig --- apps/nitro-v3-playground/tsconfig.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/nitro-v3-playground/tsconfig.json b/apps/nitro-v3-playground/tsconfig.json index 57d38c4..41466d5 100644 --- a/apps/nitro-v3-playground/tsconfig.json +++ b/apps/nitro-v3-playground/tsconfig.json @@ -4,8 +4,6 @@ "moduleResolution": "bundler", "paths": { "~/*": ["./*"], - "evlog": ["../../packages/evlog/src/index.ts"], - "evlog/*": ["../../packages/evlog/src/*"] } } } From 5a5de1868d0ace5463c4a6a669018682547767fc Mon Sep 17 00:00:00 2001 From: schplitt Date: Wed, 11 Feb 2026 20:11:56 +0100 Subject: [PATCH 25/26] docs: update Nitro v3 plugin and errorHandler registration --- .../1.getting-started/2.installation.md | 35 +++++++------------ apps/nitro-v3-playground/errorHandler.ts | 1 + apps/nitro-v3-playground/nitro.config.ts | 4 +-- apps/nitro-v3-playground/plugins/evlog.ts | 1 + packages/evlog/src/nitro-v3/errorHandler.ts | 8 ++--- packages/evlog/src/nitro-v3/plugin.ts | 9 +++++ 6 files changed, 28 insertions(+), 30 deletions(-) create mode 100644 apps/nitro-v3-playground/errorHandler.ts create mode 100644 apps/nitro-v3-playground/plugins/evlog.ts diff --git a/apps/docs/content/1.getting-started/2.installation.md b/apps/docs/content/1.getting-started/2.installation.md index 0fbb83f..35bbd5c 100644 --- a/apps/docs/content/1.getting-started/2.installation.md +++ b/apps/docs/content/1.getting-started/2.installation.md @@ -372,48 +372,37 @@ bun add evlog ``` :: -### Plugin Setup +### Nitro v2 -Add evlog as a Nitro plugin. The plugin path differs between Nitro v2 and v3: +Use the Nitro v2 plugin and error handler directly in your config: ::code-group ```typescript [nitro.config.ts] -// nitro export default defineNitroConfig({ plugins: ['evlog/nitro'], -}) -``` -```typescript [nitro.config.ts] -// nitro v3 -import { defineConfig } from 'nitro' - -export default defineConfig({ - plugins: ['evlog/nitro/v3'], + errorHandler: ['evlog/nitro'], }) ``` :: -### Error Handler +### Nitro v3 -Use the evlog error handler to properly serialize structured errors with all fields (`why`, `fix`, `link`) in the HTTP response: +Nitro v3 auto-loads plugins from `./plugins`. Create a plugin file and an error handler file next to `nitro.config.ts`: ::code-group ```typescript [nitro.config.ts] -// nitro -export default defineNitroConfig({ - plugins: ['evlog/nitro'], - errorHandler: ['evlog/nitro'], -}) -``` -```typescript [nitro.config.ts] -// nitro v3 import { defineConfig } from 'nitro' export default defineConfig({ - plugins: ['evlog/nitro/v3'], - errorHandler: ['evlog/nitro/v3'], + errorHandler: './errorHandler', }) ``` +```typescript [errorHandler.ts] +export { default } from 'evlog/nitro/v3/errorHandler' +``` +```typescript [plugins/evlog.ts] +export { default } from 'evlog/nitro/v3' +``` :: ::callout{icon="i-lucide-info" color="info"} diff --git a/apps/nitro-v3-playground/errorHandler.ts b/apps/nitro-v3-playground/errorHandler.ts new file mode 100644 index 0000000..d737b1d --- /dev/null +++ b/apps/nitro-v3-playground/errorHandler.ts @@ -0,0 +1 @@ +export { default } from 'evlog/nitro/v3/errorHandler' diff --git a/apps/nitro-v3-playground/nitro.config.ts b/apps/nitro-v3-playground/nitro.config.ts index ed86ede..3befa7b 100644 --- a/apps/nitro-v3-playground/nitro.config.ts +++ b/apps/nitro-v3-playground/nitro.config.ts @@ -2,7 +2,5 @@ import { defineConfig } from 'nitro' export default defineConfig({ serverDir: './', - // TODO: make playground work with evlog/nitro/v3 - plugins: ['../../packages/evlog/src/nitro-v3/plugin.ts'], - errorHandler: "../../packages/evlog/src/nitro-v3/errorHandler.ts" + errorHandler: './errorHandler', }) diff --git a/apps/nitro-v3-playground/plugins/evlog.ts b/apps/nitro-v3-playground/plugins/evlog.ts new file mode 100644 index 0000000..e8dcab3 --- /dev/null +++ b/apps/nitro-v3-playground/plugins/evlog.ts @@ -0,0 +1 @@ +export { default } from 'evlog/nitro/v3' diff --git a/packages/evlog/src/nitro-v3/errorHandler.ts b/packages/evlog/src/nitro-v3/errorHandler.ts index 9f50d13..b181516 100644 --- a/packages/evlog/src/nitro-v3/errorHandler.ts +++ b/packages/evlog/src/nitro-v3/errorHandler.ts @@ -13,11 +13,11 @@ import { EvlogError } from '../error' * * Usage in nitro.config.ts: * ```ts - * import { defineConfig } from 'nitro' - * import evlogErrorHandler from 'evlog/nitro/v3/errorHandler' - * + * // errorHandler.ts + * export { default } from 'evlog/nitro/v3/errorHandler' + * // nitro.config.ts * export default defineConfig({ - * errorHandler: evlogErrorHandler, + * errorHandler: './errorHandler', * }) * ``` */ diff --git a/packages/evlog/src/nitro-v3/plugin.ts b/packages/evlog/src/nitro-v3/plugin.ts index 68c853d..05acda0 100644 --- a/packages/evlog/src/nitro-v3/plugin.ts +++ b/packages/evlog/src/nitro-v3/plugin.ts @@ -119,6 +119,15 @@ async function callEnrichAndDrain( callDrainHook(hooks, emittedEvent, event, hookContext.request, hookContext.headers) } +/** + * Nitro v3 plugin entry point. + * + * Usage in Nitro v3: + * ```ts + * // plugins/evlog.ts + * export { default } from 'evlog/nitro/v3' + * ``` + */ export default definePlugin((nitroApp) => { const config = useRuntimeConfig() const evlogConfig = config.evlog as EvlogConfig | undefined From a353be6d90b49138203f3a18be0a459fdf511736 Mon Sep 17 00:00:00 2001 From: schplitt Date: Wed, 11 Feb 2026 20:17:23 +0100 Subject: [PATCH 26/26] refactor: leave unknown errors to default error handler --- packages/evlog/src/nitro-v3/errorHandler.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/evlog/src/nitro-v3/errorHandler.ts b/packages/evlog/src/nitro-v3/errorHandler.ts index b181516..dd1ba4d 100644 --- a/packages/evlog/src/nitro-v3/errorHandler.ts +++ b/packages/evlog/src/nitro-v3/errorHandler.ts @@ -21,9 +21,8 @@ import { EvlogError } from '../error' * }) * ``` */ -export const evlogErrorHandler = defineErrorHandler(async (error, event, { defaultHandler }): Promise => { +export const evlogErrorHandler = defineErrorHandler((error, event) => { // Check if this is an EvlogError (by name or by checking cause) - const evlogError = error.name === 'EvlogError' ? error : (error.cause as Error)?.name === 'EvlogError' @@ -33,18 +32,11 @@ export const evlogErrorHandler = defineErrorHandler(async (error, event, { defau : null - const isDev = process.env.NODE_ENV === 'development' const url = parseURL(event.req.url).pathname // For non-EvlogError, preserve Nitro's default response shape if (!evlogError) { - const res = await defaultHandler(error, event, { json: true }) - const body = typeof res.body === 'string' ? res.body : JSON.stringify(res.body) - return new Response(body, { - status: res.status, - statusText: res.statusText, - headers: res.headers, - }) + return }