From 58fd8897ff9ebc2c16d94aaee4414e345eafd48a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:07 -0500 Subject: [PATCH 01/31] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 (#71) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.1.3 to 4.1.4. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Commits](https://github.com/go-jose/go-jose/compare/v4.1.3...v4.1.4) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-version: 4.1.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: Sam Carson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 47cb33c0..92c9f0fb 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect diff --git a/go.sum b/go.sum index 0513935b..b4d52ae4 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug= github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= github.com/go-chi/cors v1.2.2/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= From 01846f1ef61f854cef805de77b94265b174f6f8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:09 -0500 Subject: [PATCH 02/31] chore(deps): bump defu from 6.1.4 to 6.1.6 in /web (#72) Bumps [defu](https://github.com/unjs/defu) from 6.1.4 to 6.1.6. - [Release notes](https://github.com/unjs/defu/releases) - [Changelog](https://github.com/unjs/defu/blob/main/CHANGELOG.md) - [Commits](https://github.com/unjs/defu/compare/v6.1.4...v6.1.6) --- updated-dependencies: - dependency-name: defu dependency-version: 6.1.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: Sam Carson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index f19ade1e..cf74f7d9 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -4146,9 +4146,9 @@ } }, "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.6.tgz", + "integrity": "sha512-f8mefEW4WIVg4LckePx3mALjQSPQgFlg9U8yaPdlsbdYcHQyj9n2zL2LJEA52smeYxOvmd/nB7TpMtHGMTHcug==", "license": "MIT" }, "node_modules/detect-libc": { From 0b9e46eb6725b673aed1ccaa4170911ba967a633 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:11 -0500 Subject: [PATCH 03/31] chore(deps): bump picomatch in /web (#66) Bumps and [picomatch](https://github.com/micromatch/picomatch). These dependencies needed to be updated together. Updates `picomatch` from 4.0.3 to 4.0.4 - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4) Updates `picomatch` from 2.3.1 to 2.3.2 - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4) --- updated-dependencies: - dependency-name: picomatch dependency-version: 4.0.4 dependency-type: indirect - dependency-name: picomatch dependency-version: 2.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: Sam Carson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 54 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index cf74f7d9..8ba2e441 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -3420,9 +3420,9 @@ } }, "node_modules/@vue/language-core/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -5823,9 +5823,9 @@ } }, "node_modules/npm-run-all2/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -6145,9 +6145,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -6845,9 +6845,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" @@ -7082,9 +7082,9 @@ } }, "node_modules/unplugin-utils/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" @@ -7094,9 +7094,9 @@ } }, "node_modules/unplugin/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" @@ -7390,9 +7390,9 @@ } }, "node_modules/vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" @@ -7484,9 +7484,9 @@ } }, "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -7647,9 +7647,9 @@ "license": "MIT" }, "node_modules/vue-router/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" From 10ec5976e59e7e317fe02f5caf1443ee78cd39df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:14 -0500 Subject: [PATCH 04/31] chore(deps): bump github.com/danielgtaylor/huma/v2 from 2.37.2 to 2.37.3 (#69) Bumps [github.com/danielgtaylor/huma/v2](https://github.com/danielgtaylor/huma) from 2.37.2 to 2.37.3. - [Release notes](https://github.com/danielgtaylor/huma/releases) - [Commits](https://github.com/danielgtaylor/huma/compare/v2.37.2...v2.37.3) --- updated-dependencies: - dependency-name: github.com/danielgtaylor/huma/v2 dependency-version: 2.37.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 92c9f0fb..c4bc095c 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/caarlos0/env/v11 v11.4.0 github.com/coreos/go-oidc/v3 v3.17.0 github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 - github.com/danielgtaylor/huma/v2 v2.37.2 + github.com/danielgtaylor/huma/v2 v2.37.3 github.com/docker/docker v28.5.2+incompatible github.com/doyensec/safeurl v0.2.2 github.com/go-chi/chi/v5 v5.2.5 diff --git a/go.sum b/go.sum index b4d52ae4..cb658f16 100644 --- a/go.sum +++ b/go.sum @@ -45,8 +45,8 @@ github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= -github.com/danielgtaylor/huma/v2 v2.37.2 h1:Nf9vjy2sxBJFaupPlthXL/Hy2+LurfVbaKHmCMEI7xE= -github.com/danielgtaylor/huma/v2 v2.37.2/go.mod h1:95S04G/lExFRYlBkKaBaZm9lVmxRmqX9f2CgoOZ11AM= +github.com/danielgtaylor/huma/v2 v2.37.3 h1:6Av0Vj45Vk5lDxRVfoO2iPlEdvCvwLc7pl5nbqGOkYM= +github.com/danielgtaylor/huma/v2 v2.37.3/go.mod h1:OeHHtCEAaNiuVbAVdYu4IQ0UOmnb4x3yMUOShNlZ53g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= From efcbd6ba87c242eb8ad006a7eee3f85a60be762a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:16 -0500 Subject: [PATCH 05/31] chore(deps): bump google.golang.org/genai from 1.50.0 to 1.52.0 (#70) Bumps [google.golang.org/genai](https://github.com/googleapis/go-genai) from 1.50.0 to 1.52.0. - [Release notes](https://github.com/googleapis/go-genai/releases) - [Changelog](https://github.com/googleapis/go-genai/blob/v1.52.0/CHANGELOG.md) - [Commits](https://github.com/googleapis/go-genai/compare/v1.50.0...v1.52.0) --- updated-dependencies: - dependency-name: google.golang.org/genai dependency-version: 1.52.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c4bc095c..71638b64 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/crypto v0.49.0 golang.org/x/oauth2 v0.36.0 golang.org/x/time v0.15.0 - google.golang.org/genai v1.50.0 + google.golang.org/genai v1.52.0 ) require ( diff --git a/go.sum b/go.sum index cb658f16..bb58561c 100644 --- a/go.sum +++ b/go.sum @@ -276,8 +276,8 @@ golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genai v1.50.0 h1:yHKV/vjoeN9PJ3iF0ur4cBZco4N3Kl7j09rMq7XSoWk= -google.golang.org/genai v1.50.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= +google.golang.org/genai v1.52.0 h1:ekVIxWHtLUNbt+v0WWi4j3JT4yrHDEbysMcHQcaCQoI= +google.golang.org/genai v1.52.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= From b0cbca4af59755acf8dd73fda2116755c2a471ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:18 -0500 Subject: [PATCH 06/31] chore(deps): bump github.com/lib/pq from 1.11.2 to 1.12.0 (#60) Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.11.2 to 1.12.0. - [Release notes](https://github.com/lib/pq/releases) - [Changelog](https://github.com/lib/pq/blob/master/CHANGELOG.md) - [Commits](https://github.com/lib/pq/compare/v1.11.2...v1.12.0) --- updated-dependencies: - dependency-name: github.com/lib/pq dependency-version: 1.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 71638b64..65183b83 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/golang-migrate/migrate/v4 v4.19.1 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.8.0 - github.com/lib/pq v1.11.2 + github.com/lib/pq v1.12.0 github.com/pquerna/otp v1.5.0 github.com/prometheus/client_golang v1.23.2 github.com/sony/gobreaker/v2 v2.4.0 diff --git a/go.sum b/go.sum index bb58561c..1c7e8958 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,8 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= -github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo= +github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= From 52fda94d20a28b2aaf3535b3cb50da555d926fb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:20 -0500 Subject: [PATCH 07/31] chore(deps): bump actions/setup-go from 6.3.0 to 6.4.0 (#68) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/4b73464bb391d4059bd26b0524d20df3927bd417...4a3601121dd01d1626a1e23e37211e3254c1c06c) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa49104a..05305be4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: "1.26" cache: true @@ -52,7 +52,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: "1.26" cache: true @@ -90,7 +90,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: "1.26" cache: true @@ -110,7 +110,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: "1.26" cache: true @@ -144,7 +144,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: "1.26" cache: true @@ -220,7 +220,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: "1.26" cache: true From 96c199e6acf24fc87c1afa74ccd6667ec3e1759c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:22 -0500 Subject: [PATCH 08/31] chore(deps): bump @tailwindcss/vite from 4.2.1 to 4.2.2 in /web (#65) Bumps [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) from 4.2.1 to 4.2.2. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.2/packages/@tailwindcss-vite) --- updated-dependencies: - dependency-name: "@tailwindcss/vite" dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 228 +++++++++++++++++++++--------------------- web/package.json | 2 +- 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 8ba2e441..dd985832 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,7 +8,7 @@ "name": "web", "version": "0.0.0", "dependencies": { - "@tailwindcss/vite": "^4.2.1", + "@tailwindcss/vite": "^4.2.2", "@tanstack/vue-table": "^8.21.3", "@vueuse/core": "^14.2.1", "class-variance-authority": "^0.7.1", @@ -2301,47 +2301,47 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", + "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.31.1", + "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" + "tailwindcss": "4.2.2" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz", + "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==", "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + "@tailwindcss/oxide-android-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-x64": "4.2.2", + "@tailwindcss/oxide-freebsd-x64": "4.2.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-x64-musl": "4.2.2", + "@tailwindcss/oxide-wasm32-wasi": "4.2.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz", + "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==", "cpu": [ "arm64" ], @@ -2355,9 +2355,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz", + "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==", "cpu": [ "arm64" ], @@ -2371,9 +2371,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz", + "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==", "cpu": [ "x64" ], @@ -2387,9 +2387,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz", + "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==", "cpu": [ "x64" ], @@ -2403,9 +2403,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz", + "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==", "cpu": [ "arm" ], @@ -2419,9 +2419,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz", + "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==", "cpu": [ "arm64" ], @@ -2435,9 +2435,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz", + "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==", "cpu": [ "arm64" ], @@ -2451,9 +2451,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz", + "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==", "cpu": [ "x64" ], @@ -2467,9 +2467,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz", + "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==", "cpu": [ "x64" ], @@ -2483,9 +2483,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz", + "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -2570,9 +2570,9 @@ "optional": true }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz", + "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==", "cpu": [ "arm64" ], @@ -2586,9 +2586,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz", + "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==", "cpu": [ "x64" ], @@ -2602,17 +2602,17 @@ } }, "node_modules/@tailwindcss/vite": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz", + "integrity": "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==", "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "tailwindcss": "4.2.1" + "@tailwindcss/node": "4.2.2", + "@tailwindcss/oxide": "4.2.2", + "tailwindcss": "4.2.2" }, "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "node_modules/@tanstack/table-core": { @@ -5282,9 +5282,9 @@ } }, "node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -5297,23 +5297,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], @@ -5331,9 +5331,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -5351,9 +5351,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], @@ -5371,9 +5371,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], @@ -5391,9 +5391,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], @@ -5411,9 +5411,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], @@ -5431,9 +5431,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], @@ -5451,9 +5451,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], @@ -5471,9 +5471,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], @@ -5491,9 +5491,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], @@ -5511,9 +5511,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], @@ -6776,9 +6776,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", - "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", + "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", "license": "MIT" }, "node_modules/tapable": { diff --git a/web/package.json b/web/package.json index 04710f80..b7fdb028 100644 --- a/web/package.json +++ b/web/package.json @@ -17,7 +17,7 @@ "generate-api": "openapi-typescript ../openapi.json -o src/lib/api/schema.d.ts" }, "dependencies": { - "@tailwindcss/vite": "^4.2.1", + "@tailwindcss/vite": "^4.2.2", "@tanstack/vue-table": "^8.21.3", "@vueuse/core": "^14.2.1", "class-variance-authority": "^0.7.1", From 62a7ecc786f8af0d5f71242fad59780ff9595bf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:24 -0500 Subject: [PATCH 09/31] chore(deps): bump yaml from 2.8.2 to 2.8.3 in /web (#67) Bumps [yaml](https://github.com/eemeli/yaml) from 2.8.2 to 2.8.3. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](https://github.com/eemeli/yaml/compare/v2.8.2...v2.8.3) --- updated-dependencies: - dependency-name: yaml dependency-version: 2.8.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: Sam Carson Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index dd985832..a2e4c9a9 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -7933,9 +7933,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "license": "ISC", "bin": { "yaml": "bin.mjs" From 7995dcf29adabc403d3163403a483699f9dc75aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:26 -0500 Subject: [PATCH 10/31] chore(deps): bump vue-router from 5.0.3 to 5.0.4 in /web (#63) Bumps [vue-router](https://github.com/vuejs/router) from 5.0.3 to 5.0.4. - [Release notes](https://github.com/vuejs/router/releases) - [Commits](https://github.com/vuejs/router/compare/v5.0.3...v5.0.4) --- updated-dependencies: - dependency-name: vue-router dependency-version: 5.0.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 8 ++++---- web/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index a2e4c9a9..056bcd48 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -20,7 +20,7 @@ "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", "vue": "^3.5.30", - "vue-router": "^5.0.3", + "vue-router": "^5.0.4", "vue-sonner": "^2.0.9" }, "devDependencies": { @@ -7569,9 +7569,9 @@ } }, "node_modules/vue-router": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.3.tgz", - "integrity": "sha512-nG1c7aAFac7NYj8Hluo68WyWfc41xkEjaR0ViLHCa3oDvTQ/nIuLJlXJX1NUPw/DXzx/8+OKMng045HHQKQKWw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.4.tgz", + "integrity": "sha512-lCqDLCI2+fKVRl2OzXuzdSWmxXFLQRxQbmHugnRpTMyYiT+hNaycV0faqG5FBHDXoYrZ6MQcX87BvbY8mQ20Bg==", "license": "MIT", "dependencies": { "@babel/generator": "^7.28.6", diff --git a/web/package.json b/web/package.json index b7fdb028..e9cb3deb 100644 --- a/web/package.json +++ b/web/package.json @@ -29,7 +29,7 @@ "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", "vue": "^3.5.30", - "vue-router": "^5.0.3", + "vue-router": "^5.0.4", "vue-sonner": "^2.0.9" }, "devDependencies": { From 403257e12b5198476a806106d34ee31801a4c7e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:28 -0500 Subject: [PATCH 11/31] chore(deps-dev): bump eslint from 10.0.3 to 10.1.0 in /web (#64) Bumps [eslint](https://github.com/eslint/eslint) from 10.0.3 to 10.1.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.0.3...v10.1.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 12 ++++++------ web/package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 056bcd48..51242852 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -31,7 +31,7 @@ "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.9.0", - "eslint": "^10.0.2", + "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.56.0", "eslint-plugin-vue": "~10.8.0", @@ -4340,16 +4340,16 @@ } }, "node_modules/eslint": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.3.tgz", - "integrity": "sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.1.0.tgz", + "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.3", - "@eslint/config-helpers": "^0.5.2", + "@eslint/config-helpers": "^0.5.3", "@eslint/core": "^1.1.1", "@eslint/plugin-kit": "^0.6.1", "@humanfs/node": "^0.16.6", @@ -4362,7 +4362,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.2", "eslint-visitor-keys": "^5.0.1", - "espree": "^11.1.1", + "espree": "^11.2.0", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", diff --git a/web/package.json b/web/package.json index e9cb3deb..ae0c9e08 100644 --- a/web/package.json +++ b/web/package.json @@ -40,7 +40,7 @@ "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.9.0", - "eslint": "^10.0.2", + "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.56.0", "eslint-plugin-vue": "~10.8.0", From abc07e311d5dd4937f8c668b3832b45c9eca516d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:29 -0500 Subject: [PATCH 12/31] chore(deps-dev): bump @vitest/eslint-plugin in /web (#62) Bumps [@vitest/eslint-plugin](https://github.com/vitest-dev/eslint-plugin-vitest) from 1.6.12 to 1.6.13. - [Release notes](https://github.com/vitest-dev/eslint-plugin-vitest/releases) - [Commits](https://github.com/vitest-dev/eslint-plugin-vitest/compare/v1.6.12...v1.6.13) --- updated-dependencies: - dependency-name: "@vitest/eslint-plugin" dependency-version: 1.6.13 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 12 ++++++++---- web/package.json | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 51242852..d31ddfb4 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -27,7 +27,7 @@ "@tsconfig/node24": "^24.0.4", "@types/node": "^24.11.0", "@vitejs/plugin-vue": "^6.0.4", - "@vitest/eslint-plugin": "^1.6.10", + "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.9.0", @@ -2995,9 +2995,9 @@ } }, "node_modules/@vitest/eslint-plugin": { - "version": "1.6.12", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.12.tgz", - "integrity": "sha512-4kI47BJNFE+EQ5bmPbHzBF+ibNzx2Fj0Jo9xhWsTPxMddlHwIWl6YAxagefh461hrwx/W0QwBZpxGS404kBXyg==", + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.13.tgz", + "integrity": "sha512-ui7JGWBoQpS5NKKW0FDb1eTuFEZ5EupEv2Psemuyfba7DfA5K52SeDLelt6P4pQJJ/4UGkker/BgMk/KrjH3WQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3008,11 +3008,15 @@ "node": ">=18" }, "peerDependencies": { + "@typescript-eslint/eslint-plugin": "*", "eslint": ">=8.57.0", "typescript": ">=5.0.0", "vitest": "*" }, "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, "typescript": { "optional": true }, diff --git a/web/package.json b/web/package.json index ae0c9e08..1eafb81a 100644 --- a/web/package.json +++ b/web/package.json @@ -36,7 +36,7 @@ "@tsconfig/node24": "^24.0.4", "@types/node": "^24.11.0", "@vitejs/plugin-vue": "^6.0.4", - "@vitest/eslint-plugin": "^1.6.10", + "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.9.0", From c7611ca45f53b5c041051961bea225d791a97176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:32:50 -0500 Subject: [PATCH 13/31] chore(deps): bump github.com/jackc/pgx/v5 from 5.8.0 to 5.9.1 (#59) Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.8.0 to 5.9.1. - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.8.0...v5.9.1) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-version: 5.9.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 65183b83..d1af5cbc 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.1 github.com/golang-migrate/migrate/v4 v4.19.1 github.com/google/uuid v1.6.0 - github.com/jackc/pgx/v5 v5.8.0 + github.com/jackc/pgx/v5 v5.9.1 github.com/lib/pq v1.12.0 github.com/pquerna/otp v1.5.0 github.com/prometheus/client_golang v1.23.2 diff --git a/go.sum b/go.sum index 1c7e8958..6da185c1 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo= -github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw= +github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc= +github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jhillyerd/inbucket v2.0.0+incompatible h1:gTmxV077ktqV4ZbFjB/0rjiTrdsKQGXWUqYKWjoNIrE= From 1bab411aec2bc636d72a32fa658d06962c2774b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:49:39 -0500 Subject: [PATCH 14/31] chore(deps-dev): bump vite from 7.3.1 to 8.0.1 in /web (#61) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 8.0.1. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/create-vite@8.0.1/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 1092 +++++++++++------------------------------ web/package.json | 2 +- 2 files changed, 299 insertions(+), 795 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index d31ddfb4..92fc0f13 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -43,7 +43,7 @@ "prettier": "3.8.1", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", - "vite": "^7.3.1", + "vite": "^8.0.3", "vite-plugin-vue-devtools": "^8.0.6", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" @@ -760,420 +760,38 @@ "node": ">=20.19.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", - "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", - "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", - "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", - "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", - "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", - "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", - "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", - "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", - "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", - "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", - "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", - "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", - "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", - "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", - "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", - "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", - "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", - "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", - "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", - "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", - "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", - "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", - "cpu": [ - "arm64" - ], + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "license": "MIT", "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", - "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", - "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", - "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", - "cpu": [ - "ia32" - ], + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "license": "MIT", "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "peer": true, + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", - "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", - "cpu": [ - "x64" - ], + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "license": "MIT", "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "peer": true, + "dependencies": { + "tslib": "^2.4.0" } }, "node_modules/@eslint-community/eslint-utils": { @@ -1483,6 +1101,24 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", + "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1528,6 +1164,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@oxc-project/types": { + "version": "0.122.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", + "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@oxlint/binding-android-arm-eabi": { "version": "1.56.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.56.0.tgz", @@ -1952,30 +1597,10 @@ "node": ">=10" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz", - "integrity": "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", "cpu": [ "arm64" ], @@ -1983,194 +1608,127 @@ "optional": true, "os": [ "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "cpu": [ - "arm64" ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", "cpu": [ - "loong64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", "cpu": [ - "loong64" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", + "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", "cpu": [ - "ppc64" + "arm" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", "cpu": [ - "ppc64" + "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", "cpu": [ - "riscv64" + "arm64" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", "cpu": [ - "riscv64" + "ppc64" ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", "cpu": [ "s390x" ], @@ -2178,12 +1736,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", "cpu": [ "x64" ], @@ -2191,12 +1752,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", "cpu": [ "x64" ], @@ -2204,25 +1768,15 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", - "cpu": [ - "x64" ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", "cpu": [ "arm64" ], @@ -2230,51 +1784,47 @@ "optional": true, "os": [ "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", - "cpu": [ - "arm64" ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", + "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", "cpu": [ - "ia32" + "wasm32" ], "license": "MIT", "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, + "engines": { + "node": ">=14.0.0" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", "cpu": [ "x64" ], @@ -2282,7 +1832,17 @@ "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz", + "integrity": "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==", + "dev": true, + "license": "MIT" }, "node_modules/@standard-schema/spec": { "version": "1.1.0", @@ -2680,6 +2240,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -2709,6 +2279,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { @@ -4279,47 +3850,6 @@ "dev": true, "license": "MIT" }, - "node_modules/esbuild": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", - "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.4", - "@esbuild/android-arm": "0.27.4", - "@esbuild/android-arm64": "0.27.4", - "@esbuild/android-x64": "0.27.4", - "@esbuild/darwin-arm64": "0.27.4", - "@esbuild/darwin-x64": "0.27.4", - "@esbuild/freebsd-arm64": "0.27.4", - "@esbuild/freebsd-x64": "0.27.4", - "@esbuild/linux-arm": "0.27.4", - "@esbuild/linux-arm64": "0.27.4", - "@esbuild/linux-ia32": "0.27.4", - "@esbuild/linux-loong64": "0.27.4", - "@esbuild/linux-mips64el": "0.27.4", - "@esbuild/linux-ppc64": "0.27.4", - "@esbuild/linux-riscv64": "0.27.4", - "@esbuild/linux-s390x": "0.27.4", - "@esbuild/linux-x64": "0.27.4", - "@esbuild/netbsd-arm64": "0.27.4", - "@esbuild/netbsd-x64": "0.27.4", - "@esbuild/openbsd-arm64": "0.27.4", - "@esbuild/openbsd-x64": "0.27.4", - "@esbuild/openharmony-arm64": "0.27.4", - "@esbuild/sunos-x64": "0.27.4", - "@esbuild/win32-arm64": "0.27.4", - "@esbuild/win32-ia32": "0.27.4", - "@esbuild/win32-x64": "0.27.4" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6417,49 +5947,44 @@ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, - "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "node_modules/rolldown": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", + "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" + "@oxc-project/types": "=0.122.0", + "@rolldown/pluginutils": "1.0.0-rc.12" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", - "fsevents": "~2.3.2" - } + "@rolldown/binding-android-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-x64": "1.0.0-rc.12", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", + "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", + "license": "MIT" }, "node_modules/run-applescript": { "version": "7.1.0", @@ -7165,16 +6690,15 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", + "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "bin": { @@ -7191,9 +6715,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -7206,13 +6731,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -7238,37 +6766,55 @@ } } }, - "node_modules/vite-dev-rpc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", - "integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", + "node_modules/vite-plugin-vue-devtools": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.1.0.tgz", + "integrity": "sha512-4AvNRePfni3+PqOunACmAImC6SJVpUv6f7/g4oakyre9hYdEMrvDYlNmTZQsJPzVLMcGzn1FvSEqJ/n4HQ9cDg==", "dev": true, "license": "MIT", "dependencies": { - "birpc": "^2.4.0", - "vite-hot-client": "^2.1.0" + "@vue/devtools-core": "^8.1.0", + "@vue/devtools-kit": "^8.1.0", + "@vue/devtools-shared": "^8.1.0", + "sirv": "^3.0.2", + "vite-plugin-inspect": "^11.3.3", + "vite-plugin-vue-inspector": "^5.3.2" }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "engines": { + "node": ">=v14.21.3" }, "peerDependencies": { - "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/vite-hot-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.1.0.tgz", - "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", + "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-kit": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.0.tgz", + "integrity": "sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" + "dependencies": { + "@vue/devtools-shared": "^8.1.0", + "birpc": "^2.6.1", + "hookable": "^5.5.3", + "perfect-debounce": "^2.0.0" } }, - "node_modules/vite-plugin-inspect": { + "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-shared": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.0.tgz", + "integrity": "sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-plugin-vue-devtools/node_modules/perfect-debounce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect": { "version": "11.3.3", "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.3.3.tgz", "integrity": "sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==", @@ -7300,61 +6846,36 @@ } } }, - "node_modules/vite-plugin-inspect/node_modules/perfect-debounce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", - "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite-plugin-vue-devtools": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.1.0.tgz", - "integrity": "sha512-4AvNRePfni3+PqOunACmAImC6SJVpUv6f7/g4oakyre9hYdEMrvDYlNmTZQsJPzVLMcGzn1FvSEqJ/n4HQ9cDg==", + "node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect/node_modules/vite-dev-rpc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", + "integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", "dev": true, "license": "MIT", "dependencies": { - "@vue/devtools-core": "^8.1.0", - "@vue/devtools-kit": "^8.1.0", - "@vue/devtools-shared": "^8.1.0", - "sirv": "^3.0.2", - "vite-plugin-inspect": "^11.3.3", - "vite-plugin-vue-inspector": "^5.3.2" + "birpc": "^2.4.0", + "vite-hot-client": "^2.1.0" }, - "engines": { - "node": ">=v14.21.3" + "funding": { + "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" } }, - "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-kit": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.0.tgz", - "integrity": "sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==", + "node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect/node_modules/vite-dev-rpc/node_modules/vite-hot-client": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.1.0.tgz", + "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", "dev": true, "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^8.1.0", - "birpc": "^2.6.1", - "hookable": "^5.5.3", - "perfect-debounce": "^2.0.0" + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" } }, - "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-shared": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.0.tgz", - "integrity": "sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite-plugin-vue-devtools/node_modules/perfect-debounce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", - "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", - "dev": true, - "license": "MIT" - }, "node_modules/vite-plugin-vue-inspector": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.4.0.tgz", @@ -7376,23 +6897,6 @@ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/vite/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/vite/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", diff --git a/web/package.json b/web/package.json index 1eafb81a..1b39cf4e 100644 --- a/web/package.json +++ b/web/package.json @@ -52,7 +52,7 @@ "prettier": "3.8.1", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", - "vite": "^7.3.1", + "vite": "^8.0.3", "vite-plugin-vue-devtools": "^8.0.6", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" From b6eb60debcb603196c50a8e6a78f8f8bc1301166 Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Sun, 5 Apr 2026 17:53:46 -0500 Subject: [PATCH 15/31] chore(deps): remove vite-plugin-vue-devtools (no Vite 8 support) The plugin's transitive dep vite-plugin-inspect doesn't support Vite 8 yet (vuejs/devtools#1071). It was installed but never registered in vite.config.ts. The Vue DevTools browser extension provides equivalent functionality. Re-add when upstream updates the peer dep range. Co-Authored-By: Claude Opus 4.6 (1M context) --- web/package-lock.json | 1010 ----------------------------------------- web/package.json | 3 +- 2 files changed, 1 insertion(+), 1012 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 92fc0f13..77c60743 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -44,7 +44,6 @@ "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", "vite": "^8.0.3", - "vite-plugin-vue-devtools": "^8.0.6", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" }, @@ -128,57 +127,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", @@ -195,199 +143,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", - "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", - "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -406,30 +161,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/parser": { "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", @@ -445,155 +176,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.0.tgz", - "integrity": "sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/plugin-syntax-decorators": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.28.6.tgz", - "integrity": "sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", - "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", - "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.6", - "@babel/helper-plugin-utils": "^7.28.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/types": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", @@ -1507,13 +1089,6 @@ "node": ">=14" } }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "dev": true, - "license": "MIT" - }, "node_modules/@redocly/ajv": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", @@ -2775,59 +2350,6 @@ } } }, - "node_modules/@vue/babel-helper-vue-transform-on": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz", - "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vue/babel-plugin-jsx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz", - "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.2", - "@vue/babel-helper-vue-transform-on": "1.5.0", - "@vue/babel-plugin-resolve-type": "1.5.0", - "@vue/shared": "^3.5.18" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - } - } - }, - "node_modules/@vue/babel-plugin-resolve-type": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz", - "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/parser": "^7.28.0", - "@vue/compiler-sfc": "^3.5.18" - }, - "funding": { - "url": "https://github.com/sponsors/sxzz" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@vue/compiler-core": { "version": "3.5.30", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz", @@ -2887,47 +2409,6 @@ "@vue/devtools-kit": "^7.7.9" } }, - "node_modules/@vue/devtools-core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-8.1.0.tgz", - "integrity": "sha512-LvD1VgDpoHmYL00IgKRLKktF6SsPAb0yaV8wB8q2jRwsAWvqhS8+vsMLEGKNs7uoKyymXhT92dhxgf/wir6YGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^8.1.0", - "@vue/devtools-shared": "^8.1.0" - }, - "peerDependencies": { - "vue": "^3.0.0" - } - }, - "node_modules/@vue/devtools-core/node_modules/@vue/devtools-kit": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.0.tgz", - "integrity": "sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^8.1.0", - "birpc": "^2.6.1", - "hookable": "^5.5.3", - "perfect-debounce": "^2.0.0" - } - }, - "node_modules/@vue/devtools-core/node_modules/@vue/devtools-shared": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.0.tgz", - "integrity": "sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vue/devtools-core/node_modules/perfect-debounce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", - "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", - "dev": true, - "license": "MIT" - }, "node_modules/@vue/devtools-kit": { "version": "7.7.9", "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", @@ -3227,16 +2708,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ansis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", - "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3308,19 +2779,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.8", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz", - "integrity": "sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/bidi-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", @@ -3373,77 +2831,6 @@ "node": ">=8" } }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001780", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001780.tgz", - "integrity": "sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", @@ -3677,49 +3064,6 @@ "dev": true, "license": "MIT" }, - "node_modules/default-browser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", - "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", - "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/defu": { "version": "6.1.6", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.6.tgz", @@ -3794,13 +3138,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.313", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", - "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", - "dev": true, - "license": "ISC" - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -3833,16 +3170,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/error-stack-parser-es": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", - "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", @@ -3850,16 +3177,6 @@ "dev": true, "license": "MIT" }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -4287,16 +3604,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -4444,22 +3751,6 @@ "dev": true, "license": "ISC" }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4493,25 +3784,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4541,22 +3813,6 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/is-wsl": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", - "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4794,13 +4050,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "dev": true, - "license": "MIT" - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5238,16 +4487,6 @@ "pathe": "^2.0.1" } }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -5286,13 +4525,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-releases": { - "version": "2.0.36", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", - "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", - "dev": true, - "license": "MIT" - }, "node_modules/nopt": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", @@ -5415,25 +4647,6 @@ "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", "license": "MIT" }, - "node_modules/open": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "wsl-utils": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/openapi-fetch": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.17.0.tgz", @@ -5986,19 +5199,6 @@ "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", "license": "MIT" }, - "node_modules/run-applescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6111,21 +5311,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/sirv": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", - "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -6428,16 +5613,6 @@ "node": ">=8.0" } }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/tough-cookie": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", @@ -6634,37 +5809,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -6766,137 +5910,6 @@ } } }, - "node_modules/vite-plugin-vue-devtools": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.1.0.tgz", - "integrity": "sha512-4AvNRePfni3+PqOunACmAImC6SJVpUv6f7/g4oakyre9hYdEMrvDYlNmTZQsJPzVLMcGzn1FvSEqJ/n4HQ9cDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-core": "^8.1.0", - "@vue/devtools-kit": "^8.1.0", - "@vue/devtools-shared": "^8.1.0", - "sirv": "^3.0.2", - "vite-plugin-inspect": "^11.3.3", - "vite-plugin-vue-inspector": "^5.3.2" - }, - "engines": { - "node": ">=v14.21.3" - }, - "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-kit": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.0.tgz", - "integrity": "sha512-/NZlS4WtGIB54DA/z10gzk+n/V7zaqSzYZOVlg2CfdnpIKdB61bd7JDIMxf/zrtX41zod8E2/bbEBoW/d7x70Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^8.1.0", - "birpc": "^2.6.1", - "hookable": "^5.5.3", - "perfect-debounce": "^2.0.0" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/@vue/devtools-shared": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.0.tgz", - "integrity": "sha512-h8uCb4Qs8UT8VdTT5yjY6tOJ//qH7EpxToixR0xqejR55t5OdISIg7AJ7eBkhBs8iu1qG5gY3QQNN1DF1EelAA==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite-plugin-vue-devtools/node_modules/perfect-debounce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz", - "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.3.3.tgz", - "integrity": "sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansis": "^4.1.0", - "debug": "^4.4.1", - "error-stack-parser-es": "^1.0.5", - "ohash": "^2.0.11", - "open": "^10.2.0", - "perfect-debounce": "^2.0.0", - "sirv": "^3.0.1", - "unplugin-utils": "^0.3.0", - "vite-dev-rpc": "^1.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0-0" - }, - "peerDependenciesMeta": { - "@nuxt/kit": { - "optional": true - } - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect/node_modules/vite-dev-rpc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-1.1.0.tgz", - "integrity": "sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==", - "dev": true, - "license": "MIT", - "dependencies": { - "birpc": "^2.4.0", - "vite-hot-client": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0" - } - }, - "node_modules/vite-plugin-vue-devtools/node_modules/vite-plugin-inspect/node_modules/vite-dev-rpc/node_modules/vite-hot-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.1.0.tgz", - "integrity": "sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" - } - }, - "node_modules/vite-plugin-vue-inspector": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.4.0.tgz", - "integrity": "sha512-Iq/024CydcE46FZqWPU4t4lw4uYOdLnFSO1RNxJVt2qY9zxIjmnkBqhHnYaReWM82kmNnaXs7OkfgRrV2GEjyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.23.0", - "@babel/plugin-proposal-decorators": "^7.23.0", - "@babel/plugin-syntax-import-attributes": "^7.22.5", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-transform-typescript": "^7.22.15", - "@vue/babel-plugin-jsx": "^1.1.5", - "@vue/compiler-dom": "^3.3.4", - "kolorist": "^1.8.0", - "magic-string": "^0.30.4" - }, - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, "node_modules/vite/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -7400,22 +6413,6 @@ "node": ">=8" } }, - "node_modules/wsl-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -7433,13 +6430,6 @@ "dev": true, "license": "MIT" }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, "node_modules/yaml": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", diff --git a/web/package.json b/web/package.json index 1b39cf4e..a9ed1e29 100644 --- a/web/package.json +++ b/web/package.json @@ -53,8 +53,7 @@ "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", "vite": "^8.0.3", - "vite-plugin-vue-devtools": "^8.0.6", - "vitest": "^4.0.18", +"vitest": "^4.0.18", "vue-tsc": "^3.2.5" }, "engines": { From 866ab4ab4becd032e6d8f9cedef90791e4685aec Mon Sep 17 00:00:00 2001 From: Sam Carson Date: Wed, 8 Apr 2026 00:21:58 -0500 Subject: [PATCH 16/31] feat(crypto): bind GCM ciphertext to entity context via AAD (#83) Add Additional Authenticated Data (AAD) to AES-256-GCM encrypt/decrypt, preventing ciphertext relocation between database rows. SSO client secrets are bound to org_id, MFA TOTP secrets to user_id, and the doctor encryption sentinel to a fixed label. Also adds dev/specs/sso-secret-storage.md documenting the full encryption architecture for external sharing. Co-authored-by: Claude Opus 4.6 (1M context) --- cmd/cvert-ops/rotate.go | 13 +-- cmd/cvert-ops/rotate_test.go | 8 +- dev/specs/sso-secret-storage.md | 93 +++++++++++++++++++++ internal/api/auth_mfa.go | 8 +- internal/api/auth_mfa_test.go | 2 +- internal/api/oauth_oidc.go | 2 +- internal/api/sso.go | 4 +- internal/crypto/aes.go | 24 +++--- internal/crypto/aes_test.go | 140 +++++++++++++++++++++++++++----- internal/doctor/checks.go | 8 +- 10 files changed, 248 insertions(+), 54 deletions(-) create mode 100644 dev/specs/sso-secret-storage.md diff --git a/cmd/cvert-ops/rotate.go b/cmd/cvert-ops/rotate.go index 6eefecbf..e1153858 100644 --- a/cmd/cvert-ops/rotate.go +++ b/cmd/cvert-ops/rotate.go @@ -100,21 +100,22 @@ func rotateEncryptionKeys(ctx context.Context, pool *pgxpool.Pool, currentKey, p return 0, fmt.Errorf("set bypass_rls: %w", err) } - rows, err := tx.Query(ctx, "SELECT id, client_secret_enc FROM sso_connections") + rows, err := tx.Query(ctx, "SELECT id, org_id, client_secret_enc FROM sso_connections") if err != nil { return 0, fmt.Errorf("query sso_connections: %w", err) } defer rows.Close() type pending struct { - id string - enc []byte + id string + orgID [16]byte + enc []byte } var updates []pending for rows.Next() { var p pending - if err := rows.Scan(&p.id, &p.enc); err != nil { + if err := rows.Scan(&p.id, &p.orgID, &p.enc); err != nil { return 0, fmt.Errorf("scan row: %w", err) } updates = append(updates, p) @@ -125,12 +126,12 @@ func rotateEncryptionKeys(ctx context.Context, pool *pgxpool.Pool, currentKey, p count := 0 for _, u := range updates { - plaintext, err := crypto.DecryptWithFallback(currentKey, previousKey, u.enc) + plaintext, err := crypto.DecryptWithFallback(currentKey, previousKey, u.enc, u.orgID[:]) if err != nil { return 0, fmt.Errorf("decrypt row %s: %w", u.id, err) } - newEnc, err := crypto.Encrypt(currentKey, plaintext) + newEnc, err := crypto.Encrypt(currentKey, plaintext, u.orgID[:]) if err != nil { return 0, fmt.Errorf("re-encrypt row %s: %w", u.id, err) } diff --git a/cmd/cvert-ops/rotate_test.go b/cmd/cvert-ops/rotate_test.go index fc9acd0d..b851a37c 100644 --- a/cmd/cvert-ops/rotate_test.go +++ b/cmd/cvert-ops/rotate_test.go @@ -29,9 +29,9 @@ func TestRotateEncryptionKey_ReEncryptsAllValues(t *testing.T) { } orgID := org.ID - // Encrypt a secret with the old key. + // Encrypt a secret with the old key, bound to the org. secret := []byte("my-client-secret") - enc, err := crypto.Encrypt(oldKey, secret) + enc, err := crypto.Encrypt(oldKey, secret, orgID[:]) if err != nil { t.Fatalf("encrypt with old key: %v", err) } @@ -64,7 +64,7 @@ func TestRotateEncryptionKey_ReEncryptsAllValues(t *testing.T) { t.Fatalf("read re-encrypted value: %v", err) } - plaintext, err := crypto.Decrypt(newKey, reEncrypted) + plaintext, err := crypto.Decrypt(newKey, reEncrypted, orgID[:]) if err != nil { t.Fatalf("decrypt with new key failed: %v", err) } @@ -73,7 +73,7 @@ func TestRotateEncryptionKey_ReEncryptsAllValues(t *testing.T) { } // Verify old key alone no longer works. - _, err = crypto.Decrypt(oldKey, reEncrypted) + _, err = crypto.Decrypt(oldKey, reEncrypted, orgID[:]) if err == nil { t.Error("decrypt with old key should fail on re-encrypted data, but succeeded") } diff --git a/dev/specs/sso-secret-storage.md b/dev/specs/sso-secret-storage.md new file mode 100644 index 00000000..06692346 --- /dev/null +++ b/dev/specs/sso-secret-storage.md @@ -0,0 +1,93 @@ +# SSO Secret Storage Architecture + +This document describes how CVErt Ops stores and manages user-provided secrets (specifically, OAuth/OIDC client secrets for enterprise SSO connections) in the production/SaaS configuration. + +## What's Encrypted + +The **only** user-input secret encrypted at rest in the database is `sso_connections.client_secret_enc` — the OIDC client secret that tenants provide when configuring enterprise SSO. It is stored as `BYTEA` in Postgres (migration `000028_sso_connections.up.sql`). + +## Encryption Scheme + +**AES-256-GCM** with random 12-byte nonces, implemented in `internal/crypto/aes.go`. + +- **Ciphertext format:** `nonce (12 bytes) || ciphertext + GCM authentication tag` +- **Nonce source:** `crypto/rand.Reader` (OS CSPRNG) +- **Library:** Go stdlib `crypto/aes` and `crypto/cipher` — no external crypto dependencies + +AES-256-GCM provides both confidentiality and integrity (authenticated encryption). An attacker who obtains a database dump cannot read or tamper with the client secrets without also possessing the encryption key. + +## Key Sourcing + +The encryption key is a raw 32-byte value provided as 64 hex characters via: + +1. **Startup:** The `SSO_ENCRYPTION_KEY` environment variable, parsed by `internal/config/reloadable.go` +2. **Hot-reload:** A secrets file (one `KEY=VALUE` per line) can be reloaded at runtime via `SIGHUP` signal or the admin API reload endpoint. The key is swapped atomically using `atomic.Pointer` in `config.Holder`, so in-flight requests are never disrupted + +The API handler reads the active key via `srv.ssoEncryptionKey()` in `internal/api/sso.go`, which prefers the hot-reloadable config, falling back to the startup config value. + +## Key Rotation + +Key rotation uses a **dual-key** strategy with zero downtime: + +1. **Operator** generates a new 32-byte key (`openssl rand -hex 32`) +2. **Operator** moves the current `SSO_ENCRYPTION_KEY` value to `SSO_ENCRYPTION_KEY_PREVIOUS` and sets the new key as `SSO_ENCRYPTION_KEY` in the secrets file +3. **Operator** reloads config (SIGHUP or admin API) +4. **During the transition window**, all decryption uses `crypto.DecryptWithFallback()` — tries the current key first, then falls back to the previous key on GCM authentication failure. Structural errors (truncated ciphertext, invalid key length) fail fast without attempting fallback +5. **Operator** runs `cvert-ops rotate-encryption-key`, which re-encrypts every `sso_connections.client_secret_enc` row in a single Postgres transaction: decrypt with fallback, re-encrypt with current key +6. **After re-encryption succeeds**, the operator removes `SSO_ENCRYPTION_KEY_PREVIOUS` and reloads config + +The re-encryption command is transactional — if it fails partway through, the transaction rolls back and all rows remain encrypted with the original key. Safe to retry. + +The full step-by-step procedure is documented in `docs/deployment/runbooks/secret-rotation.md`. + +## Security Boundaries and Assumptions + +| Boundary | Status | +|----------|--------| +| **Encryption at rest** | AES-256-GCM. Protects against database dump or backup theft | +| **Tenant isolation** | Row-Level Security (RLS) on `sso_connections` + `org_id` scoping. One tenant cannot read another's encrypted secret | +| **Key storage** | The encryption key lives in an environment variable or secrets file on the host. There is no KMS or HSM wrapping — compromise of the application server's environment means compromise of the key | +| **Memory exposure** | The key is held in process memory as a `[32]byte`. Standard Go runtime — no `mlock` or secure memory wipe. Acceptable for non-HSM deployments | +| **Rotation atomicity** | The `rotate-encryption-key` command runs in a single DB transaction. Failure leaves all rows encrypted with the old key (safe to retry) | +| **No envelope encryption** | There is no KMS-wrapped DEK/KEK split. `SSO_ENCRYPTION_KEY` is the data encryption key directly. Key rotation therefore requires re-encrypting every row (currently only `sso_connections`, so the blast radius is small) | + +### Deployment expectation + +The security model assumes that the deployment environment adequately protects the `SSO_ENCRYPTION_KEY` value. In practice this means: + +- **Container deployments:** Use the platform's native secret injection (Kubernetes Secrets, Docker Swarm secrets, ECS task definition secrets, etc.) +- **Cloud VMs:** Use a cloud secret manager (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) to inject the value into the environment at startup +- **Self-hosted:** Ensure the secrets file has restrictive file permissions and is excluded from backups and version control + +If CVErt Ops later needs to support a managed SaaS model where the operator controls infrastructure, the natural upgrade path would be envelope encryption with a cloud KMS wrapping the SSO encryption key. + +## What's NOT Encrypted at Rest + +These values are **not** stored in the database — they live only in environment variables or the secrets file: + +- OAuth provider secrets (`GITHUB_CLIENT_SECRET`, `GOOGLE_CLIENT_SECRET`) — app-level config, not tenant-provided +- JWT signing secrets (`JWT_SECRET`, `JWT_SECRET_PREVIOUS`) +- SMTP credentials (`SMTP_PASSWORD`) + +These values are stored in the database but use **hashing, not encryption** (correct approach — they never need to be recovered in plaintext): + +- User passwords — argon2id +- API key hashes + +## Key Files + +| File | Role | +|------|------| +| `internal/crypto/aes.go` | AES-256-GCM Encrypt / Decrypt / DecryptWithFallback | +| `internal/config/reloadable.go` | Hot-reloadable config with atomic key swap | +| `internal/api/sso.go` | SSO handler — encrypts on write, decrypts on read | +| `cmd/cvert-ops/rotate.go` | CLI re-encryption command | +| `migrations/000028_sso_connections.up.sql` | Schema with `client_secret_enc BYTEA` column + RLS | +| `internal/store/queries/sso.sql` | sqlc queries (encrypted column passed as opaque bytes) | +| `docs/deployment/runbooks/secret-rotation.md` | Operator-facing rotation procedures | + +## Dependencies + +- **Go stdlib crypto** (`crypto/aes`, `crypto/cipher`, `crypto/rand`) — no third-party crypto libraries +- **pgx** for the rotation transaction +- **Operator-managed key** — no external secrets manager SDK dependency diff --git a/internal/api/auth_mfa.go b/internal/api/auth_mfa.go index 401590b1..0ff86a11 100644 --- a/internal/api/auth_mfa.go +++ b/internal/api/auth_mfa.go @@ -374,7 +374,7 @@ func (srv *Server) verifyTOTP(ctx context.Context, userID uuid.UUID, code string return false, fmt.Errorf("encryption key: %w", err) } prevKey := srv.ssoEncryptionKeyPrevious() - secretBytes, err := crypto.DecryptWithFallback(encKey, prevKey, cred.SecretEnc) + secretBytes, err := crypto.DecryptWithFallback(encKey, prevKey, cred.SecretEnc, userID[:]) if err != nil { return false, fmt.Errorf("decrypt TOTP secret: %w", err) } @@ -580,7 +580,7 @@ func (srv *Server) mfaTOTPSetupHandler(ctx context.Context, input *mfaTOTPSetupI slog.ErrorContext(ctx, "totp-setup: encryption key", "error", err) return nil, huma.Error500InternalServerError("encryption key not configured") } - secretEnc, err := crypto.Encrypt(encKey, []byte(key.Secret())) + secretEnc, err := crypto.Encrypt(encKey, []byte(key.Secret()), userID[:]) if err != nil { slog.ErrorContext(ctx, "totp-setup: encrypt secret", "error", err) return nil, huma.Error500InternalServerError("internal error") @@ -645,7 +645,7 @@ func (srv *Server) mfaTOTPConfirmHandler(ctx context.Context, input *mfaTOTPConf return nil, huma.Error500InternalServerError("internal error") } prevKey := srv.ssoEncryptionKeyPrevious() - secretBytes, err := crypto.DecryptWithFallback(encKey, prevKey, enrollClaims.SecretEnc) + secretBytes, err := crypto.DecryptWithFallback(encKey, prevKey, enrollClaims.SecretEnc, userID[:]) if err != nil { slog.ErrorContext(ctx, "totp-confirm: decrypt secret", "error", err) return nil, huma.Error500InternalServerError("internal error") @@ -677,7 +677,7 @@ func (srv *Server) mfaTOTPConfirmHandler(ctx context.Context, input *mfaTOTPConf // Re-encrypt secret for DB storage (enrollment cookie used same key, but // re-encrypt to get a fresh nonce for defense in depth). - secretEncDB, err := crypto.Encrypt(encKey, secretBytes) + secretEncDB, err := crypto.Encrypt(encKey, secretBytes, userID[:]) if err != nil { slog.ErrorContext(ctx, "totp-confirm: re-encrypt secret", "error", err) return nil, huma.Error500InternalServerError("internal error") diff --git a/internal/api/auth_mfa_test.go b/internal/api/auth_mfa_test.go index 0fa9b817..f4531871 100644 --- a/internal/api/auth_mfa_test.go +++ b/internal/api/auth_mfa_test.go @@ -55,7 +55,7 @@ func enrollTOTP(t *testing.T, ctx context.Context, srv *Server, userID uuid.UUID if err != nil { t.Fatalf("enrollTOTP: encryption key: %v", err) } - secretEnc, err := crypto.Encrypt(encKey, []byte(secret)) + secretEnc, err := crypto.Encrypt(encKey, []byte(secret), userID[:]) if err != nil { t.Fatalf("enrollTOTP: encrypt: %v", err) } diff --git a/internal/api/oauth_oidc.go b/internal/api/oauth_oidc.go index 1b32e807..245764a0 100644 --- a/internal/api/oauth_oidc.go +++ b/internal/api/oauth_oidc.go @@ -53,7 +53,7 @@ func (srv *Server) oidcBuildOAuthConfig(ctx context.Context, conn *store.SSOConn if err != nil { return nil, nil, fmt.Errorf("encryption key: %w", err) } - secret, err := crypto.DecryptWithFallback(key, srv.ssoEncryptionKeyPrevious(), conn.ClientSecretEnc) + secret, err := crypto.DecryptWithFallback(key, srv.ssoEncryptionKeyPrevious(), conn.ClientSecretEnc, conn.OrgID[:]) if err != nil { return nil, nil, fmt.Errorf("decrypt secret: %w", err) } diff --git a/internal/api/sso.go b/internal/api/sso.go index 7a5a657a..bc9af9ef 100644 --- a/internal/api/sso.go +++ b/internal/api/sso.go @@ -171,7 +171,7 @@ func (srv *Server) createSSOHandler(w http.ResponseWriter, r *http.Request) { writeProblem(w, http.StatusInternalServerError, "server configuration error") return } - encSecret, err := crypto.Encrypt(key, []byte(req.ClientSecret)) + encSecret, err := crypto.Encrypt(key, []byte(req.ClientSecret), orgID[:]) if err != nil { slog.ErrorContext(r.Context(), "sso create: encrypt secret", "error", err) writeProblem(w, http.StatusInternalServerError, "encryption error") @@ -347,7 +347,7 @@ func (srv *Server) patchSSOHandler(w http.ResponseWriter, r *http.Request) { writeProblem(w, http.StatusInternalServerError, "server configuration error") return } - secretEnc, err = crypto.Encrypt(key, []byte(*req.ClientSecret)) + secretEnc, err = crypto.Encrypt(key, []byte(*req.ClientSecret), orgID[:]) if err != nil { slog.ErrorContext(r.Context(), "sso patch: encrypt secret", "error", err) writeProblem(w, http.StatusInternalServerError, "encryption error") diff --git a/internal/crypto/aes.go b/internal/crypto/aes.go index 2d88fe65..97d801a8 100644 --- a/internal/crypto/aes.go +++ b/internal/crypto/aes.go @@ -15,9 +15,10 @@ import ( // authentication fails and previousKey is non-zero, it retries with // previousKey. This supports seamless encryption key rotation. // Structural errors (truncated ciphertext, invalid key) fail immediately -// without attempting fallback. -func DecryptWithFallback(currentKey, previousKey [32]byte, data []byte) ([]byte, error) { - plaintext, err := Decrypt(currentKey, data) +// without attempting fallback. The aad (additional authenticated data) is +// passed through to GCM and must match the value used during encryption. +func DecryptWithFallback(currentKey, previousKey [32]byte, data []byte, aad []byte) ([]byte, error) { + plaintext, err := Decrypt(currentKey, data, aad) if err == nil { return plaintext, nil } @@ -25,7 +26,7 @@ func DecryptWithFallback(currentKey, previousKey [32]byte, data []byte) ([]byte, // Only fall back on GCM authentication failure (wrong key). // Structural errors (truncated ciphertext, invalid key) fail fast. if previousKey != [32]byte{} && isGCMAuthError(err) { - plaintext, err2 := Decrypt(previousKey, data) + plaintext, err2 := Decrypt(previousKey, data, aad) if err2 == nil { return plaintext, nil } @@ -42,8 +43,10 @@ func isGCMAuthError(err error) bool { } // Encrypt encrypts plaintext using AES-256-GCM with a random nonce. -// Returns nonce || ciphertext. -func Encrypt(key [32]byte, plaintext []byte) ([]byte, error) { +// Returns nonce || ciphertext. The aad (additional authenticated data) is +// mixed into the GCM authentication tag, binding the ciphertext to a context +// (e.g., an org_id or user_id). Pass nil for context-free encryption. +func Encrypt(key [32]byte, plaintext []byte, aad []byte) ([]byte, error) { block, err := aes.NewCipher(key[:]) if err != nil { return nil, fmt.Errorf("aes new cipher: %w", err) @@ -60,12 +63,13 @@ func Encrypt(key [32]byte, plaintext []byte) ([]byte, error) { } // Seal appends ciphertext to nonce, so result is nonce || ciphertext. - return gcm.Seal(nonce, nonce, plaintext, nil), nil + return gcm.Seal(nonce, nonce, plaintext, aad), nil } // Decrypt decrypts AES-256-GCM ciphertext produced by Encrypt. -// Expects nonce (12 bytes) || ciphertext. -func Decrypt(key [32]byte, data []byte) ([]byte, error) { +// Expects nonce (12 bytes) || ciphertext. The aad must match the value +// used during encryption; a mismatch causes an authentication failure. +func Decrypt(key [32]byte, data []byte, aad []byte) ([]byte, error) { block, err := aes.NewCipher(key[:]) if err != nil { return nil, fmt.Errorf("aes new cipher: %w", err) @@ -82,7 +86,7 @@ func Decrypt(key [32]byte, data []byte) ([]byte, error) { } nonce, ciphertext := data[:nonceSize], data[nonceSize:] - plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) + plaintext, err := gcm.Open(nil, nonce, ciphertext, aad) if err != nil { return nil, fmt.Errorf("gcm decrypt: %w", err) } diff --git a/internal/crypto/aes_test.go b/internal/crypto/aes_test.go index 1c5acf1a..2537ce87 100644 --- a/internal/crypto/aes_test.go +++ b/internal/crypto/aes_test.go @@ -23,12 +23,12 @@ func TestAESGCM_RoundTrip(t *testing.T) { key := testKey(t) plaintext := []byte("secret webhook signing key 🔑") - ciphertext, err := Encrypt(key, plaintext) + ciphertext, err := Encrypt(key, plaintext, nil) if err != nil { t.Fatalf("Encrypt: %v", err) } - got, err := Decrypt(key, ciphertext) + got, err := Decrypt(key, ciphertext, nil) if err != nil { t.Fatalf("Decrypt: %v", err) } @@ -37,16 +37,73 @@ func TestAESGCM_RoundTrip(t *testing.T) { } } +func TestAESGCM_RoundTrip_WithAAD(t *testing.T) { + t.Parallel() + key := testKey(t) + plaintext := []byte("org-scoped secret") + aad := []byte("org-id-abc-123") + + ciphertext, err := Encrypt(key, plaintext, aad) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + got, err := Decrypt(key, ciphertext, aad) + if err != nil { + t.Fatalf("Decrypt: %v", err) + } + if !bytes.Equal(got, plaintext) { + t.Errorf("round-trip mismatch: got %q, want %q", got, plaintext) + } +} + +func TestAESGCM_AADMismatch_Rejected(t *testing.T) { + t.Parallel() + key := testKey(t) + plaintext := []byte("bound to org A") + aadA := []byte("org-A") + aadB := []byte("org-B") + + ciphertext, err := Encrypt(key, plaintext, aadA) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + // Decrypting with different AAD must fail (ciphertext relocation attack). + _, err = Decrypt(key, ciphertext, aadB) + if err == nil { + t.Error("Decrypt succeeded with wrong AAD, want authentication failure") + } +} + +func TestAESGCM_AADVsNilAAD_Rejected(t *testing.T) { + t.Parallel() + key := testKey(t) + plaintext := []byte("has AAD binding") + aad := []byte("some-context") + + ciphertext, err := Encrypt(key, plaintext, aad) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + // Encrypted with AAD, decrypted without — must fail. + _, err = Decrypt(key, ciphertext, nil) + if err == nil { + t.Error("Decrypt with nil AAD succeeded on AAD-encrypted data, want failure") + } +} + func TestAESGCM_UniqueNonce(t *testing.T) { t.Parallel() key := testKey(t) plaintext := []byte("same input") - ct1, err := Encrypt(key, plaintext) + ct1, err := Encrypt(key, plaintext, nil) if err != nil { t.Fatalf("Encrypt 1: %v", err) } - ct2, err := Encrypt(key, plaintext) + ct2, err := Encrypt(key, plaintext, nil) if err != nil { t.Fatalf("Encrypt 2: %v", err) } @@ -60,7 +117,7 @@ func TestAESGCM_TamperedCiphertext(t *testing.T) { t.Parallel() key := testKey(t) - ciphertext, err := Encrypt(key, []byte("tamper me")) + ciphertext, err := Encrypt(key, []byte("tamper me"), nil) if err != nil { t.Fatalf("Encrypt: %v", err) } @@ -70,7 +127,7 @@ func TestAESGCM_TamperedCiphertext(t *testing.T) { copy(tampered, ciphertext) tampered[len(tampered)-1] ^= 0xff - _, err = Decrypt(key, tampered) + _, err = Decrypt(key, tampered, nil) if err == nil { t.Error("Decrypt succeeded on tampered ciphertext, want error") } @@ -81,12 +138,12 @@ func TestAESGCM_WrongKey(t *testing.T) { key1 := testKey(t) key2 := testKey(t) - ciphertext, err := Encrypt(key1, []byte("wrong key test")) + ciphertext, err := Encrypt(key1, []byte("wrong key test"), nil) if err != nil { t.Fatalf("Encrypt: %v", err) } - _, err = Decrypt(key2, ciphertext) + _, err = Decrypt(key2, ciphertext, nil) if err == nil { t.Error("Decrypt succeeded with wrong key, want error") } @@ -96,12 +153,12 @@ func TestAESGCM_EmptyPlaintext(t *testing.T) { t.Parallel() key := testKey(t) - ciphertext, err := Encrypt(key, []byte{}) + ciphertext, err := Encrypt(key, []byte{}, nil) if err != nil { t.Fatalf("Encrypt empty: %v", err) } - got, err := Decrypt(key, ciphertext) + got, err := Decrypt(key, ciphertext, nil) if err != nil { t.Fatalf("Decrypt empty: %v", err) } @@ -116,7 +173,7 @@ func TestAESGCM_ShortCiphertext(t *testing.T) { // ciphertext too short to contain a nonce is rejected at runtime. key := testKey(t) - _, err := Decrypt(key, []byte("short")) + _, err := Decrypt(key, []byte("short"), nil) if err == nil { t.Error("Decrypt succeeded on too-short ciphertext, want error") } @@ -130,12 +187,12 @@ func TestDecryptWithFallback_CurrentKeyWorks(t *testing.T) { previousKey := testKey(t) plaintext := []byte("current key decryption") - ciphertext, err := Encrypt(currentKey, plaintext) + ciphertext, err := Encrypt(currentKey, plaintext, nil) if err != nil { t.Fatalf("Encrypt: %v", err) } - got, err := DecryptWithFallback(currentKey, previousKey, ciphertext) + got, err := DecryptWithFallback(currentKey, previousKey, ciphertext, nil) if err != nil { t.Fatalf("DecryptWithFallback: %v", err) } @@ -150,13 +207,13 @@ func TestDecryptWithFallback_PreviousKeyWorks(t *testing.T) { newKey := testKey(t) plaintext := []byte("encrypted with old key") - ciphertext, err := Encrypt(oldKey, plaintext) + ciphertext, err := Encrypt(oldKey, plaintext, nil) if err != nil { t.Fatalf("Encrypt: %v", err) } // newKey as current fails GCM auth; oldKey as previous succeeds. - got, err := DecryptWithFallback(newKey, oldKey, ciphertext) + got, err := DecryptWithFallback(newKey, oldKey, ciphertext, nil) if err != nil { t.Fatalf("DecryptWithFallback: %v", err) } @@ -172,12 +229,12 @@ func TestDecryptWithFallback_BothKeysWrong(t *testing.T) { keyC := testKey(t) plaintext := []byte("neither key works") - ciphertext, err := Encrypt(keyA, plaintext) + ciphertext, err := Encrypt(keyA, plaintext, nil) if err != nil { t.Fatalf("Encrypt: %v", err) } - _, err = DecryptWithFallback(keyB, keyC, ciphertext) + _, err = DecryptWithFallback(keyB, keyC, ciphertext, nil) if err == nil { t.Error("DecryptWithFallback succeeded with both wrong keys, want error") } @@ -189,13 +246,13 @@ func TestDecryptWithFallback_NoPreviousKey(t *testing.T) { var zeroKey [32]byte plaintext := []byte("no previous key") - ciphertext, err := Encrypt(currentKey, plaintext) + ciphertext, err := Encrypt(currentKey, plaintext, nil) if err != nil { t.Fatalf("Encrypt: %v", err) } // Zero previous key → only current key tried. - got, err := DecryptWithFallback(currentKey, zeroKey, ciphertext) + got, err := DecryptWithFallback(currentKey, zeroKey, ciphertext, nil) if err != nil { t.Fatalf("DecryptWithFallback: %v", err) } @@ -212,7 +269,7 @@ func TestDecryptWithFallback_TruncatedCiphertext_NoFallback(t *testing.T) { previousKey := [32]byte{2} shortData := []byte("short") - _, err := DecryptWithFallback(currentKey, previousKey, shortData) + _, err := DecryptWithFallback(currentKey, previousKey, shortData, nil) if err == nil { t.Fatal("DecryptWithFallback succeeded on truncated ciphertext, want error") } @@ -231,14 +288,53 @@ func TestDecryptWithFallback_NoPreviousKeyCurrentFails(t *testing.T) { keyB := testKey(t) var zeroKey [32]byte - ciphertext, err := Encrypt(keyA, []byte("no previous key fails")) + ciphertext, err := Encrypt(keyA, []byte("no previous key fails"), nil) if err != nil { t.Fatalf("Encrypt: %v", err) } // Wrong current key, zero previous → returns error without panic. - _, err = DecryptWithFallback(keyB, zeroKey, ciphertext) + _, err = DecryptWithFallback(keyB, zeroKey, ciphertext, nil) if err == nil { t.Error("DecryptWithFallback succeeded with wrong current and zero previous, want error") } } + +func TestDecryptWithFallback_WithAAD(t *testing.T) { + t.Parallel() + currentKey := testKey(t) + previousKey := testKey(t) + plaintext := []byte("aad-bound secret") + aad := []byte("org-id-bytes") + + ciphertext, err := Encrypt(currentKey, plaintext, aad) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + got, err := DecryptWithFallback(currentKey, previousKey, ciphertext, aad) + if err != nil { + t.Fatalf("DecryptWithFallback: %v", err) + } + if !bytes.Equal(got, plaintext) { + t.Errorf("plaintext mismatch: got %q, want %q", got, plaintext) + } +} + +func TestDecryptWithFallback_AADMismatch_Rejected(t *testing.T) { + t.Parallel() + currentKey := testKey(t) + var zeroKey [32]byte + plaintext := []byte("bound to org A") + + ciphertext, err := Encrypt(currentKey, plaintext, []byte("org-A")) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + // Correct key but wrong AAD must fail. + _, err = DecryptWithFallback(currentKey, zeroKey, ciphertext, []byte("org-B")) + if err == nil { + t.Error("DecryptWithFallback succeeded with wrong AAD, want error") + } +} diff --git a/internal/doctor/checks.go b/internal/doctor/checks.go index 4f2bbf57..5593812e 100644 --- a/internal/doctor/checks.go +++ b/internal/doctor/checks.go @@ -182,7 +182,7 @@ func (c *EncryptionSentinelCheck) Run(ctx context.Context) (string, string, erro return StatusFail, fmt.Sprintf("query system_settings: %v", err), nil } - _, err = crypto.DecryptWithFallback(c.Key, c.PreviousKey, value) + _, err = crypto.DecryptWithFallback(c.Key, c.PreviousKey, value, []byte("encryption_sentinel")) if err != nil { return StatusFail, fmt.Sprintf("sentinel decryption failed: %v — encryption key may have changed", err), nil } @@ -344,8 +344,8 @@ func (c *SecurityHeadersCheck) Run(ctx context.Context) (string, string, error) required := map[string]string{ "X-Content-Type-Options": "nosniff", - "X-Frame-Options": "DENY", - "Referrer-Policy": "strict-origin-when-cross-origin", + "X-Frame-Options": "DENY", + "Referrer-Policy": "strict-origin-when-cross-origin", } var missing []string @@ -444,7 +444,7 @@ type StandardChecksConfig struct { SMTPHost string SMTPPort int SMTPUsername string - CORSAllowedOrigins string + CORSAllowedOrigins string CookieAuth bool ServerAddr string // empty in CLI mode, "http://localhost:{port}" in API mode } From 922732c7f0e7818f1ed35ca215919af460ca7774 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 00:37:07 -0500 Subject: [PATCH 17/31] chore(deps): bump reka-ui from 2.9.2 to 2.9.3 in /web (#80) Bumps [reka-ui](https://github.com/unovue/reka-ui) from 2.9.2 to 2.9.3. - [Release notes](https://github.com/unovue/reka-ui/releases) - [Commits](https://github.com/unovue/reka-ui/compare/v2.9.2...v2.9.3) --- updated-dependencies: - dependency-name: reka-ui dependency-version: 2.9.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 8 ++++---- web/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 77c60743..d0de8667 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -16,7 +16,7 @@ "lucide-vue-next": "^0.577.0", "openapi-fetch": "^0.17.0", "pinia": "^3.0.4", - "reka-ui": "^2.9.1", + "reka-ui": "^2.9.3", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", "vue": "^3.5.30", @@ -5109,9 +5109,9 @@ } }, "node_modules/reka-ui": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.9.2.tgz", - "integrity": "sha512-/t4e6y1hcG+uDuRfpg6tbMz3uUEvRzNco6NeYTufoJeUghy5Iosxos5YL/p+ieAsid84sdMX9OrgDqpEuCJhBw==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.9.3.tgz", + "integrity": "sha512-C9lCVxsSC7uYD0Nbgik1+14FNndHNprZmf0zGQt0ZDYIt5KxXV3zD0hEqNcfRUsEEJvVmoRsUkJnASBVBeaaUw==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.6.13", diff --git a/web/package.json b/web/package.json index a9ed1e29..c96719e6 100644 --- a/web/package.json +++ b/web/package.json @@ -25,7 +25,7 @@ "lucide-vue-next": "^0.577.0", "openapi-fetch": "^0.17.0", "pinia": "^3.0.4", - "reka-ui": "^2.9.1", + "reka-ui": "^2.9.3", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", "vue": "^3.5.30", From 3e95c0e75e9da87831a17d55fcb20ac4b45c39da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 00:37:09 -0500 Subject: [PATCH 18/31] chore(deps): bump vue from 3.5.30 to 3.5.32 in /web (#79) Bumps [vue](https://github.com/vuejs/core) from 3.5.30 to 3.5.32. - [Release notes](https://github.com/vuejs/core/releases) - [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md) - [Commits](https://github.com/vuejs/core/compare/v3.5.30...v3.5.32) --- updated-dependencies: - dependency-name: vue dependency-version: 3.5.32 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 112 +++++++++++++++++++++--------------------- web/package.json | 2 +- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index d0de8667..74263a0e 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -19,7 +19,7 @@ "reka-ui": "^2.9.3", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", - "vue": "^3.5.30", + "vue": "^3.5.32", "vue-router": "^5.0.4", "vue-sonner": "^2.0.9" }, @@ -2351,39 +2351,39 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz", - "integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz", + "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", - "@vue/shared": "3.5.30", + "@babel/parser": "^7.29.2", + "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz", - "integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz", + "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.30", - "@vue/shared": "3.5.30" + "@vue/compiler-core": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz", - "integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz", + "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", - "@vue/compiler-core": "3.5.30", - "@vue/compiler-dom": "3.5.30", - "@vue/compiler-ssr": "3.5.30", - "@vue/shared": "3.5.30", + "@babel/parser": "^7.29.2", + "@vue/compiler-core": "3.5.32", + "@vue/compiler-dom": "3.5.32", + "@vue/compiler-ssr": "3.5.32", + "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", @@ -2391,13 +2391,13 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz", - "integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz", + "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.30", - "@vue/shared": "3.5.30" + "@vue/compiler-dom": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/devtools-api": { @@ -2489,53 +2489,53 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz", - "integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.32.tgz", + "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.30" + "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz", - "integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.32.tgz", + "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.30", - "@vue/shared": "3.5.30" + "@vue/reactivity": "3.5.32", + "@vue/shared": "3.5.32" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz", - "integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz", + "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.30", - "@vue/runtime-core": "3.5.30", - "@vue/shared": "3.5.30", + "@vue/reactivity": "3.5.32", + "@vue/runtime-core": "3.5.32", + "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz", - "integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.32.tgz", + "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.30", - "@vue/shared": "3.5.30" + "@vue/compiler-ssr": "3.5.32", + "@vue/shared": "3.5.32" }, "peerDependencies": { - "vue": "3.5.30" + "vue": "3.5.32" } }, "node_modules/@vue/shared": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz", - "integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.32.tgz", + "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==", "license": "MIT" }, "node_modules/@vue/test-utils": { @@ -6025,16 +6025,16 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz", - "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz", + "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.30", - "@vue/compiler-sfc": "3.5.30", - "@vue/runtime-dom": "3.5.30", - "@vue/server-renderer": "3.5.30", - "@vue/shared": "3.5.30" + "@vue/compiler-dom": "3.5.32", + "@vue/compiler-sfc": "3.5.32", + "@vue/runtime-dom": "3.5.32", + "@vue/server-renderer": "3.5.32", + "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" diff --git a/web/package.json b/web/package.json index c96719e6..a427f4dd 100644 --- a/web/package.json +++ b/web/package.json @@ -28,7 +28,7 @@ "reka-ui": "^2.9.3", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", - "vue": "^3.5.30", + "vue": "^3.5.32", "vue-router": "^5.0.4", "vue-sonner": "^2.0.9" }, From 64b104ca55681883f8ee36832667e3648546f37c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 00:37:11 -0500 Subject: [PATCH 19/31] chore(deps): bump github.com/lib/pq from 1.12.0 to 1.12.3 (#76) Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.12.0 to 1.12.3. - [Release notes](https://github.com/lib/pq/releases) - [Changelog](https://github.com/lib/pq/blob/master/CHANGELOG.md) - [Commits](https://github.com/lib/pq/compare/v1.12.0...v1.12.3) --- updated-dependencies: - dependency-name: github.com/lib/pq dependency-version: 1.12.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d1af5cbc..b7ac4075 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/golang-migrate/migrate/v4 v4.19.1 github.com/google/uuid v1.6.0 github.com/jackc/pgx/v5 v5.9.1 - github.com/lib/pq v1.12.0 + github.com/lib/pq v1.12.3 github.com/pquerna/otp v1.5.0 github.com/prometheus/client_golang v1.23.2 github.com/sony/gobreaker/v2 v2.4.0 diff --git a/go.sum b/go.sum index 6da185c1..aa8b0efc 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,8 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo= -github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= +github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= From cd8c4616873c6c4570ef0af58136a7cca8569cea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 00:37:25 -0500 Subject: [PATCH 20/31] chore(deps): bump google.golang.org/genai from 1.52.0 to 1.52.1 (#75) Bumps [google.golang.org/genai](https://github.com/googleapis/go-genai) from 1.52.0 to 1.52.1. - [Release notes](https://github.com/googleapis/go-genai/releases) - [Changelog](https://github.com/googleapis/go-genai/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/go-genai/compare/v1.52.0...v1.52.1) --- updated-dependencies: - dependency-name: google.golang.org/genai dependency-version: 1.52.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b7ac4075..003b55fa 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/crypto v0.49.0 golang.org/x/oauth2 v0.36.0 golang.org/x/time v0.15.0 - google.golang.org/genai v1.52.0 + google.golang.org/genai v1.52.1 ) require ( diff --git a/go.sum b/go.sum index aa8b0efc..16586b1b 100644 --- a/go.sum +++ b/go.sum @@ -276,8 +276,8 @@ golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genai v1.52.0 h1:ekVIxWHtLUNbt+v0WWi4j3JT4yrHDEbysMcHQcaCQoI= -google.golang.org/genai v1.52.0/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= +google.golang.org/genai v1.52.1 h1:dYoljKtLDXMiBdVaClSJ/ZPwZ7j1N0lGjMhwOKOQUlk= +google.golang.org/genai v1.52.1/go.mod h1:A3kkl0nyBjyFlNjgxIwKq70julKbIxpSxqKO5gw/gmk= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= From 5bc0df702581dbd7cd64d437c033280b035ca443 Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 04:21:08 -0500 Subject: [PATCH 21/31] chore(deps-dev): bump oxlint and eslint-plugin-oxlint to ~1.58.0 eslint-plugin-oxlint 1.58.0 adds a peerDependency on oxlint ~1.58.0, so both must be bumped together. Lint and tests verified. Closes #78. Co-Authored-By: Claude Opus 4.6 (1M context) --- web/package-lock.json | 173 +++++++++++++++++++++--------------------- web/package.json | 4 +- 2 files changed, 90 insertions(+), 87 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 74263a0e..fd6e1b12 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -33,13 +33,13 @@ "@vue/tsconfig": "^0.9.0", "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-oxlint": "~1.56.0", + "eslint-plugin-oxlint": "~1.58.0", "eslint-plugin-vue": "~10.8.0", "jiti": "^2.6.1", "jsdom": "^29.0.0", "npm-run-all2": "^8.0.4", "openapi-typescript": "^7.13.0", - "oxlint": "~1.56.0", + "oxlint": "~1.58.0", "prettier": "3.8.1", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", @@ -756,9 +756,9 @@ } }, "node_modules/@oxlint/binding-android-arm-eabi": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.56.0.tgz", - "integrity": "sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.58.0.tgz", + "integrity": "sha512-1T7UN3SsWWxpWyWGn1cT3ASNJOo+pI3eUkmEl7HgtowapcV8kslYpFQcYn431VuxghXakPNlbjRwhqmR37PFOg==", "cpu": [ "arm" ], @@ -773,9 +773,9 @@ } }, "node_modules/@oxlint/binding-android-arm64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.56.0.tgz", - "integrity": "sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.58.0.tgz", + "integrity": "sha512-GryzujxuiRv2YFF7bRy8mKcxlbuAN+euVUtGJt9KKbLT8JBUIosamVhcthLh+VEr6KE6cjeVMAQxKAzJcoN7dg==", "cpu": [ "arm64" ], @@ -790,9 +790,9 @@ } }, "node_modules/@oxlint/binding-darwin-arm64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.56.0.tgz", - "integrity": "sha512-ogmbdJysnw/D4bDcpf1sPLpFThZ48lYp4aKYm10Z/6Nh1SON6NtnNhTNOlhEY296tDFItsZUz+2tgcSYqh8Eyw==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.58.0.tgz", + "integrity": "sha512-7/bRSJIwl4GxeZL9rPZ11anNTyUO9epZrfEJH/ZMla3+/gbQ6xZixh9nOhsZ0QwsTW7/5J2A/fHbD1udC5DQQA==", "cpu": [ "arm64" ], @@ -807,9 +807,9 @@ } }, "node_modules/@oxlint/binding-darwin-x64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.56.0.tgz", - "integrity": "sha512-x8QE1h+RAtQ2g+3KPsP6Fk/tdz6zJQUv5c7fTrJxXV3GHOo+Ry5p/PsogU4U+iUZg0rj6hS+E4xi+mnwwlDCWQ==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.58.0.tgz", + "integrity": "sha512-EqdtJSiHweS2vfILNrpyJ6HUwpEq2g7+4Zx1FPi4hu3Hu7tC3znF6ufbXO8Ub2LD4mGgznjI7kSdku9NDD1Mkg==", "cpu": [ "x64" ], @@ -824,9 +824,9 @@ } }, "node_modules/@oxlint/binding-freebsd-x64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.56.0.tgz", - "integrity": "sha512-6G+WMZvwJpMvY7my+/SHEjb7BTk/PFbePqLpmVmUJRIsJMy/UlyYqjpuh0RCgYYkPLcnXm1rUM04kbTk8yS1Yg==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.58.0.tgz", + "integrity": "sha512-VQt5TH4M42mY20F545G637RKxV/yjwVtKk2vfXuazfReSIiuvWBnv+FVSvIV5fKVTJNjt3GSJibh6JecbhGdBw==", "cpu": [ "x64" ], @@ -841,9 +841,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-gnueabihf": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.56.0.tgz", - "integrity": "sha512-YYHBsk/sl7fYwQOok+6W5lBPeUEvisznV/HZD2IfZmF3Bns6cPC3Z0vCtSEOaAWTjYWN3jVsdu55jMxKlsdlhg==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.58.0.tgz", + "integrity": "sha512-fBYcj4ucwpAtjJT3oeBdFBYKvNyjRSK+cyuvBOTQjh0jvKp4yeA4S/D0IsCHus/VPaNG5L48qQkh+Vjy3HL2/Q==", "cpu": [ "arm" ], @@ -858,9 +858,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-musleabihf": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.56.0.tgz", - "integrity": "sha512-+AZK8rOUr78y8WT6XkDb04IbMRqauNV+vgT6f8ZLOH8wnpQ9i7Nol0XLxAu+Cq7Sb+J9wC0j6Km5hG8rj47/yQ==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.58.0.tgz", + "integrity": "sha512-0BeuFfwlUHlJ1xpEdSD1YO3vByEFGPg36uLjK1JgFaxFb4W6w17F8ET8sz5cheZ4+x5f2xzdnRrrWv83E3Yd8g==", "cpu": [ "arm" ], @@ -875,9 +875,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.56.0.tgz", - "integrity": "sha512-urse2SnugwJRojUkGSSeH2LPMaje5Q50yQtvtL9HFckiyeqXzoFwOAZqD5TR29R2lq7UHidfFDM9EGcchcbb8A==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.58.0.tgz", + "integrity": "sha512-TXlZgnPTlxrQzxG9ZXU7BNwx1Ilrr17P3GwZY0If2EzrinqRH3zXPc3HrRcBJgcsoZNMuNL5YivtkJYgp467UQ==", "cpu": [ "arm64" ], @@ -892,9 +892,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-musl": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.56.0.tgz", - "integrity": "sha512-rkTZkBfJ4TYLjansjSzL6mgZOdN5IvUnSq3oNJSLwBcNvy3dlgQtpHPrRxrCEbbcp7oQ6If0tkNaqfOsphYZ9g==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.58.0.tgz", + "integrity": "sha512-zSoYRo5dxHLcUx93Stl2hW3hSNjPt99O70eRVWt5A1zwJ+FPjeCCANCD2a9R4JbHsdcl11TIQOjyigcRVOH2mw==", "cpu": [ "arm64" ], @@ -909,9 +909,9 @@ } }, "node_modules/@oxlint/binding-linux-ppc64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.56.0.tgz", - "integrity": "sha512-uqL1kMH3u69/e1CH2EJhP3CP28jw2ExLsku4o8RVAZ7fySo9zOyI2fy9pVlTAp4voBLVgzndXi3SgtdyCTa2aA==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.58.0.tgz", + "integrity": "sha512-NQ0U/lqxH2/VxBYeAIvMNUK1y0a1bJ3ZicqkF2c6wfakbEciP9jvIE4yNzCFpZaqeIeRYaV7AVGqEO1yrfVPjA==", "cpu": [ "ppc64" ], @@ -926,9 +926,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.56.0.tgz", - "integrity": "sha512-j0CcMBOgV6KsRaBdsebIeiy7hCjEvq2KdEsiULf2LZqAq0v1M1lWjelhCV57LxsqaIGChXFuFJ0RiFrSRHPhSg==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.58.0.tgz", + "integrity": "sha512-X9J+kr3gIC9FT8GuZt0ekzpNUtkBVzMVU4KiKDSlocyQuEgi3gBbXYN8UkQiV77FTusLDPsovjo95YedHr+3yg==", "cpu": [ "riscv64" ], @@ -943,9 +943,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-musl": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.56.0.tgz", - "integrity": "sha512-7VDOiL8cDG3DQ/CY3yKjbV1c4YPvc4vH8qW09Vv+5ukq3l/Kcyr6XGCd5NvxUmxqDb2vjMpM+eW/4JrEEsUetA==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.58.0.tgz", + "integrity": "sha512-CDze3pi1OO3Wvb/QsXjmLEY4XPKGM6kIo82ssNOgmcl1IdndF9VSGAE38YLhADWmOac7fjqhBw82LozuUVxD0Q==", "cpu": [ "riscv64" ], @@ -960,9 +960,9 @@ } }, "node_modules/@oxlint/binding-linux-s390x-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.56.0.tgz", - "integrity": "sha512-JGRpX0M+ikD3WpwJ7vKcHKV6Kg0dT52BW2Eu2BupXotYeqGXBrbY+QPkAyKO6MNgKozyTNaRh3r7g+VWgyAQYQ==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.58.0.tgz", + "integrity": "sha512-b/89glbxFaEAcA6Uf1FvCNecBJEgcUTsV1quzrqXM/o4R1M4u+2KCVuyGCayN2UpsRWtGGLb+Ver0tBBpxaPog==", "cpu": [ "s390x" ], @@ -977,9 +977,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-gnu": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.56.0.tgz", - "integrity": "sha512-dNaICPvtmuxFP/VbqdofrLqdS3bM/AKJN3LMJD52si44ea7Be1cBk6NpfIahaysG9Uo+L98QKddU9CD5L8UHnQ==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.58.0.tgz", + "integrity": "sha512-0/yYpkq9VJFCEcuRlrViGj8pJUFFvNS4EkEREaN7CB1EcLXJIaVSSa5eCihwBGXtOZxhnblWgxks9juRdNQI7w==", "cpu": [ "x64" ], @@ -994,9 +994,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-musl": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.56.0.tgz", - "integrity": "sha512-pF1vOtM+GuXmbklM1hV8WMsn6tCNPvkUzklj/Ej98JhlanbmA2RB1BILgOpwSuCTRTIYx2MXssmEyQQ90QF5aA==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.58.0.tgz", + "integrity": "sha512-hr6FNvmcAXiH+JxSvaJ4SJ1HofkdqEElXICW9sm3/Rd5eC3t7kzvmLyRAB3NngKO2wzXRCAm4Z/mGWfrsS4X8w==", "cpu": [ "x64" ], @@ -1011,9 +1011,9 @@ } }, "node_modules/@oxlint/binding-openharmony-arm64": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.56.0.tgz", - "integrity": "sha512-bp8NQ4RE6fDIFLa4bdBiOA+TAvkNkg+rslR+AvvjlLTYXLy9/uKAYLQudaQouWihLD/hgkrXIKKzXi5IXOewwg==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.58.0.tgz", + "integrity": "sha512-R+O368VXgRql1K6Xar+FEo7NEwfo13EibPMoTv3sesYQedRXd6m30Dh/7lZMxnrQVFfeo4EOfYIP4FpcgWQNHg==", "cpu": [ "arm64" ], @@ -1028,9 +1028,9 @@ } }, "node_modules/@oxlint/binding-win32-arm64-msvc": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.56.0.tgz", - "integrity": "sha512-PxT4OJDfMOQBzo3OlzFb9gkoSD+n8qSBxyVq2wQSZIHFQYGEqIRTo9M0ZStvZm5fdhMqaVYpOnJvH2hUMEDk/g==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.58.0.tgz", + "integrity": "sha512-Q0FZiAY/3c4YRj4z3h9K1PgaByrifrfbBoODSeX7gy97UtB7pySPUQfC2B/GbxWU6k7CzQrRy5gME10PltLAFQ==", "cpu": [ "arm64" ], @@ -1045,9 +1045,9 @@ } }, "node_modules/@oxlint/binding-win32-ia32-msvc": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.56.0.tgz", - "integrity": "sha512-PTRy6sIEPqy2x8PTP1baBNReN/BNEFmde0L+mYeHmjXE1Vlcc9+I5nsqENsB2yAm5wLkzPoTNCMY/7AnabT4/A==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.58.0.tgz", + "integrity": "sha512-Y8FKBABrSPp9H0QkRLHDHOSUgM/309a3IvOVgPcVxYcX70wxJrk608CuTg7w+C6vEd724X5wJoNkBcGYfH7nNQ==", "cpu": [ "ia32" ], @@ -1062,9 +1062,9 @@ } }, "node_modules/@oxlint/binding-win32-x64-msvc": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.56.0.tgz", - "integrity": "sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.58.0.tgz", + "integrity": "sha512-bCn5rbiz5My+Bj7M09sDcnqW0QJyINRVxdZ65x1/Y2tGrMwherwK/lpk+HRQCKvXa8pcaQdF5KY5j54VGZLwNg==", "cpu": [ "x64" ], @@ -3263,13 +3263,16 @@ } }, "node_modules/eslint-plugin-oxlint": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-oxlint/-/eslint-plugin-oxlint-1.56.0.tgz", - "integrity": "sha512-s47/OjE4cfQ+CD4eA38g+5axvwuyswY5H6acCdVGIvowYuLVJ6zrR7N260XfVVLRuyjjPO9L77qNYwSbmRNyuw==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-oxlint/-/eslint-plugin-oxlint-1.58.0.tgz", + "integrity": "sha512-L3aZSg0x2fL0dXyOgoK8A1QUbnfGzXt6bX4AFD7Scauw6zVUBOZrES5eRTzLLGgeVg0el5lvqHGl1WFAGo14DA==", "dev": true, "license": "MIT", "dependencies": { "jsonc-parser": "^3.3.1" + }, + "peerDependencies": { + "oxlint": "~1.58.0" } }, "node_modules/eslint-plugin-vue": { @@ -4702,9 +4705,9 @@ } }, "node_modules/oxlint": { - "version": "1.56.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.56.0.tgz", - "integrity": "sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g==", + "version": "1.58.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.58.0.tgz", + "integrity": "sha512-t4s9leczDMqlvOSjnbCQe7gtoLkWgBGZ7sBdCJ9EOj5IXFSG/X7OAzK4yuH4iW+4cAYe8kLFbC8tuYMwWZm+Cg==", "dev": true, "license": "MIT", "bin": { @@ -4717,28 +4720,28 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxlint/binding-android-arm-eabi": "1.56.0", - "@oxlint/binding-android-arm64": "1.56.0", - "@oxlint/binding-darwin-arm64": "1.56.0", - "@oxlint/binding-darwin-x64": "1.56.0", - "@oxlint/binding-freebsd-x64": "1.56.0", - "@oxlint/binding-linux-arm-gnueabihf": "1.56.0", - "@oxlint/binding-linux-arm-musleabihf": "1.56.0", - "@oxlint/binding-linux-arm64-gnu": "1.56.0", - "@oxlint/binding-linux-arm64-musl": "1.56.0", - "@oxlint/binding-linux-ppc64-gnu": "1.56.0", - "@oxlint/binding-linux-riscv64-gnu": "1.56.0", - "@oxlint/binding-linux-riscv64-musl": "1.56.0", - "@oxlint/binding-linux-s390x-gnu": "1.56.0", - "@oxlint/binding-linux-x64-gnu": "1.56.0", - "@oxlint/binding-linux-x64-musl": "1.56.0", - "@oxlint/binding-openharmony-arm64": "1.56.0", - "@oxlint/binding-win32-arm64-msvc": "1.56.0", - "@oxlint/binding-win32-ia32-msvc": "1.56.0", - "@oxlint/binding-win32-x64-msvc": "1.56.0" + "@oxlint/binding-android-arm-eabi": "1.58.0", + "@oxlint/binding-android-arm64": "1.58.0", + "@oxlint/binding-darwin-arm64": "1.58.0", + "@oxlint/binding-darwin-x64": "1.58.0", + "@oxlint/binding-freebsd-x64": "1.58.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.58.0", + "@oxlint/binding-linux-arm-musleabihf": "1.58.0", + "@oxlint/binding-linux-arm64-gnu": "1.58.0", + "@oxlint/binding-linux-arm64-musl": "1.58.0", + "@oxlint/binding-linux-ppc64-gnu": "1.58.0", + "@oxlint/binding-linux-riscv64-gnu": "1.58.0", + "@oxlint/binding-linux-riscv64-musl": "1.58.0", + "@oxlint/binding-linux-s390x-gnu": "1.58.0", + "@oxlint/binding-linux-x64-gnu": "1.58.0", + "@oxlint/binding-linux-x64-musl": "1.58.0", + "@oxlint/binding-openharmony-arm64": "1.58.0", + "@oxlint/binding-win32-arm64-msvc": "1.58.0", + "@oxlint/binding-win32-ia32-msvc": "1.58.0", + "@oxlint/binding-win32-x64-msvc": "1.58.0" }, "peerDependencies": { - "oxlint-tsgolint": ">=0.15.0" + "oxlint-tsgolint": ">=0.18.0" }, "peerDependenciesMeta": { "oxlint-tsgolint": { diff --git a/web/package.json b/web/package.json index a427f4dd..868b198b 100644 --- a/web/package.json +++ b/web/package.json @@ -42,13 +42,13 @@ "@vue/tsconfig": "^0.9.0", "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-oxlint": "~1.56.0", + "eslint-plugin-oxlint": "~1.58.0", "eslint-plugin-vue": "~10.8.0", "jiti": "^2.6.1", "jsdom": "^29.0.0", "npm-run-all2": "^8.0.4", "openapi-typescript": "^7.13.0", - "oxlint": "~1.56.0", + "oxlint": "~1.58.0", "prettier": "3.8.1", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", From ea50feef6aa790c6492edc681c7f7db7d5793908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 04:38:05 -0500 Subject: [PATCH 22/31] chore(deps-dev): bump @types/node from 24.12.0 to 25.5.2 in /web (#77) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.12.0 to 25.5.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.5.2 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 16 ++++++++-------- web/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index fd6e1b12..8ee2d333 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -25,7 +25,7 @@ }, "devDependencies": { "@tsconfig/node24": "^24.0.4", - "@types/node": "^24.11.0", + "@types/node": "^25.5.2", "@vitejs/plugin-vue": "^6.0.4", "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", @@ -1865,13 +1865,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", - "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", + "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", "devOptional": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/web-bluetooth": { @@ -5752,9 +5752,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "devOptional": true, "license": "MIT" }, diff --git a/web/package.json b/web/package.json index 868b198b..227b78a3 100644 --- a/web/package.json +++ b/web/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "@tsconfig/node24": "^24.0.4", - "@types/node": "^24.11.0", + "@types/node": "^25.5.2", "@vitejs/plugin-vue": "^6.0.4", "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", From 6efb34b7ddd5a9a925cf136f0c5f35d4995f5841 Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 04:48:01 -0500 Subject: [PATCH 23/31] chore(deps): upgrade TypeScript 5.9 to 6.0 - Bump typescript from ~5.9.3 to ~6.0.2 - Bump @vue/tsconfig from ^0.9.0 to ^0.9.1 (adds TS6 peer support) - Remove deprecated baseUrl from tsconfig.json and tsconfig.app.json (TS6 resolves paths relative to the tsconfig file by default) Type-check, lint, and all 419 unit tests pass. Closes #81. Co-Authored-By: Claude Opus 4.6 (1M context) --- web/package-lock.json | 168 +++++++++++++++++++++--------------------- web/package.json | 4 +- web/tsconfig.app.json | 1 - web/tsconfig.json | 1 - 4 files changed, 86 insertions(+), 88 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index ec1b880d..4b576766 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -30,7 +30,7 @@ "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", - "@vue/tsconfig": "^0.9.0", + "@vue/tsconfig": "^0.9.1", "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.58.0", @@ -42,7 +42,7 @@ "oxlint": "~1.58.0", "prettier": "3.8.1", "tw-animate-css": "^1.4.0", - "typescript": "~5.9.3", + "typescript": "~6.0.2", "vite": "^8.0.5", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" @@ -1881,20 +1881,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.1.tgz", + "integrity": "sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/type-utils": "8.58.1", + "@typescript-eslint/utils": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1904,9 +1904,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.1", + "@typescript-eslint/parser": "^8.58.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -1920,16 +1920,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", - "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.1.tgz", + "integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3" }, "engines": { @@ -1941,18 +1941,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.1.tgz", + "integrity": "sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", + "@typescript-eslint/tsconfig-utils": "^8.58.1", + "@typescript-eslint/types": "^8.58.1", "debug": "^4.4.3" }, "engines": { @@ -1963,18 +1963,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.1.tgz", + "integrity": "sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1985,9 +1985,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.1.tgz", + "integrity": "sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==", "dev": true, "license": "MIT", "engines": { @@ -1998,21 +1998,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.1.tgz", + "integrity": "sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1", + "@typescript-eslint/utils": "8.58.1", "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2023,13 +2023,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.1.tgz", + "integrity": "sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==", "dev": true, "license": "MIT", "engines": { @@ -2041,21 +2041,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.1.tgz", + "integrity": "sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/project-service": "8.58.1", + "@typescript-eslint/tsconfig-utils": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/visitor-keys": "8.58.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2065,20 +2065,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.1.tgz", + "integrity": "sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "@typescript-eslint/scope-manager": "8.58.1", + "@typescript-eslint/types": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2089,17 +2089,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.1.tgz", + "integrity": "sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/types": "8.58.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2550,13 +2550,13 @@ } }, "node_modules/@vue/tsconfig": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.9.0.tgz", - "integrity": "sha512-RP+v9Cpbsk1ZVXltCHHkYBr7+624x6gcijJXVjIcsYk7JXqvIpRtMwU2ARLvWDhmy9ffdFYxhsfJnPztADBohQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.9.1.tgz", + "integrity": "sha512-buvjm+9NzLCJL29KY1j1991YYJ5e6275OiK+G4jtmfIb+z4POywbdm0wXusT9adVWqe0xqg70TbI7+mRx4uU9w==", "dev": true, "license": "MIT", "peerDependencies": { - "typescript": "5.x", + "typescript": ">= 5.8", "vue": "^3.4.0" }, "peerDependenciesMeta": { @@ -5643,9 +5643,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -5698,9 +5698,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -5712,16 +5712,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.1.tgz", - "integrity": "sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==", + "version": "8.58.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.58.1.tgz", + "integrity": "sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.57.1", - "@typescript-eslint/parser": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1" + "@typescript-eslint/eslint-plugin": "8.58.1", + "@typescript-eslint/parser": "8.58.1", + "@typescript-eslint/typescript-estree": "8.58.1", + "@typescript-eslint/utils": "8.58.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5732,7 +5732,7 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/ufo": { diff --git a/web/package.json b/web/package.json index 436ed838..c298260e 100644 --- a/web/package.json +++ b/web/package.json @@ -39,7 +39,7 @@ "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", - "@vue/tsconfig": "^0.9.0", + "@vue/tsconfig": "^0.9.1", "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.58.0", @@ -51,7 +51,7 @@ "oxlint": "~1.58.0", "prettier": "3.8.1", "tw-animate-css": "^1.4.0", - "typescript": "~5.9.3", + "typescript": "~6.0.2", "vite": "^8.0.5", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" diff --git a/web/tsconfig.app.json b/web/tsconfig.app.json index dccf2bd6..4be693aa 100644 --- a/web/tsconfig.app.json +++ b/web/tsconfig.app.json @@ -9,7 +9,6 @@ "noUncheckedIndexedAccess": true, // Path mapping for cleaner imports. - "baseUrl": ".", "paths": { "@/*": ["./src/*"] }, diff --git a/web/tsconfig.json b/web/tsconfig.json index 1702e9dd..a3e245f9 100644 --- a/web/tsconfig.json +++ b/web/tsconfig.json @@ -12,7 +12,6 @@ } ], "compilerOptions": { - "baseUrl": ".", "paths": { "@/*": ["./src/*"] } From 02c847457e51c9b710f63df1308fee40c54a750f Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 04:53:47 -0500 Subject: [PATCH 24/31] revert(deps): revert TypeScript 6 upgrade, keep baseUrl removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openapi-typescript@7.13.0 requires peer typescript ^5.x with no TS6 support yet. Revert typescript and @vue/tsconfig version bumps. Keep the baseUrl removal from tsconfig.json and tsconfig.app.json — paths resolve relative to the tsconfig file without it on TS 5.9 too, and this prepares for TS6 when the ecosystem catches up. Co-Authored-By: Claude Opus 4.6 (1M context) --- web/package-lock.json | 10 +++++----- web/package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 4b576766..370f0c6f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -30,7 +30,7 @@ "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", - "@vue/tsconfig": "^0.9.1", + "@vue/tsconfig": "^0.9.0", "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.58.0", @@ -42,7 +42,7 @@ "oxlint": "~1.58.0", "prettier": "3.8.1", "tw-animate-css": "^1.4.0", - "typescript": "~6.0.2", + "typescript": "~5.9.3", "vite": "^8.0.5", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" @@ -5698,9 +5698,9 @@ } }, "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", "bin": { diff --git a/web/package.json b/web/package.json index c298260e..436ed838 100644 --- a/web/package.json +++ b/web/package.json @@ -39,7 +39,7 @@ "@vitest/eslint-plugin": "^1.6.13", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", - "@vue/tsconfig": "^0.9.1", + "@vue/tsconfig": "^0.9.0", "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.58.0", @@ -51,7 +51,7 @@ "oxlint": "~1.58.0", "prettier": "3.8.1", "tw-animate-css": "^1.4.0", - "typescript": "~6.0.2", + "typescript": "~5.9.3", "vite": "^8.0.5", "vitest": "^4.0.18", "vue-tsc": "^3.2.5" From 1763dbb38774fb662b2b4bad5946c43db00b28c7 Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 04:56:10 -0500 Subject: [PATCH 25/31] chore(lint): disable require-mock-type-parameters rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New in oxlint 1.58.0 under the correctness category. Requires type parameters on all vi.fn() calls — a style preference, not a correctness issue. Disable rather than modifying 147 test call sites. Co-Authored-By: Claude Opus 4.6 (1M context) --- web/.oxlintrc.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/.oxlintrc.json b/web/.oxlintrc.json index 86b5cc27..8bfa41f8 100644 --- a/web/.oxlintrc.json +++ b/web/.oxlintrc.json @@ -6,5 +6,8 @@ }, "categories": { "correctness": "error" + }, + "rules": { + "vitest/require-mock-type-parameters": "off" } } From 26873dd5459a137c752dd98d3a3e92502e04e40e Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 04:56:44 -0500 Subject: [PATCH 26/31] Revert "chore(lint): disable require-mock-type-parameters rule" This reverts commit 1763dbb38774fb662b2b4bad5946c43db00b28c7. --- web/.oxlintrc.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/web/.oxlintrc.json b/web/.oxlintrc.json index 8bfa41f8..86b5cc27 100644 --- a/web/.oxlintrc.json +++ b/web/.oxlintrc.json @@ -6,8 +6,5 @@ }, "categories": { "correctness": "error" - }, - "rules": { - "vitest/require-mock-type-parameters": "off" } } From e85a60a014703c529d77c537b8a48a9a93816609 Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 05:01:45 -0500 Subject: [PATCH 27/31] fix(lint): add type parameters to all vi.fn() mock calls oxlint 1.58.0 enables require-mock-type-parameters under correctness. Untyped vi.fn() returns Mock<(...args: any[]) => any>, silently discarding type safety on mock arguments and return values. Add explicit type parameters to all 147 vi.fn() call sites across 28 test files. All tests pass (419/419). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/__tests__/AppSidebar.test.ts | 10 +-- .../cve/__tests__/CveResultsTable.test.ts | 9 +- .../cve/__tests__/CveSearchFilters.test.ts | 4 +- .../cve/__tests__/CveSourceComparison.test.ts | 8 +- .../settings/__tests__/GroupDialog.test.ts | 12 +-- .../__tests__/GroupMembersDialog.test.ts | 25 +++--- .../__tests__/InviteMemberDialog.test.ts | 17 ++-- .../watchlist/__tests__/AddItemDialog.test.ts | 16 ++-- .../__tests__/CreateWatchlistDialog.test.ts | 17 ++-- web/src/lib/api/__tests__/client.test.ts | 10 +-- web/src/router/__tests__/guards.test.ts | 4 +- web/src/stores/__tests__/auth.test.ts | 82 +++++++++++++---- web/src/views/__tests__/CreateOrgView.test.ts | 15 ++-- web/src/views/__tests__/CveDetailView.test.ts | 24 ++--- web/src/views/__tests__/CveSearchView.test.ts | 89 +++++++++++-------- .../views/__tests__/FeedStatusView.test.ts | 10 ++- .../__tests__/ForgotPasswordView.test.ts | 22 +++-- web/src/views/__tests__/GroupsView.test.ts | 18 ++-- .../views/__tests__/InvitationView.test.ts | 12 +-- web/src/views/__tests__/LoginView.test.ts | 14 +-- web/src/views/__tests__/MembersView.test.ts | 78 +++++++++------- web/src/views/__tests__/NotFoundView.test.ts | 4 +- web/src/views/__tests__/RegisterView.test.ts | 10 +-- .../views/__tests__/ResetPasswordView.test.ts | 22 +++-- .../views/__tests__/VerifyEmailView.test.ts | 17 ++-- .../__tests__/WatchlistDetailView.test.ts | 18 ++-- .../views/__tests__/WatchlistListView.test.ts | 14 +-- .../admin/__tests__/AdminSystemView.test.ts | 4 +- 28 files changed, 345 insertions(+), 240 deletions(-) diff --git a/web/src/components/__tests__/AppSidebar.test.ts b/web/src/components/__tests__/AppSidebar.test.ts index 04696d2e..fdef46e2 100644 --- a/web/src/components/__tests__/AppSidebar.test.ts +++ b/web/src/components/__tests__/AppSidebar.test.ts @@ -8,8 +8,8 @@ import { useAuthStore } from '@/stores/auth' // Mock vue-router vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ path: '/cves' })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ path: '/cves' })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -20,8 +20,8 @@ vi.mock('vue-router', () => ({ // Mock API client (needed by auth store) vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -126,7 +126,7 @@ describe('OrgSwitcher', () => { user_id: 'u1', email: 'sam@example.com', display_name: 'Sam Carter', - is_site_admin: false, + is_site_admin: false, orgs: [ { org_id: 'org-1', name: 'Acme Corp', role: 'owner' }, { org_id: 'org-2', name: 'Globex Inc', role: 'member' }, diff --git a/web/src/components/cve/__tests__/CveResultsTable.test.ts b/web/src/components/cve/__tests__/CveResultsTable.test.ts index bc46c910..956aca4f 100644 --- a/web/src/components/cve/__tests__/CveResultsTable.test.ts +++ b/web/src/components/cve/__tests__/CveResultsTable.test.ts @@ -8,8 +8,8 @@ import type { components } from '@/lib/api/schema' type CVEItem = components['schemas']['CVEItem'] vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ query: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -20,7 +20,8 @@ vi.mock('vue-router', () => ({ function makeCVE(overrides: Partial = {}): CVEItem { return { cve_id: 'CVE-2024-12345', - description_primary: 'A critical vulnerability in Apache Log4j allows remote code execution via crafted log messages.', + description_primary: + 'A critical vulnerability in Apache Log4j allows remote code execution via crafted log messages.', cvss_v3_score: 9.8, epss_score: 0.975, severity: 'critical', @@ -133,7 +134,7 @@ describe('CveResultsTable', () => { const wrapper = await mountTable({ items }) const cells = wrapper.findAll('td') - const epssCell = cells.find(c => c.text() === '\u2014') + const epssCell = cells.find((c) => c.text() === '\u2014') expect(epssCell).toBeDefined() }) }) diff --git a/web/src/components/cve/__tests__/CveSearchFilters.test.ts b/web/src/components/cve/__tests__/CveSearchFilters.test.ts index 9d2c4056..c41aa524 100644 --- a/web/src/components/cve/__tests__/CveSearchFilters.test.ts +++ b/web/src/components/cve/__tests__/CveSearchFilters.test.ts @@ -5,8 +5,8 @@ import { describe, it, expect, vi } from 'vitest' import { mount } from '@vue/test-utils' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ query: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], diff --git a/web/src/components/cve/__tests__/CveSourceComparison.test.ts b/web/src/components/cve/__tests__/CveSourceComparison.test.ts index 7898396b..ad3678ec 100644 --- a/web/src/components/cve/__tests__/CveSourceComparison.test.ts +++ b/web/src/components/cve/__tests__/CveSourceComparison.test.ts @@ -8,8 +8,8 @@ import type { components } from '@/lib/api/schema' type CVESourceResponse = components['schemas']['CVESourceResponse'] vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ query: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -34,9 +34,7 @@ function makeSource(overrides: Partial = {}): CVESourceRespon } async function mountComponent(props: Record = {}) { - const { default: CveSourceComparison } = await import( - '@/components/cve/CveSourceComparison.vue' - ) + const { default: CveSourceComparison } = await import('@/components/cve/CveSourceComparison.vue') return mount(CveSourceComparison, { props: props as any }) } diff --git a/web/src/components/settings/__tests__/GroupDialog.test.ts b/web/src/components/settings/__tests__/GroupDialog.test.ts index 765a02c0..3c97ab64 100644 --- a/web/src/components/settings/__tests__/GroupDialog.test.ts +++ b/web/src/components/settings/__tests__/GroupDialog.test.ts @@ -8,8 +8,8 @@ import { useAuthStore } from '@/stores/auth' import type { GroupEntry } from '@/components/settings/GroupDialog.vue' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ params: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -17,15 +17,15 @@ vi.mock('vue-router', () => ({ }, })) -const mockPOST = vi.fn() -const mockPATCH = vi.fn() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() +const mockPATCH = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), POST: (...args: unknown[]) => mockPOST(...args), PATCH: (...args: unknown[]) => mockPATCH(...args), - DELETE: vi.fn(), + DELETE: vi.fn<(...args: unknown[]) => unknown>(), }, })) diff --git a/web/src/components/settings/__tests__/GroupMembersDialog.test.ts b/web/src/components/settings/__tests__/GroupMembersDialog.test.ts index 311f3902..223b6184 100644 --- a/web/src/components/settings/__tests__/GroupMembersDialog.test.ts +++ b/web/src/components/settings/__tests__/GroupMembersDialog.test.ts @@ -7,8 +7,8 @@ import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ params: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -16,15 +16,15 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockPOST = vi.fn() -const mockDELETE = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() +const mockDELETE = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), POST: (...args: unknown[]) => mockPOST(...args), - PATCH: vi.fn(), + PATCH: vi.fn<(...args: unknown[]) => unknown>(), DELETE: (...args: unknown[]) => mockDELETE(...args), }, })) @@ -93,9 +93,8 @@ function bodyText(): string { let wrapper: VueWrapper async function mountDialog(props: { open?: boolean; groupId?: string; groupName?: string } = {}) { - const { default: GroupMembersDialog } = await import( - '@/components/settings/GroupMembersDialog.vue' - ) + const { default: GroupMembersDialog } = + await import('@/components/settings/GroupMembersDialog.vue') wrapper = mount(GroupMembersDialog, { props: { open: true, @@ -110,7 +109,9 @@ async function mountDialog(props: { open?: boolean; groupId?: string; groupName? // Clean up portaled DOM elements function cleanupPortals() { - document.querySelectorAll('[data-reka-portal], [data-radix-popper-content-wrapper]').forEach((el) => el.remove()) + document + .querySelectorAll('[data-reka-portal], [data-radix-popper-content-wrapper]') + .forEach((el) => el.remove()) } describe('GroupMembersDialog', () => { @@ -250,9 +251,7 @@ describe('GroupMembersDialog', () => { describe('add member', () => { it('shows available org members not already in group', async () => { - mockGroupMembersSuccess([ - makeGroupMember({ user_id: 'u1', email: 'alice@example.com' }), - ]) + mockGroupMembersSuccess([makeGroupMember({ user_id: 'u1', email: 'alice@example.com' })]) mockOrgMembersSuccess([ makeOrgMember({ user_id: 'u1', email: 'alice@example.com' }), makeOrgMember({ user_id: 'u2', email: 'bob@example.com', display_name: 'Bob' }), diff --git a/web/src/components/settings/__tests__/InviteMemberDialog.test.ts b/web/src/components/settings/__tests__/InviteMemberDialog.test.ts index aa08f61d..52686e87 100644 --- a/web/src/components/settings/__tests__/InviteMemberDialog.test.ts +++ b/web/src/components/settings/__tests__/InviteMemberDialog.test.ts @@ -7,8 +7,8 @@ import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ params: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -16,14 +16,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockPOST = vi.fn() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), POST: (...args: unknown[]) => mockPOST(...args), - PATCH: vi.fn(), - DELETE: vi.fn(), + PATCH: vi.fn<(...args: unknown[]) => unknown>(), + DELETE: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -74,9 +74,8 @@ async function clickTestId(testId: string) { let wrapper: VueWrapper async function mountDialog(props: { open?: boolean; currentUserRole?: string } = {}) { - const { default: InviteMemberDialog } = await import( - '@/components/settings/InviteMemberDialog.vue' - ) + const { default: InviteMemberDialog } = + await import('@/components/settings/InviteMemberDialog.vue') wrapper = mount(InviteMemberDialog, { props: { open: true, currentUserRole: 'admin', ...props }, attachTo: document.body, diff --git a/web/src/components/watchlist/__tests__/AddItemDialog.test.ts b/web/src/components/watchlist/__tests__/AddItemDialog.test.ts index 0bbe1718..d1492428 100644 --- a/web/src/components/watchlist/__tests__/AddItemDialog.test.ts +++ b/web/src/components/watchlist/__tests__/AddItemDialog.test.ts @@ -7,8 +7,8 @@ import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ params: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -16,14 +16,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockPOST = vi.fn() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), POST: (...args: unknown[]) => mockPOST(...args), - PATCH: vi.fn(), - DELETE: vi.fn(), + PATCH: vi.fn<(...args: unknown[]) => unknown>(), + DELETE: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -112,9 +112,7 @@ async function clickTestId(testId: string) { let wrapper: VueWrapper async function mountDialog(open = true) { - const { default: AddItemDialog } = await import( - '@/components/watchlist/AddItemDialog.vue' - ) + const { default: AddItemDialog } = await import('@/components/watchlist/AddItemDialog.vue') wrapper = mount(AddItemDialog, { props: { open, watchlistId: TEST_WATCHLIST_ID }, attachTo: document.body, diff --git a/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts b/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts index e06ad824..1ea7ccde 100644 --- a/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts +++ b/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts @@ -7,8 +7,8 @@ import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ params: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -16,14 +16,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockPOST = vi.fn() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), POST: (...args: unknown[]) => mockPOST(...args), - PATCH: vi.fn(), - DELETE: vi.fn(), + PATCH: vi.fn<(...args: unknown[]) => unknown>(), + DELETE: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -91,9 +91,8 @@ async function clickTestId(testId: string) { let wrapper: VueWrapper async function mountDialog(open = true) { - const { default: CreateWatchlistDialog } = await import( - '@/components/watchlist/CreateWatchlistDialog.vue' - ) + const { default: CreateWatchlistDialog } = + await import('@/components/watchlist/CreateWatchlistDialog.vue') wrapper = mount(CreateWatchlistDialog, { props: { open }, attachTo: document.body, diff --git a/web/src/lib/api/__tests__/client.test.ts b/web/src/lib/api/__tests__/client.test.ts index 289ad5b0..907cb5b5 100644 --- a/web/src/lib/api/__tests__/client.test.ts +++ b/web/src/lib/api/__tests__/client.test.ts @@ -119,7 +119,7 @@ describe('refresh middleware', () => { it('does not attempt refresh for auth endpoints', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn() + const fetchMock = vi.fn<(...args: unknown[]) => unknown>() globalThis.fetch = fetchMock const loginRequest = new Request('http://localhost/api/v1/auth/login') @@ -136,7 +136,7 @@ describe('refresh middleware', () => { it('does not attempt refresh for auth/me endpoint', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn() + const fetchMock = vi.fn<(...args: unknown[]) => unknown>() globalThis.fetch = fetchMock const meRequest = new Request('http://localhost/api/v1/auth/me') @@ -153,7 +153,7 @@ describe('refresh middleware', () => { it('does not attempt refresh for the refresh endpoint itself', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn() + const fetchMock = vi.fn<(...args: unknown[]) => unknown>() globalThis.fetch = fetchMock const refreshRequest = new Request('http://localhost/api/v1/auth/refresh') @@ -172,7 +172,7 @@ describe('refresh middleware', () => { const { refreshMiddleware } = await import('../client') const retryResponse = new Response('ok', { status: 200 }) - const fetchMock = vi.fn() + const fetchMock = vi.fn<(...args: unknown[]) => unknown>() // First call: refresh succeeds. fetchMock.mockResolvedValueOnce(new Response('', { status: 200 })) // Second call: retry the original request. @@ -198,7 +198,7 @@ describe('refresh middleware', () => { it('returns original 401 response when refresh fails', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn() + const fetchMock = vi.fn<(...args: unknown[]) => unknown>() // Refresh returns 401 (failure). fetchMock.mockResolvedValueOnce(new Response('', { status: 401 })) globalThis.fetch = fetchMock diff --git a/web/src/router/__tests__/guards.test.ts b/web/src/router/__tests__/guards.test.ts index 08b57dc3..9909ef56 100644 --- a/web/src/router/__tests__/guards.test.ts +++ b/web/src/router/__tests__/guards.test.ts @@ -11,8 +11,8 @@ import { routes, authGuard, titleGuard } from '../index' // Mock the API client so fetchMe doesn't make real HTTP calls. vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) diff --git a/web/src/stores/__tests__/auth.test.ts b/web/src/stores/__tests__/auth.test.ts index aa0d23eb..4231a55f 100644 --- a/web/src/stores/__tests__/auth.test.ts +++ b/web/src/stores/__tests__/auth.test.ts @@ -8,8 +8,8 @@ import { useAuthStore } from '../auth' // Mock the API client vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -120,7 +120,11 @@ describe('auth store', () => { is_site_admin: false, orgs: [{ org_id: 'org-1', name: 'Org One', role: 'owner' }], } - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() const result = await auth.fetchMe() @@ -131,7 +135,11 @@ describe('auth store', () => { }) it('returns false on API error', async () => { - vi.mocked(client.GET).mockResolvedValue({ data: undefined, error: { type: 'about:blank', detail: 'unauthorized' }, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: undefined, + error: { type: 'about:blank', detail: 'unauthorized' }, + response: {} as Response, + }) const auth = useAuthStore() const result = await auth.fetchMe() @@ -148,7 +156,11 @@ describe('auth store', () => { is_site_admin: false, orgs: [{ org_id: 'only-org', name: 'Only Org', role: 'admin' }], } - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() await auth.fetchMe() @@ -168,7 +180,11 @@ describe('auth store', () => { { org_id: 'org-2', name: 'Org Two', role: 'member' }, ], } - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() await auth.fetchMe() @@ -185,7 +201,11 @@ describe('auth store', () => { is_site_admin: false, orgs: [{ org_id: 'current-org', name: 'Current', role: 'admin' }], } - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() await auth.fetchMe() @@ -207,7 +227,11 @@ describe('auth store', () => { { org_id: 'org-2', name: 'Org Two', role: 'member' }, ], } - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() await auth.fetchMe() @@ -230,7 +254,11 @@ describe('auth store', () => { is_site_admin: false, orgs: [], } - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() await auth.fetchMe() @@ -239,7 +267,11 @@ describe('auth store', () => { }) it('is set to true after failed fetchMe', async () => { - vi.mocked(client.GET).mockResolvedValue({ data: undefined, error: { type: 'about:blank', detail: 'unauthorized' }, response: {} as Response }) + vi.mocked(client.GET).mockResolvedValue({ + data: undefined, + error: { type: 'about:blank', detail: 'unauthorized' }, + response: {} as Response, + }) const auth = useAuthStore() await auth.fetchMe() @@ -248,7 +280,11 @@ describe('auth store', () => { }) it('is reset to false on clearAuth', async () => { - vi.mocked(client.POST).mockResolvedValue({ data: undefined, error: undefined, response: {} as Response }) + vi.mocked(client.POST).mockResolvedValue({ + data: undefined, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() auth.sessionChecked = true @@ -268,8 +304,16 @@ describe('auth store', () => { is_site_admin: false, orgs: [{ org_id: 'org-1', name: 'Org One', role: 'admin' }], } - vi.mocked(client.POST).mockResolvedValue({ data: undefined, error: undefined, response: {} as Response }) - vi.mocked(client.GET).mockResolvedValue({ data: meData, error: undefined, response: {} as Response }) + vi.mocked(client.POST).mockResolvedValue({ + data: undefined, + error: undefined, + response: {} as Response, + }) + vi.mocked(client.GET).mockResolvedValue({ + data: meData, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() const result = await auth.login('test@example.com', 'password123') @@ -280,7 +324,11 @@ describe('auth store', () => { }) it('returns error on failed login', async () => { - vi.mocked(client.POST).mockResolvedValue({ data: undefined, error: { type: 'about:blank', detail: 'bad creds' }, response: {} as Response }) + vi.mocked(client.POST).mockResolvedValue({ + data: undefined, + error: { type: 'about:blank', detail: 'bad creds' }, + response: {} as Response, + }) const auth = useAuthStore() const result = await auth.login('bad@example.com', 'wrong') @@ -293,7 +341,11 @@ describe('auth store', () => { describe('logout', () => { it('calls logout endpoint and clears auth state', async () => { - vi.mocked(client.POST).mockResolvedValue({ data: undefined, error: undefined, response: {} as Response }) + vi.mocked(client.POST).mockResolvedValue({ + data: undefined, + error: undefined, + response: {} as Response, + }) const auth = useAuthStore() auth.user = { diff --git a/web/src/views/__tests__/CreateOrgView.test.ts b/web/src/views/__tests__/CreateOrgView.test.ts index 5d37fade..5b6b7717 100644 --- a/web/src/views/__tests__/CreateOrgView.test.ts +++ b/web/src/views/__tests__/CreateOrgView.test.ts @@ -6,11 +6,11 @@ import { mount, flushPromises } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: {} })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { query: Record }>(() => ({ query: {} })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -18,11 +18,11 @@ vi.mock('vue-router', () => ({ }, })) -const mockPOST = vi.fn() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), POST: (...args: unknown[]) => mockPOST(...args), }, })) @@ -65,7 +65,10 @@ describe('CreateOrgView', () => { let resolvePost: (value: unknown) => void mockPOST.mockImplementation( - () => new Promise((resolve) => { resolvePost = resolve }), + () => + new Promise((resolve) => { + resolvePost = resolve + }), ) const wrapper = await mountCreateOrg() diff --git a/web/src/views/__tests__/CveDetailView.test.ts b/web/src/views/__tests__/CveDetailView.test.ts index 4db8745e..b98d5e7b 100644 --- a/web/src/views/__tests__/CveDetailView.test.ts +++ b/web/src/views/__tests__/CveDetailView.test.ts @@ -12,13 +12,15 @@ type CVESourceResponse = components['schemas']['CVESourceResponse'] let mockRouteParams: Record = {} vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ + useRoute: vi.fn<() => { params: Record; query: Record }>(() => ({ params: mockRouteParams, query: {}, })), - useRouter: vi.fn(() => ({ - push: vi.fn(), - back: vi.fn(), + useRouter: vi.fn< + () => { push: (...args: unknown[]) => unknown; back: (...args: unknown[]) => unknown } + >(() => ({ + push: vi.fn<(...args: unknown[]) => unknown>(), + back: vi.fn<(...args: unknown[]) => unknown>(), })), RouterLink: { name: 'RouterLink', @@ -27,12 +29,12 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), - POST: vi.fn(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -200,7 +202,7 @@ describe('CveDetailView', () => { await flushPromises() const scoreCards = wrapper.findAll('[data-testid="score-card"]') - const cvssCard = scoreCards.find(c => c.text().includes('CVSS')) + const cvssCard = scoreCards.find((c) => c.text().includes('CVSS')) expect(cvssCard?.text()).toContain('N/A') }) @@ -210,7 +212,7 @@ describe('CveDetailView', () => { await flushPromises() const scoreCards = wrapper.findAll('[data-testid="score-card"]') - const epssCard = scoreCards.find(c => c.text().includes('EPSS')) + const epssCard = scoreCards.find((c) => c.text().includes('EPSS')) expect(epssCard?.text()).toContain('N/A') }) @@ -280,7 +282,7 @@ describe('CveDetailView', () => { await flushPromises() const links = wrapper.findAll('a[target="_blank"]') - const urls = links.map(l => l.attributes('href')) + const urls = links.map((l) => l.attributes('href')) expect(urls).toContain('https://nvd.nist.gov/vuln/detail/CVE-2024-12345') expect(urls).toContain('https://github.com/advisories/GHSA-xxxx-xxxx-xxxx') }) @@ -370,7 +372,9 @@ describe('CveDetailView', () => { // Set up a slow response (will become stale) let resolveStale: (v: unknown) => void - const stalePromise = new Promise((resolve) => { resolveStale = resolve }) + const stalePromise = new Promise((resolve) => { + resolveStale = resolve + }) mockGET.mockReturnValueOnce(stalePromise) // Trigger first refetch — increments fetchId diff --git a/web/src/views/__tests__/CveSearchView.test.ts b/web/src/views/__tests__/CveSearchView.test.ts index bd6e3a17..ecf22a24 100644 --- a/web/src/views/__tests__/CveSearchView.test.ts +++ b/web/src/views/__tests__/CveSearchView.test.ts @@ -8,13 +8,18 @@ import type { components } from '@/lib/api/schema' type CVEItem = components['schemas']['CVEItem'] -const mockPush = vi.fn() -const mockReplace = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() +const mockReplace = vi.fn<(...args: unknown[]) => unknown>() let mockRouteQuery: Record = {} vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: mockRouteQuery })), - useRouter: vi.fn(() => ({ push: mockPush, replace: mockReplace })), + useRoute: vi.fn<() => { query: Record }>(() => ({ + query: mockRouteQuery, + })), + useRouter: vi.fn<() => { push: typeof mockPush; replace: typeof mockReplace }>(() => ({ + push: mockPush, + replace: mockReplace, + })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -22,12 +27,12 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), - POST: vi.fn(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -114,11 +119,14 @@ describe('CveSearchView', () => { await mountView() await flushPromises() - expect(mockGET).toHaveBeenCalledWith('/cves', expect.objectContaining({ - params: expect.objectContaining({ - query: expect.any(Object), + expect(mockGET).toHaveBeenCalledWith( + '/cves', + expect.objectContaining({ + params: expect.objectContaining({ + query: expect.any(Object), + }), }), - })) + ) }) it('displays fetched CVE results', async () => { @@ -139,13 +147,16 @@ describe('CveSearchView', () => { await mountView() await flushPromises() - expect(mockGET).toHaveBeenCalledWith('/cves', expect.objectContaining({ - params: { - query: expect.objectContaining({ - q: 'apache', - }), - }, - })) + expect(mockGET).toHaveBeenCalledWith( + '/cves', + expect.objectContaining({ + params: { + query: expect.objectContaining({ + q: 'apache', + }), + }, + }), + ) }) it('passes severity filter to API', async () => { @@ -154,13 +165,16 @@ describe('CveSearchView', () => { await mountView() await flushPromises() - expect(mockGET).toHaveBeenCalledWith('/cves', expect.objectContaining({ - params: { - query: expect.objectContaining({ - severity: ['critical'], - }), - }, - })) + expect(mockGET).toHaveBeenCalledWith( + '/cves', + expect.objectContaining({ + params: { + query: expect.objectContaining({ + severity: ['critical'], + }), + }, + }), + ) }) }) @@ -190,11 +204,13 @@ describe('CveSearchView', () => { await wrapper.find('form').trigger('submit') await flushPromises() - expect(mockReplace).toHaveBeenCalledWith(expect.objectContaining({ - query: expect.objectContaining({ - q: 'openssl', + expect(mockReplace).toHaveBeenCalledWith( + expect.objectContaining({ + query: expect.objectContaining({ + q: 'openssl', + }), }), - })) + ) }) }) @@ -240,13 +256,16 @@ describe('CveSearchView', () => { await wrapper.find('[data-testid="next-page"]').trigger('click') await flushPromises() - expect(mockGET).toHaveBeenCalledWith('/cves', expect.objectContaining({ - params: { - query: expect.objectContaining({ - cursor: 'cursor-page2', - }), - }, - })) + expect(mockGET).toHaveBeenCalledWith( + '/cves', + expect.objectContaining({ + params: { + query: expect.objectContaining({ + cursor: 'cursor-page2', + }), + }, + }), + ) expect(wrapper.text()).toContain('CVE-2024-0002') }) diff --git a/web/src/views/__tests__/FeedStatusView.test.ts b/web/src/views/__tests__/FeedStatusView.test.ts index ae6d8cd0..f959a355 100644 --- a/web/src/views/__tests__/FeedStatusView.test.ts +++ b/web/src/views/__tests__/FeedStatusView.test.ts @@ -5,8 +5,10 @@ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ path: '/admin/feeds' })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => { path: string }>(() => ({ path: '/admin/feeds' })), + useRouter: vi.fn<() => { push: (...args: unknown[]) => unknown }>(() => ({ + push: vi.fn<(...args: unknown[]) => unknown>(), + })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -14,8 +16,8 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockPOST = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { diff --git a/web/src/views/__tests__/ForgotPasswordView.test.ts b/web/src/views/__tests__/ForgotPasswordView.test.ts index efc2c661..efe29204 100644 --- a/web/src/views/__tests__/ForgotPasswordView.test.ts +++ b/web/src/views/__tests__/ForgotPasswordView.test.ts @@ -7,8 +7,10 @@ import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: {} })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => { query: Record }>(() => ({ query: {} })), + useRouter: vi.fn<() => { push: (...args: unknown[]) => unknown }>(() => ({ + push: vi.fn<(...args: unknown[]) => unknown>(), + })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -18,14 +20,14 @@ vi.mock('vue-router', () => ({ vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) import { useAuthStore } from '@/stores/auth' -const mockFetch = vi.fn() +const mockFetch = vi.fn<(...args: unknown[]) => unknown>() vi.stubGlobal('fetch', mockFetch) async function mountForgotPassword() { @@ -96,7 +98,10 @@ describe('ForgotPasswordView', () => { it('shows success message even on failure (anti-enumeration)', async () => { const auth = useAuthStore() - vi.spyOn(auth, 'forgotPassword').mockResolvedValue({ success: false, error: 'something went wrong' }) + vi.spyOn(auth, 'forgotPassword').mockResolvedValue({ + success: false, + error: 'something went wrong', + }) const wrapper = await mountForgotPassword() @@ -125,7 +130,10 @@ describe('ForgotPasswordView', () => { const auth = useAuthStore() let resolveForgot: (value: { success: boolean }) => void vi.spyOn(auth, 'forgotPassword').mockImplementation( - () => new Promise((resolve) => { resolveForgot = resolve }), + () => + new Promise((resolve) => { + resolveForgot = resolve + }), ) const wrapper = await mountForgotPassword() diff --git a/web/src/views/__tests__/GroupsView.test.ts b/web/src/views/__tests__/GroupsView.test.ts index e201066f..2a94212e 100644 --- a/web/src/views/__tests__/GroupsView.test.ts +++ b/web/src/views/__tests__/GroupsView.test.ts @@ -6,11 +6,11 @@ import { mount, flushPromises, VueWrapper } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { params: Record }>(() => ({ params: {} })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -18,14 +18,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockDELETE = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockDELETE = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), - POST: vi.fn(), - PATCH: vi.fn(), + POST: vi.fn<(...args: unknown[]) => unknown>(), + PATCH: vi.fn<(...args: unknown[]) => unknown>(), DELETE: (...args: unknown[]) => mockDELETE(...args), }, })) @@ -97,7 +97,9 @@ async function mountView() { // Clean up portaled DOM elements (reka-ui Select, AlertDialog, Dialog) function cleanupPortals() { - document.querySelectorAll('[data-reka-portal], [data-radix-popper-content-wrapper]').forEach((el) => el.remove()) + document + .querySelectorAll('[data-reka-portal], [data-radix-popper-content-wrapper]') + .forEach((el) => el.remove()) } describe('GroupsView', () => { diff --git a/web/src/views/__tests__/InvitationView.test.ts b/web/src/views/__tests__/InvitationView.test.ts index ee585084..39738d9a 100644 --- a/web/src/views/__tests__/InvitationView.test.ts +++ b/web/src/views/__tests__/InvitationView.test.ts @@ -7,11 +7,11 @@ import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' let mockRouteParams: Record = { token: 'test-token-abc' } -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: mockRouteParams })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { params: Record }>(() => ({ params: mockRouteParams })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -19,8 +19,8 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockPOST = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockPOST = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { @@ -178,7 +178,7 @@ describe('InvitationView', () => { user_id: 'u1', email: 'sam@example.com', display_name: 'Sam Carter', - is_site_admin: false, + is_site_admin: false, orgs: [ { org_id: 'org-old', name: 'Old Org', role: 'admin' }, { org_id: 'org-new', name: 'Acme Corp', role: 'member' }, diff --git a/web/src/views/__tests__/LoginView.test.ts b/web/src/views/__tests__/LoginView.test.ts index 22b9057e..8de55d27 100644 --- a/web/src/views/__tests__/LoginView.test.ts +++ b/web/src/views/__tests__/LoginView.test.ts @@ -6,12 +6,12 @@ import { mount, flushPromises } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() const mockRouteQuery = { redirect: undefined as string | undefined } vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: mockRouteQuery })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { query: typeof mockRouteQuery }>(() => ({ query: mockRouteQuery })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -21,8 +21,8 @@ vi.mock('vue-router', () => ({ vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) @@ -271,7 +271,7 @@ describe('LoginView', () => { it('GitHub button redirects to OAuth endpoint', async () => { mockProvidersResponse(true, false) const originalLocation = window.location.href - const hrefSetter = vi.fn() + const hrefSetter = vi.fn<(v: string) => void>() Object.defineProperty(window, 'location', { value: { ...window.location, @@ -299,7 +299,7 @@ describe('LoginView', () => { it('Google button redirects to OAuth endpoint', async () => { mockProvidersResponse(false, true) const originalLocation = window.location.href - const hrefSetter = vi.fn() + const hrefSetter = vi.fn<(v: string) => void>() Object.defineProperty(window, 'location', { value: { ...window.location, diff --git a/web/src/views/__tests__/MembersView.test.ts b/web/src/views/__tests__/MembersView.test.ts index 5b7eaf22..266a53fd 100644 --- a/web/src/views/__tests__/MembersView.test.ts +++ b/web/src/views/__tests__/MembersView.test.ts @@ -6,11 +6,11 @@ import { mount, flushPromises, VueWrapper } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => unknown>(() => ({ params: {} })), + useRouter: vi.fn<() => unknown>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -18,14 +18,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockPATCH = vi.fn() -const mockDELETE = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockPATCH = vi.fn<(...args: unknown[]) => unknown>() +const mockDELETE = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), - POST: vi.fn(), + POST: vi.fn<(...args: unknown[]) => unknown>(), PATCH: (...args: unknown[]) => mockPATCH(...args), DELETE: (...args: unknown[]) => mockDELETE(...args), }, @@ -121,7 +121,9 @@ async function openRoleSelectAndGetOptions(): Promise { trigger.hasPointerCapture = () => false trigger.releasePointerCapture = () => {} } - trigger.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, cancelable: true, button: 0, pointerId: 1 })) + trigger.dispatchEvent( + new PointerEvent('pointerdown', { bubbles: true, cancelable: true, button: 0, pointerId: 1 }), + ) await flushPromises() const options = document.querySelectorAll('[role="option"]') return Array.from(options).map((el) => el.textContent?.trim() ?? '') @@ -139,7 +141,9 @@ async function mountView() { // Clean up portaled DOM elements (reka-ui Select, AlertDialog, Dialog) function cleanupPortals() { - document.querySelectorAll('[data-reka-portal], [data-radix-popper-content-wrapper]').forEach((el) => el.remove()) + document + .querySelectorAll('[data-reka-portal], [data-radix-popper-content-wrapper]') + .forEach((el) => el.remove()) } describe('MembersView', () => { @@ -193,8 +197,18 @@ describe('MembersView', () => { it('renders members table with data', async () => { setupAuthStore('admin') mockMembersSuccess([ - makeMember({ user_id: 'u1', email: 'alice@example.com', display_name: 'Alice', role: 'admin' }), - makeMember({ user_id: 'u2', email: 'bob@example.com', display_name: 'Bob', role: 'member' }), + makeMember({ + user_id: 'u1', + email: 'alice@example.com', + display_name: 'Alice', + role: 'admin', + }), + makeMember({ + user_id: 'u2', + email: 'bob@example.com', + display_name: 'Bob', + role: 'member', + }), ]) mockInvitationsSuccess([]) await mountView() @@ -322,9 +336,7 @@ describe('MembersView', () => { it('hides remove button on owner members', async () => { setupAuthStore('admin') - mockMembersSuccess([ - makeMember({ user_id: 'u1', role: 'owner', email: 'owner@example.com' }), - ]) + mockMembersSuccess([makeMember({ user_id: 'u1', role: 'owner', email: 'owner@example.com' })]) mockInvitationsSuccess([]) await mountView() await flushPromises() @@ -364,8 +376,18 @@ describe('MembersView', () => { it('calls DELETE on confirmation and removes from list', async () => { setupAuthStore('admin') mockMembersSuccess([ - makeMember({ user_id: 'u1', email: 'keep@example.com', display_name: 'Keep', role: 'member' }), - makeMember({ user_id: 'u2', email: 'remove@example.com', display_name: 'Remove', role: 'member' }), + makeMember({ + user_id: 'u1', + email: 'keep@example.com', + display_name: 'Keep', + role: 'member', + }), + makeMember({ + user_id: 'u2', + email: 'remove@example.com', + display_name: 'Remove', + role: 'member', + }), ]) mockInvitationsSuccess([]) await mountView() @@ -428,9 +450,7 @@ describe('MembersView', () => { it('shows role select for admin on non-owner members', async () => { setupAuthStore('admin') - mockMembersSuccess([ - makeMember({ user_id: 'u1', role: 'member' }), - ]) + mockMembersSuccess([makeMember({ user_id: 'u1', role: 'member' })]) mockInvitationsSuccess([]) await mountView() await flushPromises() @@ -441,9 +461,7 @@ describe('MembersView', () => { it('shows plain text role for owner members (not changeable)', async () => { setupAuthStore('admin') - mockMembersSuccess([ - makeMember({ user_id: 'u1', role: 'owner' }), - ]) + mockMembersSuccess([makeMember({ user_id: 'u1', role: 'owner' })]) mockInvitationsSuccess([]) await mountView() await flushPromises() @@ -458,9 +476,7 @@ describe('MembersView', () => { it('calls PATCH when role is changed', async () => { setupAuthStore('owner') - mockMembersSuccess([ - makeMember({ user_id: 'u1', role: 'member' }), - ]) + mockMembersSuccess([makeMember({ user_id: 'u1', role: 'member' })]) mockInvitationsSuccess([]) await mountView() await flushPromises() @@ -484,9 +500,7 @@ describe('MembersView', () => { it('shows plain text role badge for non-admin users', async () => { setupAuthStore('viewer') - mockMembersSuccess([ - makeMember({ user_id: 'u1', role: 'member' }), - ]) + mockMembersSuccess([makeMember({ user_id: 'u1', role: 'member' })]) await mountView() await flushPromises() @@ -552,9 +566,7 @@ describe('MembersView', () => { it('shows error when cancelling invitation fails', async () => { setupAuthStore('admin') mockMembersSuccess([makeMember()]) - mockInvitationsSuccess([ - makeInvitation({ id: 'inv-1', email: 'fail@example.com' }), - ]) + mockInvitationsSuccess([makeInvitation({ id: 'inv-1', email: 'fail@example.com' })]) await mountView() await flushPromises() @@ -577,9 +589,7 @@ describe('MembersView', () => { describe('role change error handling', () => { it('reverts role display and shows error when PATCH fails', async () => { setupAuthStore('owner') - mockMembersSuccess([ - makeMember({ user_id: 'u1', role: 'admin', email: 'admin@example.com' }), - ]) + mockMembersSuccess([makeMember({ user_id: 'u1', role: 'admin', email: 'admin@example.com' })]) mockInvitationsSuccess([]) await mountView() await flushPromises() diff --git a/web/src/views/__tests__/NotFoundView.test.ts b/web/src/views/__tests__/NotFoundView.test.ts index 86f4bdb5..f9822485 100644 --- a/web/src/views/__tests__/NotFoundView.test.ts +++ b/web/src/views/__tests__/NotFoundView.test.ts @@ -5,8 +5,8 @@ import { describe, it, expect, beforeEach, vi } from 'vitest' import { mount } from '@vue/test-utils' vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ path: '/nonexistent' })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => unknown>(() => ({ path: '/nonexistent' })), + useRouter: vi.fn<() => unknown>(() => ({ push: vi.fn<(...args: unknown[]) => unknown>() })), RouterLink: { name: 'RouterLink', props: ['to'], diff --git a/web/src/views/__tests__/RegisterView.test.ts b/web/src/views/__tests__/RegisterView.test.ts index 99352f27..7018452f 100644 --- a/web/src/views/__tests__/RegisterView.test.ts +++ b/web/src/views/__tests__/RegisterView.test.ts @@ -6,11 +6,11 @@ import { mount, flushPromises } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: {} })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { query: Record }>(() => ({ query: {} })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -20,8 +20,8 @@ vi.mock('vue-router', () => ({ vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) diff --git a/web/src/views/__tests__/ResetPasswordView.test.ts b/web/src/views/__tests__/ResetPasswordView.test.ts index 226d388d..aea30908 100644 --- a/web/src/views/__tests__/ResetPasswordView.test.ts +++ b/web/src/views/__tests__/ResetPasswordView.test.ts @@ -6,12 +6,12 @@ import { mount, flushPromises } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() const mockRouteQuery = { token: undefined as string | undefined } vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: mockRouteQuery })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { query: typeof mockRouteQuery }>(() => ({ query: mockRouteQuery })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -21,14 +21,14 @@ vi.mock('vue-router', () => ({ vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) import { useAuthStore } from '@/stores/auth' -const mockFetch = vi.fn() +const mockFetch = vi.fn<(...args: unknown[]) => unknown>() vi.stubGlobal('fetch', mockFetch) async function mountResetPassword() { @@ -118,7 +118,10 @@ describe('ResetPasswordView', () => { await wrapper.find('form').trigger('submit') await flushPromises() - expect(auth.resetPassword).toHaveBeenCalledWith('valid-hex-token-abc123', 'new-password-1234567') + expect(auth.resetPassword).toHaveBeenCalledWith( + 'valid-hex-token-abc123', + 'new-password-1234567', + ) }) it('shows success message after successful reset', async () => { @@ -187,7 +190,10 @@ describe('ResetPasswordView', () => { const auth = useAuthStore() let resolveReset: (value: { success: boolean }) => void vi.spyOn(auth, 'resetPassword').mockImplementation( - () => new Promise((resolve) => { resolveReset = resolve }), + () => + new Promise((resolve) => { + resolveReset = resolve + }), ) const wrapper = await mountResetPassword() diff --git a/web/src/views/__tests__/VerifyEmailView.test.ts b/web/src/views/__tests__/VerifyEmailView.test.ts index ac0bbcfc..14ac4b31 100644 --- a/web/src/views/__tests__/VerifyEmailView.test.ts +++ b/web/src/views/__tests__/VerifyEmailView.test.ts @@ -8,8 +8,10 @@ import { createPinia, setActivePinia } from 'pinia' const mockRouteQuery = { token: undefined as string | undefined } vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ query: mockRouteQuery })), - useRouter: vi.fn(() => ({ push: vi.fn() })), + useRoute: vi.fn<() => { query: typeof mockRouteQuery }>(() => ({ query: mockRouteQuery })), + useRouter: vi.fn<() => { push: (...args: unknown[]) => unknown }>(() => ({ + push: vi.fn<(...args: unknown[]) => unknown>(), + })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -19,14 +21,14 @@ vi.mock('vue-router', () => ({ vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn(), - POST: vi.fn(), + GET: vi.fn<(...args: unknown[]) => unknown>(), + POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) import { useAuthStore } from '@/stores/auth' -const mockFetch = vi.fn() +const mockFetch = vi.fn<(...args: unknown[]) => unknown>() vi.stubGlobal('fetch', mockFetch) async function mountVerifyEmail() { @@ -109,7 +111,10 @@ describe('VerifyEmailView', () => { it('shows helpful expired link text on error', async () => { const auth = useAuthStore() - vi.spyOn(auth, 'verifyEmail').mockResolvedValue({ success: false, error: 'Verification failed' }) + vi.spyOn(auth, 'verifyEmail').mockResolvedValue({ + success: false, + error: 'Verification failed', + }) const wrapper = await mountVerifyEmail() await flushPromises() diff --git a/web/src/views/__tests__/WatchlistDetailView.test.ts b/web/src/views/__tests__/WatchlistDetailView.test.ts index f3a37ce8..458cc9b1 100644 --- a/web/src/views/__tests__/WatchlistDetailView.test.ts +++ b/web/src/views/__tests__/WatchlistDetailView.test.ts @@ -7,11 +7,11 @@ import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' let mockRouteParams: Record = { id: 'wl-123' } -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: mockRouteParams })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { params: Record }>(() => ({ params: mockRouteParams })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -19,14 +19,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockPATCH = vi.fn() -const mockDELETE = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockPATCH = vi.fn<(...args: unknown[]) => unknown>() +const mockDELETE = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), - POST: vi.fn(), + POST: vi.fn<(...args: unknown[]) => unknown>(), PATCH: (...args: unknown[]) => mockPATCH(...args), DELETE: (...args: unknown[]) => mockDELETE(...args), }, @@ -134,9 +134,7 @@ async function clickTestId(testId: string) { let wrapper: VueWrapper async function mountView() { - const { default: WatchlistDetailView } = await import( - '@/views/WatchlistDetailView.vue' - ) + const { default: WatchlistDetailView } = await import('@/views/WatchlistDetailView.vue') wrapper = mount(WatchlistDetailView, { attachTo: document.body, }) diff --git a/web/src/views/__tests__/WatchlistListView.test.ts b/web/src/views/__tests__/WatchlistListView.test.ts index a580dc5f..13892b7f 100644 --- a/web/src/views/__tests__/WatchlistListView.test.ts +++ b/web/src/views/__tests__/WatchlistListView.test.ts @@ -6,11 +6,11 @@ import { mount, flushPromises, VueWrapper } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { useAuthStore } from '@/stores/auth' -const mockPush = vi.fn() +const mockPush = vi.fn<(...args: unknown[]) => unknown>() vi.mock('vue-router', () => ({ - useRoute: vi.fn(() => ({ params: {} })), - useRouter: vi.fn(() => ({ push: mockPush })), + useRoute: vi.fn<() => { params: Record }>(() => ({ params: {} })), + useRouter: vi.fn<() => { push: typeof mockPush }>(() => ({ push: mockPush })), RouterLink: { name: 'RouterLink', props: ['to'], @@ -18,14 +18,14 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn() -const mockDELETE = vi.fn() +const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockDELETE = vi.fn<(...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { GET: (...args: unknown[]) => mockGET(...args), - POST: vi.fn(), - PATCH: vi.fn(), + POST: vi.fn<(...args: unknown[]) => unknown>(), + PATCH: vi.fn<(...args: unknown[]) => unknown>(), DELETE: (...args: unknown[]) => mockDELETE(...args), }, })) diff --git a/web/src/views/admin/__tests__/AdminSystemView.test.ts b/web/src/views/admin/__tests__/AdminSystemView.test.ts index 6a901f66..4412e139 100644 --- a/web/src/views/admin/__tests__/AdminSystemView.test.ts +++ b/web/src/views/admin/__tests__/AdminSystemView.test.ts @@ -24,7 +24,9 @@ const unhealthyDoctor = { // Stub the openapi-fetch client used by the component. vi.mock('@/lib/api/client', () => ({ default: { - GET: vi.fn().mockResolvedValue({ data: null, error: { status: 500 } }), + GET: vi + .fn<(...args: unknown[]) => unknown>() + .mockResolvedValue({ data: null, error: { status: 500 } }), }, })) From e53c0307a4ecc147017e1d06230d3f3fc96f27a2 Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 05:13:50 -0500 Subject: [PATCH 28/31] fix(lint): use precise mock types where generic unknown breaks type-check Three files needed more specific type parameters than the generic (...args: unknown[]) => unknown pattern: - CreateWatchlistDialog: cast mock.calls access for body property access - client.test.ts: type fetchMock as typeof fetch (assigned to globalThis.fetch) - CveDetailView: type mockGET first arg as string (used in mockImplementation) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../watchlist/__tests__/CreateWatchlistDialog.test.ts | 4 ++-- web/src/lib/api/__tests__/client.test.ts | 10 +++++----- web/src/views/__tests__/CveDetailView.test.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts b/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts index 1ea7ccde..c1c1820c 100644 --- a/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts +++ b/web/src/components/watchlist/__tests__/CreateWatchlistDialog.test.ts @@ -165,7 +165,7 @@ describe('CreateWatchlistDialog', () => { ) // Verify the body includes name and description - const callArgs = mockPOST.mock.calls[0]! + const callArgs = mockPOST.mock.calls[0] as [string, { body: Record }] expect(callArgs[1].body.name).toBe('Test WL') expect(callArgs[1].body.description).toBe('Desc') }) @@ -182,7 +182,7 @@ describe('CreateWatchlistDialog', () => { await clickTestId('create-watchlist-btn') await flushPromises() - const callArgs = mockPOST.mock.calls[0]! + const callArgs = mockPOST.mock.calls[0] as [string, { body: Record }] expect(callArgs[1].body.name).toBe('Name Only') expect(callArgs[1].body.description).toBeNull() }) diff --git a/web/src/lib/api/__tests__/client.test.ts b/web/src/lib/api/__tests__/client.test.ts index 907cb5b5..744ab851 100644 --- a/web/src/lib/api/__tests__/client.test.ts +++ b/web/src/lib/api/__tests__/client.test.ts @@ -119,7 +119,7 @@ describe('refresh middleware', () => { it('does not attempt refresh for auth endpoints', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn<(...args: unknown[]) => unknown>() + const fetchMock = vi.fn() globalThis.fetch = fetchMock const loginRequest = new Request('http://localhost/api/v1/auth/login') @@ -136,7 +136,7 @@ describe('refresh middleware', () => { it('does not attempt refresh for auth/me endpoint', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn<(...args: unknown[]) => unknown>() + const fetchMock = vi.fn() globalThis.fetch = fetchMock const meRequest = new Request('http://localhost/api/v1/auth/me') @@ -153,7 +153,7 @@ describe('refresh middleware', () => { it('does not attempt refresh for the refresh endpoint itself', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn<(...args: unknown[]) => unknown>() + const fetchMock = vi.fn() globalThis.fetch = fetchMock const refreshRequest = new Request('http://localhost/api/v1/auth/refresh') @@ -172,7 +172,7 @@ describe('refresh middleware', () => { const { refreshMiddleware } = await import('../client') const retryResponse = new Response('ok', { status: 200 }) - const fetchMock = vi.fn<(...args: unknown[]) => unknown>() + const fetchMock = vi.fn() // First call: refresh succeeds. fetchMock.mockResolvedValueOnce(new Response('', { status: 200 })) // Second call: retry the original request. @@ -198,7 +198,7 @@ describe('refresh middleware', () => { it('returns original 401 response when refresh fails', async () => { const { refreshMiddleware } = await import('../client') - const fetchMock = vi.fn<(...args: unknown[]) => unknown>() + const fetchMock = vi.fn() // Refresh returns 401 (failure). fetchMock.mockResolvedValueOnce(new Response('', { status: 401 })) globalThis.fetch = fetchMock diff --git a/web/src/views/__tests__/CveDetailView.test.ts b/web/src/views/__tests__/CveDetailView.test.ts index b98d5e7b..b148f4e5 100644 --- a/web/src/views/__tests__/CveDetailView.test.ts +++ b/web/src/views/__tests__/CveDetailView.test.ts @@ -29,7 +29,7 @@ vi.mock('vue-router', () => ({ }, })) -const mockGET = vi.fn<(...args: unknown[]) => unknown>() +const mockGET = vi.fn<(path: string, ...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { From 558e9d3bc165b560939e54cc2f3f12efd55e319e Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Wed, 8 Apr 2026 05:15:34 -0500 Subject: [PATCH 29/31] fix(lint): match proxy signature to typed mockGET in CveDetailView test The spread proxy (...args: unknown[]) can't spread into a (string, ...unknown[]) parameter. Match the proxy's signature. Co-Authored-By: Claude Opus 4.6 (1M context) --- web/src/views/__tests__/CveDetailView.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/views/__tests__/CveDetailView.test.ts b/web/src/views/__tests__/CveDetailView.test.ts index b148f4e5..a4bfe559 100644 --- a/web/src/views/__tests__/CveDetailView.test.ts +++ b/web/src/views/__tests__/CveDetailView.test.ts @@ -33,7 +33,7 @@ const mockGET = vi.fn<(path: string, ...args: unknown[]) => unknown>() vi.mock('@/lib/api/client', () => ({ default: { - GET: (...args: unknown[]) => mockGET(...args), + GET: (path: string, ...args: unknown[]) => mockGET(path, ...args), POST: vi.fn<(...args: unknown[]) => unknown>(), }, })) From 2366a83a71347c32eb8a89ea30dba9708f1a4eca Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Thu, 23 Apr 2026 03:10:55 -0500 Subject: [PATCH 30/31] =?UTF-8?q?docs:=20fix=20accomodate=20=E2=86=92=20ac?= =?UTF-8?q?commodate=20and=20architectutral=20=E2=86=92=20architectural=20?= =?UTF-8?q?typos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both typos propagated here from the shared agent-guidance ruleset heritage. Same two typos were fixed in laserfiche-cli-temp#125. Caught this time by a codespell pass during related work in laserfiche. CLAUDE.md and AGENTS.md both carry the same 4 typo instances (each file has 'architectutral' at line 39 and 'accomodate' at line 56); all 4 fixed. PRing (line 150 in CLAUDE.md) was also flagged by codespell but is intentional GitHub/dev vernacular for 'creating a pull request'; skipped as a false positive. Co-Authored-By: Claude Opus 4.7 (1M context) --- AGENTS.md | 4 ++-- CLAUDE.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8d3dea51..a46cfc80 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,7 +36,7 @@ Rule #1: If you want exception to ANY rule, YOU MUST STOP and get explicit permi - If you're uncomfortable pushing back out loud, just say "Strange things are afoot at the Circle K". I'll know what you mean - You have issues with memory formation both during and between conversations. Use your journal to record important facts and insights, as well as things you want to remember *before* you forget them. - You search your journal when you trying to remember or figure stuff out. -- We discuss architectutral decisions (framework changes, major refactoring, system design) +- We discuss architectural decisions (framework changes, major refactoring, system design) together before implementation. Routine fixes and clear implementations don't need discussion. @@ -53,7 +53,7 @@ When asked to do something, just do it - including obvious follow-up actions nee ## Designing software -- YAGNI. The best code is no code. Don't add features we don't need right now, unless they're foundational to later planned work and refactoring to accomodate would be difficult. +- YAGNI. The best code is no code. Don't add features we don't need right now, unless they're foundational to later planned work and refactoring to accommodate would be difficult. - When it doesn't conflict with YAGNI, architect for extensibility and flexibility. ## Third-Party Dependencies diff --git a/CLAUDE.md b/CLAUDE.md index 0053c468..be8d3626 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -36,7 +36,7 @@ Rule #1: If you want exception to ANY rule, YOU MUST STOP and get explicit permi - If you're uncomfortable pushing back out loud, just say "Strange things are afoot at the Circle K". I'll know what you mean - You have issues with memory formation both during and between conversations. Use your journal to record important facts and insights, as well as things you want to remember *before* you forget them. - You search your journal when you trying to remember or figure stuff out. -- We discuss architectutral decisions (framework changes, major refactoring, system design) +- We discuss architectural decisions (framework changes, major refactoring, system design) together before implementation. Routine fixes and clear implementations don't need discussion. @@ -53,7 +53,7 @@ When asked to do something, just do it - including obvious follow-up actions nee ## Designing software -- YAGNI. The best code is no code. Don't add features we don't need right now, unless they're foundational to later planned work and refactoring to accomodate would be difficult. +- YAGNI. The best code is no code. Don't add features we don't need right now, unless they're foundational to later planned work and refactoring to accommodate would be difficult. - When it doesn't conflict with YAGNI, architect for extensibility and flexibility. ## Third-Party Dependencies From 08e0f2d8c2c09cd4506a2a5357accf26f5f6818e Mon Sep 17 00:00:00 2001 From: Samuel Carson Date: Thu, 23 Apr 2026 19:19:37 -0500 Subject: [PATCH 31/31] docs: refresh README with SCIM, MFA, and infrastructure updates Anchored to the last README update on 2026-03-17, catching up on five weeks of drift: - SCIM 2.0 moved from "planned" to a shipped feature section - added Multi-Factor Authentication section (TOTP + email OTP) - CLI table expanded from 3 to 8 cvert-ops subcommands plus the standalone healthcheck binary - refreshed test counts (2,200+ funcs, 200+ files, 100+ integration) and added SeedCorpus + golden-file fixture description - noted per-feed circuit breakers (sony/gobreaker v2) and SSRF-hardened shared feed client - added crypto, doctor, metrics, secure, tier packages to the project layout - fixed stale docs/plans/ path (now dev/plans/) - softened coverage percentages that are 5 weeks stale Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0117ff22..88fc7ac3 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ CVErt Ops pulls from 10 vulnerability data sources and merges them into a unifie - **CSAF** — Common Security Advisory Framework documents - **Generic** — Configurable adapter for custom or internal feeds -Each source is ingested independently, and a merge pipeline recomputes the canonical CVE record from all available sources on every update. A material hash (SHA-256 over normalized fields) tracks meaningful changes and drives alert evaluation — cosmetic updates don't trigger false alerts. +Each source is ingested independently through a shared HTTP client with per-feed circuit breakers (sony/gobreaker v2), SSRF-hardened transport, and response-body size limits. A merge pipeline recomputes the canonical CVE record from all available sources on every update. A material hash (SHA-256 over normalized fields) tracks meaningful changes and drives alert evaluation — cosmetic updates don't trigger false alerts. ### Full-Text Search and Faceted Filtering @@ -76,9 +76,17 @@ Every org gets full data isolation through dual-layer tenant separation: Four RBAC roles control access: **Owner** > **Admin** > **Member** > **Viewer**. Per-route middleware enforces minimum role requirements. API key authentication is supported with org-scoping and role caps. +### Multi-Factor Authentication + +MFA can be required per-org or per-user, with TOTP (authenticator apps) and email OTP as second factors. Enrollment is a multi-step flow gated by pending tokens that encode the remaining MFA requirements directly in their claims — the client can't skip a step by replaying an earlier token. TOTP verification uses `FOR UPDATE` locking with skew-aware step tracking to prevent code replay. Email OTP challenges have per-attempt rate limits and emit security events when exhausted. Admins can reset a user's MFA atomically, and password reset completion itself is MFA-gated. + ### Enterprise SSO -Organizations can configure OIDC-based single sign-on with domain-based auto-discovery. Supports GitHub OAuth, Google OIDC, and generic OIDC providers. Users can link SSO identities to existing accounts. SCIM provisioning for automated user lifecycle management is planned. +Organizations can configure OIDC-based single sign-on with domain-based auto-discovery. Supports GitHub OAuth, Google OIDC, and generic OIDC providers. Users can link SSO identities to existing accounts. + +### SCIM Provisioning + +Full SCIM 2.0 support for automated user lifecycle management via your identity provider (Okta, Azure AD, Google Workspace, etc.). Bearer-token authenticated endpoints expose standard `/Users` and `/Groups` resources with create/read/update/patch/delete and filter parsing. Group-to-role mappings let you drive RBAC membership directly from IdP groups — changes take effect on the next SCIM sync with no admin action required. Org members can be flagged `scim_exempt` to keep local accounts (emergency access, service accounts) from being deactivated by an IdP sync. A dedicated per-org rate limiter isolates SCIM traffic from the main API budget. ### Site Administration @@ -92,13 +100,13 @@ Site admins get a dedicated set of endpoints and UI views for: ### Testing -CVErt Ops has extensive test coverage — over 1,600 Go test functions across 147 test files, plus 32 frontend test suites. Aggregate statement coverage is 62%, but that number is diluted by generated code (sqlc output), test infrastructure, and CLI boilerplate — all at 0%. Business logic packages where coverage matters most range from 80% to 100%: alert DSL 94%, feed adapters 84-100%, auth 89%, merge 87%, retention 96%, worker 91%. +CVErt Ops has extensive test coverage — over 2,200 Go test functions across 200+ test files, plus 32 frontend test suites. Aggregate statement coverage is diluted by generated code (sqlc output), test infrastructure, and CLI boilerplate — all at 0% by design. Business logic packages where coverage matters most — alert DSL, feed adapters, auth, merge, retention, worker — sit consistently in the 80–100% range. -**Integration tests hit real infrastructure.** Over 70 test files run against a real PostgreSQL instance (via testcontainers) with full RLS enforcement, real migrations, and seeded data. API tests stand up real HTTP servers and exercise the full middleware stack — auth, RBAC, CSRF, tier enforcement, rate limiting. No mocking away the hard parts. +**Integration tests hit real infrastructure.** Over 100 test files run against a real PostgreSQL instance (via testcontainers) with full RLS enforcement, real migrations, and seeded data. API tests stand up real HTTP servers and exercise the full middleware stack — auth, RBAC, MFA, SCIM, CSRF, tier enforcement, rate limiting. No mocking away the hard parts. -**Shared test infrastructure** in `internal/testutil/` provides reusable helpers: a managed test database with automatic migration, seed data utilities, a mock OIDC provider for SSO testing, and a local SMTP server for email delivery tests. This keeps individual test files focused on the behavior under test rather than setup boilerplate. +**Shared test infrastructure** in `internal/testutil/` provides reusable helpers: a managed test database with automatic migration, seed data utilities, a mock OIDC provider for SSO testing, and a local SMTP server for email delivery tests. `testutil.SeedCorpus` seeds a test database with 65 real CVEs across 8 feeds (NVD, MITRE, GHSA, OSV, KEV, MSRC, Red Hat, EPSS) by running captured upstream responses through the real merge pipeline — giving downstream tests (alert evaluation, search, reports) a realistic corpus without hand-crafted fixtures. -**Feed adapter tests** use recorded HTTP responses to verify parsing, streaming, error handling, and rate limit compliance without hitting upstream APIs. Alert DSL tests cover the compiler, evaluator, and all three evaluation paths (realtime, batch, EPSS). Notification delivery tests verify the transactional safety guarantees — claim, commit, deliver, record — with real database state. +**Feed adapter tests** use captured HTTP responses served via `httptest` to verify parsing, streaming, error handling, and rate limit compliance without hitting upstream APIs. Each adapter has a golden-file test that runs real captured responses end-to-end, catching upstream schema drift that unit tests with hand-crafted fixtures cannot detect. Alert DSL tests cover the compiler, evaluator, and all three evaluation paths (realtime, batch, EPSS). Notification delivery tests verify the transactional safety guarantees — claim, commit, deliver, record — with real database state. The frontend uses Vitest with jsdom and Vue Test Utils for component and composable testing. @@ -118,17 +126,23 @@ This project is developed with [Claude Code](https://claude.com/claude-code) usi **Supply chain security** — GitHub CodeQL scans on every PR, Dependabot alerts and automated security update PRs for vulnerable dependencies, secret scanning with push protection, and weekly version update PRs for Go modules, npm packages, and GitHub Actions. -**Structured planning** — features are designed in `docs/plans/` before implementation, with research notes in `dev/research-findings/` capturing technical investigations and trade-off analyses for architectural decisions. +**Structured planning** — features are designed in `dev/plans/` before implementation, with research notes in `dev/research-findings/` capturing technical investigations and trade-off analyses for architectural decisions. ## Architecture -CVErt Ops is a single Go binary with three runtime modes: +CVErt Ops is a single Go binary (`cvert-ops`) with cobra subcommands covering every operational task. A second small binary (`healthcheck`) ships alongside it for container probes. | Command | What it runs | |---------|-------------| | `cvert-ops serve` | HTTP API server + embedded background worker pool | | `cvert-ops worker` | Standalone worker pool (no HTTP) | | `cvert-ops migrate` | Database migrations | +| `cvert-ops import-bulk` | Bulk-import CVE data from a file (dev seed / airgapped loader) | +| `cvert-ops doctor` | System health checks (DB, feeds, config, migrations) | +| `cvert-ops validate-feeds` | Validate feed configuration without running a sync | +| `cvert-ops quota` | Manage per-org AI quota (`set`/`get`/`list`/`delete`) | +| `cvert-ops rotate-encryption-key` | Rotate the at-rest encryption key with re-encrypt pass | +| `healthcheck` | Minimal container liveness/readiness probe | The background worker handles feed ingestion, alert evaluation, notification delivery, retention cleanup, and report generation — all via an internal job queue in PostgreSQL. No Redis, no RabbitMQ, no external dependencies beyond Postgres. @@ -150,21 +164,27 @@ The background worker handles feed ingestion, alert evaluation, notification del ``` cmd/cvert-ops/ CLI entry points (cobra subcommands) +cmd/healthcheck/ Container liveness/readiness probe binary internal/ ai/ LLM client, quota, sanitization alert/ Alert DSL compiler and evaluator - api/ HTTP handlers and middleware + api/ HTTP handlers and middleware (REST + SCIM 2.0) audit/ Audit logging - auth/ JWT, OAuth, API keys, Argon2id + auth/ JWT, OAuth/OIDC, MFA (TOTP + email OTP), API keys, Argon2id config/ Environment-based configuration - feed/ Feed adapters (NVD, MITRE, KEV, OSV, GHSA, EPSS, ...) + crypto/ Encryption helpers (AES-GCM with AAD binding) + doctor/ System health check framework + feed/ Feed adapters + circuit breaker + SSRF-hardened client ingest/ Feed ingestion orchestrator merge/ CVE merge pipeline + metrics/ Prometheus counters and histograms notify/ Notification channels and delivery report/ Scheduled report generation retention/ Data retention policies search/ Full-text search and facets - store/ Repository layer (sqlc + squirrel) + secure/ Async security event pipeline + store/ Repository layer (sqlc + squirrel) + SCIM store methods + tier/ Subscription tier logic worker/ Job queue and worker pool migrations/ SQL migration files (embedded) templates/ Notification and report templates (embedded)