diff --git a/README.md b/README.md
index 901bc90..fa620db 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,8 @@
-
-
+
+
### 🤖 AI-Generated Code
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 53081ec..e463cc2 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -14,32 +14,32 @@
"@fastify/multipart": "^10.0.0",
"@fastify/rate-limit": "^10.3.0",
"@fastify/sensible": "^6.0.4",
- "@fastify/static": "^9.1.0",
+ "@fastify/static": "^9.1.3",
"@fastify/swagger": "^9.7.0",
- "@fastify/swagger-ui": "^5.2.5",
- "@libsql/client": "^0.17.2",
+ "@fastify/swagger-ui": "^5.2.6",
+ "@libsql/client": "^0.17.3",
"argon2": "^0.44.0",
"dotenv": "^17.4.2",
"drizzle-orm": "^0.45.2",
- "fastify": "^5.8.4",
+ "fastify": "^5.8.5",
"fastify-plugin": "^5.0.1",
- "jose": "^6.2.2",
- "nodemailer": "^8.0.5",
- "openid-client": "^6.8.2",
+ "jose": "^6.2.3",
+ "nodemailer": "^8.0.7",
+ "openid-client": "^6.8.4",
"sharp": "^0.34.5",
"zod": "^3.23.8"
},
"devDependencies": {
- "@biomejs/biome": "^2.4.11",
+ "@biomejs/biome": "^2.4.14",
"@types/node": "^25.6.0",
"@types/nodemailer": "^8.0.0",
"@types/supertest": "^7.2.0",
- "@vitest/coverage-v8": "^4.1.4",
+ "@vitest/coverage-v8": "^4.1.5",
"drizzle-kit": "^0.31.10",
"pino-pretty": "^13.1.3",
"supertest": "^7.2.2",
"tsx": "^4.19.0",
- "typescript": "^6.0.2",
+ "typescript": "^6.0.3",
"vitest": "^4.0.16"
}
},
@@ -104,9 +104,9 @@
}
},
"node_modules/@biomejs/biome": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.11.tgz",
- "integrity": "sha512-nWxHX8tf3Opb/qRgZpBbsTOqOodkbrkJ7S+JxJAruxOReaDPPmPuLBAGQ8vigyUgo0QBB+oQltNEAvalLcjggA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.14.tgz",
+ "integrity": "sha512-TmAvxOEgrpLypzVGJ8FulIZnlyA9TxrO1hyqYrCz9r+bwma9xXxuLA5IuYnj55XQneFx460KjRbx6SWGLkg3bQ==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -120,20 +120,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
- "@biomejs/cli-darwin-arm64": "2.4.11",
- "@biomejs/cli-darwin-x64": "2.4.11",
- "@biomejs/cli-linux-arm64": "2.4.11",
- "@biomejs/cli-linux-arm64-musl": "2.4.11",
- "@biomejs/cli-linux-x64": "2.4.11",
- "@biomejs/cli-linux-x64-musl": "2.4.11",
- "@biomejs/cli-win32-arm64": "2.4.11",
- "@biomejs/cli-win32-x64": "2.4.11"
+ "@biomejs/cli-darwin-arm64": "2.4.14",
+ "@biomejs/cli-darwin-x64": "2.4.14",
+ "@biomejs/cli-linux-arm64": "2.4.14",
+ "@biomejs/cli-linux-arm64-musl": "2.4.14",
+ "@biomejs/cli-linux-x64": "2.4.14",
+ "@biomejs/cli-linux-x64-musl": "2.4.14",
+ "@biomejs/cli-win32-arm64": "2.4.14",
+ "@biomejs/cli-win32-x64": "2.4.14"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.11.tgz",
- "integrity": "sha512-wOt+ed+L2dgZanWyL6i29qlXMc088N11optzpo10peayObBaAshbTcxKUchzEMp9QSY8rh5h6VfAFE3WTS1rqg==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.14.tgz",
+ "integrity": "sha512-XvgoE9XOawUOQPdmvs4J7wPhi/DLwSCGks3AlPJDmh34O0awRTqCED1HRcRDdpf1Zrp4us4MGOOdIxNpbqNF5Q==",
"cpu": [
"arm64"
],
@@ -148,9 +148,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.11.tgz",
- "integrity": "sha512-gZ6zR8XmZlExfi/Pz/PffmdpWOQ8Qhy7oBztgkR8/ylSRyLwfRPSadmiVCV8WQ8PoJ2MWUy2fgID9zmtgUUJmw==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.14.tgz",
+ "integrity": "sha512-jE7hKBCFhOx3uUh+ZkWBfOHxAcILPfhFplNkuID/eZeSTLHzfZzoZxW8fbqY9xXRnPi7jGNAf1iPVR+0yWsM/Q==",
"cpu": [
"x64"
],
@@ -165,9 +165,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.11.tgz",
- "integrity": "sha512-avdJaEElXrKceK0va9FkJ4P5ci3N01TGkc6ni3P8l3BElqbOz42Wg2IyX3gbh0ZLEd4HVKEIrmuVu/AMuSeFFA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.14.tgz",
+ "integrity": "sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==",
"cpu": [
"arm64"
],
@@ -182,9 +182,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.11.tgz",
- "integrity": "sha512-+Sbo1OAmlegtdwqFE8iOxFIWLh1B3OEgsuZfBpyyN/kWuqZ8dx9ZEes6zVnDMo+zRHF2wLynRVhoQmV7ohxl2Q==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.14.tgz",
+ "integrity": "sha512-/z+6gqAqqUQTHazwStxSXKHg9b8UvqBmDFRp+c4wYbq2KXhELQDon9EoC9RpmQ8JWkqQx/lIUy/cs+MhzDZp6A==",
"cpu": [
"arm64"
],
@@ -199,9 +199,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.11.tgz",
- "integrity": "sha512-TagWV0iomp5LnEnxWFg4nQO+e52Fow349vaX0Q/PIcX6Zhk4GGBgp3qqZ8PVkpC+cuehRctMf3+6+FgQ8jCEFQ==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.14.tgz",
+ "integrity": "sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==",
"cpu": [
"x64"
],
@@ -216,9 +216,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.11.tgz",
- "integrity": "sha512-bexd2IklK7ZgPhrz6jXzpIL6dEAH9MlJU1xGTrypx+FICxrXUp4CqtwfiuoDKse+UlgAlWtzML3jrMqeEAHEhA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.14.tgz",
+ "integrity": "sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==",
"cpu": [
"x64"
],
@@ -233,9 +233,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.11.tgz",
- "integrity": "sha512-RJhaTnY8byzxDt4bDVb7AFPHkPcjOPK3xBip4ZRTrN3TEfyhjLRm3r3mqknqydgVTB74XG8l4jMLwEACEeihVg==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.14.tgz",
+ "integrity": "sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==",
"cpu": [
"arm64"
],
@@ -250,9 +250,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.11.tgz",
- "integrity": "sha512-A8D3JM/00C2KQgUV3oj8Ba15EHEYwebAGCy5Sf9GAjr5Y3+kJIYOiESoqRDeuRZueuMdCsbLZIUqmPhpYXJE9A==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.14.tgz",
+ "integrity": "sha512-WL0EG5qE+EAKomGXbf2g6VnSKJhTL3tXC0QRzWRwA5VpjxNYa6H4P7ZWfymbGE4IhZZQi1KXQ2R0YjwInmz2fA==",
"cpu": [
"x64"
],
@@ -274,9 +274,9 @@
"license": "Apache-2.0"
},
"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==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -286,9 +286,9 @@
}
},
"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==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"license": "MIT",
"optional": true,
"dependencies": {
@@ -1063,9 +1063,9 @@
}
},
"node_modules/@fastify/static": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/@fastify/static/-/static-9.1.0.tgz",
- "integrity": "sha512-EPRNQYqEYEYTK8yyGbcM0iHpyJaupb94bey5O6iCQfLTADr02kaZU+qeHSdd9H9TiMwTBVkrMa59V8CMbn3avQ==",
+ "version": "9.1.3",
+ "resolved": "https://registry.npmjs.org/@fastify/static/-/static-9.1.3.tgz",
+ "integrity": "sha512-aXrYtsiryLhRxRNaxNqsn7FUISeb7rB9q4eHUPIot5aeQBLNahnz1m6thzm7JWC1poSGXS9XrX8DvuMivp2hkQ==",
"funding": [
{
"type": "github",
@@ -1110,9 +1110,9 @@
}
},
"node_modules/@fastify/swagger-ui": {
- "version": "5.2.5",
- "resolved": "https://registry.npmjs.org/@fastify/swagger-ui/-/swagger-ui-5.2.5.tgz",
- "integrity": "sha512-ky3I0LAkXKX/prwSDpoQ3kscBKsj2Ha6Gp1/JfgQSqyx0bm9F2bE//XmGVGj2cR9l5hUjZYn60/hqn7e+OLgWQ==",
+ "version": "5.2.6",
+ "resolved": "https://registry.npmjs.org/@fastify/swagger-ui/-/swagger-ui-5.2.6.tgz",
+ "integrity": "sha512-OMnms0O5s9wb6wis/K5nlrAMLsgUbr1GA8uphM41IasWe3AFdgxz6r/3bA9HTxlDNUYc2FGGKeqMp3ntxmSiNA==",
"funding": [
{
"type": "github",
@@ -1125,7 +1125,7 @@
],
"license": "MIT",
"dependencies": {
- "@fastify/static": "^9.0.0",
+ "@fastify/static": "^9.1.2",
"fastify-plugin": "^5.0.0",
"openapi-types": "^12.1.3",
"rfdc": "^1.3.1",
@@ -1635,22 +1635,22 @@
}
},
"node_modules/@libsql/client": {
- "version": "0.17.2",
- "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.17.2.tgz",
- "integrity": "sha512-0aw0S3iQMHvOxfRt5j1atoCCPMT3gjsB2PS8/uxSM1DcDn39xqz6RlgSMxtP8I3JsxIXAFuw7S41baLEw0Zi+Q==",
+ "version": "0.17.3",
+ "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.17.3.tgz",
+ "integrity": "sha512-HXk9wiAoJbKFbyBH4O+aEhN6ir5ERXuXvwE5OD2eR4/5RUa3Pw/8L9zrnVdU+iNJitRvisPWaIwmhkO3bH7giA==",
"license": "MIT",
"dependencies": {
- "@libsql/core": "^0.17.2",
- "@libsql/hrana-client": "^0.9.0",
+ "@libsql/core": "^0.17.3",
+ "@libsql/hrana-client": "^0.10.0",
"js-base64": "^3.7.5",
"libsql": "^0.5.28",
"promise-limit": "^2.7.0"
}
},
"node_modules/@libsql/core": {
- "version": "0.17.2",
- "resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.17.2.tgz",
- "integrity": "sha512-L8qv12HZ/jRBcETVR3rscP0uHNxh+K3EABSde6scCw7zfOdiLqO3MAkJaeE1WovPsjXzsN/JBoZED4+7EZVT3g==",
+ "version": "0.17.3",
+ "resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.17.3.tgz",
+ "integrity": "sha512-2UjK1i7JBkMduJo4WdvvBxMMvVJ31pArBZNONyz/GCJJAH+1UHat2X6vn10S/WpY5fKzIT98WqYFl2vzWRLOfg==",
"license": "MIT",
"dependencies": {
"js-base64": "^3.7.5"
@@ -1683,15 +1683,13 @@
]
},
"node_modules/@libsql/hrana-client": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.9.0.tgz",
- "integrity": "sha512-pxQ1986AuWfPX4oXzBvLwBnfgKDE5OMhAdR/5cZmRaB4Ygz5MecQybvwZupnRz341r2CtFmbk/BhSu7k2Lm+Jw==",
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.10.0.tgz",
+ "integrity": "sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==",
"license": "MIT",
"dependencies": {
"@libsql/isomorphic-ws": "^0.1.5",
- "cross-fetch": "^4.0.0",
- "js-base64": "^3.7.5",
- "node-fetch": "^3.3.2"
+ "js-base64": "^3.7.5"
}
},
"node_modules/@libsql/isomorphic-ws": {
@@ -1805,9 +1803,9 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz",
- "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
+ "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -1843,9 +1841,9 @@
}
},
"node_modules/@oxc-project/types": {
- "version": "0.124.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz",
- "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==",
+ "version": "0.127.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz",
+ "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -1878,9 +1876,9 @@
"license": "MIT"
},
"node_modules/@rolldown/binding-android-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==",
"cpu": [
"arm64"
],
@@ -1895,9 +1893,9 @@
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==",
"cpu": [
"arm64"
],
@@ -1912,9 +1910,9 @@
}
},
"node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz",
- "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==",
"cpu": [
"x64"
],
@@ -1929,9 +1927,9 @@
}
},
"node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz",
- "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==",
"cpu": [
"x64"
],
@@ -1946,9 +1944,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz",
- "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz",
+ "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==",
"cpu": [
"arm"
],
@@ -1963,9 +1961,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==",
"cpu": [
"arm64"
],
@@ -1980,9 +1978,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz",
- "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz",
+ "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==",
"cpu": [
"arm64"
],
@@ -1997,9 +1995,9 @@
}
},
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==",
"cpu": [
"ppc64"
],
@@ -2014,9 +2012,9 @@
}
},
"node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==",
"cpu": [
"s390x"
],
@@ -2031,9 +2029,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==",
"cpu": [
"x64"
],
@@ -2048,9 +2046,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz",
- "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz",
+ "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==",
"cpu": [
"x64"
],
@@ -2065,9 +2063,9 @@
}
},
"node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==",
"cpu": [
"arm64"
],
@@ -2082,9 +2080,9 @@
}
},
"node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz",
- "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz",
+ "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==",
"cpu": [
"wasm32"
],
@@ -2092,18 +2090,18 @@
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/core": "1.9.2",
- "@emnapi/runtime": "1.9.2",
- "@napi-rs/wasm-runtime": "^1.1.3"
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
},
"engines": {
- "node": ">=14.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz",
- "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz",
+ "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==",
"cpu": [
"arm64"
],
@@ -2118,9 +2116,9 @@
}
},
"node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz",
- "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz",
+ "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==",
"cpu": [
"x64"
],
@@ -2135,9 +2133,9 @@
}
},
"node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz",
- "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz",
+ "integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==",
"dev": true,
"license": "MIT"
},
@@ -2251,14 +2249,14 @@
}
},
"node_modules/@vitest/coverage-v8": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.4.tgz",
- "integrity": "sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.5.tgz",
+ "integrity": "sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^1.0.2",
- "@vitest/utils": "4.1.4",
+ "@vitest/utils": "4.1.5",
"ast-v8-to-istanbul": "^1.0.0",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
@@ -2272,8 +2270,8 @@
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
- "@vitest/browser": "4.1.4",
- "vitest": "4.1.4"
+ "@vitest/browser": "4.1.5",
+ "vitest": "4.1.5"
},
"peerDependenciesMeta": {
"@vitest/browser": {
@@ -2282,16 +2280,16 @@
}
},
"node_modules/@vitest/expect": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.4.tgz",
- "integrity": "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz",
+ "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.1.0",
"@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/spy": "4.1.5",
+ "@vitest/utils": "4.1.5",
"chai": "^6.2.2",
"tinyrainbow": "^3.1.0"
},
@@ -2300,13 +2298,13 @@
}
},
"node_modules/@vitest/mocker": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.4.tgz",
- "integrity": "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz",
+ "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "4.1.4",
+ "@vitest/spy": "4.1.5",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.21"
},
@@ -2327,9 +2325,9 @@
}
},
"node_modules/@vitest/pretty-format": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz",
- "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz",
+ "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2340,13 +2338,13 @@
}
},
"node_modules/@vitest/runner": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.4.tgz",
- "integrity": "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz",
+ "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "4.1.4",
+ "@vitest/utils": "4.1.5",
"pathe": "^2.0.3"
},
"funding": {
@@ -2354,14 +2352,14 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.4.tgz",
- "integrity": "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz",
+ "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/pretty-format": "4.1.5",
+ "@vitest/utils": "4.1.5",
"magic-string": "^0.30.21",
"pathe": "^2.0.3"
},
@@ -2370,9 +2368,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.4.tgz",
- "integrity": "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz",
+ "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -2380,13 +2378,13 @@
}
},
"node_modules/@vitest/utils": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz",
- "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz",
+ "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.4",
+ "@vitest/pretty-format": "4.1.5",
"convert-source-map": "^2.0.0",
"tinyrainbow": "^3.1.0"
},
@@ -2682,35 +2680,6 @@
"node": ">=20"
}
},
- "node_modules/cross-fetch": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
- "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
- "license": "MIT",
- "dependencies": {
- "node-fetch": "^2.7.0"
- }
- },
- "node_modules/cross-fetch/node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2725,15 +2694,6 @@
"node": ">= 8"
}
},
- "node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
"node_modules/dateformat": {
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
@@ -3186,9 +3146,9 @@
"license": "BSD-3-Clause"
},
"node_modules/fastify": {
- "version": "5.8.4",
- "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.8.4.tgz",
- "integrity": "sha512-sa42J1xylbBAYUWALSBoyXKPDUvM3OoNOibIefA+Oha57FryXKKCZarA1iDntOCWp3O35voZLuDg2mdODXtPzQ==",
+ "version": "5.8.5",
+ "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.8.5.tgz",
+ "integrity": "sha512-Yqptv59pQzPgQUSIm87hMqHJmdkb1+GPxdE6vW6FRyVE9G86mt7rOghitiU4JHRaTyDUk9pfeKmDeu70lAwM4Q==",
"funding": [
{
"type": "github",
@@ -3261,29 +3221,6 @@
}
}
},
- "node_modules/fetch-blob": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
- "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
- },
- "engines": {
- "node": "^12.20 || >= 14.13"
- }
- },
"node_modules/find-my-way": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.3.0.tgz",
@@ -3338,18 +3275,6 @@
"node": ">= 0.6"
}
},
- "node_modules/formdata-polyfill": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
- "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
- "license": "MIT",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
"node_modules/formidable": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz",
@@ -3655,9 +3580,9 @@
}
},
"node_modules/jose": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz",
- "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==",
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz",
+ "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
@@ -4249,44 +4174,6 @@
"node": "^18 || ^20 || >= 21"
}
},
- "node_modules/node-domexception": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
- "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
- "deprecated": "Use your platform's native DOMException instead",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "github",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=10.5.0"
- }
- },
- "node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "license": "MIT",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
@@ -4299,18 +4186,18 @@
}
},
"node_modules/nodemailer": {
- "version": "8.0.5",
- "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.5.tgz",
- "integrity": "sha512-0PF8Yb1yZuQfQbq+5/pZJrtF6WQcjTd5/S4JOHs9PGFxuTqoB/icwuB44pOdURHJbRKX1PPoJZtY7R4VUoCC8w==",
+ "version": "8.0.7",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.7.tgz",
+ "integrity": "sha512-pkjE4mkBzQjdJT4/UmlKl3pX0rC9fZmjh7c6C9o7lv66Ac6w9WCnzPzhbPNxwZAzlF4mdq4CSWB5+FbK6FWCow==",
"license": "MIT-0",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/oauth4webapi": {
- "version": "3.8.4",
- "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.4.tgz",
- "integrity": "sha512-EKlVEgav8zH31IXxvhCqjEgQws6S9QmnmJyLXmeV5REf59g7VmqRVa5l/rhGWtUqGm2rLVTNwukn9hla5kJ2WQ==",
+ "version": "3.8.5",
+ "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.5.tgz",
+ "integrity": "sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
@@ -4366,13 +4253,13 @@
"license": "MIT"
},
"node_modules/openid-client": {
- "version": "6.8.2",
- "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.8.2.tgz",
- "integrity": "sha512-uOvTCndr4udZsKihJ68H9bUICrriHdUVJ6Az+4Ns6cW55rwM5h0bjVIzDz2SxgOI84LKjFyjOFvERLzdTUROGA==",
+ "version": "6.8.4",
+ "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.8.4.tgz",
+ "integrity": "sha512-QSw0BA08piujetEwfZsHoTrDpMEha7GDZDicQqVwX4u0ChCjefvjDB++TZ8BTg76UpwhzIQgdvvfgfl3HpCSAw==",
"license": "MIT",
"dependencies": {
- "jose": "^6.1.3",
- "oauth4webapi": "^3.8.4"
+ "jose": "^6.2.2",
+ "oauth4webapi": "^3.8.5"
},
"funding": {
"url": "https://github.com/sponsors/panva"
@@ -4503,9 +4390,9 @@
"license": "MIT"
},
"node_modules/postcss": {
- "version": "8.5.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
- "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==",
+ "version": "8.5.12",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz",
+ "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==",
"dev": true,
"funding": [
{
@@ -4640,14 +4527,14 @@
"license": "MIT"
},
"node_modules/rolldown": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz",
- "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz",
+ "integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/types": "=0.124.0",
- "@rolldown/pluginutils": "1.0.0-rc.15"
+ "@oxc-project/types": "=0.127.0",
+ "@rolldown/pluginutils": "1.0.0-rc.17"
},
"bin": {
"rolldown": "bin/cli.mjs"
@@ -4656,21 +4543,21 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.0.0-rc.15",
- "@rolldown/binding-darwin-arm64": "1.0.0-rc.15",
- "@rolldown/binding-darwin-x64": "1.0.0-rc.15",
- "@rolldown/binding-freebsd-x64": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15",
- "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15",
- "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15",
- "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15",
- "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15",
- "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15"
+ "@rolldown/binding-android-arm64": "1.0.0-rc.17",
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.17",
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.17",
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.17",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17"
}
},
"node_modules/safe-regex2": {
@@ -5116,12 +5003,6 @@
"node": ">=0.6"
}
},
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -5164,9 +5045,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": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -5193,17 +5074,17 @@
}
},
"node_modules/vite": {
- "version": "8.0.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz",
- "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
+ "version": "8.0.10",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz",
+ "integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==",
"dev": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
- "postcss": "^8.5.8",
- "rolldown": "1.0.0-rc.15",
- "tinyglobby": "^0.2.15"
+ "postcss": "^8.5.10",
+ "rolldown": "1.0.0-rc.17",
+ "tinyglobby": "^0.2.16"
},
"bin": {
"vite": "bin/vite.js"
@@ -5271,19 +5152,19 @@
}
},
"node_modules/vitest": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.4.tgz",
- "integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz",
+ "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/expect": "4.1.4",
- "@vitest/mocker": "4.1.4",
- "@vitest/pretty-format": "4.1.4",
- "@vitest/runner": "4.1.4",
- "@vitest/snapshot": "4.1.4",
- "@vitest/spy": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/expect": "4.1.5",
+ "@vitest/mocker": "4.1.5",
+ "@vitest/pretty-format": "4.1.5",
+ "@vitest/runner": "4.1.5",
+ "@vitest/snapshot": "4.1.5",
+ "@vitest/spy": "4.1.5",
+ "@vitest/utils": "4.1.5",
"es-module-lexer": "^2.0.0",
"expect-type": "^1.3.0",
"magic-string": "^0.30.21",
@@ -5311,12 +5192,12 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.1.4",
- "@vitest/browser-preview": "4.1.4",
- "@vitest/browser-webdriverio": "4.1.4",
- "@vitest/coverage-istanbul": "4.1.4",
- "@vitest/coverage-v8": "4.1.4",
- "@vitest/ui": "4.1.4",
+ "@vitest/browser-playwright": "4.1.5",
+ "@vitest/browser-preview": "4.1.5",
+ "@vitest/browser-webdriverio": "4.1.5",
+ "@vitest/coverage-istanbul": "4.1.5",
+ "@vitest/coverage-v8": "4.1.5",
+ "@vitest/ui": "4.1.5",
"happy-dom": "*",
"jsdom": "*",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -5360,31 +5241,6 @@
}
}
},
- "node_modules/web-streams-polyfill": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
- "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -5425,9 +5281,9 @@
"license": "ISC"
},
"node_modules/ws": {
- "version": "8.19.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
- "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
+ "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
diff --git a/backend/package.json b/backend/package.json
index cbf2bd8..d349961 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -23,32 +23,32 @@
"@fastify/multipart": "^10.0.0",
"@fastify/rate-limit": "^10.3.0",
"@fastify/sensible": "^6.0.4",
- "@fastify/static": "^9.1.0",
+ "@fastify/static": "^9.1.3",
"@fastify/swagger": "^9.7.0",
- "@fastify/swagger-ui": "^5.2.5",
- "@libsql/client": "^0.17.2",
+ "@fastify/swagger-ui": "^5.2.6",
+ "@libsql/client": "^0.17.3",
"argon2": "^0.44.0",
"dotenv": "^17.4.2",
"drizzle-orm": "^0.45.2",
- "fastify": "^5.8.4",
+ "fastify": "^5.8.5",
"fastify-plugin": "^5.0.1",
- "jose": "^6.2.2",
- "nodemailer": "^8.0.5",
- "openid-client": "^6.8.2",
+ "jose": "^6.2.3",
+ "nodemailer": "^8.0.7",
+ "openid-client": "^6.8.4",
"sharp": "^0.34.5",
"zod": "^3.23.8"
},
"devDependencies": {
- "@biomejs/biome": "^2.4.11",
+ "@biomejs/biome": "^2.4.14",
"@types/node": "^25.6.0",
"@types/nodemailer": "^8.0.0",
"@types/supertest": "^7.2.0",
- "@vitest/coverage-v8": "^4.1.4",
+ "@vitest/coverage-v8": "^4.1.5",
"drizzle-kit": "^0.31.10",
"pino-pretty": "^13.1.3",
"supertest": "^7.2.2",
"tsx": "^4.19.0",
- "typescript": "^6.0.2",
+ "typescript": "^6.0.3",
"vitest": "^4.0.16"
},
"overrides": {
diff --git a/backend/src/test/image-upload.test.ts b/backend/src/test/image-upload.test.ts
new file mode 100644
index 0000000..3d60ea2
--- /dev/null
+++ b/backend/src/test/image-upload.test.ts
@@ -0,0 +1,87 @@
+import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+import { Readable } from "node:stream";
+import sharp from "sharp";
+import { afterEach, describe, expect, it, vi } from "vitest";
+import {
+ getThumbFilename,
+ MAX_IMAGE_UPLOAD_BYTES,
+ removeImageFiles,
+ streamToBuffer,
+ writeOptimizedImageSet,
+} from "../utils/image-upload";
+
+describe("image-upload utils", () => {
+ const MOCK_TIMESTAMP_MS = 1_700_000_000_000;
+ const tempDirs: string[] = [];
+
+ afterEach(() => {
+ vi.restoreAllMocks();
+ for (const dir of tempDirs.splice(0)) {
+ rmSync(dir, { recursive: true, force: true });
+ }
+ });
+
+ it("builds thumb filename with and without extension", () => {
+ expect(getThumbFilename("avatar.png")).toBe("avatar-thumb.webp");
+ expect(getThumbFilename("avatar")).toBe("avatar-thumb.webp");
+ });
+
+ it("removes original and thumb files when they exist", () => {
+ const imagesDir = mkdtempSync(join(tmpdir(), "medassist-image-upload-"));
+ tempDirs.push(imagesDir);
+
+ const imageFilename = "profile.webp";
+ const imagePath = join(imagesDir, imageFilename);
+ const thumbPath = join(imagesDir, getThumbFilename(imageFilename));
+ writeFileSync(imagePath, Buffer.from("image"));
+ writeFileSync(thumbPath, Buffer.from("thumb"));
+
+ removeImageFiles(imagesDir, imageFilename);
+
+ expect(() => readFileSync(imagePath)).toThrow();
+ expect(() => readFileSync(thumbPath)).toThrow();
+ });
+
+ it("buffers stream chunks and rejects payloads above max size", async () => {
+ const stream = Readable.from([Buffer.from("hello"), Buffer.from("world")]);
+ await expect(streamToBuffer(stream)).resolves.toEqual(Buffer.from("helloworld"));
+
+ const oversized = Readable.from([Buffer.alloc(MAX_IMAGE_UPLOAD_BYTES + 1)]);
+ await expect(streamToBuffer(oversized)).rejects.toThrow("IMAGE_TOO_LARGE");
+ });
+
+ it("writes optimized full and thumbnail webp variants", async () => {
+ const imagesDir = mkdtempSync(join(tmpdir(), "medassist-image-upload-"));
+ tempDirs.push(imagesDir);
+ vi.spyOn(Date, "now").mockReturnValue(MOCK_TIMESTAMP_MS);
+
+ const uploadBuffer = await sharp({
+ create: {
+ width: 64,
+ height: 48,
+ channels: 3,
+ background: { r: 255, g: 0, b: 0 },
+ },
+ })
+ .png()
+ .toBuffer();
+
+ const result = await writeOptimizedImageSet(imagesDir, "med-42", uploadBuffer, {
+ maxEdgePx: 32,
+ thumbSizePx: 16,
+ });
+
+ expect(result.filename).toBe("med-42-1700000000000.webp");
+ expect(result.thumbFilename).toBe("med-42-1700000000000-thumb.webp");
+
+ const optimizedMeta = await sharp(join(imagesDir, result.filename)).metadata();
+ const thumbMeta = await sharp(join(imagesDir, result.thumbFilename)).metadata();
+ expect(optimizedMeta.format).toBe("webp");
+ expect(thumbMeta.format).toBe("webp");
+ expect(Math.max(optimizedMeta.width ?? 0, optimizedMeta.height ?? 0)).toBeLessThanOrEqual(32);
+ expect(thumbMeta.width).toBe(16);
+ expect(thumbMeta.height).toBe(16);
+ });
+});
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index c017804..18f63aa 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -8,17 +8,17 @@
"name": "medassist-ng-frontend",
"version": "1.23.0",
"dependencies": {
- "i18next": "^26.0.4",
+ "i18next": "^26.0.8",
"i18next-browser-languagedetector": "^8.2.1",
- "lucide-react": "^1.8.0",
+ "lucide-react": "^1.14.0",
"react": "^19.2.5",
"react-dom": "^19.2.5",
- "react-i18next": "^17.0.2",
- "react-router-dom": "^7.14.0",
- "zod": "^4.3.6"
+ "react-i18next": "^17.0.6",
+ "react-router-dom": "^7.14.2",
+ "zod": "^4.4.2"
},
"devDependencies": {
- "@biomejs/biome": "^2.4.11",
+ "@biomejs/biome": "^2.4.14",
"@playwright/test": "^1.59.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
@@ -28,10 +28,10 @@
"@types/react-dom": "^19.2.3",
"@types/react-router-dom": "^5.3.3",
"@vitejs/plugin-react": "^6.0.1",
- "@vitest/coverage-v8": "^4.1.4",
- "jsdom": "^29.0.2",
- "typescript": "^6.0.2",
- "vite": "^8.0.8",
+ "@vitest/coverage-v8": "^4.1.5",
+ "jsdom": "^29.1.1",
+ "typescript": "^6.0.3",
+ "vite": "^8.0.10",
"vitest": "^4.1.0"
}
},
@@ -43,14 +43,15 @@
"license": "MIT"
},
"node_modules/@asamuzakjp/css-color": {
- "version": "5.1.10",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.10.tgz",
- "integrity": "sha512-02OhhkKtgNRuicQ/nF3TRnGsxL9wp0r3Y7VlKWyOHHGmGyvXv03y+PnymU8FKFJMTjIr1Bk8U2g1HWSLrpAHww==",
+ "version": "5.1.11",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz",
+ "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@csstools/css-calc": "^3.1.1",
- "@csstools/css-color-parser": "^4.0.2",
+ "@asamuzakjp/generational-cache": "^1.0.1",
+ "@csstools/css-calc": "^3.2.0",
+ "@csstools/css-color-parser": "^4.1.0",
"@csstools/css-parser-algorithms": "^4.0.0",
"@csstools/css-tokenizer": "^4.0.0"
},
@@ -59,12 +60,13 @@
}
},
"node_modules/@asamuzakjp/dom-selector": {
- "version": "7.0.9",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.0.9.tgz",
- "integrity": "sha512-r3ElRr7y8ucyN2KdICwGsmj19RoN13CLCa/pvGydghWK6ZzeKQ+TcDjVdtEZz2ElpndM5jXw//B9CEee0mWnVg==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz",
+ "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "@asamuzakjp/generational-cache": "^1.0.1",
"@asamuzakjp/nwsapi": "^2.3.9",
"bidi-js": "^1.0.3",
"css-tree": "^3.2.1",
@@ -74,6 +76,16 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
+ "node_modules/@asamuzakjp/generational-cache": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz",
+ "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
"node_modules/@asamuzakjp/nwsapi": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
@@ -167,9 +179,9 @@
}
},
"node_modules/@biomejs/biome": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.11.tgz",
- "integrity": "sha512-nWxHX8tf3Opb/qRgZpBbsTOqOodkbrkJ7S+JxJAruxOReaDPPmPuLBAGQ8vigyUgo0QBB+oQltNEAvalLcjggA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.14.tgz",
+ "integrity": "sha512-TmAvxOEgrpLypzVGJ8FulIZnlyA9TxrO1hyqYrCz9r+bwma9xXxuLA5IuYnj55XQneFx460KjRbx6SWGLkg3bQ==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -183,20 +195,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
- "@biomejs/cli-darwin-arm64": "2.4.11",
- "@biomejs/cli-darwin-x64": "2.4.11",
- "@biomejs/cli-linux-arm64": "2.4.11",
- "@biomejs/cli-linux-arm64-musl": "2.4.11",
- "@biomejs/cli-linux-x64": "2.4.11",
- "@biomejs/cli-linux-x64-musl": "2.4.11",
- "@biomejs/cli-win32-arm64": "2.4.11",
- "@biomejs/cli-win32-x64": "2.4.11"
+ "@biomejs/cli-darwin-arm64": "2.4.14",
+ "@biomejs/cli-darwin-x64": "2.4.14",
+ "@biomejs/cli-linux-arm64": "2.4.14",
+ "@biomejs/cli-linux-arm64-musl": "2.4.14",
+ "@biomejs/cli-linux-x64": "2.4.14",
+ "@biomejs/cli-linux-x64-musl": "2.4.14",
+ "@biomejs/cli-win32-arm64": "2.4.14",
+ "@biomejs/cli-win32-x64": "2.4.14"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.11.tgz",
- "integrity": "sha512-wOt+ed+L2dgZanWyL6i29qlXMc088N11optzpo10peayObBaAshbTcxKUchzEMp9QSY8rh5h6VfAFE3WTS1rqg==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.14.tgz",
+ "integrity": "sha512-XvgoE9XOawUOQPdmvs4J7wPhi/DLwSCGks3AlPJDmh34O0awRTqCED1HRcRDdpf1Zrp4us4MGOOdIxNpbqNF5Q==",
"cpu": [
"arm64"
],
@@ -211,9 +223,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.11.tgz",
- "integrity": "sha512-gZ6zR8XmZlExfi/Pz/PffmdpWOQ8Qhy7oBztgkR8/ylSRyLwfRPSadmiVCV8WQ8PoJ2MWUy2fgID9zmtgUUJmw==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.14.tgz",
+ "integrity": "sha512-jE7hKBCFhOx3uUh+ZkWBfOHxAcILPfhFplNkuID/eZeSTLHzfZzoZxW8fbqY9xXRnPi7jGNAf1iPVR+0yWsM/Q==",
"cpu": [
"x64"
],
@@ -228,9 +240,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.11.tgz",
- "integrity": "sha512-avdJaEElXrKceK0va9FkJ4P5ci3N01TGkc6ni3P8l3BElqbOz42Wg2IyX3gbh0ZLEd4HVKEIrmuVu/AMuSeFFA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.14.tgz",
+ "integrity": "sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==",
"cpu": [
"arm64"
],
@@ -245,9 +257,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.11.tgz",
- "integrity": "sha512-+Sbo1OAmlegtdwqFE8iOxFIWLh1B3OEgsuZfBpyyN/kWuqZ8dx9ZEes6zVnDMo+zRHF2wLynRVhoQmV7ohxl2Q==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.14.tgz",
+ "integrity": "sha512-/z+6gqAqqUQTHazwStxSXKHg9b8UvqBmDFRp+c4wYbq2KXhELQDon9EoC9RpmQ8JWkqQx/lIUy/cs+MhzDZp6A==",
"cpu": [
"arm64"
],
@@ -262,9 +274,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.11.tgz",
- "integrity": "sha512-TagWV0iomp5LnEnxWFg4nQO+e52Fow349vaX0Q/PIcX6Zhk4GGBgp3qqZ8PVkpC+cuehRctMf3+6+FgQ8jCEFQ==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.14.tgz",
+ "integrity": "sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==",
"cpu": [
"x64"
],
@@ -279,9 +291,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.11.tgz",
- "integrity": "sha512-bexd2IklK7ZgPhrz6jXzpIL6dEAH9MlJU1xGTrypx+FICxrXUp4CqtwfiuoDKse+UlgAlWtzML3jrMqeEAHEhA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.14.tgz",
+ "integrity": "sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==",
"cpu": [
"x64"
],
@@ -296,9 +308,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.11.tgz",
- "integrity": "sha512-RJhaTnY8byzxDt4bDVb7AFPHkPcjOPK3xBip4ZRTrN3TEfyhjLRm3r3mqknqydgVTB74XG8l4jMLwEACEeihVg==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.14.tgz",
+ "integrity": "sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==",
"cpu": [
"arm64"
],
@@ -313,9 +325,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.11.tgz",
- "integrity": "sha512-A8D3JM/00C2KQgUV3oj8Ba15EHEYwebAGCy5Sf9GAjr5Y3+kJIYOiESoqRDeuRZueuMdCsbLZIUqmPhpYXJE9A==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.14.tgz",
+ "integrity": "sha512-WL0EG5qE+EAKomGXbf2g6VnSKJhTL3tXC0QRzWRwA5VpjxNYa6H4P7ZWfymbGE4IhZZQi1KXQ2R0YjwInmz2fA==",
"cpu": [
"x64"
],
@@ -438,9 +450,9 @@
}
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.1.tgz",
- "integrity": "sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.3.tgz",
+ "integrity": "sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==",
"dev": true,
"funding": [
{
@@ -483,9 +495,9 @@
}
},
"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==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -495,9 +507,9 @@
}
},
"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==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -563,9 +575,9 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz",
- "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
+ "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -582,9 +594,9 @@
}
},
"node_modules/@oxc-project/types": {
- "version": "0.124.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz",
- "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==",
+ "version": "0.127.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz",
+ "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -608,9 +620,9 @@
}
},
"node_modules/@rolldown/binding-android-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==",
"cpu": [
"arm64"
],
@@ -625,9 +637,9 @@
}
},
"node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==",
"cpu": [
"arm64"
],
@@ -642,9 +654,9 @@
}
},
"node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz",
- "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==",
"cpu": [
"x64"
],
@@ -659,9 +671,9 @@
}
},
"node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz",
- "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==",
"cpu": [
"x64"
],
@@ -676,9 +688,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz",
- "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz",
+ "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==",
"cpu": [
"arm"
],
@@ -693,9 +705,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==",
"cpu": [
"arm64"
],
@@ -710,9 +722,9 @@
}
},
"node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz",
- "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz",
+ "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==",
"cpu": [
"arm64"
],
@@ -727,9 +739,9 @@
}
},
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==",
"cpu": [
"ppc64"
],
@@ -744,9 +756,9 @@
}
},
"node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==",
"cpu": [
"s390x"
],
@@ -761,9 +773,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz",
- "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==",
"cpu": [
"x64"
],
@@ -778,9 +790,9 @@
}
},
"node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz",
- "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz",
+ "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==",
"cpu": [
"x64"
],
@@ -795,9 +807,9 @@
}
},
"node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz",
- "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==",
"cpu": [
"arm64"
],
@@ -812,9 +824,9 @@
}
},
"node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz",
- "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz",
+ "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==",
"cpu": [
"wasm32"
],
@@ -822,18 +834,18 @@
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/core": "1.9.2",
- "@emnapi/runtime": "1.9.2",
- "@napi-rs/wasm-runtime": "^1.1.3"
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
},
"engines": {
- "node": ">=14.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz",
- "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz",
+ "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==",
"cpu": [
"arm64"
],
@@ -848,9 +860,9 @@
}
},
"node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz",
- "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz",
+ "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==",
"cpu": [
"x64"
],
@@ -1099,14 +1111,14 @@
}
},
"node_modules/@vitest/coverage-v8": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.4.tgz",
- "integrity": "sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.5.tgz",
+ "integrity": "sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^1.0.2",
- "@vitest/utils": "4.1.4",
+ "@vitest/utils": "4.1.5",
"ast-v8-to-istanbul": "^1.0.0",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
@@ -1120,8 +1132,8 @@
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
- "@vitest/browser": "4.1.4",
- "vitest": "4.1.4"
+ "@vitest/browser": "4.1.5",
+ "vitest": "4.1.5"
},
"peerDependenciesMeta": {
"@vitest/browser": {
@@ -1130,16 +1142,16 @@
}
},
"node_modules/@vitest/expect": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.4.tgz",
- "integrity": "sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.5.tgz",
+ "integrity": "sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.1.0",
"@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/spy": "4.1.5",
+ "@vitest/utils": "4.1.5",
"chai": "^6.2.2",
"tinyrainbow": "^3.1.0"
},
@@ -1148,13 +1160,13 @@
}
},
"node_modules/@vitest/mocker": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.4.tgz",
- "integrity": "sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.5.tgz",
+ "integrity": "sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "4.1.4",
+ "@vitest/spy": "4.1.5",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.21"
},
@@ -1175,9 +1187,9 @@
}
},
"node_modules/@vitest/pretty-format": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.4.tgz",
- "integrity": "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.5.tgz",
+ "integrity": "sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1188,13 +1200,13 @@
}
},
"node_modules/@vitest/runner": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.4.tgz",
- "integrity": "sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.5.tgz",
+ "integrity": "sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "4.1.4",
+ "@vitest/utils": "4.1.5",
"pathe": "^2.0.3"
},
"funding": {
@@ -1202,14 +1214,14 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.4.tgz",
- "integrity": "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.5.tgz",
+ "integrity": "sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/pretty-format": "4.1.5",
+ "@vitest/utils": "4.1.5",
"magic-string": "^0.30.21",
"pathe": "^2.0.3"
},
@@ -1218,9 +1230,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.4.tgz",
- "integrity": "sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.5.tgz",
+ "integrity": "sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -1228,13 +1240,13 @@
}
},
"node_modules/@vitest/utils": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.4.tgz",
- "integrity": "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.5.tgz",
+ "integrity": "sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "4.1.4",
+ "@vitest/pretty-format": "4.1.5",
"convert-source-map": "^2.0.0",
"tinyrainbow": "^3.1.0"
},
@@ -1424,13 +1436,13 @@
"peer": true
},
"node_modules/entities": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
- "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
+ "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
- "node": ">=0.12"
+ "node": ">=20.19.0"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
@@ -1536,9 +1548,9 @@
}
},
"node_modules/i18next": {
- "version": "26.0.4",
- "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.0.4.tgz",
- "integrity": "sha512-gXF7U9bfioXPLv7mw8Qt2nfO7vij5MyINvPgVv99pX3fL1Y01pw2mKBFrlYpRxRCl2wz3ISenj6VsMJT2isfuA==",
+ "version": "26.0.8",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.0.8.tgz",
+ "integrity": "sha512-BRzLom0mhDhV9v0QhgUUHWQJuwFmnr1194xEcNLYD6ym8y8s542n4jXUvRLnhNTbh9PmpU6kGZamyuGHQMsGjw==",
"funding": [
{
"type": "individual",
@@ -1554,9 +1566,6 @@
}
],
"license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.29.2"
- },
"peerDependencies": {
"typescript": "^5 || ^6"
},
@@ -1640,28 +1649,28 @@
"peer": true
},
"node_modules/jsdom": {
- "version": "29.0.2",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.0.2.tgz",
- "integrity": "sha512-9VnGEBosc/ZpwyOsJBCQ/3I5p7Q5ngOY14a9bf5btenAORmZfDse1ZEheMiWcJ3h81+Fv7HmJFdS0szo/waF2w==",
+ "version": "29.1.1",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz",
+ "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@asamuzakjp/css-color": "^5.1.5",
- "@asamuzakjp/dom-selector": "^7.0.6",
+ "@asamuzakjp/css-color": "^5.1.11",
+ "@asamuzakjp/dom-selector": "^7.1.1",
"@bramus/specificity": "^2.4.2",
- "@csstools/css-syntax-patches-for-csstree": "^1.1.1",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.3",
"@exodus/bytes": "^1.15.0",
"css-tree": "^3.2.1",
"data-urls": "^7.0.0",
"decimal.js": "^10.6.0",
"html-encoding-sniffer": "^6.0.0",
"is-potential-custom-element-name": "^1.0.1",
- "lru-cache": "^11.2.7",
- "parse5": "^8.0.0",
+ "lru-cache": "^11.3.5",
+ "parse5": "^8.0.1",
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^6.0.1",
- "undici": "^7.24.5",
+ "undici": "^7.25.0",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^8.0.1",
"whatwg-mimetype": "^5.0.0",
@@ -1942,9 +1951,9 @@
}
},
"node_modules/lru-cache": {
- "version": "11.3.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.3.tgz",
- "integrity": "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==",
+ "version": "11.3.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz",
+ "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -1952,9 +1961,9 @@
}
},
"node_modules/lucide-react": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.8.0.tgz",
- "integrity": "sha512-WuvlsjngSk7TnTBJ1hsCy3ql9V9VOdcPkd3PKcSmM34vJD8KG6molxz7m7zbYFgICwsanQWmJ13JlYs4Zp7Arw==",
+ "version": "1.14.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.14.0.tgz",
+ "integrity": "sha512-+1mdWcfSJVUsaTIjN9zoezmUhfXo5l0vP7ekBMPo3jcS/aIkxHnXqAPsByszMZx/Y8oQBRJxJx5xg+RH3urzxA==",
"license": "ISC",
"peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -2057,13 +2066,13 @@
"license": "MIT"
},
"node_modules/parse5": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz",
- "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz",
+ "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "entities": "^6.0.0"
+ "entities": "^8.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
@@ -2129,9 +2138,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.8",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
- "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
+ "version": "8.5.10",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
+ "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
"dev": true,
"funding": [
{
@@ -2205,9 +2214,9 @@
}
},
"node_modules/react-i18next": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.2.tgz",
- "integrity": "sha512-shBftH2vaTWK2Bsp7FiL+cevx3xFJlvFxmsDFQSrJc+6twHkP0tv/bGa01VVWzpreUVVwU+3Hev5iFqRg65RwA==",
+ "version": "17.0.6",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.6.tgz",
+ "integrity": "sha512-WzJ6SMKF+GTD7JZZqxSR1AKKmXjaSu39sClUrNlwxS4Tl7a99O+ltFy6yhPMO+wgZuxpQjJ2PZkfrQKmAqrLhw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.29.2",
@@ -2240,9 +2249,9 @@
"peer": true
},
"node_modules/react-router": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz",
- "integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.2.tgz",
+ "integrity": "sha512-yCqNne6I8IB6rVCH7XUvlBK7/QKyqypBFGv+8dj4QBFJiiRX+FG7/nkdAvGElyvVZ/HQP5N19wzteuTARXi5Gw==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
@@ -2262,12 +2271,12 @@
}
},
"node_modules/react-router-dom": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz",
- "integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.2.tgz",
+ "integrity": "sha512-YZcM5ES8jJSM+KrJ9BdvHHqlnGTg5tH3sC5ChFRj4inosKctdyzBDhOyyHdGk597q2OT6NTrCA1OvB/YDwfekQ==",
"license": "MIT",
"dependencies": {
- "react-router": "7.14.0"
+ "react-router": "7.14.2"
},
"engines": {
"node": ">=20.0.0"
@@ -2302,14 +2311,14 @@
}
},
"node_modules/rolldown": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz",
- "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz",
+ "integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@oxc-project/types": "=0.124.0",
- "@rolldown/pluginutils": "1.0.0-rc.15"
+ "@oxc-project/types": "=0.127.0",
+ "@rolldown/pluginutils": "1.0.0-rc.17"
},
"bin": {
"rolldown": "bin/cli.mjs"
@@ -2318,27 +2327,27 @@
"node": "^20.19.0 || >=22.12.0"
},
"optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.0.0-rc.15",
- "@rolldown/binding-darwin-arm64": "1.0.0-rc.15",
- "@rolldown/binding-darwin-x64": "1.0.0-rc.15",
- "@rolldown/binding-freebsd-x64": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15",
- "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15",
- "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15",
- "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15",
- "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15",
- "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15",
- "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15"
+ "@rolldown/binding-android-arm64": "1.0.0-rc.17",
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.17",
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.17",
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.17",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17"
}
},
"node_modules/rolldown/node_modules/@rolldown/pluginutils": {
- "version": "1.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz",
- "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==",
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz",
+ "integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==",
"dev": true,
"license": "MIT"
},
@@ -2462,14 +2471,14 @@
}
},
"node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
- "picomatch": "^4.0.3"
+ "picomatch": "^4.0.4"
},
"engines": {
"node": ">=12.0.0"
@@ -2543,9 +2552,9 @@
"optional": true
},
"node_modules/typescript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz",
- "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==",
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"devOptional": true,
"license": "Apache-2.0",
"bin": {
@@ -2557,9 +2566,9 @@
}
},
"node_modules/undici": {
- "version": "7.24.5",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.5.tgz",
- "integrity": "sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz",
+ "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2583,17 +2592,17 @@
}
},
"node_modules/vite": {
- "version": "8.0.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz",
- "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
+ "version": "8.0.10",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz",
+ "integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==",
"dev": true,
"license": "MIT",
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
- "postcss": "^8.5.8",
- "rolldown": "1.0.0-rc.15",
- "tinyglobby": "^0.2.15"
+ "postcss": "^8.5.10",
+ "rolldown": "1.0.0-rc.17",
+ "tinyglobby": "^0.2.16"
},
"bin": {
"vite": "bin/vite.js"
@@ -2676,19 +2685,19 @@
}
},
"node_modules/vitest": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.4.tgz",
- "integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.5.tgz",
+ "integrity": "sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/expect": "4.1.4",
- "@vitest/mocker": "4.1.4",
- "@vitest/pretty-format": "4.1.4",
- "@vitest/runner": "4.1.4",
- "@vitest/snapshot": "4.1.4",
- "@vitest/spy": "4.1.4",
- "@vitest/utils": "4.1.4",
+ "@vitest/expect": "4.1.5",
+ "@vitest/mocker": "4.1.5",
+ "@vitest/pretty-format": "4.1.5",
+ "@vitest/runner": "4.1.5",
+ "@vitest/snapshot": "4.1.5",
+ "@vitest/spy": "4.1.5",
+ "@vitest/utils": "4.1.5",
"es-module-lexer": "^2.0.0",
"expect-type": "^1.3.0",
"magic-string": "^0.30.21",
@@ -2716,12 +2725,12 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.1.4",
- "@vitest/browser-preview": "4.1.4",
- "@vitest/browser-webdriverio": "4.1.4",
- "@vitest/coverage-istanbul": "4.1.4",
- "@vitest/coverage-v8": "4.1.4",
- "@vitest/ui": "4.1.4",
+ "@vitest/browser-playwright": "4.1.5",
+ "@vitest/browser-preview": "4.1.5",
+ "@vitest/browser-webdriverio": "4.1.5",
+ "@vitest/coverage-istanbul": "4.1.5",
+ "@vitest/coverage-v8": "4.1.5",
+ "@vitest/ui": "4.1.5",
"happy-dom": "*",
"jsdom": "*",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -2857,9 +2866,9 @@
"license": "MIT"
},
"node_modules/zod": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
- "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.2.tgz",
+ "integrity": "sha512-IynmDyxsEsb9RKzO3J9+4SxXnl2FTFSzNBaKKaMV6tsSk0rw9gYw9gs+JFCq/qk2LCZ78KDwyj+Z289TijSkUw==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
diff --git a/frontend/package.json b/frontend/package.json
index 123030f..dfd16ca 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -27,17 +27,17 @@
"test:e2e:report": "playwright show-report"
},
"dependencies": {
- "i18next": "^26.0.4",
+ "i18next": "^26.0.8",
"i18next-browser-languagedetector": "^8.2.1",
- "lucide-react": "^1.8.0",
+ "lucide-react": "^1.14.0",
"react": "^19.2.5",
"react-dom": "^19.2.5",
- "react-i18next": "^17.0.2",
- "react-router-dom": "^7.14.0",
- "zod": "^4.3.6"
+ "react-i18next": "^17.0.6",
+ "react-router-dom": "^7.14.2",
+ "zod": "^4.4.2"
},
"devDependencies": {
- "@biomejs/biome": "^2.4.11",
+ "@biomejs/biome": "^2.4.14",
"@playwright/test": "^1.59.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
@@ -47,10 +47,10 @@
"@types/react-dom": "^19.2.3",
"@types/react-router-dom": "^5.3.3",
"@vitejs/plugin-react": "^6.0.1",
- "@vitest/coverage-v8": "^4.1.4",
- "jsdom": "^29.0.2",
- "typescript": "^6.0.2",
- "vite": "^8.0.8",
+ "@vitest/coverage-v8": "^4.1.5",
+ "jsdom": "^29.1.1",
+ "typescript": "^6.0.3",
+ "vite": "^8.0.10",
"vitest": "^4.1.0"
}
}
diff --git a/frontend/src/test/features/schedule/formatters.test.ts b/frontend/src/test/features/schedule/formatters.test.ts
new file mode 100644
index 0000000..1e39fa5
--- /dev/null
+++ b/frontend/src/test/features/schedule/formatters.test.ts
@@ -0,0 +1,76 @@
+import { describe, expect, it } from "vitest";
+import { formatScheduleDoseUsageLabel, formatScheduleTotalUsageLabel } from "../../../features/schedule/formatters";
+
+const t = (key: string, options?: Record): string => {
+ switch (key) {
+ case "form.packageAmountUnitMl":
+ return "ml";
+ case "form.blisters.teaspoons":
+ return Number(options?.count) === 1 ? "teaspoon" : "teaspoons";
+ case "form.blisters.tablespoons":
+ return Number(options?.count) === 1 ? "tablespoon" : "tablespoons";
+ case "form.blisters.applications":
+ return Number(options?.count) === 1 ? "application" : "applications";
+ case "common.pill":
+ return "pill";
+ case "common.pills":
+ return "pills";
+ case "common.pillsTotal":
+ return `${options?.count ?? 0} pills total`;
+ default:
+ return key;
+ }
+};
+
+describe("schedule formatters", () => {
+ it("formats liquid dose labels in base and converted units", () => {
+ expect(formatScheduleDoseUsageLabel({ packageType: "liquid_container" }, 0, t, "ml")).toBe("0 ml");
+ expect(formatScheduleDoseUsageLabel({ packageType: "liquid_container" }, 2, t, "tsp")).toBe("2 teaspoons 10 ml");
+ });
+
+ it("formats tube doses as applications by default and ml for liquid forms", () => {
+ expect(formatScheduleDoseUsageLabel({ packageType: "tube" }, 1, t)).toBe("1 application");
+ expect(formatScheduleDoseUsageLabel({ packageType: "tube", medicationForm: "liquid" }, 3, t)).toBe("3 ml");
+ });
+
+ it("formats liquid totals from dose units and mixed-unit conversion", () => {
+ expect(
+ formatScheduleTotalUsageLabel(
+ { packageType: "liquid_container" },
+ 0,
+ t,
+ [
+ { usage: 1, intakeUnit: "tsp" },
+ { usage: 2, intakeUnit: "tsp" },
+ ],
+ "ml"
+ )
+ ).toBe("3 teaspoons 15 ml");
+
+ expect(
+ formatScheduleTotalUsageLabel(
+ { packageType: "liquid_container" },
+ 0,
+ t,
+ [
+ { usage: 1, intakeUnit: "tsp" },
+ { usage: 1, intakeUnit: "tbsp" },
+ ],
+ "ml"
+ )
+ ).toBe("20 ml");
+ });
+
+ it("falls back to total and non-liquid totals when dose list is not usable", () => {
+ expect(
+ formatScheduleTotalUsageLabel(
+ { packageType: "liquid_container" },
+ 4,
+ t,
+ [{ usage: -1, intakeUnit: "ml" }],
+ "tbsp"
+ )
+ ).toBe("4 tablespoons 60 ml");
+ expect(formatScheduleTotalUsageLabel({ packageType: "blister" }, 3, t)).toBe("3 pills total");
+ });
+});
diff --git a/frontend/src/test/features/schedule/interactions.test.ts b/frontend/src/test/features/schedule/interactions.test.ts
new file mode 100644
index 0000000..3526e49
--- /dev/null
+++ b/frontend/src/test/features/schedule/interactions.test.ts
@@ -0,0 +1,35 @@
+import { describe, expect, it } from "vitest";
+import {
+ areAllDoseIdsTaken,
+ countTakenDoseIds,
+ resolveCollapsedState,
+ toggleDateInSet,
+} from "../../../features/schedule/interactions";
+
+describe("schedule interactions", () => {
+ it("toggles dates without mutating the original set", () => {
+ const previous = new Set(["2026-01-01"]);
+ const added = toggleDateInSet(previous, "2026-01-02");
+ const removed = toggleDateInSet(added, "2026-01-01");
+
+ expect(previous).toEqual(new Set(["2026-01-01"]));
+ expect(added).toEqual(new Set(["2026-01-01", "2026-01-02"]));
+ expect(removed).toEqual(new Set(["2026-01-02"]));
+ });
+
+ it("resolves auto and manual collapsed states", () => {
+ expect(resolveCollapsedState(true, "2026-01-01", new Set(), new Set())).toBe(true);
+ expect(resolveCollapsedState(true, "2026-01-01", new Set(["2026-01-01"]), new Set())).toBe(false);
+ expect(resolveCollapsedState(false, "2026-01-01", new Set(), new Set(["2026-01-01"]))).toBe(true);
+ });
+
+ it("counts and checks taken dose ids", () => {
+ const taken = new Set(["a", "c"]);
+ const isDoseTaken = (doseId: string) => taken.has(doseId);
+
+ expect(countTakenDoseIds(["a", "b", "c"], isDoseTaken)).toBe(2);
+ expect(areAllDoseIdsTaken(["a", "c"], isDoseTaken)).toBe(true);
+ expect(areAllDoseIdsTaken(["a", "b"], isDoseTaken)).toBe(false);
+ expect(areAllDoseIdsTaken([], isDoseTaken)).toBe(false);
+ });
+});
diff --git a/package-lock.json b/package-lock.json
index 5f574e1..4604a17 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "medassist-ng",
"devDependencies": {
- "@biomejs/biome": "^2.4.11",
+ "@biomejs/biome": "^2.4.14",
"husky": "^9.1.0",
"lint-staged": "^16.4.0"
}
@@ -76,9 +76,9 @@
}
},
"node_modules/@biomejs/biome": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.11.tgz",
- "integrity": "sha512-nWxHX8tf3Opb/qRgZpBbsTOqOodkbrkJ7S+JxJAruxOReaDPPmPuLBAGQ8vigyUgo0QBB+oQltNEAvalLcjggA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.14.tgz",
+ "integrity": "sha512-TmAvxOEgrpLypzVGJ8FulIZnlyA9TxrO1hyqYrCz9r+bwma9xXxuLA5IuYnj55XQneFx460KjRbx6SWGLkg3bQ==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
@@ -92,20 +92,20 @@
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
- "@biomejs/cli-darwin-arm64": "2.4.11",
- "@biomejs/cli-darwin-x64": "2.4.11",
- "@biomejs/cli-linux-arm64": "2.4.11",
- "@biomejs/cli-linux-arm64-musl": "2.4.11",
- "@biomejs/cli-linux-x64": "2.4.11",
- "@biomejs/cli-linux-x64-musl": "2.4.11",
- "@biomejs/cli-win32-arm64": "2.4.11",
- "@biomejs/cli-win32-x64": "2.4.11"
+ "@biomejs/cli-darwin-arm64": "2.4.14",
+ "@biomejs/cli-darwin-x64": "2.4.14",
+ "@biomejs/cli-linux-arm64": "2.4.14",
+ "@biomejs/cli-linux-arm64-musl": "2.4.14",
+ "@biomejs/cli-linux-x64": "2.4.14",
+ "@biomejs/cli-linux-x64-musl": "2.4.14",
+ "@biomejs/cli-win32-arm64": "2.4.14",
+ "@biomejs/cli-win32-x64": "2.4.14"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.11.tgz",
- "integrity": "sha512-wOt+ed+L2dgZanWyL6i29qlXMc088N11optzpo10peayObBaAshbTcxKUchzEMp9QSY8rh5h6VfAFE3WTS1rqg==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.14.tgz",
+ "integrity": "sha512-XvgoE9XOawUOQPdmvs4J7wPhi/DLwSCGks3AlPJDmh34O0awRTqCED1HRcRDdpf1Zrp4us4MGOOdIxNpbqNF5Q==",
"cpu": [
"arm64"
],
@@ -120,9 +120,9 @@
}
},
"node_modules/@biomejs/cli-darwin-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.11.tgz",
- "integrity": "sha512-gZ6zR8XmZlExfi/Pz/PffmdpWOQ8Qhy7oBztgkR8/ylSRyLwfRPSadmiVCV8WQ8PoJ2MWUy2fgID9zmtgUUJmw==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.14.tgz",
+ "integrity": "sha512-jE7hKBCFhOx3uUh+ZkWBfOHxAcILPfhFplNkuID/eZeSTLHzfZzoZxW8fbqY9xXRnPi7jGNAf1iPVR+0yWsM/Q==",
"cpu": [
"x64"
],
@@ -137,9 +137,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.11.tgz",
- "integrity": "sha512-avdJaEElXrKceK0va9FkJ4P5ci3N01TGkc6ni3P8l3BElqbOz42Wg2IyX3gbh0ZLEd4HVKEIrmuVu/AMuSeFFA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.14.tgz",
+ "integrity": "sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==",
"cpu": [
"arm64"
],
@@ -154,9 +154,9 @@
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.11.tgz",
- "integrity": "sha512-+Sbo1OAmlegtdwqFE8iOxFIWLh1B3OEgsuZfBpyyN/kWuqZ8dx9ZEes6zVnDMo+zRHF2wLynRVhoQmV7ohxl2Q==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.14.tgz",
+ "integrity": "sha512-/z+6gqAqqUQTHazwStxSXKHg9b8UvqBmDFRp+c4wYbq2KXhELQDon9EoC9RpmQ8JWkqQx/lIUy/cs+MhzDZp6A==",
"cpu": [
"arm64"
],
@@ -171,9 +171,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.11.tgz",
- "integrity": "sha512-TagWV0iomp5LnEnxWFg4nQO+e52Fow349vaX0Q/PIcX6Zhk4GGBgp3qqZ8PVkpC+cuehRctMf3+6+FgQ8jCEFQ==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.14.tgz",
+ "integrity": "sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==",
"cpu": [
"x64"
],
@@ -188,9 +188,9 @@
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.11.tgz",
- "integrity": "sha512-bexd2IklK7ZgPhrz6jXzpIL6dEAH9MlJU1xGTrypx+FICxrXUp4CqtwfiuoDKse+UlgAlWtzML3jrMqeEAHEhA==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.14.tgz",
+ "integrity": "sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==",
"cpu": [
"x64"
],
@@ -205,9 +205,9 @@
}
},
"node_modules/@biomejs/cli-win32-arm64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.11.tgz",
- "integrity": "sha512-RJhaTnY8byzxDt4bDVb7AFPHkPcjOPK3xBip4ZRTrN3TEfyhjLRm3r3mqknqydgVTB74XG8l4jMLwEACEeihVg==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.14.tgz",
+ "integrity": "sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==",
"cpu": [
"arm64"
],
@@ -222,9 +222,9 @@
}
},
"node_modules/@biomejs/cli-win32-x64": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.11.tgz",
- "integrity": "sha512-A8D3JM/00C2KQgUV3oj8Ba15EHEYwebAGCy5Sf9GAjr5Y3+kJIYOiESoqRDeuRZueuMdCsbLZIUqmPhpYXJE9A==",
+ "version": "2.4.14",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.14.tgz",
+ "integrity": "sha512-WL0EG5qE+EAKomGXbf2g6VnSKJhTL3tXC0QRzWRwA5VpjxNYa6H4P7ZWfymbGE4IhZZQi1KXQ2R0YjwInmz2fA==",
"cpu": [
"x64"
],
diff --git a/package.json b/package.json
index ffc3aed..626c68e 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"lint:fix": "cd backend && npm run lint:fix && cd ../frontend && npm run lint:fix"
},
"devDependencies": {
- "@biomejs/biome": "^2.4.11",
+ "@biomejs/biome": "^2.4.14",
"husky": "^9.1.0",
"lint-staged": "^16.4.0"
},