build(deps): upgrade next to 16.2.2 and align test assertions

Update the direct Next.js dependency to a patched release in response
to the reported audit findings.

Switch the provider diversity test to Vitest's expect API for
consistent test runner usage and add the audit report snapshot for
release verification.
This commit is contained in:
diegosouzapw
2026-04-06 17:01:53 -03:00
parent d33c0ed1b5
commit c608742b84
4 changed files with 282 additions and 68 deletions
+203
View File
@@ -0,0 +1,203 @@
{
"auditReportVersion": 2,
"vulnerabilities": {
"next": {
"name": "next",
"severity": "high",
"isDirect": true,
"via": [
{
"source": 1112592,
"name": "next",
"dependency": "next",
"title": "Next.js self-hosted applications vulnerable to DoS via Image Optimizer remotePatterns configuration",
"url": "https://github.com/advisories/GHSA-9g9p-9gw9-jx7f",
"severity": "moderate",
"cwe": ["CWE-400", "CWE-770"],
"cvss": {
"score": 5.9,
"vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"
},
"range": ">=15.6.0-canary.0 <16.1.5"
},
{
"source": 1112646,
"name": "next",
"dependency": "next",
"title": "Next.js HTTP request deserialization can lead to DoS when using insecure React Server Components",
"url": "https://github.com/advisories/GHSA-h25m-26qc-wcjf",
"severity": "high",
"cwe": ["CWE-400", "CWE-502"],
"cvss": {
"score": 7.5,
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
},
"range": ">=16.0.0-beta.0 <16.0.11"
},
{
"source": 1112990,
"name": "next",
"dependency": "next",
"title": "Next.js has Unbounded Memory Consumption via PPR Resume Endpoint ",
"url": "https://github.com/advisories/GHSA-5f7q-jpqc-wp7h",
"severity": "moderate",
"cwe": ["CWE-400", "CWE-409", "CWE-770"],
"cvss": {
"score": 5.9,
"vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"
},
"range": ">=16.0.0-beta.0 <16.1.5"
},
{
"source": 1114898,
"name": "next",
"dependency": "next",
"title": "Next.js: HTTP request smuggling in rewrites",
"url": "https://github.com/advisories/GHSA-ggv3-7p47-pfv8",
"severity": "moderate",
"cwe": ["CWE-444"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=16.0.0-beta.0 <16.1.7"
},
{
"source": 1114941,
"name": "next",
"dependency": "next",
"title": "Next.js: Unbounded next/image disk cache growth can exhaust storage",
"url": "https://github.com/advisories/GHSA-3x4c-7xq6-9pq8",
"severity": "moderate",
"cwe": ["CWE-400"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=16.0.0-beta.0 <16.1.7"
},
{
"source": 1114942,
"name": "next",
"dependency": "next",
"title": "Next.js: Unbounded postponed resume buffering can lead to DoS",
"url": "https://github.com/advisories/GHSA-h27x-g6w4-24gq",
"severity": "moderate",
"cwe": ["CWE-770"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=16.0.1 <16.1.7"
},
{
"source": 1114943,
"name": "next",
"dependency": "next",
"title": "Next.js: null origin can bypass Server Actions CSRF checks",
"url": "https://github.com/advisories/GHSA-mq59-m269-xvcx",
"severity": "moderate",
"cwe": ["CWE-352"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=16.0.1 <16.1.7"
},
{
"source": 1115360,
"name": "next",
"dependency": "next",
"title": "Next.js: null origin can bypass dev HMR websocket CSRF checks",
"url": "https://github.com/advisories/GHSA-jcc7-9wpm-mj36",
"severity": "low",
"cwe": ["CWE-1385"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=16.0.1 <16.1.7"
}
],
"effects": [],
"range": "15.6.0-canary.0 - 16.1.6",
"nodes": ["node_modules/next"],
"fixAvailable": {
"name": "next",
"version": "16.2.2",
"isSemVerMajor": false
}
},
"vite": {
"name": "vite",
"severity": "high",
"isDirect": false,
"via": [
{
"source": 1116007,
"name": "vite",
"dependency": "vite",
"title": "Vite Vulnerable to Path Traversal in Optimized Deps `.map` Handling",
"url": "https://github.com/advisories/GHSA-4w7w-66w2-5vf9",
"severity": "moderate",
"cwe": ["CWE-22", "CWE-200"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=8.0.0 <=8.0.4"
},
{
"source": 1116009,
"name": "vite",
"dependency": "vite",
"title": "Vite: `server.fs.deny` bypassed with queries",
"url": "https://github.com/advisories/GHSA-v2wj-q39q-566r",
"severity": "high",
"cwe": ["CWE-180", "CWE-284"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=8.0.0 <=8.0.4"
},
{
"source": 1116012,
"name": "vite",
"dependency": "vite",
"title": "Vite Vulnerable to Arbitrary File Read via Vite Dev Server WebSocket",
"url": "https://github.com/advisories/GHSA-p9ff-h696-f583",
"severity": "high",
"cwe": ["CWE-200", "CWE-306"],
"cvss": {
"score": 0,
"vectorString": null
},
"range": ">=8.0.0 <=8.0.4"
}
],
"effects": [],
"range": "8.0.0 - 8.0.4",
"nodes": ["node_modules/vite"],
"fixAvailable": true
}
},
"metadata": {
"vulnerabilities": {
"info": 0,
"low": 0,
"moderate": 0,
"high": 2,
"critical": 0,
"total": 2
},
"dependencies": {
"prod": 407,
"dev": 485,
"optional": 154,
"peer": 480,
"peerOptional": 0,
"total": 1455
}
}
}
@@ -1,5 +1,4 @@
import { describe, it, beforeEach } from "node:test";
import assert from "node:assert/strict";
import { describe, it, beforeEach, expect } from "vitest";
import {
recordProviderUsage,
calculateDiversityScore,
@@ -16,14 +15,14 @@ describe("providerDiversity", () => {
describe("calculateDiversityScore", () => {
it("returns 1.0 when no data is recorded", () => {
assert.equal(calculateDiversityScore(), 1.0);
expect(calculateDiversityScore()).toBe(1.0);
});
it("returns 0.0 when all requests go to one provider", () => {
for (let i = 0; i < 20; i++) {
recordProviderUsage("claude");
}
assert.equal(calculateDiversityScore(), 0.0);
expect(calculateDiversityScore()).toBe(0.0);
});
it("returns 1.0 for perfectly even distribution across 2 providers", () => {
@@ -31,7 +30,7 @@ describe("providerDiversity", () => {
recordProviderUsage("claude");
recordProviderUsage("openai");
}
assert.equal(calculateDiversityScore(), 1.0);
expect(calculateDiversityScore()).toBe(1.0);
});
it("returns value between 0 and 1 for uneven distribution", () => {
@@ -39,8 +38,8 @@ describe("providerDiversity", () => {
for (let i = 0; i < 5; i++) recordProviderUsage("openai");
const score = calculateDiversityScore();
assert.ok(score > 0, "should be > 0 (not single provider)");
assert.ok(score < 1, "should be < 1 (not perfectly even)");
expect(score).toBeGreaterThan(0);
expect(score).toBeLessThan(1);
});
it("higher entropy with more providers", () => {
@@ -63,14 +62,14 @@ describe("providerDiversity", () => {
const score4 = calculateDiversityScore();
// Both should be 1.0 (perfectly distributed within their pool)
assert.equal(score2, 1.0);
assert.equal(score4, 1.0);
expect(score2).toBe(1.0);
expect(score4).toBe(1.0);
});
});
describe("getProviderDiversityBoost", () => {
it("returns 0.5 when no data is recorded", () => {
assert.equal(getProviderDiversityBoost("claude"), 0.5);
expect(getProviderDiversityBoost("claude")).toBe(0.5);
});
it("returns low boost for heavily used provider", () => {
@@ -80,16 +79,16 @@ describe("providerDiversity", () => {
const claudeBoost = getProviderDiversityBoost("claude");
const openaiBoost = getProviderDiversityBoost("openai");
assert.ok(claudeBoost < openaiBoost, "heavily used provider should have lower boost");
assert.ok(claudeBoost < 0.2, "90% used provider should have very low boost");
assert.ok(openaiBoost > 0.8, "10% used provider should have high boost");
expect(claudeBoost).toBeLessThan(openaiBoost);
expect(claudeBoost).toBeLessThan(0.2);
expect(openaiBoost).toBeGreaterThan(0.8);
});
it("returns 1.0 for never-used provider", () => {
for (let i = 0; i < 10; i++) recordProviderUsage("claude");
const boost = getProviderDiversityBoost("google");
assert.equal(boost, 1.0);
expect(boost).toBe(1.0);
});
});
@@ -101,12 +100,12 @@ describe("providerDiversity", () => {
const report = getDiversityReport();
assert.equal(report.totalRequests, 3);
assert.ok(report.score > 0);
assert.ok(report.score < 1);
assert.equal(report.providers["claude"].count, 2);
assert.equal(report.providers["openai"].count, 1);
assert.ok(Math.abs(report.providers["claude"].share - 2 / 3) < 0.01);
expect(report.totalRequests).toBe(3);
expect(report.score).toBeGreaterThan(0);
expect(report.score).toBeLessThan(1);
expect(report.providers["claude"].count).toBe(2);
expect(report.providers["openai"].count).toBe(1);
expect(Math.abs(report.providers["claude"].share - 2 / 3)).toBeLessThan(0.01);
});
});
@@ -119,7 +118,7 @@ describe("providerDiversity", () => {
}
const report = getDiversityReport();
assert.ok(report.totalRequests <= 10, "should not exceed window size");
expect(report.totalRequests).toBeLessThanOrEqual(10);
});
});
});
+58 -46
View File
@@ -29,7 +29,7 @@
"js-yaml": "^4.1.0",
"lowdb": "^7.0.1",
"monaco-editor": "^0.55.1",
"next": "16.0.10",
"next": "^16.2.2",
"next-intl": "^4.8.3",
"node-machine-id": "^1.1.12",
"open": "^11.0.0",
@@ -2796,9 +2796,9 @@
}
},
"node_modules/@next/env": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.10.tgz",
"integrity": "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.2.tgz",
"integrity": "sha512-LqSGz5+xGk9EL/iBDr2yo/CgNQV6cFsNhRR2xhSXYh7B/hb4nePCxlmDvGEKG30NMHDFf0raqSyOZiQrO7BkHQ==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
@@ -2812,9 +2812,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.10.tgz",
"integrity": "sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.2.tgz",
"integrity": "sha512-B92G3ulrwmkDSEJEp9+XzGLex5wC1knrmCSIylyVeiAtCIfvEJYiN3v5kXPlYt5R4RFlsfO/v++aKV63Acrugg==",
"cpu": [
"arm64"
],
@@ -2828,9 +2828,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.10.tgz",
"integrity": "sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.2.tgz",
"integrity": "sha512-7ZwSgNKJNQiwW0CKhNm9B1WS2L1Olc4B2XY0hPYCAL3epFnugMhuw5TMWzMilQ3QCZcCHoYm9NGWTHbr5REFxw==",
"cpu": [
"x64"
],
@@ -2844,12 +2844,15 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.10.tgz",
"integrity": "sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.2.tgz",
"integrity": "sha512-c3m8kBHMziMgo2fICOP/cd/5YlrxDU5YYjAJeQLyFsCqVF8xjOTH/QYG4a2u48CvvZZSj1eHQfBCbyh7kBr30Q==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2860,12 +2863,15 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.10.tgz",
"integrity": "sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.2.tgz",
"integrity": "sha512-VKLuscm0P/mIfzt+SDdn2+8TNNJ7f0qfEkA+az7OqQbjzKdBxAHs0UvuiVoCtbwX+dqMEL9U54b5wQ/aN3dHeg==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2876,12 +2882,15 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.10.tgz",
"integrity": "sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.2.tgz",
"integrity": "sha512-kU3OPHJq6sBUjOk7wc5zJ7/lipn8yGldMoAv4z67j6ov6Xo/JvzA7L7LCsyzzsXmgLEhk3Qkpwqaq/1+XpNR3g==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2892,12 +2901,15 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.10.tgz",
"integrity": "sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.2.tgz",
"integrity": "sha512-CKXRILyErMtUftp+coGcZ38ZwE/Aqq45VMCcRLr2I4OXKrgxIBDXHnBgeX/UMil0S09i2JXaDL3Q+TN8D/cKmg==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2908,9 +2920,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.10.tgz",
"integrity": "sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.2.tgz",
"integrity": "sha512-sS/jSk5VUoShUqINJFvNjVT7JfR5ORYj/+/ZpOYbbIohv/lQfduWnGAycq2wlknbOql2xOR0DoV0s6Xfcy49+g==",
"cpu": [
"arm64"
],
@@ -2924,9 +2936,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.10.tgz",
"integrity": "sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.2.tgz",
"integrity": "sha512-aHaKceJgdySReT7qeck5oShucxWRiiEuwCGK8HHALe6yZga8uyFpLkPgaRw3kkF04U7ROogL/suYCNt/+CuXGA==",
"cpu": [
"x64"
],
@@ -7828,7 +7840,6 @@
"version": "2.10.13",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.13.tgz",
"integrity": "sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"baseline-browser-mapping": "dist/cli.cjs"
@@ -15469,13 +15480,14 @@
}
},
"node_modules/next": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/next/-/next-16.0.10.tgz",
"integrity": "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==",
"version": "16.2.2",
"resolved": "https://registry.npmjs.org/next/-/next-16.2.2.tgz",
"integrity": "sha512-i6AJdyVa4oQjyvX/6GeER8dpY/xlIV+4NMv/svykcLtURJSy/WzDnnUk/TM4d0uewFHK7xSQz4TbIwPgjky+3A==",
"license": "MIT",
"dependencies": {
"@next/env": "16.0.10",
"@next/env": "16.2.2",
"@swc/helpers": "0.5.15",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
"styled-jsx": "5.1.6"
@@ -15487,15 +15499,15 @@
"node": ">=20.9.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "16.0.10",
"@next/swc-darwin-x64": "16.0.10",
"@next/swc-linux-arm64-gnu": "16.0.10",
"@next/swc-linux-arm64-musl": "16.0.10",
"@next/swc-linux-x64-gnu": "16.0.10",
"@next/swc-linux-x64-musl": "16.0.10",
"@next/swc-win32-arm64-msvc": "16.0.10",
"@next/swc-win32-x64-msvc": "16.0.10",
"sharp": "^0.34.4"
"@next/swc-darwin-arm64": "16.2.2",
"@next/swc-darwin-x64": "16.2.2",
"@next/swc-linux-arm64-gnu": "16.2.2",
"@next/swc-linux-arm64-musl": "16.2.2",
"@next/swc-linux-x64-gnu": "16.2.2",
"@next/swc-linux-x64-musl": "16.2.2",
"@next/swc-win32-arm64-msvc": "16.2.2",
"@next/swc-win32-x64-msvc": "16.2.2",
"sharp": "^0.34.5"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -20126,9 +20138,9 @@
}
},
"node_modules/vite": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz",
"integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==",
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.5.tgz",
"integrity": "sha512-nmu43Qvq9UopTRfMx2jOYW5l16pb3iDC1JH6yMuPkpVbzK0k+L7dfsEDH4jRgYFmsg0sTAqkojoZgzLMlwHsCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -20153,7 +20165,7 @@
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
"@vitejs/devtools": "^0.1.0",
"esbuild": "^0.27.0",
"esbuild": "^0.27.0 || ^0.28.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
"sass": "^1.70.0",
+1 -1
View File
@@ -102,7 +102,7 @@
"js-yaml": "^4.1.0",
"lowdb": "^7.0.1",
"monaco-editor": "^0.55.1",
"next": "16.0.10",
"next": "^16.2.2",
"next-intl": "^4.8.3",
"node-machine-id": "^1.1.12",
"open": "^11.0.0",