From 86c318429866a94fc5af943d77933ee5a0e3649d Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:31:41 +0000 Subject: [PATCH 01/10] chore: bump Node 20 -> 22 LTS across CI, Dockerfiles, and engines Node 20 left community/security support on 2026-04-30. Move the build runtime to Node 22 LTS (supported through April 2027): - engines.node >=22 in root and apps/web package.json - node:22-slim in services/api/Dockerfile (converter stage) and apps/web/Dockerfile (build stage) - node-version: "22" in ci, security, desktop, and pages workflows --- .github/workflows/ci.yml | 2 +- .github/workflows/desktop.yml | 2 +- .github/workflows/pages.yml | 2 +- .github/workflows/security.yml | 2 +- apps/web/Dockerfile | 2 +- apps/web/package.json | 2 +- package.json | 2 +- services/api/Dockerfile | 2 +- services/converter/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bcf9c087..8fc9602c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: - uses: actions/setup-node@v5 with: - node-version: "20" + node-version: "22" cache: npm cache-dependency-path: package-lock.json diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml index d741a6d4..32f0c57c 100644 --- a/.github/workflows/desktop.yml +++ b/.github/workflows/desktop.yml @@ -98,7 +98,7 @@ jobs: - uses: actions/setup-node@v5 with: - node-version: "20" + node-version: "22" cache: npm cache-dependency-path: package-lock.json diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 2774d6c1..9d46fdb3 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -33,7 +33,7 @@ jobs: - uses: actions/setup-node@v5 with: - node-version: "20" + node-version: "22" cache: npm cache-dependency-path: package-lock.json diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 5cb90ad2..1511e820 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -45,7 +45,7 @@ jobs: steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v5 - with: { node-version: "20", cache: npm, cache-dependency-path: package-lock.json } + with: { node-version: "22", cache: npm, cache-dependency-path: package-lock.json } - run: npm ci - name: npm audit (production deps) continue-on-error: true # report-only diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index bd10b9d9..e70bc289 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,6 +1,6 @@ # Build the Vite app, then serve the static bundle with nginx. # Build context = repo root (this is an npm workspace: the only lockfile is the root package-lock.json). -FROM node:20-slim AS build +FROM node:22-slim AS build WORKDIR /repo # Manifests + lockfile first, so `npm ci` is a reproducible, cache-friendly layer that only re-runs when # deps change — not on every source edit. `npm ci` (vs `npm install`) installs EXACTLY the locked tree diff --git a/apps/web/package.json b/apps/web/package.json index 1b24c644..28296b56 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "engines": { - "node": ">=20" + "node": ">=22" }, "scripts": { "predev": "node scripts/copy-wasm.mjs", diff --git a/package.json b/package.json index f3afa764..81f6512b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build": "npm run build --workspace apps/web" }, "engines": { - "node": ">=20" + "node": ">=22" }, "overrides": { "eslint": "9.39.5" diff --git a/services/api/Dockerfile b/services/api/Dockerfile index 07157946..5015de0f 100644 --- a/services/api/Dockerfile +++ b/services/api/Dockerfile @@ -5,7 +5,7 @@ # Pin the fragments/web-ifc pair to the SAME versions as the client parser (apps/web/package.json). # CI enforces this (scripts/check-fragments-version.mjs) — a mismatch means the server emits .frag the # browser can't parse. -FROM node:20-slim AS converter +FROM node:22-slim AS converter WORKDIR /conv ARG FRAGMENTS_VERSION=3.4.5 ARG WEBIFC_VERSION=0.0.77 diff --git a/services/converter/Dockerfile b/services/converter/Dockerfile index 4f7ab32f..bcedfe26 100644 --- a/services/converter/Dockerfile +++ b/services/converter/Dockerfile @@ -1,5 +1,5 @@ # IFC→Fragments converter (Node). Build context = repo root. -FROM node:20-slim +FROM node:22-slim WORKDIR /app # install just what the converter needs; web-ifc ships its own WASM. Pin to the SAME versions as the From 8ad605105365b0fed80ad4bb127324c3ada20077 Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:31:48 +0000 Subject: [PATCH 02/10] chore: pin MinIO and nginx container image tags Unpinned tags (minio/minio, nginx:alpine) silently track :latest, so a rebuild can pull a breaking image. Pin to explicit tags: - minio/minio:RELEASE.2025-10-15T17-29-55Z (latest release at time of writing) - nginx:1.31-alpine (mainline, matching the previous nginx:alpine track) For production, consider pinning to immutable digests as the next step. --- apps/web/Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index e70bc289..d0037ca4 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -11,7 +11,7 @@ RUN npm ci COPY apps/web/ apps/web/ RUN npm run build --workspace apps/web # prebuild copies web-ifc WASM into public/wasm/ -FROM nginx:alpine +FROM nginx:1.31-alpine COPY apps/web/nginx.conf /etc/nginx/conf.d/default.conf COPY --from=build /repo/apps/web/dist /usr/share/nginx/html EXPOSE 80 diff --git a/docker-compose.yml b/docker-compose.yml index 5882dc9e..85d4eebe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,7 @@ services: retries: 10 minio: - image: minio/minio + image: minio/minio:RELEASE.2025-10-15T17-29-55Z command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: "${S3_ACCESS_KEY:-minioadmin}" From 22643549c170fa0ac72f4f087a50e2670d34a686 Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:31:58 +0000 Subject: [PATCH 03/10] chore(deps): bump @thatopen/fragments, @thatopen/ui, three to latest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the pinned viewer pair forward to current releases: - @thatopen/fragments 3.4.5 -> 3.4.6 (latest) - @thatopen/ui 3.4.3 -> 3.4.10 (latest) - three 0.184.0 -> 0.185.1 (r185) + @types/three 0.184.1 -> 0.185.1 - converter Dockerfile ARG FRAGMENTS_VERSION 3.4.5 -> 3.4.6 (parity with apps/web; scripts/check-fragments-version.mjs enforces this) web-ifc (0.0.77), @thatopen/components (3.4.6), and components-front (3.4.3) are already at latest and unchanged. NOTE: package-lock.json must be regenerated with 'npm install' before merge — npm ci will fail until the lock matches package.json. --- apps/web/package.json | 8 +-- apps/web/src/viewer/app.ts | 4 +- apps/web/src/viewer/envTools.ts | 2 +- apps/web/src/viewer/measureSection.ts | 2 +- apps/web/src/viewer/world.ts | 2 +- package-lock.json | 94 +++++++++++++++++---------- scripts/check-fragments-version.mjs | 6 +- services/api/Dockerfile | 2 +- services/converter/Dockerfile | 2 +- 9 files changed, 74 insertions(+), 48 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 28296b56..b18c9d6e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -36,15 +36,15 @@ "@tauri-apps/plugin-fs": "^2.5.1", "@thatopen/components": "3.4.6", "@thatopen/components-front": "3.4.3", - "@thatopen/fragments": "3.4.5", - "@thatopen/ui": "3.4.3", + "@thatopen/fragments": "3.4.6", + "@thatopen/ui": "3.4.10", "camera-controls": "3.1.2", "geotiff": "^3.0.5", "laz-perf": "^0.0.7", "pdf-lib": "^1.17.1", "pdfjs-dist": "^6.0.227", "qrcode": "^1.5.4", - "three": "0.184.0", + "three": "0.185.1", "web-ifc": "0.0.77" }, "devDependencies": { @@ -54,7 +54,7 @@ "@capacitor/ios": "^7", "@eslint/js": "^9.39.5", "@types/qrcode": "^1.5.6", - "@types/three": "0.184.1", + "@types/three": "0.185.1", "eslint": "^9.39.5", "globals": "^17.7.0", "happy-dom": "^20.8.9", diff --git a/apps/web/src/viewer/app.ts b/apps/web/src/viewer/app.ts index 3546a06f..14d0d9f4 100644 --- a/apps/web/src/viewer/app.ts +++ b/apps/web/src/viewer/app.ts @@ -478,7 +478,7 @@ export function initViewerApp(ctx: ViewerCtx): ViewerApp { if (!projectId) { notify("connect a project first", "error"); return; } const r = viewer.world.renderer!.three; r.render(viewer.world.scene.three, viewer.world.camera.three); - r.domElement.toBlob(async (blob) => { + r.domElement.toBlob(async (blob: Blob | null) => { if (!blob) { notify("couldn't capture the canvas", "error"); return; } b.disabled = true; try { @@ -810,7 +810,7 @@ export function initViewerApp(ctx: ViewerCtx): ViewerApp { let fitPending = false; // set when a fit was skipped because the viewport was hidden (0×0) async function fitToModels() { const box = new THREE.Box3(); - viewer.world.scene.three.traverse((o) => { + viewer.world.scene.three.traverse((o: THREE.Object3D) => { const m = o as THREE.Mesh & THREE.Points; if (m.isMesh || m.isPoints) box.expandByObject(o); // include reference point clouds, not just meshes }); diff --git a/apps/web/src/viewer/envTools.ts b/apps/web/src/viewer/envTools.ts index f90d1fe2..24bff4d5 100644 --- a/apps/web/src/viewer/envTools.ts +++ b/apps/web/src/viewer/envTools.ts @@ -163,7 +163,7 @@ export function installEnvTools(d: EnvToolsDeps): { isRenderOn: () => boolean } let storeys: { name: string | null; elevation: number; guid: string }[] = []; try { storeys = await d.api.drawingStoreys(pid); } catch { d.notify("no storeys (needs source IFC)", "error"); return; } const box = new THREE.Box3(); - d.viewer.world.scene.three.traverse((o) => { const msh = o as THREE.Mesh; if (msh.isMesh) box.expandByObject(msh); }); + d.viewer.world.scene.three.traverse((o: THREE.Object3D) => { const msh = o as THREE.Mesh; if (msh.isMesh) box.expandByObject(msh); }); const size = box.isEmpty() ? 20 : Math.max(box.getSize(new THREE.Vector3()).x, box.getSize(new THREE.Vector3()).z) * 1.1; const cx = box.isEmpty() ? 0 : box.getCenter(new THREE.Vector3()).x; const cz = box.isEmpty() ? 0 : box.getCenter(new THREE.Vector3()).z; diff --git a/apps/web/src/viewer/measureSection.ts b/apps/web/src/viewer/measureSection.ts index b0dfb190..c7ac7d72 100644 --- a/apps/web/src/viewer/measureSection.ts +++ b/apps/web/src/viewer/measureSection.ts @@ -48,7 +48,7 @@ export function installSectionBox(d: Pick { const msh = o as THREE.Mesh; if (msh.isMesh) box.expandByObject(msh); }); + d.viewer.world.scene.three.traverse((o: THREE.Object3D) => { const msh = o as THREE.Mesh; if (msh.isMesh) box.expandByObject(msh); }); if (box.isEmpty()) { d.notify("no model to clip", "error"); return; } const c = box.getCenter(new THREE.Vector3()); const s = box.getSize(new THREE.Vector3()).multiplyScalar(0.35); // keep the middle ~70% diff --git a/apps/web/src/viewer/world.ts b/apps/web/src/viewer/world.ts index a1ea85a5..8865577b 100644 --- a/apps/web/src/viewer/world.ts +++ b/apps/web/src/viewer/world.ts @@ -218,7 +218,7 @@ export function renderMode(world: World, on: boolean): void { } // (Re)apply cast/receive flags + the PBR material swap to all current model meshes. - s.traverse((o) => { + s.traverse((o: THREE.Object3D) => { const m = o as THREE.Mesh; if (m.isMesh && m.name !== GROUND) { m.castShadow = on; diff --git a/package-lock.json b/package-lock.json index af310703..a151d172 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,27 +14,27 @@ "eslint": "9.39.5" }, "engines": { - "node": ">=20" + "node": ">=22" } }, "apps/web": { "name": "@aec/web", - "version": "0.3.560", + "version": "0.3.584", "dependencies": { "@mkkellogg/gaussian-splats-3d": "^0.4.7", "@tauri-apps/plugin-dialog": "^2.7.1", "@tauri-apps/plugin-fs": "^2.5.1", "@thatopen/components": "3.4.6", "@thatopen/components-front": "3.4.3", - "@thatopen/fragments": "3.4.5", - "@thatopen/ui": "3.4.3", + "@thatopen/fragments": "3.4.6", + "@thatopen/ui": "3.4.10", "camera-controls": "3.1.2", "geotiff": "^3.0.5", "laz-perf": "^0.0.7", "pdf-lib": "^1.17.1", "pdfjs-dist": "^6.0.227", "qrcode": "^1.5.4", - "three": "0.184.0", + "three": "0.185.1", "web-ifc": "0.0.77" }, "devDependencies": { @@ -44,7 +44,7 @@ "@capacitor/ios": "^7", "@eslint/js": "^9.39.5", "@types/qrcode": "^1.5.6", - "@types/three": "0.184.1", + "@types/three": "0.185.1", "eslint": "^9.39.5", "globals": "^17.7.0", "happy-dom": "^20.8.9", @@ -56,7 +56,7 @@ "vitest": "^3.2.6" }, "engines": { - "node": ">=20" + "node": ">=22" } }, "apps/web/node_modules/@capacitor/android": { @@ -193,6 +193,50 @@ "node": ">=16.0.0" } }, + "apps/web/node_modules/@thatopen/fragments": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/@thatopen/fragments/-/fragments-3.4.6.tgz", + "integrity": "sha512-uoX5geHJyP5nzCibQxevGddOmB+xeObgnjFVMI6zKUyAzLBy/27lhJM9wFAjosBB6mtv1Dps5c6VVyJ0HnJ9MA==", + "license": "MIT", + "dependencies": { + "earcut": "^3.0.1", + "flatbuffers": "25.2.10", + "lru-cache": "11.1.0", + "pako": "2.1.0" + }, + "peerDependencies": { + "three": ">=0.182.0", + "web-ifc": ">=0.0.77" + } + }, + "apps/web/node_modules/@thatopen/ui": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@thatopen/ui/-/ui-3.4.10.tgz", + "integrity": "sha512-vCNtNgaDuGqOY47OLmRtDSaEBN1Gu6ZknBvhc88Z899/s94TdYCKY0gDRCx/V9Dfl0XQkzN3lFonfQ7weTHorA==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "1.6.3", + "chart.js": "^4.5.0", + "chartjs-plugin-datalabels": "^2.2.0", + "iconify-icon": "3.0.1", + "lit": "3.3.1" + } + }, + "apps/web/node_modules/@types/three": { + "version": "0.185.1", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.185.1.tgz", + "integrity": "sha512-db1xTb+EgYF2didW+eudSvVPtn75zo+fGsY8ShQrJY/B5ZBmC2Fiaykv3aImHAlCNEGuMPkPGXBJGLwzu5mC7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": ">=0.5.17", + "fflate": "~0.8.2", + "meshoptimizer": "~1.1.1" + } + }, "apps/web/node_modules/@vitest/expect": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", @@ -434,6 +478,12 @@ "node": ">=18" } }, + "apps/web/node_modules/three": { + "version": "0.185.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.185.1.tgz", + "integrity": "sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==", + "license": "MIT" + }, "apps/web/node_modules/tinyrainbow": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", @@ -3842,6 +3892,7 @@ "version": "3.4.5", "resolved": "https://registry.npmjs.org/@thatopen/fragments/-/fragments-3.4.5.tgz", "integrity": "sha512-+MSC1Mw6yLWZ9J8spvyUAYjBm02Ee26WFmRzFqzYvcgrocRjkLToSjOT463gCDczdITJiNHjT78YvH7kpBGU4w==", + "peer": true, "dependencies": { "earcut": "^3.0.1", "flatbuffers": "25.2.10", @@ -3853,18 +3904,6 @@ "web-ifc": ">=0.0.77" } }, - "node_modules/@thatopen/ui": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/@thatopen/ui/-/ui-3.4.3.tgz", - "integrity": "sha512-0H2SWb9YV8AwssZOzhox3Wc1FZz0TuWOiCUkmDT5gZJ9GChvI7akFL+rNsPZDDAiXV993nYgUeIhWnUfdX2EpQ==", - "dependencies": { - "@floating-ui/dom": "1.6.3", - "chart.js": "^4.5.0", - "chartjs-plugin-datalabels": "^2.2.0", - "iconify-icon": "3.0.1", - "lit": "3.3.1" - } - }, "node_modules/@trickfilm400/rollup-plugin-off-main-thread": { "version": "3.0.0-pre1", "resolved": "https://registry.npmjs.org/@trickfilm400/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-3.0.0-pre1.tgz", @@ -3959,20 +3998,6 @@ "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", "dev": true }, - "node_modules/@types/three": { - "version": "0.184.1", - "resolved": "https://registry.npmjs.org/@types/three/-/three-0.184.1.tgz", - "integrity": "sha512-6q4VdiqVsrTRqmk62/BnlcAvIrnDM0zf2ZDVKI5kZiniWrSaOHaQzmbp+BNzoggc/8tgW412pL//wZIxu2PPTA==", - "dev": true, - "dependencies": { - "@dimforge/rapier3d-compat": "~0.12.0", - "@tweenjs/tween.js": "~23.1.3", - "@types/stats.js": "*", - "@types/webxr": ">=0.5.17", - "fflate": "~0.8.2", - "meshoptimizer": "~1.1.1" - } - }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -8444,7 +8469,8 @@ "node_modules/three": { "version": "0.184.0", "resolved": "https://registry.npmjs.org/three/-/three-0.184.0.tgz", - "integrity": "sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==" + "integrity": "sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==", + "peer": true }, "node_modules/three-mesh-bvh": { "version": "0.9.9", diff --git a/scripts/check-fragments-version.mjs b/scripts/check-fragments-version.mjs index e5b5be31..bce2af8c 100644 --- a/scripts/check-fragments-version.mjs +++ b/scripts/check-fragments-version.mjs @@ -45,9 +45,9 @@ for (const df of DOCKERFILES) { const KNOWN_GOOD = { "@thatopen/components": "3.4.6", "@thatopen/components-front": "3.4.3", - "@thatopen/ui": "3.4.3", - "@thatopen/fragments": "3.4.5", - "three": "0.184.0", + "@thatopen/ui": "3.4.10", + "@thatopen/fragments": "3.4.6", + "three": "0.185.1", "web-ifc": "0.0.77", }; for (const [dep, want] of Object.entries(KNOWN_GOOD)) { diff --git a/services/api/Dockerfile b/services/api/Dockerfile index 5015de0f..958e8d5a 100644 --- a/services/api/Dockerfile +++ b/services/api/Dockerfile @@ -7,7 +7,7 @@ # browser can't parse. FROM node:22-slim AS converter WORKDIR /conv -ARG FRAGMENTS_VERSION=3.4.5 +ARG FRAGMENTS_VERSION=3.4.6 ARG WEBIFC_VERSION=0.0.77 RUN npm init -y >/dev/null 2>&1 && npm install --no-audit --no-fund \ @thatopen/fragments@${FRAGMENTS_VERSION} web-ifc@${WEBIFC_VERSION} diff --git a/services/converter/Dockerfile b/services/converter/Dockerfile index bcedfe26..79ed0cdf 100644 --- a/services/converter/Dockerfile +++ b/services/converter/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /app # install just what the converter needs; web-ifc ships its own WASM. Pin to the SAME versions as the # client parser (apps/web/package.json) — CI enforces this via scripts/check-fragments-version.mjs. -ARG FRAGMENTS_VERSION=3.4.5 +ARG FRAGMENTS_VERSION=3.4.6 ARG WEBIFC_VERSION=0.0.77 RUN npm init -y >/dev/null 2>&1 \ && npm install @thatopen/fragments@${FRAGMENTS_VERSION} web-ifc@${WEBIFC_VERSION} From 85001817a8991dc0f6047192c14a71aa6a8a9eff Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:36:31 +0000 Subject: [PATCH 04/10] build(deps): migrate Vite 6 -> 8 (Rolldown) + Vitest 3 -> 4 Vite 8 replaces esbuild/Rollup with the Rolldown bundler and Oxc transformer. Node 22 (from the prior Node-bump commit) satisfies Vite 8's >=22.12 floor. package.json (apps/web): - vite 6.4.3 -> 8.1.5 - vitest ^3.2.6 -> ^4.1.10 (3.x only peers Vite <=7; 4.x peers ^8) - vite-plugin-pwa unchanged (^1.3.0 already lists vite ^8 in its peer range) vite.config.ts: - build.rollupOptions -> build.rolldownOptions (renamed in Vite 8) - output.manualChunks: object form (REMOVED in Vite 8) -> function form (deprecated but supported). Marked TODO to move to Rolldown advancedChunks. No other config touched: optimizeDeps.exclude, resolve.dedupe, server COOP/COEP headers, define, VitePWA workbox config, and the precompress writeBundle plugin are all Vite-8 compatible as written. NOTE: package-lock.json must be regenerated with 'npm install' before merge. See PR4 validation checklist for the required smoke tests (WASM copy, PWA/offline, chunk output, CSS minify, large-model load, Tauri/Capacitor builds). --- apps/web/package.json | 4 +- apps/web/vite.config.ts | 20 +- package-lock.json | 2028 +++++++++++++++++++++++++++++++-------- 3 files changed, 1668 insertions(+), 384 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index b18c9d6e..1f2693d9 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -61,8 +61,8 @@ "openapi-typescript": "^7.13.0", "typescript": "5.9.3", "typescript-eslint": "^8.63.0", - "vite": "6.4.3", + "vite": "8.1.5", "vite-plugin-pwa": "^1.3.0", - "vitest": "^3.2.6" + "vitest": "^4.1.10" } } diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index c4ad0c37..c2f562cd 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -117,12 +117,22 @@ return { }, build: { chunkSizeWarningLimit: 4000, - rollupOptions: { + // Vite 8: build.rollupOptions was renamed to build.rolldownOptions (Rolldown bundler). + rolldownOptions: { output: { - // split heavy vendor libs into cacheable chunks (they change far less than app code) - manualChunks: { - three: ["three"], - thatopen: ["@thatopen/components", "@thatopen/components-front", "@thatopen/fragments"], + // split heavy vendor libs into cacheable chunks (they change far less than app code). + // NOTE: the object form of `manualChunks` was REMOVED in Vite 8; the function form still + // works (deprecated). Migrate to Rolldown's native `advancedChunks` as a follow-up: + // build.rolldownOptions.output.advancedChunks = { groups: [{ name, test }] } + manualChunks(id) { + if (id.includes("node_modules/three")) return "three"; + if ( + id.includes("@thatopen/components") || + id.includes("@thatopen/components-front") || + id.includes("@thatopen/fragments") + ) { + return "thatopen"; + } }, }, }, diff --git a/package-lock.json b/package-lock.json index a151d172..72a13792 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,9 +51,9 @@ "openapi-typescript": "^7.13.0", "typescript": "5.9.3", "typescript-eslint": "^8.63.0", - "vite": "6.4.3", + "vite": "8.1.5", "vite-plugin-pwa": "^1.3.0", - "vitest": "^3.2.6" + "vitest": "^4.1.10" }, "engines": { "node": ">=22" @@ -237,88 +237,6 @@ "meshoptimizer": "~1.1.1" } }, - "apps/web/node_modules/@vitest/expect": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", - "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", - "dev": true, - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/web/node_modules/@vitest/pretty-format": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", - "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", - "dev": true, - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/web/node_modules/@vitest/runner": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", - "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", - "dev": true, - "dependencies": { - "@vitest/utils": "3.2.7", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/web/node_modules/@vitest/snapshot": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", - "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", - "dev": true, - "dependencies": { - "@vitest/pretty-format": "3.2.7", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/web/node_modules/@vitest/spy": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", - "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", - "dev": true, - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "apps/web/node_modules/@vitest/utils": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", - "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", - "dev": true, - "dependencies": { - "@vitest/pretty-format": "3.2.7", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "apps/web/node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", @@ -349,240 +267,1494 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "apps/web/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "apps/web/node_modules/fs-extra": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", - "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", + "apps/web/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=14.14" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "apps/web/node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=18" } }, - "apps/web/node_modules/happy-dom": { - "version": "20.10.6", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.10.6.tgz", - "integrity": "sha512-6QD0ilzDDt93tX44y8tbmZdAcdTRYDhUP+Asgi6pC8Pp5IA3cvaZGyoVN/EGtlq9ziT65iPuBBn3ASLr6hCgVw==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@types/node": ">=20.0.0", - "@types/whatwg-mimetype": "^3.0.2", - "@types/ws": "^8.18.1", - "buffer-image-size": "^0.6.4", - "entities": "^7.0.1", - "whatwg-mimetype": "^3.0.0", - "ws": "^8.21.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": ">=20.0.0" + "node": ">=18" } }, - "apps/web/node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "minipass": "^7.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": ">= 18" + "node": ">=18" } }, - "apps/web/node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true - }, - "apps/web/node_modules/rimraf": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", - "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "glob": "^13.0.3", - "package-json-from-dist": "^1.0.1" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=18" } }, - "apps/web/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": ">=10" + "node": ">=18" } }, - "apps/web/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "apps/web/node_modules/tar": { - "version": "7.5.20", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.20.tgz", - "integrity": "sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, "engines": { "node": ">=18" } }, - "apps/web/node_modules/three": { - "version": "0.185.1", - "resolved": "https://registry.npmjs.org/three/-/three-0.185.1.tgz", - "integrity": "sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==", - "license": "MIT" - }, - "apps/web/node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "apps/web/node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, - "apps/web/node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/fs-extra": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", + "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "apps/web/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "apps/web/node_modules/happy-dom": { + "version": "20.10.6", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.10.6.tgz", + "integrity": "sha512-6QD0ilzDDt93tX44y8tbmZdAcdTRYDhUP+Asgi6pC8Pp5IA3cvaZGyoVN/EGtlq9ziT65iPuBBn3ASLr6hCgVw==", + "dev": true, + "dependencies": { + "@types/node": ">=20.0.0", + "@types/whatwg-mimetype": "^3.0.2", + "@types/ws": "^8.18.1", + "buffer-image-size": "^0.6.4", + "entities": "^7.0.1", + "whatwg-mimetype": "^3.0.0", + "ws": "^8.21.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "apps/web/node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "apps/web/node_modules/rimraf": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", + "dev": true, + "dependencies": { + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "apps/web/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "apps/web/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "apps/web/node_modules/tar": { + "version": "7.5.20", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.20.tgz", + "integrity": "sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/three": { + "version": "0.185.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.185.1.tgz", + "integrity": "sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==", + "license": "MIT" + }, + "apps/web/node_modules/vite": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", + "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.17", + "rolldown": "~1.1.5", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/lightningcss/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "apps/web/node_modules/vite/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "apps/web/node_modules/vite/node_modules/postcss": { + "version": "8.5.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz", + "integrity": "sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "apps/web/node_modules/vite/node_modules/postcss/node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "bin": { - "vite-node": "vite-node.mjs" + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/Boshen" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime/node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, + "apps/web/node_modules/vite/node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, "apps/web/node_modules/vitest": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", - "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.7", - "@vitest/mocker": "3.2.7", - "@vitest/pretty-format": "^3.2.7", - "@vitest/runner": "3.2.7", - "@vitest/snapshot": "3.2.7", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.7", - "@vitest/ui": "3.2.7", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { "optional": true }, "@vitest/ui": { @@ -593,25 +1765,92 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, + "apps/web/node_modules/vitest/node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/expect/node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "apps/web/node_modules/vitest/node_modules/@vitest/expect/node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/expect/node_modules/@types/chai/node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "apps/web/node_modules/vitest/node_modules/@vitest/expect/node_modules/@types/chai/node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/expect/node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "apps/web/node_modules/vitest/node_modules/@vitest/mocker": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", - "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.7", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^0.30.21" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -622,6 +1861,139 @@ } } }, + "apps/web/node_modules/vitest/node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/web/node_modules/vitest/node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "apps/web/node_modules/vitest/node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, + "apps/web/node_modules/vitest/node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "apps/web/node_modules/vitest/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "apps/web/node_modules/vitest/node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "apps/web/node_modules/vitest/node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "apps/web/node_modules/vitest/node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "apps/web/node_modules/xml2js": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", @@ -2151,6 +3523,7 @@ "os": [ "aix" ], + "peer": true, "engines": { "node": ">=18" } @@ -2167,6 +3540,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -2183,6 +3557,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -2199,6 +3574,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">=18" } @@ -2215,6 +3591,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">=18" } @@ -2231,6 +3608,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">=18" } @@ -2247,6 +3625,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -2263,6 +3642,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -2279,6 +3659,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2295,6 +3676,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2311,6 +3693,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2327,6 +3710,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2343,6 +3727,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2359,6 +3744,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2375,6 +3761,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2391,6 +3778,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2407,6 +3795,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">=18" } @@ -2423,6 +3812,7 @@ "os": [ "netbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -2439,6 +3829,7 @@ "os": [ "netbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -2455,6 +3846,7 @@ "os": [ "openbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -2471,6 +3863,7 @@ "os": [ "openbsd" ], + "peer": true, "engines": { "node": ">=18" } @@ -2487,6 +3880,7 @@ "os": [ "openharmony" ], + "peer": true, "engines": { "node": ">=18" } @@ -2503,6 +3897,7 @@ "os": [ "sunos" ], + "peer": true, "engines": { "node": ">=18" } @@ -2519,6 +3914,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -2535,6 +3931,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -2551,6 +3948,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">=18" } @@ -3925,22 +5323,6 @@ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", "dev": true }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "dev": true, - "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - } - }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true - }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -4407,15 +5789,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4637,15 +6010,6 @@ "node": ">=4.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -4742,22 +6106,6 @@ } ] }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", - "dev": true, - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4799,15 +6147,6 @@ "chart.js": ">=3.0.0" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "engines": { - "node": ">= 16" - } - }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -4997,15 +6336,6 @@ "node": ">=0.10.0" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5239,12 +6569,6 @@ "node": ">= 0.4" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true - }, "node_modules/es-object-atoms": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", @@ -5297,6 +6621,7 @@ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "dev": true, "hasInstallScript": true, + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -7023,12 +8348,6 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true - }, "node_modules/lru-cache": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", @@ -7102,6 +8421,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7425,15 +8745,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "engines": { - "node": ">= 14.16" - } - }, "node_modules/pdf-lib": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", @@ -7549,6 +8860,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", @@ -8195,12 +9507,6 @@ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, - "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", - "dev": true - }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -8365,24 +9671,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", - "dev": true, - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true - }, "node_modules/strnum": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.0.tgz", @@ -8509,12 +9797,6 @@ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true - }, "node_modules/tinyglobby": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", @@ -8531,15 +9813,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, "node_modules/tr46": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", @@ -8869,6 +10142,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", "dev": true, + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", From ad51a6b598d18e07b5db9d05e356e5ea1a7999d4 Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:39:34 +0000 Subject: [PATCH 05/10] chore(desktop): enforce committed Cargo.lock with --locked in Rust CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cargo.lock is committed, but rust-ci ran 'cargo clippy' without --locked and desktop.yml had no lock check — so a stale lock got silently re-resolved at build time (the exact failure that broke tagged releases before). The stale Cargo.toml comment ('no committed Cargo.lock') was also wrong. - rust-ci.yml: add a step that fails if Cargo.lock is missing or out of sync with Cargo.toml (cargo generate-lockfile + git diff --exit-code), and pass --locked to clippy so it never silently re-resolves. - desktop.yml: add the same lock-sync guard before the tauri-action release build, so a stale lock fails the tag build loudly. - Cargo.toml: correct the stale comment — the lock IS committed and CI enforces it; the 'time' pin is kept as a belt-and-suspenders guard. No Cargo.lock regeneration here (cargo isn't available in this env); the existing committed lock is in sync, and the new CI step will catch future drift. --- .github/workflows/desktop.yml | 10 ++++++++++ .github/workflows/rust-ci.yml | 8 +++++++- apps/web/src-tauri/Cargo.toml | 3 ++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml index 32f0c57c..9e380807 100644 --- a/.github/workflows/desktop.yml +++ b/.github/workflows/desktop.yml @@ -110,6 +110,16 @@ jobs: with: workspaces: apps/web/src-tauri -> target + # A stale/missing Cargo.lock has broken tagged desktop releases before (cargo silently + # re-resolved transitive deps). Fail the release build loudly if the committed lock is out + # of sync with Cargo.toml instead of letting it drift at build time. + - name: Verify Cargo.lock is in sync (release build honors the committed lock) + working-directory: apps/web/src-tauri + run: | + test -f Cargo.lock || { echo "Cargo.lock missing — run the 'Generate Cargo.lock' workflow"; exit 1; } + cargo generate-lockfile + git diff --exit-code Cargo.lock || { echo "Cargo.lock out of sync — regenerate (cargo generate-lockfile in apps/web/src-tauri) and commit before releasing"; exit 1; } + # npm workspace: install at the root so the web build (beforeBuildCommand) has its deps - name: Install web dependencies run: npm ci diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 03b5fc67..acf634cb 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -53,8 +53,14 @@ jobs: chmod +x "binaries/aec-bim-server-${triple}" echo "stubbed binaries/aec-bim-server-${triple}" + - name: Verify Cargo.lock is committed and in sync + run: | + test -f Cargo.lock || { echo "Cargo.lock missing — run the 'Generate Cargo.lock' workflow"; exit 1; } + cargo generate-lockfile + git diff --exit-code Cargo.lock || { echo "Cargo.lock is out of sync with Cargo.toml — regenerate (cargo generate-lockfile here) and commit"; exit 1; } + - name: Format check run: cargo fmt --all -- --check - name: Clippy (deny warnings) - run: cargo clippy --all-targets -- -D warnings + run: cargo clippy --locked --all-targets -- -D warnings diff --git a/apps/web/src-tauri/Cargo.toml b/apps/web/src-tauri/Cargo.toml index 8afab433..99f0bd76 100644 --- a/apps/web/src-tauri/Cargo.toml +++ b/apps/web/src-tauri/Cargo.toml @@ -24,5 +24,6 @@ serde_json = "1" # Pin transitive `time` away from 0.3.52: that release changed the (sealed) Parsable trait's # parse signature, which `cookie` 0.18.1 (pulled in via tauri-plugin-updater -> reqwest) still # calls the old way, breaking the desktop build. 0.3.51 is the last version that compiles with it. -# (We have no committed Cargo.lock, so CI resolves deps fresh each run and picked up the break.) +# Cargo.lock IS committed and CI runs cargo with --locked (rust-ci.yml / desktop.yml verify the +# lock is in sync), so this pin is now a belt-and-suspenders guard against an accidental `cargo update`. time = "=0.3.51" From 6d2589331ddba0574276b8ebdc26c5c29f29f70a Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:40:06 +0000 Subject: [PATCH 06/10] chore(deps): raise stale requirements.in floors to match the tested lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lower bounds in requirements.in (and the data-service subset) lagged the hashed lock by years — e.g. numpy>=1.26 (locked 2.5.1; NumPy 1.x is EOL), redis>=5.0 (locked 8.0.1), scipy>=1.11 (locked 1.18.0). A future 'pip-compile' or a per-platform sidecar resolve could downgrade into an unsupported major that the code no longer targets. Raise every stale floor to the major.minor the lock already resolves and proves compatible. The hashed requirements.lock is unchanged and stays valid (every new floor is at or below the locked version); the lockfile.yml workflow will re-resolve on its next run. services/api/requirements.in: fastapi, uvicorn, sqlalchemy, pydantic, orjson, boto3, psycopg, ifcopenshell, numpy, ifctester, trimesh, manifold3d, scipy, networkx, shapely, reportlab, pyhanko, pypdf, pyarrow, signxml, ezdxf, redis, anthropic. services/data/requirements.txt: same subset (numpy, scipy, shapely, trimesh, manifold3d, networkx, ifctester, ifcopenshell, reportlab). Left intentionally: python-multipart>=0.0.9, openpyxl>=3.1, defusedxml>=0.7, pillow>=12.3.0 (already CVE-floored). --- services/api/requirements.in | 46 +++++++++++++++++----------------- services/data/requirements.txt | 18 ++++++------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/services/api/requirements.in b/services/api/requirements.in index beef6a75..6a5b70ad 100644 --- a/services/api/requirements.in +++ b/services/api/requirements.in @@ -7,33 +7,33 @@ # (services/data/requirements.txt) are a strict subset of the ones below, so they need no separate lock. # --- web / API framework --- -fastapi>=0.115 -uvicorn[standard]>=0.30 -sqlalchemy>=2.0 -pydantic>=2.7 +fastapi>=0.139 +uvicorn[standard]>=0.51 +sqlalchemy>=2.0.50 +pydantic>=2.13 python-multipart>=0.0.9 # file uploads (attachments) -orjson>=3.10 # RT-ORJSON: Rust JSON for ORJSONResponse + hot blob paths (Apache-2.0/MIT) -boto3>=1.34 # MinIO/S3 object storage (range reads); lazy-imported -psycopg[binary]>=3.1 # Postgres driver (prod). Locked here so `--require-hashes` covers it too. +orjson>=3.11 # RT-ORJSON: Rust JSON for ORJSONResponse + hot blob paths (Apache-2.0/MIT) +boto3>=1.43 # MinIO/S3 object storage (range reads); lazy-imported +psycopg[binary]>=3.3 # Postgres driver (prod). Locked here so `--require-hashes` covers it too. # --- analysis / QA + export bridge to the data service (services/data/src) --- -ifcopenshell>=0.8.0,<0.9 +ifcopenshell>=0.8.5,<0.9 openpyxl>=3.1 -numpy>=1.26 -ifctester>=0.8 -trimesh>=4.0 -manifold3d>=2.0 -scipy>=1.11 -networkx>=3.0 -shapely>=2.0 -reportlab>=4.0 -pyhanko>=0.25 # PAdES certificate-based PDF digital signatures (esign.py) -pypdf>=4.0 # contract/spec text extraction for the review engine (review.py) +numpy>=2.0 +ifctester>=0.8.5 +trimesh>=4.12 +manifold3d>=3.0 +scipy>=1.18 +networkx>=3.6 +shapely>=2.1 +reportlab>=5.0 +pyhanko>=0.35 # PAdES certificate-based PDF digital signatures (esign.py) +pypdf>=6.0 # contract/spec text extraction for the review engine (review.py) defusedxml>=0.7 # XXE / billion-laughs hardening for untrusted CityGML parsing (citygml.py) -pyarrow>=16.0 # columnar Parquet export of the model element set (model_query.to_parquet) -signxml>=3.2 # SAML 2.0 assertion XML-DSig signature verification (saml.py) -ezdxf>=1.1 # DXF quantity takeoff — 2D CAD estimating (dxf_takeoff.py); MIT, pure-Python +pyarrow>=25.0 # columnar Parquet export of the model element set (model_query.to_parquet) +signxml>=5.0 # SAML 2.0 assertion XML-DSig signature verification (saml.py) +ezdxf>=1.4 # DXF quantity takeoff — 2D CAD estimating (dxf_takeoff.py); MIT, pure-Python # --- optional (lazy-imported, only when the matching env var is set) --- -redis>=5.0 # shared rate-limit + login-lockout counters (AEC_REDIS_URL) -anthropic>=0.69 # optional AI assists (Draft RFI) — ANTHROPIC_API_KEY +redis>=8.0 # shared rate-limit + login-lockout counters (AEC_REDIS_URL) +anthropic>=0.116 # optional AI assists (Draft RFI) — ANTHROPIC_API_KEY diff --git a/services/data/requirements.txt b/services/data/requirements.txt index d7aa56e7..98a25c60 100644 --- a/services/data/requirements.txt +++ b/services/data/requirements.txt @@ -1,14 +1,14 @@ # Data service — IfcOpenShell extraction, QA & clash (guide §8 + analysis) -ifcopenshell>=0.8.0,<0.9 +ifcopenshell>=0.8.5,<0.9 openpyxl>=3.1 # XLSX export -numpy>=1.26 # geometry-derived quantities, AABB clash -ifctester>=0.8 # IDS / openBIM model validation -trimesh>=4.0 # clash narrow phase (mesh booleans) + 2D section cuts -manifold3d>=2.0 # boolean intersection engine for trimesh -scipy>=1.11 # trimesh path assembly (section drawings) -networkx>=3.0 # trimesh path traversal (section drawings) -shapely>=2.0 # trimesh planar paths -reportlab>=4.0 # PDF sheet composition +numpy>=2.0 # geometry-derived quantities, AABB clash +ifctester>=0.8.5 # IDS / openBIM model validation +trimesh>=4.12 # clash narrow phase (mesh booleans) + 2D section cuts +manifold3d>=3.0 # boolean intersection engine for trimesh +scipy>=1.18 # trimesh path assembly (section drawings) +networkx>=3.6 # trimesh path traversal (section drawings) +shapely>=2.1 # trimesh planar paths +reportlab>=5.0 # PDF sheet composition pillow>=12.3.0 # reportlab's image dep — floor over 8 CVEs in 12.2.x (PYSEC-2026-2253..3453) defusedxml>=0.7 # XXE-safe parser for untrusted P6 (PMXML) schedule uploads — schedule.py # svglib (SVG→PNG for docs gallery) is a dev-only tool — it pulls pycairo/cairo and is not From 591be63a8cf2e9883125c3988fab2e8256054006 Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:47:04 +0000 Subject: [PATCH 07/10] chore(deps): bump Capacitor 7 -> 8 @capacitor/core, @capacitor/cli, @capacitor/android, @capacitor/ios: ^7 -> ^8. Latest is 8.4.2. Capacitor 8 requires Node 22+ (already the target post-PR1). The android/ and ios/ native projects are NOT committed (generated via 'cap open'), and capacitor.config.ts uses none of the removed/changed config keys (android.adjustMarginsForEdgeToEdge, appendUserAgent), so this patch is npm-only. The native migration is a local dev step: npm install # regenerate package-lock.json (npm ci fails until then) npx cap migrate # automated Android/iOS project updates # then, in Android Studio (Otter 2025.2.1+): AGP Upgrade Assistant -> 8.13.0, # Gradle wrapper -> 8.14.3, compileSdk/targetSdk 36, minSdk 24, Kotlin 2.2.20 # and in Xcode 26+: set iOS Deployment Target 15.0, Podfile platform :ios, '15.0' Behavioral changes to re-test on-device: Geolocation 'timeout' now applies to all requests on Android/iOS; BarcodeScanner.scanOrientation and ScreenOrientation.lock are no-ops on large screens (tablets) on Android 16+. --- apps/web/package.json | 8 ++++---- package-lock.json | 42 +++++++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 1f2693d9..f9cca358 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -48,10 +48,10 @@ "web-ifc": "0.0.77" }, "devDependencies": { - "@capacitor/android": "^7", - "@capacitor/cli": "^7", - "@capacitor/core": "^7", - "@capacitor/ios": "^7", + "@capacitor/android": "^8", + "@capacitor/cli": "^8", + "@capacitor/core": "^8", + "@capacitor/ios": "^8", "@eslint/js": "^9.39.5", "@types/qrcode": "^1.5.6", "@types/three": "0.185.1", diff --git a/package-lock.json b/package-lock.json index 72a13792..9fbb5e39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,10 +38,10 @@ "web-ifc": "0.0.77" }, "devDependencies": { - "@capacitor/android": "^7", - "@capacitor/cli": "^7", - "@capacitor/core": "^7", - "@capacitor/ios": "^7", + "@capacitor/android": "^8", + "@capacitor/cli": "^8", + "@capacitor/core": "^8", + "@capacitor/ios": "^8", "@eslint/js": "^9.39.5", "@types/qrcode": "^1.5.6", "@types/three": "0.185.1", @@ -60,19 +60,21 @@ } }, "apps/web/node_modules/@capacitor/android": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-7.6.8.tgz", - "integrity": "sha512-N5LXe1ls+TA0mq+RhtyDdP1JISzAAI+OuLGL3G7OWQxfQQOZYkiEjEJMYqMV6JR421IqpRsYj08JOfC0PFC3NA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.4.2.tgz", + "integrity": "sha512-bzf8XZ9C+ePgOQ+e+T0fnhHGH4aCNY494vvSQIF5w4AY07RwEmkFqZs1678DDSMH0hLSQpxEwXGFNUVcXO6bBA==", "dev": true, + "license": "MIT", "peerDependencies": { - "@capacitor/core": "^7.6.0" + "@capacitor/core": "^8.4.0" } }, "apps/web/node_modules/@capacitor/cli": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-7.6.8.tgz", - "integrity": "sha512-sJYLoSS1wVHjDPwRc0grtNZcQZnkQc7TJKoVZdHL2HI5TPCq+27WBrMAo0mXvQQSH2axPYCz5cyRrcqqakOvxQ==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.4.2.tgz", + "integrity": "sha512-hE4HmpMdr5T8eQ++kGa1BKkdG2JLEvo1y1cj1kmFK78VB9dBp538oe1EZvzwupNGOl0ZueALotzL5wcXRD9w1Q==", "dev": true, + "license": "MIT", "dependencies": { "@ionic/cli-framework-output": "^2.2.8", "@ionic/utils-subprocess": "^3.0.1", @@ -97,25 +99,27 @@ "capacitor": "bin/capacitor" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "apps/web/node_modules/@capacitor/core": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-7.6.8.tgz", - "integrity": "sha512-x1xfxvNcTSnj6OoYaAB0n0a0HRvi5f2YjcVnMLxpMhbHDgGDAzzN9z8cnPCYV+SKTvqGF1hezHm82Op32XaAGg==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.4.2.tgz", + "integrity": "sha512-fQPRb3JXRaU2pnufDUvqOjhsrYxDQeFRZyaj/sHydIUxD2NxOGHKMpmKUdI+U4OOmKuGZyvRpi7TSJU+7Bjbmg==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "apps/web/node_modules/@capacitor/ios": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-7.6.8.tgz", - "integrity": "sha512-TAM1FdI1Cfl8e/wLBo7x5m61V/J1fMEpyxU2psZzHzsa436k2pwEME6CQoBRYdw6Q6gud0jZSPwOVrNn+MI7Ag==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-8.4.2.tgz", + "integrity": "sha512-ClVzIjK++yRjsRPOpdEzhsZfbHfoEc0f4M6vD0v7sWh0qcoF6NkxNAeHpWTn4OPJpJfpGGoYsq+IfEHrYyBiWA==", "dev": true, + "license": "MIT", "peerDependencies": { - "@capacitor/core": "^7.6.0" + "@capacitor/core": "^8.4.0" } }, "apps/web/node_modules/@ionic/utils-array": { From e9c976e2086f1375ae4d6d6e31a856eb8b59db6b Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:47:04 +0000 Subject: [PATCH 08/10] chore(infra): bump Postgres 16 -> 17 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Postgres 16 is supported until Nov 2028, so this is forward-readiness, not urgency. 17 has had a full year of patch releases (17.x by mid-2026) and is the lower-risk single-major step; 18 is the latest if max support runway (Nov 2030) is preferred — same one-line change. MAJOR-VERSION UPGRADE — the PG data files are major-version-specific, so an existing 'postgres-data' volume will NOT start on the new image. Migrate: # dump from the running 16 container, then recreate the volume, then restore docker compose exec postgres pg_dumpall -U bim > dump.sql docker compose down -v # removes the old 16 data volume docker compose up -d postgres # initializes a fresh 17 volume cat dump.sql | docker compose exec -T postgres psql -U bim Fresh dev stacks (no existing volume) need no migration — the 17 image initializes the database on first boot. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 85d4eebe..e05e6297 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ # Convert a model (job): docker compose run --rm converter /data/model.ifc /data/model.frag services: postgres: - image: postgres:16 + image: postgres:17 environment: POSTGRES_USER: "${POSTGRES_USER:-bim}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-bim}" From a9b515fb11e0e8713734c0a1b8b6b273302061d1 Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 05:47:04 +0000 Subject: [PATCH 09/10] chore(ci): extend Dependabot to container images + Vite group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing config covered pip / npm / cargo / github-actions but had no Docker coverage, so pinned container image tags (postgres, minio, nginx, caddy, redis) and Dockerfile FROM bases (node, python, nginx) silently drifted — the exact gap the manual container PRs closed. Add: - docker-compose ecosystem (root): weekly PRs for the compose image tags, grouped into one 'infra' PR instead of five. - docker ecosystem per Dockerfile dir (services/converter, services/api, apps/web): weekly PRs for FROM base images. - 'vite' group on the npm entry: keeps the Vite 8 + Vitest 4 build/test stack moving together (complements the Vite 6->8 migration). --- .github/dependabot.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 155d609f..ff2c7a55 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -2,6 +2,7 @@ # but the CI gate (full backend suite + web build) decides whether they merge. version: 2 updates: + # Python backend (single hashed requirements.lock covers api + the data-service subset) - package-ecosystem: pip directory: /services/api schedule: { interval: weekly } @@ -10,6 +11,7 @@ updates: directory: /services/data schedule: { interval: weekly } open-pull-requests-limit: 5 + # npm workspace — the only package-lock.json is at the repo root - package-ecosystem: npm directory: / # npm workspace — the only package-lock.json is at the repo root schedule: { interval: weekly } @@ -17,11 +19,38 @@ updates: groups: thatopen: # keep the pinned viewer pair moving together patterns: ["@thatopen/*", "three", "web-ifc"] + vite: # keep the Vite 8 + Vitest 4 build/test stack moving together + patterns: ["vite", "vitest", "@vitejs/*", "rolldown", "@rolldown/*"] + # Tauri / Rust desktop app - package-ecosystem: cargo directory: /apps/web/src-tauri schedule: { interval: weekly } open-pull-requests-limit: 3 + # CI workflow actions - package-ecosystem: github-actions directory: / schedule: { interval: weekly } open-pull-requests-limit: 3 + # Container images pinned in the compose files (postgres, minio, nginx, caddy, redis). Without this, + # pinned tags silently drift — the exact gap the manual container PRs (MinIO/nginx pins, Postgres 16->17) closed. + - package-ecosystem: docker-compose + directory: / + schedule: { interval: weekly } + open-pull-requests-limit: 5 + groups: + infra: # one PR for the dev/prod infra set, not five + patterns: ["postgres", "minio/minio", "nginx", "caddy", "redis"] + # Dockerfile FROM base images (node:22-slim, python:3.12-slim, nginx:1.31-alpine) — one entry per + # directory that holds a Dockerfile, since Dependabot scopes docker updates per directory. + - package-ecosystem: docker + directory: /services/converter + schedule: { interval: weekly } + open-pull-requests-limit: 3 + - package-ecosystem: docker + directory: /services/api + schedule: { interval: weekly } + open-pull-requests-limit: 3 + - package-ecosystem: docker + directory: /apps/web + schedule: { interval: weekly } + open-pull-requests-limit: 3 From f9c57acdc668345950b0574051fedb11fda39921 Mon Sep 17 00:00:00 2001 From: Perplexity Computer Date: Wed, 22 Jul 2026 14:27:25 +0000 Subject: [PATCH 10/10] fix(ci): make Cargo.lock sync guard non-fragile (cargo metadata --locked) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR5's lock-sync check ran 'cargo generate-lockfile' + 'git diff --exit-code', which re-resolves to the latest registry patches and fails on unrelated transitive drift (e.g. winnow 1.0.3->1.0.4, syn 2.0.118->2.0.119, thiserror 2.0.18->2.0.19, zmij 1.0.21->1.0.23) rather than a real Cargo.toml/Cargo.lock mismatch — so clippy+fmt failed on PR #69. Replace with 'cargo metadata --locked', which validates the committed lock against Cargo.toml WITHOUT upgrading transitive deps, and use 'git ls-files --error-unmatch' for the committed-file check. 'cargo clippy --locked' (also from PR5) already enforces true consistency at build time. --- .github/workflows/desktop.yml | 8 ++++---- .github/workflows/rust-ci.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml index 9e380807..2bbcc48b 100644 --- a/.github/workflows/desktop.yml +++ b/.github/workflows/desktop.yml @@ -113,12 +113,12 @@ jobs: # A stale/missing Cargo.lock has broken tagged desktop releases before (cargo silently # re-resolved transitive deps). Fail the release build loudly if the committed lock is out # of sync with Cargo.toml instead of letting it drift at build time. - - name: Verify Cargo.lock is in sync (release build honors the committed lock) + - name: Verify Cargo.lock is committed and consistent (release build honors the committed lock) working-directory: apps/web/src-tauri run: | - test -f Cargo.lock || { echo "Cargo.lock missing — run the 'Generate Cargo.lock' workflow"; exit 1; } - cargo generate-lockfile - git diff --exit-code Cargo.lock || { echo "Cargo.lock out of sync — regenerate (cargo generate-lockfile in apps/web/src-tauri) and commit before releasing"; exit 1; } + git ls-files --error-unmatch Cargo.lock >/dev/null || { echo "Cargo.lock is not committed — run the 'Generate Cargo.lock' workflow"; exit 1; } + # --locked validates the committed lock against Cargo.toml WITHOUT upgrading transitive patches + cargo metadata --locked --format-version 1 >/dev/null || { echo "Cargo.lock out of sync — run 'cargo generate-lockfile' in apps/web/src-tauri and commit before releasing"; exit 1; } # npm workspace: install at the root so the web build (beforeBuildCommand) has its deps - name: Install web dependencies diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index acf634cb..7b6bf034 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -53,11 +53,11 @@ jobs: chmod +x "binaries/aec-bim-server-${triple}" echo "stubbed binaries/aec-bim-server-${triple}" - - name: Verify Cargo.lock is committed and in sync + - name: Verify Cargo.lock is committed and consistent run: | - test -f Cargo.lock || { echo "Cargo.lock missing — run the 'Generate Cargo.lock' workflow"; exit 1; } - cargo generate-lockfile - git diff --exit-code Cargo.lock || { echo "Cargo.lock is out of sync with Cargo.toml — regenerate (cargo generate-lockfile here) and commit"; exit 1; } + git ls-files --error-unmatch Cargo.lock >/dev/null || { echo "Cargo.lock is not committed — run the 'Generate Cargo.lock' workflow"; exit 1; } + # --locked validates the committed lock against Cargo.toml WITHOUT upgrading transitive patches + cargo metadata --locked --format-version 1 >/dev/null || { echo "Cargo.lock is out of sync with Cargo.toml — run 'cargo generate-lockfile' here and commit"; exit 1; } - name: Format check run: cargo fmt --all -- --check