diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..570a2edb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.husky/* text eol=lf +*.sh text eol=lf diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 26892add..0e641550 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -31,6 +31,9 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Dependency security audit + run: pnpm deps:audit + - name: Lint run: pnpm biome:lint diff --git a/.gitignore b/.gitignore index fa734ee4..1dbed918 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ test-results/ playwright-report/ blob-report/ .aider* + +/public/vendor/tinymce/ diff --git a/docs/operations/cms-error-center.md b/docs/operations/cms-error-center.md new file mode 100644 index 00000000..71d086d2 --- /dev/null +++ b/docs/operations/cms-error-center.md @@ -0,0 +1,65 @@ +# CMS error center and dependency maintenance + +Open **HK > DevOps > CMS error center** (`/admin/devops/cms-errors`). +The previous `/admin/devops/errors` page still displays emulator errors. + +## Access and workflow + +- Read: existing `admin.devops.view` permission, checked on the server. +- Mark resolved: `admin.devops.edit`, checked again in the server action; recorded in the staff audit log. +- Search by event reference, Next.js digest, route, message or deployment version. +- Expand a group for its latest stack, sanitized context and occurrence references. +- Marking a group resolved does not delete evidence. A later occurrence reopens it. +- Refresh is manual so inspecting an expanded error is not interrupted by polling. + +## What is collected + +Pino `logger.error`, `logServerError`, unexpected action errors, Next.js request +failures, React error boundaries, uncaught browser errors and unhandled browser +promise rejections. API wrapper failures return an `errorId`; Next.js boundary +errors can be correlated by their digest. Release identifiers come from the build. +Browser reports retain their own client release separately from the receiving server. + +Reports are stored in `storage/cms-errors`, using the existing persistent storage +mount. No third-party service, token or new database table is required. +Storage does not depend on database availability; viewing the HK and its permission +checks still require authentication/database availability. Server console logs +remain the fallback when the CMS itself cannot serve requests. + +Retention: seven days; approximately 10 MB/day, 100 queued server writes, and the +latest 1,000 events in the viewer. Limits are per CMS process/storage volume; +this is intended for the existing single-instance deployment. Daily expiry runs +on the next write. The browser endpoint is same-origin, body-size bounded and +rate-limited. Browser reports are untrusted observations and cannot grant access. +Known credential patterns and URL parameters are redacted; arbitrary object +metadata and request bodies are excluded. Avoid putting personal data in error +messages: this is pattern-based redaction, not a universal data-loss filter. + +This does not collect historical console logs, process crashes before framework +startup, nginx failures, all `console.error` calls, or every handled business +validation error. A browser stack may point at minified chunks; private source-map +symbolication and distributed traces are not part of this local viewer. A recorded +stack is diagnostic evidence, not an automatic root-cause determination. + +## Dependencies + +`pnpm install --frozen-lockfile`, `pnpm deps:audit`, `pnpm typecheck`, `pnpm test`, +`pnpm knip`, `pnpm biome:lint`, and `pnpm build` are the verification sequence. +`pnpm analyze --output` writes a Next.js bundle analysis (not an application build). + +TinyMCE 8.9 is pinned in pnpm. `pnpm assets:editor` copies its runtime files and +license notices to ignored `public/vendor/tinymce`; dev/build run this first. +The Docker build includes the generated assets. The editor retains its existing +HTML fields and toolbar; validate saved content and preview when upgrading it. + +Lenis has been removed; the public site now uses native scrolling. Other used +runtime libraries remain. Vitest and its coverage provider are upgraded together; +`clearMocks: false` preserves initialization-time permission contract assertions. + +Renovate uses separate development/UI/Vitest groups with manual merge and a +three-day release age. The existing external Gitea bot configuration is retained. +Node/pnpm upgrades remain coordinated with Docker and the runner toolchain. +Obsolete global overrides were removed; a scoped esbuild override remains because +Drizzle Kit's loader still resolves a vulnerable legacy development-server build. +The two deprecated esbuild-kit packages remain upstream dependencies of Drizzle +Kit; replacing the ORM is not warranted for this tooling issue. diff --git a/knip.json b/knip.json index f7774b60..2b614c66 100644 --- a/knip.json +++ b/knip.json @@ -12,6 +12,6 @@ "scripts/furni-diagnose-now.ts" ], "project": ["src/**/*.{ts,tsx,css}", "scripts/**/*.{ts,js}"], - "ignoreDependencies": ["@sentry/nextjs", "pino-pretty", "husky"], + "ignoreDependencies": ["pino-pretty"], "ignoreBinaries": ["sendmail"] } diff --git a/next.config.ts b/next.config.ts index 618d221b..201d4d3d 100644 --- a/next.config.ts +++ b/next.config.ts @@ -27,6 +27,10 @@ const securityHeaders = [ const nextConfig: NextConfig = { output: "standalone", + env: { + NEXT_PUBLIC_CMS_RELEASE: + process.env.NEXT_DEPLOYMENT_ID?.trim() || getGitCommit() || "unknown", + }, deploymentId: process.env.NEXT_DEPLOYMENT_ID?.trim() || getGitCommit(), distDir: process.env.NEXT_DIST_DIR?.trim() || ".next", reactStrictMode: true, diff --git a/package.json b/package.json index 6468d2bb..920bb7db 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ }, "packageManager": "pnpm@11.25.0+sha512.5cde925b4f075f725eb71fbae18a42ffe784524789f19b61c731cb8721ec28aaee160e01a8d5af4fedb2a42cdbf300efe23db356b0d4a17b4d63e11f8ab7c956", "scripts": { - "dev": "next dev", - "build": "next build", + "dev": "pnpm assets:editor && next dev", + "build": "pnpm assets:editor && next build", "start": "next start", "toolchain:check": "node scripts/check-node-toolchain.mjs", "lint": "biome check .", @@ -25,14 +25,18 @@ "db:migrate:status": "tsx scripts/apply-migrations.ts --status", "db:studio": "drizzle-kit studio", "hk:matrix:check": "tsx scripts/verify-housekeeping-matrix.ts", - "test:housekeeping": "vitest run --coverage.enabled=false src/features/housekeeping src/lib/admin-theme-source-audit.test.ts src/lib/admin/authorization-contract.test.ts" + "test:housekeeping": "vitest run --coverage.enabled=false src/features/housekeeping src/lib/admin-theme-source-audit.test.ts src/lib/admin/authorization-contract.test.ts", + "prepare": "node scripts/prepare-hooks.mjs", + "assets:editor": "node scripts/copy-editor-assets.mjs", + "deps:audit": "pnpm audit --audit-level=high", + "analyze": "next experimental-analyze" }, "lint-staged": { "*.{js,ts,jsx,tsx,json}": "biome check --write --no-errors-on-unmatched", "*.{ts,tsx}": "node scripts/check-admin-colors.mjs" }, "dependencies": { - "@base-ui/react": "1.7.0", + "@base-ui/react": "1.8.0", "@dnd-kit/core": "6.3.1", "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", @@ -49,46 +53,46 @@ "jpeg-js": "0.4.4", "jsonc-parser": "3.3.1", "jszip": "3.10.1", - "lenis": "1.3.26", - "lucide-react": "1.38.0", + "lucide-react": "1.41.0", "lzma-wasm": "1.0.7", - "motion": "13.1.1", + "motion": "13.2.0", "music-metadata": "11.15.0", - "mysql2": "3.24.2", + "mysql2": "3.24.3", "next": "16.3.4", "next-auth": "5.0.0-beta.32", - "next-intl": "4.14.1", + "next-intl": "4.14.2", "otplib": "13.5.0", "pino": "10.3.1", "react": "19.2.8", "react-dom": "19.2.8", "react-hook-form": "7.87.0", - "resend": "6.25.0", + "resend": "6.26.0", "server-only": "0.0.1", "sharp": "^0.35.4", "sonner": "2.0.8", "tailwind-merge": "3.6.0", - "zod": "4.5.4" + "zod": "4.5.4", + "tinymce": "8.9.0" }, "devDependencies": { - "@biomejs/biome": "2.5.11", + "@biomejs/biome": "2.5.12", "@playwright/test": "^1.62.1", "@tailwindcss/forms": "0.5.11", "@tailwindcss/postcss": "4.3.3", "@tailwindcss/typography": "0.5.20", - "@types/node": "26.4.0", + "@types/node": "26.4.1", "@types/react": "19.2.18", - "@types/react-dom": "19.2.5", - "@vitest/coverage-v8": "4.1.11", + "@types/react-dom": "19.2.7", + "@vitest/coverage-v8": "5.0.0", "drizzle-kit": "0.31.10", "husky": "9.1.7", - "knip": "6.33.0", + "knip": "6.34.0", "lint-staged": "17.4.1", "pino-pretty": "13.1.3", - "postcss": "^8.5.26", + "postcss": "8.5.28", "tailwindcss": "4.3.3", "tsx": "4.23.13", "typescript": "7.0.2", - "vitest": "4.1.11" + "vitest": "5.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dd86480b..a54e2485 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,26 +5,17 @@ settings: excludeLinksFromLockfile: false overrides: - glob: ^11.0.3 - rimraf: ^6.0.1 - uuid: ^11.1.0 - fast-uri: ^3.1.3 - '@hono/node-server': ^1.19.13 - postcss: ^8.5.26 - tmp: ^0.2.6 - sharp: ^0.35.4 - brace-expansion: ^5.0.8 + '@esbuild-kit/core-utils>esbuild': ^0.25.9 '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 - esbuild: ^0.25.9 + '@types/react-dom': 19.2.7 importers: .: dependencies: '@base-ui/react': - specifier: 1.7.0 - version: 1.7.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: 1.8.0 + version: 1.8.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@dnd-kit/core': specifier: 6.3.1 version: 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -48,13 +39,13 @@ importers: version: 2.1.1 cmdk: specifier: 1.1.1 - version: 1.1.1(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 1.1.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) croner: specifier: 10.0.1 version: 10.0.1 drizzle-orm: specifier: 0.45.2 - version: 0.45.2(mysql2@3.24.2(@types/node@26.4.0)) + version: 0.45.2(mysql2@3.24.3(@types/node@26.4.1)) hash-wasm: specifier: 4.12.0 version: 4.12.0 @@ -73,33 +64,30 @@ importers: jszip: specifier: 3.10.1 version: 3.10.1 - lenis: - specifier: 1.3.26 - version: 1.3.26(react@19.2.8) lucide-react: - specifier: 1.38.0 - version: 1.38.0(react@19.2.8) + specifier: 1.41.0 + version: 1.41.0(react@19.2.8) lzma-wasm: specifier: 1.0.7 version: 1.0.7 motion: - specifier: 13.1.1 - version: 13.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: 13.2.0 + version: 13.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) music-metadata: specifier: 11.15.0 version: 11.15.0(supports-color@7.2.0) mysql2: - specifier: 3.24.2 - version: 3.24.2(@types/node@26.4.0) + specifier: 3.24.3 + version: 3.24.3(@types/node@26.4.1) next: specifier: 16.3.4 - version: 16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-auth: specifier: 5.0.0-beta.32 - version: 5.0.0-beta.32(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8) + version: 5.0.0-beta.32(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8) next-intl: - specifier: 4.14.1 - version: 4.14.1(@swc/helpers@0.5.23)(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8) + specifier: 4.14.2 + version: 4.14.2(@swc/helpers@0.5.23)(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8) otplib: specifier: 13.5.0 version: 13.5.0 @@ -116,27 +104,30 @@ importers: specifier: 7.87.0 version: 7.87.0(react@19.2.8) resend: - specifier: 6.25.0 - version: 6.25.0 + specifier: 6.26.0 + version: 6.26.0 server-only: specifier: 0.0.1 version: 0.0.1 sharp: specifier: ^0.35.4 - version: 0.35.4(@types/node@26.4.0) + version: 0.35.4(@types/node@26.4.1) sonner: specifier: 2.0.8 version: 2.0.8(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) tailwind-merge: specifier: 3.6.0 version: 3.6.0 + tinymce: + specifier: 8.9.0 + version: 8.9.0 zod: specifier: 4.5.4 version: 4.5.4 devDependencies: '@biomejs/biome': - specifier: 2.5.11 - version: 2.5.11 + specifier: 2.5.12 + version: 2.5.12 '@playwright/test': specifier: ^1.62.1 version: 1.62.1 @@ -150,17 +141,17 @@ importers: specifier: 0.5.20 version: 0.5.20(tailwindcss@4.3.3) '@types/node': - specifier: 26.4.0 - version: 26.4.0 + specifier: 26.4.1 + version: 26.4.1 '@types/react': specifier: 19.2.18 version: 19.2.18 '@types/react-dom': - specifier: 19.2.5 - version: 19.2.5(@types/react@19.2.18) + specifier: 19.2.7 + version: 19.2.7(@types/react@19.2.18) '@vitest/coverage-v8': - specifier: 4.1.11 - version: 4.1.11(vitest@4.1.11) + specifier: 5.0.0 + version: 5.0.0(vitest@5.0.0) drizzle-kit: specifier: 0.31.10 version: 0.31.10 @@ -168,8 +159,8 @@ importers: specifier: 9.1.7 version: 9.1.7 knip: - specifier: 6.33.0 - version: 6.33.0 + specifier: 6.34.0 + version: 6.34.0 lint-staged: specifier: 17.4.1 version: 17.4.1 @@ -177,8 +168,8 @@ importers: specifier: 13.1.3 version: 13.1.3 postcss: - specifier: ^8.5.26 - version: 8.5.26 + specifier: 8.5.28 + version: 8.5.28 tailwindcss: specifier: 4.3.3 version: 4.3.3 @@ -189,8 +180,8 @@ importers: specifier: 7.0.2 version: 7.0.2 vitest: - specifier: 4.1.11 - version: 4.1.11(@types/node@26.4.0)(@vitest/coverage-v8@4.1.11)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)) + specifier: 5.0.0 + version: 5.0.0(@types/node@26.4.1)(@vitest/coverage-v8@5.0.0)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)) packages: @@ -241,8 +232,8 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} - '@base-ui/react@1.7.0': - resolution: {integrity: sha512-j+8QjX44C32jrXD/qyEAGpFr70FRpGL2CY61mQd9nBPWN737CK0xxD1ceJ055rW4RtdvFDT1e7otzdlfxvsYug==} + '@base-ui/react@1.8.0': + resolution: {integrity: sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==} engines: {node: '>=14.0.0'} peerDependencies: '@date-fns/tz': ^1.2.0 @@ -258,8 +249,8 @@ packages: date-fns: optional: true - '@base-ui/utils@0.3.2': - resolution: {integrity: sha512-oWy1aq/I2GmYjpl4PhEAhzflF8VPGKgZeq0xAWTbfD5KBWyxcN0ZP2+WHSUm/5Z6lVMBDLReLcoXwSYoRc/zNQ==} + '@base-ui/utils@0.4.0': + resolution: {integrity: sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==} peerDependencies: '@types/react': 19.2.18 react: ^17 || ^18 || ^19 @@ -272,59 +263,59 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@2.5.11': - resolution: {integrity: sha512-Tj0dnkLPdW0ASjHfj2D/ZkkvPU2wrFmnE1jWTD2xzV1ycapV1DutbYXk4NDnR3rYTi1ZCbNFD4G2gRMEY65WaA==} + '@biomejs/biome@2.5.12': + resolution: {integrity: sha512-Lw4VHZRebrReBBnlHa12JQjnIBm3JJAA55PDB9LbBVBF0q4RYphm6KfmIjqtPhf61MxZ5Q9KoK8R8x+7per5Aw==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.5.11': - resolution: {integrity: sha512-6SGZxoKbXvUjMn1t6A98HqWISPnGNbYs0R/Rt2JarmXBSev+lva4QxUMWEBX9lX1Wo1XTJ78uk5xVDtG58SRZg==} + '@biomejs/cli-darwin-arm64@2.5.12': + resolution: {integrity: sha512-lCRY1rwgNeWNgTr4DI/u6ZwXTRwRLHAvbaio1YLLGS+4r1nhvB2ssyPqIpfUSmRveNfv0fn/N58C7CAdK2XVrg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.5.11': - resolution: {integrity: sha512-nYkXY7tLBEgnGbYapDKAyKzgt44ZEyG+AKalvTXtCWKYgepI9dw327q+cVgedxm+Udi1ZzHKUyZrIusHi/KQbw==} + '@biomejs/cli-darwin-x64@2.5.12': + resolution: {integrity: sha512-vhPgwnh+6tN3ArdAXuET99xaNbFt7CG82Bqn+omHVLC5xdVx45JsYjGPmUIGNzjDek5XdNCP1HKksK7fn8+3bQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.5.11': - resolution: {integrity: sha512-qhyZUMyCbWYFV2bAwRNVvfMVZ+hv7WYl6mossGrxC+uiQQXhvsuWWU8zz6jYX0mChZd9MgQZbm4vozTmG/5iGw==} + '@biomejs/cli-linux-arm64-musl@2.5.12': + resolution: {integrity: sha512-couHYjFLL5uuI8ne6zhT7KwEsXo5YP7ry/2xmEqah7qanu0YmfDi3mwJg47YXSuv/NpZj22CZzcRH/5c4gjPSQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.5.11': - resolution: {integrity: sha512-3PVLSTD9RR73rvVPt5G3T1gc+ycggWEGfTD7RvzzbtcDPD27NxgxBbAFfpm7DXJKW6VLHWE1lLMGvFt2Qxjcow==} + '@biomejs/cli-linux-arm64@2.5.12': + resolution: {integrity: sha512-2gp8aVwXYKdAtmBfRFCUuyDMcfN1ahHqUkGfLYrZlNRFmryMATLVvJgWKvyA8wu4Rwn5OSxM1UcUmOuOFNGeBQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.5.11': - resolution: {integrity: sha512-oRRlrchG5EfrEL/EmtT1qUjSNHk3/5LGeZhQqADBBAJF1b1ET6964xEKe7aGlGARzDfza8H/seEsFJl7S6Ql9w==} + '@biomejs/cli-linux-x64-musl@2.5.12': + resolution: {integrity: sha512-8A0oDW58/w9f/PQNYuq0sGUZtGtGrkNF4Z6n0PUoXpLCshi85vtKTv1XSznQawhdE4MXJ8ufpzHXyLFe87M/+w==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.5.11': - resolution: {integrity: sha512-JOytptlsgM33B2MMFUg8iBrb4IKpbD5JnJrSeYiaFEeAj4vuXx0iQSQZ4qK7sqyMtfjZxxPdNdMZZVL4y/mFyA==} + '@biomejs/cli-linux-x64@2.5.12': + resolution: {integrity: sha512-SnvOs3TSTiuia4SQOUNe1aWC9RT4+YkjcKnOhL/nsKOV0k5ycgBkDzF0lUxKn1V7Q8CLTRq6iV23ZAivHomRoA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.5.11': - resolution: {integrity: sha512-e49E6K9hzH/ohJNx8Y26mY8HaV4I4ZViIeoqhKsmoXLKHhQnMeBAVqCgsGf2Wa3lXlS7RkporDXMHHWkzvZzFw==} + '@biomejs/cli-win32-arm64@2.5.12': + resolution: {integrity: sha512-b9vtoZFsuZt1pdjNwJvXl0f+BpayRzV008uS2+JpmwIKdSE2qdu4A/l04FESwLoou5g2E/Qlec0xwJydZplH+A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.5.11': - resolution: {integrity: sha512-QSQr/KjOgXA7OzXJUWS+oguKyAZ3Q0l/lnlDGbu397eKo83atuWUjBPJrsqbKNF6CARGw8XXJLGzpHC8Ryhd4Q==} + '@biomejs/cli-win32-x64@2.5.12': + resolution: {integrity: sha512-B1R/l+CwEpKFSuqiwePzPNRk1EiJN8kc0UhdafNz6MZN9v5OFP9HYP1irptvWzHrwVI4blVNGMbxc5zt70m3IA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -397,14 +388,14 @@ packages: '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - '@eloqnt/config@0.0.2': - resolution: {integrity: sha512-xz86UU1TJQPSzb0XJ3PkoyDlv3wdIiHfuu2wD/8m9ponHx0uSasYRDj4S+dpwQkIQaPYibN1oRr5HBll2GQkog==} + '@eloqnt/config@0.1.0': + resolution: {integrity: sha512-SLR6ZSHxu6XdZtmOz3xRmC3gsY/sCzqtLMD1gxbW2I3XXPBbupwL5RZbkLU/NcZm74AKZrIUPfz3CtEJfxUKqQ==} - '@eloqnt/format-json@0.0.3': - resolution: {integrity: sha512-zgDUVryBYQyM0WZGAoVr+FXjrzRjKkBGJran0E3i5LBcvTycl9ScFVhkF7aRBg8mHrU9xxvclUtSDIYg2mRTQg==} + '@eloqnt/format-json@0.1.0': + resolution: {integrity: sha512-4Pkb+HyzgWNJXoU48aJhUyNZSjZvMGooPCNG1ZFmBm55xTiNNPQCNXH66Ob6sXS6RvbWZrRpCf+Uo/Jz9K9g+A==} - '@eloqnt/format-po@0.0.3': - resolution: {integrity: sha512-4r36qEd7KJFV+IMKUv5czNXbGVys8ahxlQKWoUDV20eGl4Oxr+YZ2O5IEQU09S+d7FvPJ1USnyc/wtCLNCo1Ng==} + '@eloqnt/format-po@0.1.0': + resolution: {integrity: sha512-odgtuICWs67GdkNqY51/d2vaIukuOdlGalKASUGkI5c4cyWOmv/WIVyk5gZyn3xr614RzwWp57s9WB40lRLlBw==} '@emnapi/core@1.11.2': resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} @@ -432,156 +423,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.12': resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.12': resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.12': resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.12': resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.12': resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.12': resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.12': resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.12': resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.12': resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.12': resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.12': resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.12': resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.12': resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.12': resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.12': resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.12': resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.12': resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.12': resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.12': resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.12': resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.12': resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.12': resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.12': resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.12': resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.12': resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@exodus/bytes@1.15.1': resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -1310,7 +1457,7 @@ packages: resolution: {integrity: sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==} peerDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 + '@types/react-dom': 19.2.7 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -1323,7 +1470,7 @@ packages: resolution: {integrity: sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==} peerDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 + '@types/react-dom': 19.2.7 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -1345,7 +1492,7 @@ packages: resolution: {integrity: sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==} peerDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 + '@types/react-dom': 19.2.7 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -1367,7 +1514,7 @@ packages: resolution: {integrity: sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==} peerDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 + '@types/react-dom': 19.2.7 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -1380,7 +1527,7 @@ packages: resolution: {integrity: sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==} peerDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 + '@types/react-dom': 19.2.7 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -1393,7 +1540,7 @@ packages: resolution: {integrity: sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==} peerDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5 + '@types/react-dom': 19.2.7 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -1787,11 +1934,11 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - '@types/node@26.4.0': - resolution: {integrity: sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==} + '@types/node@26.4.1': + resolution: {integrity: sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==} - '@types/react-dom@19.2.5': - resolution: {integrity: sha512-fMPwH9v7r/pp43yUd2/Mbiex5KouJwwR3dzHkhLREUC6764VyDsqxhAxv6OFEYR1RhjOyD1naqba8ECDBe7ZQg==} + '@types/react-dom@19.2.7': + resolution: {integrity: sha512-I8bPpDLcHBv1qiIiXDCy71Rt8eQDKJP0sMSWJphDdAcdqiJ1sGpZamavoEIRZmYzjia9LuEb2HlYdDpmoENpvQ==} peerDependencies: '@types/react': 19.2.18 @@ -1921,20 +2068,25 @@ packages: cpu: [x64] os: [win32] - '@vitest/coverage-v8@4.1.11': - resolution: {integrity: sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==} + '@vitest/coverage-v8@5.0.0': + resolution: {integrity: sha512-toMg6PZGCIa/lQNCDoASrfb1ly4hsUKXFtFYC9kD4t78o5Y6LyNJU7AENt8eHPr3quYdxaxK7hj2mnbFfUk9NA==} peerDependencies: - '@vitest/browser': 4.1.11 - vitest: 4.1.11 + '@vitest/browser': 5.0.0 + vitest: 5.0.0 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.11': - resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==} + '@vitest/istanbul-lib-coverage@1.0.1': + resolution: {integrity: sha512-k3DJZ8LhMBK9NS4SclF1ASD3OgXEWDorbIcPTRDK0/Zae6fRvu+fJRxtFdLfHsa9Y24beCdPnoNZ4LviTNstfA==} + engines: {node: '>=22'} - '@vitest/mocker@4.1.11': - resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==} + '@vitest/istanbul-lib-report@1.0.1': + resolution: {integrity: sha512-1EOLRfsTMnyAr3+kEAsP4o9dhaDlGPpD7H5iLBBeq//YpNB1VIahkPhB+eRp9N2Dkfw8oySROjE3yf9XDeaIkQ==} + engines: {node: '>=22'} + + '@vitest/mocker@5.0.0': + resolution: {integrity: sha512-66PGTMIiVJP3t4a5yxU9qPtf7MdTBs8jmToMvy+HVflB3Yy13WJZTtPePdvU+wjRV02SKK5doLbSA6o9pwOmiA==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1944,20 +2096,8 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.11': - resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} - - '@vitest/runner@4.1.11': - resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==} - - '@vitest/snapshot@4.1.11': - resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} - - '@vitest/spy@4.1.11': - resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==} - - '@vitest/utils@4.1.11': - resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} + '@vitest/spy@5.0.0': + resolution: {integrity: sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==} aria-hidden@1.2.6: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} @@ -2023,9 +2163,6 @@ packages: resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} engines: {node: '>=18'} - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -2193,6 +2330,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -2230,8 +2372,8 @@ packages: engines: {node: '>=18.3.0'} hasBin: true - framer-motion@13.1.1: - resolution: {integrity: sha512-B/xn2TPS4f61cEBLFjiYlQFnBZUW1YVj/LM+C+N4OP8Rs95VLEI2ot/RlfBg111la/EiyECFaJJi/A3FWA8MUA==} + framer-motion@13.2.0: + resolution: {integrity: sha512-9E33ebgMaO33w1nN/jEdW8z3/GO483fMi4rqbMG9rt83XgW9QLKRe4NcmJ8s+fQ3O34++UHrIQwlIWGIWTITjA==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 @@ -2278,9 +2420,6 @@ packages: resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -2290,8 +2429,8 @@ packages: resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} engines: {node: '>=0.10.0'} - icu-minify@4.14.1: - resolution: {integrity: sha512-I8lz1epVvPmTSCfElYrOVZPMlxXYO6u/HDAd8bAksU0WmL8774lqg/h4PSHIisEYbqYcxXGU2y5b5sbhzCIi0A==} + icu-minify@4.14.2: + resolution: {integrity: sha512-2eJ9ooR8xXWbe0IivG58TFL96AUp5ts8FJ4qSMzn8YRJXpLmtPNWcUkIZ8t3iz0+eaVzG+mN+rdNIigHDvYa2Q==} ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2330,18 +2469,6 @@ packages: resolution: {integrity: sha512-vjQwQSxyEkJHO6g+KIDlWj8swAzUB01pJu9GU9cLGHjE10d59GFzJkgtB2Lj5WTOoq9JeHlYjR/FFuqeopPO0Q==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true @@ -2374,25 +2501,11 @@ packages: jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - knip@6.33.0: - resolution: {integrity: sha512-gMXWV2bqgJcdZKsaRgl1oH5V2J0VumhJ2ujfP4M6b9ftpca2BNpvlX3Dq++vVtEey7sU67EXCvZGNkQfG2w1RQ==} + knip@6.34.0: + resolution: {integrity: sha512-bbHIrnGspYwe4EBPjjx+lvkUor0F2qfKQc5BPzPI4SOAImYA+k2ueVpIcF7d/W1LEVT7XoJUPt6zELeGZhXBgA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - lenis@1.3.26: - resolution: {integrity: sha512-s/xTCZCxTFvHbAN1OzuhNaN5YPJH2ail0XAkctKW1b+RUAG4nUL5UHLXwNko1h8aEeT2jspBXegMgPJd8zcuag==} - peerDependencies: - '@nuxt/kit': '>=3.0.0' - react: '>=17.0.0' - vue: '>=3.0.0' - peerDependenciesMeta: - '@nuxt/kit': - optional: true - react: - optional: true - vue: - optional: true - lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} @@ -2560,8 +2673,8 @@ packages: resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} - lucide-react@1.38.0: - resolution: {integrity: sha512-xZCyBd/wiVUDactoCc+42TjL0aB7EBOXsuX+tjz+W/sGzw2KhHpL1NOH3FIaVUcpimvUBpIYfz34Ofj9S5JEzQ==} + lucide-react@1.41.0: + resolution: {integrity: sha512-6lksP35l6KszDKUeRTi4LV7i6DEe0Yzl2ALJm9j4c5xEYN91GdW1xGsawGMOg2mgjF5GHBVX8pKX9kP+cWsP3Q==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2572,13 +2685,12 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@1.2.3: + resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==} + magicast@0.5.4: resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} @@ -2593,14 +2705,14 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - motion-dom@13.1.1: - resolution: {integrity: sha512-XSf8VYWSB6G/0IY3rWVbyLcxWXtAVHkN1PQE2agTaCv3u8RGvbwu56TyyR/MNzBqqNavEBTZzErcxI1TxBrjcA==} + motion-dom@13.2.0: + resolution: {integrity: sha512-N6gdSoWRDk0Rh/fVtlqUtLs+fEN3ELFZI3cn3IQE9Mnf3E+Mh8wjO6MstzCOPFh4Yf0L1as5m2eUyYWj8ylVSQ==} motion-utils@13.0.0: resolution: {integrity: sha512-7DnN7TmbLcYXcG4RVadXIihWlyuM9afoUww8Y5Agg431kGKiuL2/OMyP4mJ5wLz+pvN3t5ySClLOaVXJ+wekRQ==} - motion@13.1.1: - resolution: {integrity: sha512-WNZoK6xiF+kkTqkZ5K7FDDh6A8BG4i5Hc7KXtW8gtTxkpJFds+hIOrDaQGKjQj/AE/i4hJqAaUHEqp/Qo02y6Q==} + motion@13.2.0: + resolution: {integrity: sha512-4Hrb5vD6HhjFstLUiCmWvtpsw+WTpP4R+QXfSDYZBz7+uxE/LrRg3aV0ReJxHrTRffHhbIE6svEqnotngXvesQ==} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 @@ -2617,8 +2729,8 @@ packages: resolution: {integrity: sha512-TN+kO1/oOc8UzDW5N3vSDncBcv9WyNnQQe/NFMcFWq6G1+zVeYUkGvkYpQ/S8wb8vKtUD7i78dIaY0cv+cmPRA==} engines: {node: '>=18'} - mysql2@3.24.2: - resolution: {integrity: sha512-l9kXeKGwd6VCbSjmpO/bLWb+YCYpbvE4whte8ec6InXebvCNyEEydyRCnRU+TSHNqRLJ8B+Tk1uWb+vMCJgJzA==} + mysql2@3.24.3: + resolution: {integrity: sha512-OKfWHkMAg9v06neq8FmSyhbxPQKABN9PAW5G9/bDTXzJBO5xXtkKL0V27vju7HQWk9UD4Od5BZsvCtBTB1CPEw==} engines: {node: '>= 8.0'} peerDependencies: '@types/node': '>= 8' @@ -2652,11 +2764,11 @@ packages: nodemailer: optional: true - next-intl-swc-plugin-extractor@4.14.1: - resolution: {integrity: sha512-ixZCS/z1Nx0sto4rWFfoCqahzqXjdhVuQzYrITVwXsrVzYi1ZKrWP8evoXTB5+F+j9FpLQIMIYB6gp3k+zePWA==} + next-intl-swc-plugin-extractor@4.14.2: + resolution: {integrity: sha512-R+i9Xw6XKyn1QVx+I5IDZQNGQBwT79ugGwzbuJudgejob/IYnXXrRKMlLhmMxLdKH8jUWh92nqwNnp+5rtSVJA==} - next-intl@4.14.1: - resolution: {integrity: sha512-7o7ZyYIWoB0w87n13sezA8r1uLH0ipZCGrMHFKVhwFnwUI1/tym04P/T5NiyULaXUQ276m60xsmInE+HnfAq3A==} + next-intl@4.14.2: + resolution: {integrity: sha512-rIq8me1uOa2qXnttJ6dUGYnHHL63Rh1FAIIDTJP5av5KSBmUzNBS17QAi07QDrUMY6KxFNeoCTRzSZRPUc97lg==} peerDependencies: next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -2718,9 +2830,6 @@ packages: parse5@8.0.1: resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2762,8 +2871,12 @@ packages: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} engines: {node: '>=4'} - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + postcss@8.5.23: + resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.28: + resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} preact-render-to-string@6.5.11: @@ -2856,8 +2969,8 @@ packages: reselect@5.3.0: resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==} - resend@6.25.0: - resolution: {integrity: sha512-iptUEycs+6Hu+W8mExK708LrDiMYOuGgnCP+wTD5L4Zrqqd2B86h1oyAmNe0khZWQw0ccI7jz8OgAaplEsyaIA==} + resend@6.26.0: + resolution: {integrity: sha512-vkrULozV5nGF8o7tyun/t0+qFgtPpn+cyRhVqeorhOsPUNDiSc/9p/pn8AprdHqJpYaTvftpnQgWurW++FkCdw==} engines: {node: '>=20'} peerDependencies: '@react-email/render': '*' @@ -3013,8 +3126,9 @@ packages: resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==} engines: {node: '>=20'} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinybench@6.1.4: + resolution: {integrity: sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==} + engines: {node: '>=20.0.0'} tinyexec@1.3.0: resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} @@ -3024,6 +3138,9 @@ packages: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} + tinymce@8.9.0: + resolution: {integrity: sha512-zh9NKpdF89vnqOB3VEkTHiPtltrY6i3vTEVF5+l7vLxMX6lBju7d0UV9wWV7Vm1NyO1PccDCwa6qxAb2pWSvfg==} + tinyrainbow@3.1.1: resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} engines: {node: '>=14.0.0'} @@ -3085,8 +3202,8 @@ packages: '@types/react': optional: true - use-intl@4.14.1: - resolution: {integrity: sha512-p6Ggq6AZJDJQpjj4WEjByfid1IEifH7OYpL283y29dzVT2M6vbMoHmYA9KQ/L1A9jHED8uzCNvWic0mJ23kU5A==} + use-intl@4.14.2: + resolution: {integrity: sha512-XffvbD4q4uZjRbuO8CgK6Ei8hvYn7aegoSad2YPho1ZRjYEs+k4erhYq0vfm5ttF4lnja3riXCeJrtUdNdQG3g==} peerDependencies: react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 @@ -3115,7 +3232,7 @@ packages: peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.4.0 || ^0.5.0 - esbuild: ^0.25.9 + esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -3151,23 +3268,23 @@ packages: yaml: optional: true - vitest@4.1.11: - resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + vitest@5.0.0: + resolution: {integrity: sha512-gpsMNoRhMjMktVxPtstOH4/PJuPyovVaMDr4oDilXaGH1EcqM2OE96SoHT2VIQ6fTGtTjqmHDrEu2X9RQiXf8Q==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.11 - '@vitest/browser-preview': 4.1.11 - '@vitest/browser-webdriverio': 4.1.11 - '@vitest/coverage-istanbul': 4.1.11 - '@vitest/coverage-v8': 4.1.11 - '@vitest/ui': 4.1.11 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.0 + '@vitest/browser-preview': 5.0.0 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.0 + '@vitest/coverage-v8': 5.0.0 + '@vitest/ui': 5.0.0 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -3284,10 +3401,10 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@base-ui/react@1.7.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@base-ui/react@1.8.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.29.7 - '@base-ui/utils': 0.3.2(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@base-ui/utils': 0.4.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@floating-ui/react-dom': 2.1.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@floating-ui/utils': 0.2.12 react: 19.2.8 @@ -3296,7 +3413,7 @@ snapshots: optionalDependencies: '@types/react': 19.2.18 - '@base-ui/utils@0.3.2(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@base-ui/utils@0.4.0(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@babel/runtime': 7.29.7 '@floating-ui/utils': 0.2.12 @@ -3309,39 +3426,39 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@2.5.11': + '@biomejs/biome@2.5.12': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.5.11 - '@biomejs/cli-darwin-x64': 2.5.11 - '@biomejs/cli-linux-arm64': 2.5.11 - '@biomejs/cli-linux-arm64-musl': 2.5.11 - '@biomejs/cli-linux-x64': 2.5.11 - '@biomejs/cli-linux-x64-musl': 2.5.11 - '@biomejs/cli-win32-arm64': 2.5.11 - '@biomejs/cli-win32-x64': 2.5.11 + '@biomejs/cli-darwin-arm64': 2.5.12 + '@biomejs/cli-darwin-x64': 2.5.12 + '@biomejs/cli-linux-arm64': 2.5.12 + '@biomejs/cli-linux-arm64-musl': 2.5.12 + '@biomejs/cli-linux-x64': 2.5.12 + '@biomejs/cli-linux-x64-musl': 2.5.12 + '@biomejs/cli-win32-arm64': 2.5.12 + '@biomejs/cli-win32-x64': 2.5.12 - '@biomejs/cli-darwin-arm64@2.5.11': + '@biomejs/cli-darwin-arm64@2.5.12': optional: true - '@biomejs/cli-darwin-x64@2.5.11': + '@biomejs/cli-darwin-x64@2.5.12': optional: true - '@biomejs/cli-linux-arm64-musl@2.5.11': + '@biomejs/cli-linux-arm64-musl@2.5.12': optional: true - '@biomejs/cli-linux-arm64@2.5.11': + '@biomejs/cli-linux-arm64@2.5.12': optional: true - '@biomejs/cli-linux-x64-musl@2.5.11': + '@biomejs/cli-linux-x64-musl@2.5.12': optional: true - '@biomejs/cli-linux-x64@2.5.11': + '@biomejs/cli-linux-x64@2.5.12': optional: true - '@biomejs/cli-win32-arm64@2.5.11': + '@biomejs/cli-win32-arm64@2.5.12': optional: true - '@biomejs/cli-win32-x64@2.5.11': + '@biomejs/cli-win32-x64@2.5.12': optional: true '@borewit/text-codec@0.2.2': {} @@ -3401,15 +3518,15 @@ snapshots: '@drizzle-team/brocli@0.10.2': {} - '@eloqnt/config@0.0.2': {} + '@eloqnt/config@0.1.0': {} - '@eloqnt/format-json@0.0.3': + '@eloqnt/format-json@0.1.0': dependencies: - '@eloqnt/config': 0.0.2 + '@eloqnt/config': 0.1.0 - '@eloqnt/format-po@0.0.3': + '@eloqnt/format-po@0.1.0': dependencies: - '@eloqnt/config': 0.0.2 + '@eloqnt/config': 0.1.0 po-parser: 2.2.0 '@emnapi/core@1.11.2': @@ -3446,81 +3563,159 @@ snapshots: '@esbuild/aix-ppc64@0.25.12': optional: true + '@esbuild/aix-ppc64@0.28.2': + optional: true + '@esbuild/android-arm64@0.25.12': optional: true + '@esbuild/android-arm64@0.28.2': + optional: true + '@esbuild/android-arm@0.25.12': optional: true + '@esbuild/android-arm@0.28.2': + optional: true + '@esbuild/android-x64@0.25.12': optional: true + '@esbuild/android-x64@0.28.2': + optional: true + '@esbuild/darwin-arm64@0.25.12': optional: true + '@esbuild/darwin-arm64@0.28.2': + optional: true + '@esbuild/darwin-x64@0.25.12': optional: true + '@esbuild/darwin-x64@0.28.2': + optional: true + '@esbuild/freebsd-arm64@0.25.12': optional: true + '@esbuild/freebsd-arm64@0.28.2': + optional: true + '@esbuild/freebsd-x64@0.25.12': optional: true + '@esbuild/freebsd-x64@0.28.2': + optional: true + '@esbuild/linux-arm64@0.25.12': optional: true + '@esbuild/linux-arm64@0.28.2': + optional: true + '@esbuild/linux-arm@0.25.12': optional: true + '@esbuild/linux-arm@0.28.2': + optional: true + '@esbuild/linux-ia32@0.25.12': optional: true + '@esbuild/linux-ia32@0.28.2': + optional: true + '@esbuild/linux-loong64@0.25.12': optional: true + '@esbuild/linux-loong64@0.28.2': + optional: true + '@esbuild/linux-mips64el@0.25.12': optional: true + '@esbuild/linux-mips64el@0.28.2': + optional: true + '@esbuild/linux-ppc64@0.25.12': optional: true + '@esbuild/linux-ppc64@0.28.2': + optional: true + '@esbuild/linux-riscv64@0.25.12': optional: true + '@esbuild/linux-riscv64@0.28.2': + optional: true + '@esbuild/linux-s390x@0.25.12': optional: true + '@esbuild/linux-s390x@0.28.2': + optional: true + '@esbuild/linux-x64@0.25.12': optional: true + '@esbuild/linux-x64@0.28.2': + optional: true + '@esbuild/netbsd-arm64@0.25.12': optional: true + '@esbuild/netbsd-arm64@0.28.2': + optional: true + '@esbuild/netbsd-x64@0.25.12': optional: true + '@esbuild/netbsd-x64@0.28.2': + optional: true + '@esbuild/openbsd-arm64@0.25.12': optional: true + '@esbuild/openbsd-arm64@0.28.2': + optional: true + '@esbuild/openbsd-x64@0.25.12': optional: true + '@esbuild/openbsd-x64@0.28.2': + optional: true + '@esbuild/openharmony-arm64@0.25.12': optional: true + '@esbuild/openharmony-arm64@0.28.2': + optional: true + '@esbuild/sunos-x64@0.25.12': optional: true + '@esbuild/sunos-x64@0.28.2': + optional: true + '@esbuild/win32-arm64@0.25.12': optional: true + '@esbuild/win32-arm64@0.28.2': + optional: true + '@esbuild/win32-ia32@0.25.12': optional: true + '@esbuild/win32-ia32@0.28.2': + optional: true + '@esbuild/win32-x64@0.25.12': optional: true + '@esbuild/win32-x64@0.28.2': + optional: true + '@exodus/bytes@1.15.1(@noble/hashes@2.4.0)': optionalDependencies: '@noble/hashes': 2.4.0 @@ -3951,18 +4146,18 @@ snapshots: optionalDependencies: '@types/react': 19.2.18 - '@radix-ui/react-dialog@1.1.23(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@radix-ui/react-dialog@1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.7 '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8) '@radix-ui/react-context': 1.2.2(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-dismissable-layer': 1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-focus-guards': 1.1.6(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-focus-scope': 1.1.16(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-focus-scope': 1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-portal': 1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-presence': 1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8) '@radix-ui/react-use-controllable-state': 1.2.6(@types/react@19.2.18)(react@19.2.8) '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8) @@ -3972,20 +4167,20 @@ snapshots: react-remove-scroll: 2.7.2(@types/react@19.2.18)(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5(@types/react@19.2.18) + '@types/react-dom': 19.2.7(@types/react@19.2.18) - '@radix-ui/react-dismissable-layer@1.1.19(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@radix-ui/react-dismissable-layer@1.1.19(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/primitive': 1.1.7 '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8) '@radix-ui/react-use-effect-event': 0.0.5(@types/react@19.2.18)(react@19.2.8) react: 19.2.8 react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5(@types/react@19.2.18) + '@types/react-dom': 19.2.7(@types/react@19.2.18) '@radix-ui/react-focus-guards@1.1.6(@types/react@19.2.18)(react@19.2.8)': dependencies: @@ -3993,16 +4188,16 @@ snapshots: optionalDependencies: '@types/react': 19.2.18 - '@radix-ui/react-focus-scope@1.1.16(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@radix-ui/react-focus-scope@1.1.16(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-use-callback-ref': 1.1.4(@types/react@19.2.18)(react@19.2.8) react: 19.2.8 react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5(@types/react@19.2.18) + '@types/react-dom': 19.2.7(@types/react@19.2.18) '@radix-ui/react-id@1.1.4(@types/react@19.2.18)(react@19.2.8)': dependencies: @@ -4011,33 +4206,33 @@ snapshots: optionalDependencies: '@types/react': 19.2.18 - '@radix-ui/react-portal@1.1.17(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@radix-ui/react-portal@1.1.17(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: - '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8) react: 19.2.8 react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5(@types/react@19.2.18) + '@types/react-dom': 19.2.7(@types/react@19.2.18) - '@radix-ui/react-presence@1.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@radix-ui/react-presence@1.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.4(@types/react@19.2.18)(react@19.2.8) react: 19.2.8 react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5(@types/react@19.2.18) + '@types/react-dom': 19.2.7(@types/react@19.2.18) - '@radix-ui/react-primitive@2.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@radix-ui/react-primitive@2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@radix-ui/react-slot': 1.3.3(@types/react@19.2.18)(react@19.2.8) react: 19.2.8 react-dom: 19.2.8(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 - '@types/react-dom': 19.2.5(@types/react@19.2.18) + '@types/react-dom': 19.2.7(@types/react@19.2.18) '@radix-ui/react-slot@1.3.3(@types/react@19.2.18)(react@19.2.8)': dependencies: @@ -4127,7 +4322,8 @@ snapshots: '@stablelib/base64@1.0.1': {} - '@standard-schema/spec@1.1.0': {} + '@standard-schema/spec@1.1.0': + optional: true '@standard-schema/utils@0.3.0': {} @@ -4267,7 +4463,7 @@ snapshots: '@alloc/quick-lru': 5.2.0 '@tailwindcss/node': 4.3.3 '@tailwindcss/oxide': 4.3.3 - postcss: 8.5.26 + postcss: 8.5.28 tailwindcss: 4.3.3 '@tailwindcss/typography@0.5.20(tailwindcss@4.3.3)': @@ -4306,11 +4502,11 @@ snapshots: '@types/estree@1.0.9': {} - '@types/node@26.4.0': + '@types/node@26.4.1': dependencies: undici-types: 8.3.0 - '@types/react-dom@19.2.5(@types/react@19.2.18)': + '@types/react-dom@19.2.7(@types/react@19.2.18)': dependencies: '@types/react': 19.2.18 @@ -4381,60 +4577,34 @@ snapshots: '@typescript/typescript-win32-x64@7.0.2': optional: true - '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': + '@vitest/coverage-v8@5.0.0(vitest@5.0.0)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.11 + '@vitest/istanbul-lib-coverage': 1.0.1 + '@vitest/istanbul-lib-report': 1.0.1 ast-v8-to-istanbul: 1.0.5 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 magicast: 0.5.4 obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.11(@types/node@26.4.0)(@vitest/coverage-v8@4.1.11)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)) + vitest: 5.0.0(@types/node@26.4.1)(@vitest/coverage-v8@5.0.0)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)) - '@vitest/expect@4.1.11': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.11 - '@vitest/utils': 4.1.11 - chai: 6.2.2 - tinyrainbow: 3.1.1 + '@vitest/istanbul-lib-coverage@1.0.1': {} - '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0))': + '@vitest/istanbul-lib-report@1.0.1': dependencies: - '@vitest/spy': 4.1.11 + '@vitest/istanbul-lib-coverage': 1.0.1 + + '@vitest/mocker@5.0.0(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0))': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.0 estree-walker: 3.0.3 - magic-string: 0.30.21 + magic-string: 1.2.3 optionalDependencies: - vite: 8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0) + vite: 8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0) - '@vitest/pretty-format@4.1.11': - dependencies: - tinyrainbow: 3.1.1 - - '@vitest/runner@4.1.11': - dependencies: - '@vitest/utils': 4.1.11 - pathe: 2.0.3 - - '@vitest/snapshot@4.1.11': - dependencies: - '@vitest/pretty-format': 4.1.11 - '@vitest/utils': 4.1.11 - magic-string: 0.30.21 - pathe: 2.0.3 - - '@vitest/spy@4.1.11': {} - - '@vitest/utils@4.1.11': - dependencies: - '@vitest/pretty-format': 4.1.11 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.1 + '@vitest/spy@5.0.0': {} aria-hidden@1.2.6: dependencies: @@ -4474,12 +4644,12 @@ snapshots: cluster-key-slot@1.1.1: {} - cmdk@1.1.1(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + cmdk@1.1.1(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@radix-ui/react-compose-refs': 1.1.5(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-dialog': 1.1.23(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-dialog': 1.1.23(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@radix-ui/react-id': 1.1.4(@types/react@19.2.18)(react@19.2.8) - '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@radix-ui/react-primitive': 2.1.10(@types/react-dom@19.2.7(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react: 19.2.8 react-dom: 19.2.8(react@19.2.8) transitivePeerDependencies: @@ -4490,8 +4660,6 @@ snapshots: content-type@2.1.0: {} - convert-source-map@2.0.0: {} - core-util-is@1.0.3: {} croner@10.0.1: {} @@ -4539,9 +4707,9 @@ snapshots: esbuild: 0.25.12 tsx: 4.23.13 - drizzle-orm@0.45.2(mysql2@3.24.2(@types/node@26.4.0)): + drizzle-orm@0.45.2(mysql2@3.24.3(@types/node@26.4.1)): optionalDependencies: - mysql2: 3.24.2(@types/node@26.4.0) + mysql2: 3.24.3(@types/node@26.4.1) end-of-stream@1.4.5: dependencies: @@ -4585,6 +4753,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 @@ -4619,9 +4816,9 @@ snapshots: fd-package-json: 2.0.0 package-manager-detector: 1.8.0 - framer-motion@13.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + framer-motion@13.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - motion-dom: 13.1.1 + motion-dom: 13.2.0 motion-utils: 13.0.0 tslib: 2.8.1 optionalDependencies: @@ -4646,7 +4843,8 @@ snapshots: graceful-fs@4.2.11: {} - has-flag@4.0.0: {} + has-flag@4.0.0: + optional: true hash-wasm@4.12.0: {} @@ -4658,15 +4856,13 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' - html-escaper@2.0.2: {} - husky@9.1.7: {} iconv-lite@0.7.3: dependencies: safer-buffer: 2.1.2 - icu-minify@4.14.1: + icu-minify@4.14.2: dependencies: '@formatjs/icu-messageformat-parser': 3.5.17 @@ -4712,19 +4908,6 @@ snapshots: - '@noble/hashes' - canvas - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - jiti@2.7.0: {} jose@6.2.10: {} @@ -4770,7 +4953,7 @@ snapshots: readable-stream: 2.3.8 setimmediate: 1.0.5 - knip@6.33.0: + knip@6.34.0: dependencies: fdir: 6.5.0(picomatch@4.0.7) formatly: 0.7.0 @@ -4786,10 +4969,6 @@ snapshots: yaml: 2.9.0 zod: 4.5.4 - lenis@1.3.26(react@19.2.8): - optionalDependencies: - react: 19.2.8 - lie@3.3.0: dependencies: immediate: 3.0.6 @@ -4906,7 +5085,7 @@ snapshots: lru.min@1.1.4: {} - lucide-react@1.38.0(react@19.2.8): + lucide-react@1.41.0(react@19.2.8): dependencies: react: 19.2.8 @@ -4916,16 +5095,16 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 + magic-string@1.2.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + magicast@0.5.4: dependencies: '@babel/parser': 7.29.8 '@babel/types': 7.29.8 source-map-js: 1.2.1 - make-dir@4.0.0: - dependencies: - semver: 7.8.5 - mdn-data@2.27.1: {} media-typer@2.0.0: {} @@ -4934,15 +5113,15 @@ snapshots: minimist@1.2.8: {} - motion-dom@13.1.1: + motion-dom@13.2.0: dependencies: motion-utils: 13.0.0 motion-utils@13.0.0: {} - motion@13.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + motion@13.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - framer-motion: 13.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + framer-motion: 13.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) tslib: 2.8.1 optionalDependencies: react: 19.2.8 @@ -4965,9 +5144,9 @@ snapshots: transitivePeerDependencies: - supports-color - mysql2@3.24.2(@types/node@26.4.0): + mysql2@3.24.3(@types/node@26.4.1): dependencies: - '@types/node': 26.4.0 + '@types/node': 26.4.1 aws-ssl-profiles: 1.1.2 generate-function: 2.3.1 iconv-lite: 0.7.3 @@ -4986,38 +5165,38 @@ snapshots: dependencies: content-type: 2.1.0 - next-auth@5.0.0-beta.32(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8): + next-auth@5.0.0-beta.32(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8): dependencies: '@auth/core': 0.41.3 - next: 16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + next: 16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react: 19.2.8 - next-intl-swc-plugin-extractor@4.14.1: {} + next-intl-swc-plugin-extractor@4.14.2: {} - next-intl@4.14.1(@swc/helpers@0.5.23)(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8): + next-intl@4.14.2(@swc/helpers@0.5.23)(next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8): dependencies: - '@eloqnt/config': 0.0.2 - '@eloqnt/format-json': 0.0.3 - '@eloqnt/format-po': 0.0.3 + '@eloqnt/config': 0.1.0 + '@eloqnt/format-json': 0.1.0 + '@eloqnt/format-po': 0.1.0 '@formatjs/intl-localematcher': 0.8.13 '@parcel/watcher': 2.6.0 '@swc/core': 1.16.1(@swc/helpers@0.5.23) - icu-minify: 4.14.1 + icu-minify: 4.14.2 negotiator: 1.1.0 - next: 16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - next-intl-swc-plugin-extractor: 4.14.1 + next: 16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + next-intl-swc-plugin-extractor: 4.14.2 react: 19.2.8 - use-intl: 4.14.1(react@19.2.8) + use-intl: 4.14.2(react@19.2.8) transitivePeerDependencies: - '@swc/helpers' - next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + next@16.3.4(@playwright/test@1.62.1)(@types/node@26.4.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@next/env': 16.3.4 '@swc/helpers': 0.5.23 baseline-browser-mapping: 2.11.20 caniuse-lite: 1.0.30001810 - postcss: 8.5.26 + postcss: 8.5.23 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) styled-jsx: 5.1.6(react@19.2.8) @@ -5031,7 +5210,7 @@ snapshots: '@next/swc-win32-arm64-msvc': 16.3.4 '@next/swc-win32-x64-msvc': 16.3.4 '@playwright/test': 1.62.1 - sharp: 0.35.4(@types/node@26.4.0) + sharp: 0.35.4(@types/node@26.4.1) transitivePeerDependencies: - '@babel/core' - '@types/node' @@ -5112,8 +5291,6 @@ snapshots: dependencies: entities: 8.0.0 - pathe@2.0.3: {} - picocolors@1.1.1: {} picomatch@4.0.7: {} @@ -5171,7 +5348,13 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.5.26: + postcss@8.5.23: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.28: dependencies: nanoid: 3.3.18 picocolors: 1.1.1 @@ -5254,7 +5437,7 @@ snapshots: reselect@5.3.0: {} - resend@6.25.0: + resend@6.26.0: dependencies: postal-mime: 2.7.5 standardwebhooks: 1.0.0 @@ -5302,7 +5485,7 @@ snapshots: setimmediate@1.0.5: {} - sharp@0.35.4(@types/node@26.4.0): + sharp@0.35.4(@types/node@26.4.1): dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 @@ -5333,7 +5516,7 @@ snapshots: '@img/sharp-win32-arm64': 0.35.4 '@img/sharp-win32-ia32': 0.35.4 '@img/sharp-win32-x64': 0.35.4 - '@types/node': 26.4.0 + '@types/node': 26.4.1 siginfo@2.0.0: {} @@ -5394,6 +5577,7 @@ snapshots: supports-color@7.2.0: dependencies: has-flag: 4.0.0 + optional: true symbol-tree@3.2.4: {} @@ -5407,7 +5591,7 @@ snapshots: dependencies: real-require: 1.0.0 - tinybench@2.9.0: {} + tinybench@6.1.4: {} tinyexec@1.3.0: {} @@ -5416,6 +5600,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.7) picomatch: 4.0.7 + tinymce@8.9.0: {} + tinyrainbow@3.1.1: {} tldts-core@7.4.11: {} @@ -5442,7 +5628,7 @@ snapshots: tsx@4.23.13: dependencies: - esbuild: 0.25.12 + esbuild: 0.28.2 optionalDependencies: fsevents: 2.3.3 @@ -5484,11 +5670,11 @@ snapshots: optionalDependencies: '@types/react': 19.2.18 - use-intl@4.14.1(react@19.2.8): + use-intl@4.14.2(react@19.2.8): dependencies: '@formatjs/fast-memoize': 3.1.7 '@schummar/icu-type-parser': 1.21.5 - icu-minify: 4.14.1 + icu-minify: 4.14.2 intl-messageformat: 11.2.14 react: 19.2.8 @@ -5506,46 +5692,40 @@ snapshots: util-deprecate@1.0.2: {} - vite@8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0): + vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 - postcss: 8.5.26 + postcss: 8.5.28 rolldown: 1.2.5 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 26.4.0 - esbuild: 0.25.12 + '@types/node': 26.4.1 + esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 tsx: 4.23.13 yaml: 2.9.0 - vitest@4.1.11(@types/node@26.4.0)(@vitest/coverage-v8@4.1.11)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)): + vitest@5.0.0(@types/node@26.4.1)(@vitest/coverage-v8@5.0.0)(jsdom@30.0.1(@noble/hashes@2.4.0))(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)): dependencies: - '@vitest/expect': 4.1.11 - '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.11 - '@vitest/runner': 4.1.11 - '@vitest/snapshot': 4.1.11 - '@vitest/spy': 4.1.11 - '@vitest/utils': 4.1.11 + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.0(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0)) + chai: 6.2.2 es-module-lexer: 2.3.2 expect-type: 1.4.0 - magic-string: 0.30.21 + magic-string: 1.2.3 obug: 2.1.4 - pathe: 2.0.3 picomatch: 4.0.7 std-env: 4.2.0 - tinybench: 2.9.0 + tinybench: 6.1.4 tinyexec: 1.3.0 tinyglobby: 0.2.17 - tinyrainbow: 3.1.1 - vite: 8.2.2(@types/node@26.4.0)(esbuild@0.25.12)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0) + vite: 8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 26.4.0 - '@vitest/coverage-v8': 4.1.11(vitest@4.1.11) + '@types/node': 26.4.1 + '@vitest/coverage-v8': 5.0.0(vitest@5.0.0) jsdom: 30.0.1(@noble/hashes@2.4.0) transitivePeerDependencies: - msw diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1a7b3f49..27a66bd5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,80 +1,13 @@ -# pnpm-workspace.yaml - allowBuilds: esbuild: true sharp: true "@parcel/watcher": true "@swc/core": true - bcrypt: true -minimumReleaseAgeExclude: - - "@base-ui/react@1.7.0" - - "@base-ui/utils@0.3.2" - - "@biomejs/biome@2.5.7" - - "@biomejs/cli-darwin-arm64@2.5.7" - - "@biomejs/cli-darwin-x64@2.5.7" - - "@biomejs/cli-linux-arm64-musl@2.5.7" - - "@biomejs/cli-linux-arm64@2.5.7" - - "@biomejs/cli-linux-x64-musl@2.5.7" - - "@biomejs/cli-linux-x64@2.5.7" - - "@biomejs/cli-win32-arm64@2.5.7" - - "@biomejs/cli-win32-x64@2.5.7" - - "@hookform/resolvers@5.8.0" - - "@next/bundle-analyzer@16.3.0" - - "@next/bundle-analyzer@16.3.1" - - "@next/env@16.3.0" - - "@next/env@16.3.1" - - "@next/swc-darwin-arm64@16.3.0" - - "@next/swc-darwin-arm64@16.3.1" - - "@next/swc-darwin-x64@16.3.0" - - "@next/swc-darwin-x64@16.3.1" - - "@next/swc-linux-arm64-gnu@16.3.0" - - "@next/swc-linux-arm64-gnu@16.3.1" - - "@next/swc-linux-arm64-musl@16.3.0" - - "@next/swc-linux-arm64-musl@16.3.1" - - "@next/swc-linux-x64-gnu@16.3.0" - - "@next/swc-linux-x64-gnu@16.3.1" - - "@next/swc-linux-x64-musl@16.3.0" - - "@next/swc-linux-x64-musl@16.3.1" - - "@next/swc-win32-arm64-msvc@16.3.0" - - "@next/swc-win32-arm64-msvc@16.3.1" - - "@next/swc-win32-x64-msvc@16.3.0" - - "@next/swc-win32-x64-msvc@16.3.1" - - "icu-minify@4.13.5" - - "lenis@1.3.26" - - "next-intl-swc-plugin-extractor@4.13.5" - - "next-intl@4.13.5" - - "next@16.3.0" - - "next@16.3.1" - - "resend@6.20.0" - - "tsx@4.23.8" - - "use-intl@4.13.5" +minimumReleaseAge: 1440 overrides: - glob: "^11.0.3" - rimraf: "^6.0.1" - uuid: "^11.1.0" - fast-uri: "^3.1.3" - "@hono/node-server": "^1.19.13" - postcss: "^8.5.26" - tmp: "^0.2.6" - sharp: "^0.35.4" - brace-expansion: "^5.0.8" + # drizzle-kit still uses an obsolete development-server dependency. + "@esbuild-kit/core-utils>esbuild": "^0.25.9" "@types/react": "19.2.18" - "@types/react-dom": "19.2.5" - # Tijdelijke mitigatie voor drizzle-kit audit - esbuild: "^0.25.9" - -allowedDeprecatedVersions: - "@esbuild-kit/esm-loader": "*" - "@esbuild-kit/core-utils": "*" - -ignoredBuiltDependencies: - - "@prisma/engines" - - "prisma" - -peerDependencyRules: - allowedVersions: - nodemailer: "9.0.3" - ignoreMissing: - - nodemailer \ No newline at end of file + "@types/react-dom": "19.2.7" diff --git a/renovate.json b/renovate.json index b18a9dd3..ebf662cc 100644 --- a/renovate.json +++ b/renovate.json @@ -14,29 +14,36 @@ "prConcurrentLimit": 5, "packageRules": [ { - "description": "Group all dependency updates into a single PR", - "matchPackagePatterns": ["*"], - "groupName": "All dependencies", - "groupSlug": "all", - "automerge": true + "matchDepTypes": ["devDependencies"], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "Development tools", + "automerge": false + }, + { + "matchPackageNames": [ + "@base-ui/react", + "lucide-react", + "motion", + "@dnd-kit/**" + ], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "Interface libraries", + "automerge": false + }, + { + "matchPackageNames": ["vitest", "@vitest/coverage-v8"], + "groupName": "Vitest", + "automerge": false }, { - "description": "Major updates need manual review", "matchUpdateTypes": ["major"], - "labels": ["dependencies", "major"], - "automerge": false, - "assignees": [], - "reviewers": [] + "automerge": false }, { - "description": "Disable updates for engine pins", "matchPackageNames": ["node", "pnpm"], "enabled": false - }, - { - "description": "Disable server-only (abandoned, pinned at 0.0.1)", - "matchPackageNames": ["server-only"], - "enabled": false } - ] + ], + "minimumReleaseAge": "3 days", + "automerge": false } diff --git a/scripts/copy-editor-assets.mjs b/scripts/copy-editor-assets.mjs new file mode 100644 index 00000000..f4edd9f3 --- /dev/null +++ b/scripts/copy-editor-assets.mjs @@ -0,0 +1,22 @@ +import { cp, mkdir } from "node:fs/promises"; +import { createRequire } from "node:module"; +import path from "node:path"; + +const require = createRequire(import.meta.url); +const source = path.dirname(require.resolve("tinymce/package.json")); +const target = path.resolve("public/vendor/tinymce"); +await mkdir(target, { recursive: true }); +for (const name of [ + "tinymce.min.js", + "icons", + "models", + "plugins", + "skins", + "themes", + "license.md", + "notices.txt", +]) { + await cp(path.join(source, name), path.join(target, name), { + recursive: true, + }); +} diff --git a/scripts/prepare-hooks.mjs b/scripts/prepare-hooks.mjs new file mode 100644 index 00000000..8a7856c5 --- /dev/null +++ b/scripts/prepare-hooks.mjs @@ -0,0 +1,5 @@ +// Production builds and CI do not need Git hooks or dev-only executables. +if (process.env.NODE_ENV !== "production" && !process.env.CI) { + const { default: husky } = await import("husky"); + husky(); +} diff --git a/src/app/(site)/error.tsx b/src/app/(site)/error.tsx index 696637f5..38816451 100644 --- a/src/app/(site)/error.tsx +++ b/src/app/(site)/error.tsx @@ -2,9 +2,10 @@ import { Home, RefreshCw } from "lucide-react"; import { useTranslations } from "next-intl"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { ErrorScreen } from "@/components/error-screen"; import Link from "@/components/link"; +import { reportBrowserError } from "@/lib/browser-errors"; /** * Site route-segment error boundary. Renders inside the site shell layout. @@ -19,8 +20,10 @@ export default function SiteErrorPage({ }) { const t = useTranslations("pages.error"); + const [reference, setReference] = useState(error.digest); useEffect(() => { - console.error(error); + setReference(error.digest ?? reportBrowserError(error, "browser.boundary")); + if (error.digest) reportBrowserError(error, "browser.boundary"); }, [error]); return ( @@ -46,9 +49,9 @@ export default function SiteErrorPage({ > } footer={ - error.digest ? ( + reference ? (
- {t("reference", { digest: error.digest })} + {t("reference", { digest: reference })}
) : null } diff --git a/src/app/admin/devops/cms-errors/actions.test.ts b/src/app/admin/devops/cms-errors/actions.test.ts new file mode 100644 index 00000000..161ae070 --- /dev/null +++ b/src/app/admin/devops/cms-errors/actions.test.ts @@ -0,0 +1,39 @@ +import { expect, it, vi } from "vitest"; + +const mocks = vi.hoisted(() => ({ + guard: vi.fn(), + resolve: vi.fn(), + audit: vi.fn(), +})); +vi.mock("@/lib/admin/guard", () => ({ requirePermission: mocks.guard })); +vi.mock("@/lib/error-monitor", () => ({ + ErrorStore: class { + resolve = mocks.resolve; + }, +})); +vi.mock("@/lib/permissions", () => ({ + PERMS: { DEVOPS_EDIT: "admin.devops.edit" }, +})); +vi.mock("@/lib/services/audit", () => ({ logAudit: mocks.audit })); +vi.mock("next/cache", () => ({ revalidatePath: vi.fn() })); + +import { resolveCmsError } from "./actions"; + +it("requires edit permission before resolving or auditing", async () => { + mocks.guard.mockRejectedValue(new Error("denied")); + await expect(resolveCmsError(new FormData())).rejects.toThrow("denied"); + expect(mocks.resolve).not.toHaveBeenCalled(); + expect(mocks.audit).not.toHaveBeenCalled(); +}); +it("records who resolved the problem", async () => { + mocks.guard.mockResolvedValue({ id: 42 }); + mocks.resolve.mockResolvedValue(undefined); + mocks.audit.mockResolvedValue(undefined); + const data = new FormData(); + data.set("fingerprint", "aabbccddeeff0011"); + await resolveCmsError(data); + expect(mocks.guard).toHaveBeenCalledWith("admin.devops.edit"); + expect(mocks.audit).toHaveBeenCalledWith( + expect.objectContaining({ userId: 42, action: "cms.error.resolve" }), + ); +}); diff --git a/src/app/admin/devops/cms-errors/actions.ts b/src/app/admin/devops/cms-errors/actions.ts new file mode 100644 index 00000000..ae8edacc --- /dev/null +++ b/src/app/admin/devops/cms-errors/actions.ts @@ -0,0 +1,17 @@ +"use server"; +import { revalidatePath } from "next/cache"; +import { requirePermission } from "@/lib/admin/guard"; +import { ErrorStore } from "@/lib/error-monitor"; +import { PERMS } from "@/lib/permissions"; +import { logAudit } from "@/lib/services/audit"; +export async function resolveCmsError(data: FormData) { + const staff = await requirePermission(PERMS.DEVOPS_EDIT); + await new ErrorStore().resolve(String(data.get("fingerprint") ?? "")); + await logAudit({ + userId: staff.id, + action: "cms.error.resolve", + target: "cms-error", + after: { fingerprint: String(data.get("fingerprint")) }, + }); + revalidatePath("/admin/devops/cms-errors"); +} diff --git a/src/app/admin/devops/cms-errors/page.test.ts b/src/app/admin/devops/cms-errors/page.test.ts new file mode 100644 index 00000000..a10f3091 --- /dev/null +++ b/src/app/admin/devops/cms-errors/page.test.ts @@ -0,0 +1,32 @@ +import { expect, it, vi } from "vitest"; + +const mocks = vi.hoisted(() => ({ read: vi.fn(), access: vi.fn() })); +vi.mock("@/lib/permissions", () => ({ + getAdminContext: async () => ({ + session: { user: { rank: 1 } }, + permissions: {}, + }), + canAccess: mocks.access, + PERMS: { DEVOPS_VIEW: "devops.view" }, +})); +vi.mock("next/navigation", () => ({ + redirect: () => { + throw new Error("redirect"); + }, +})); +vi.mock("@/lib/error-monitor", () => ({ + ErrorStore: class { + read = mocks.read; + }, +})); +vi.mock("@/components/link", () => ({ default: () => null })); + +import Page from "./page"; + +it("rejects access before reading diagnostic data", async () => { + mocks.access.mockReturnValue(false); + await expect(Page({ searchParams: Promise.resolve({}) })).rejects.toThrow( + "redirect", + ); + expect(mocks.read).not.toHaveBeenCalled(); +}); diff --git a/src/app/admin/devops/cms-errors/page.tsx b/src/app/admin/devops/cms-errors/page.tsx new file mode 100644 index 00000000..ea194223 --- /dev/null +++ b/src/app/admin/devops/cms-errors/page.tsx @@ -0,0 +1,181 @@ +import { redirect } from "next/navigation"; +import Link from "@/components/link"; +import { ErrorStore } from "@/lib/error-monitor"; +import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; +import { resolveCmsError } from "./actions"; +export default async function CmsErrorsPage({ + searchParams, +}: { + searchParams: Promise+ Server and browser errors from the last 7 days. Browser reports are + unverified client observations. +
++ {filtered.length} occurrences · {groups.size} groups.{" "} + {result.truncated + ? "Showing the latest 1,000 events. Narrowing filters searches this retained window." + : ""}{" "} + Storage is limited to 10 MB per day; excess events remain in server logs + where available. +
+ {groups.size === 0 ? ( +{r.event}
+{r.message}
+
+ Reference: {r.id}
+
+ Release: {r.release}
+
+ {JSON.stringify(r.context, null, 2)}
+
+
+ {r.stack ||
+ "No stack supplied. Use the reference or digest to correlate server logs."}
+
+ {!r.resolved &&
+ canAccess(permissions, PERMS.DEVOPS_EDIT, session.user.rank) ? (
+
+ ) : null}
+ + Browser stack traces may reference compiled chunks. This view + does not infer a root cause or include request bodies. +
+{total} total errors — showing page {page} of {lastPage}
diff --git a/src/app/admin/devops/page.tsx b/src/app/admin/devops/page.tsx index 062ef1d2..e28e1d58 100644 --- a/src/app/admin/devops/page.tsx +++ b/src/app/admin/devops/page.tsx @@ -55,6 +55,9 @@ export default async function DevOpsPage() { return (- {t("reference", { digest: error.digest })} + {t("reference", { digest: reference })}
) : null}
{error.stack ?? error.message}
- {error.digest ? (
+ {reference ? (
- Reference: {error.digest} + Reference: {reference}
) : null}