From 7ff824a5a8dba00a04e41aaf62dbe027c6d78e2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 03:26:01 +0000 Subject: [PATCH 01/16] chore(deps): update dependency @playwright/test to v1.51.1 (#2806) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index b27fce4d02..f5e2779071 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6705,12 +6705,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz", - "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.1.tgz", + "integrity": "sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==", "dev": true, "dependencies": { - "playwright": "1.48.1" + "playwright": "1.51.1" }, "bin": { "playwright": "cli.js" @@ -32213,12 +32213,12 @@ } }, "node_modules/playwright": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz", - "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz", + "integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==", "dev": true, "dependencies": { - "playwright-core": "1.48.1" + "playwright-core": "1.51.1" }, "bin": { "playwright": "cli.js" @@ -32231,9 +32231,9 @@ } }, "node_modules/playwright-core": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", - "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz", + "integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -40547,12 +40547,12 @@ "optional": true }, "@playwright/test": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz", - "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.1.tgz", + "integrity": "sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==", "dev": true, "requires": { - "playwright": "1.48.1" + "playwright": "1.51.1" } }, "@protobufjs/aspromise": { @@ -58532,19 +58532,19 @@ } }, "playwright": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz", - "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz", + "integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==", "dev": true, "requires": { "fsevents": "2.3.2", - "playwright-core": "1.48.1" + "playwright-core": "1.51.1" } }, "playwright-core": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", - "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz", + "integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==", "dev": true }, "pluralize": { From 7792c1571061b0862197743e32a75210fe7679a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 05:30:39 +0000 Subject: [PATCH 02/16] chore(deps): update dependency msw to v2.7.3 (#2807) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 528 +++++++++++++++------------------------------- 1 file changed, 171 insertions(+), 357 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5e2779071..5b0e5bbdc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -577,12 +577,12 @@ "dev": true }, "node_modules/@bundled-es-modules/cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", - "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", "dev": true, "dependencies": { - "cookie": "^0.5.0" + "cookie": "^0.7.2" } }, "node_modules/@bundled-es-modules/statuses": { @@ -3353,41 +3353,51 @@ "dev": true }, "node_modules/@inquirer/confirm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.0.0.tgz", - "integrity": "sha512-LHeuYP1D8NmQra1eR4UqvZMXwxEdDXyElJmmZfU44xdNLL6+GcQBS0uE16vyfZVjH8c22p9e+DStROfE/hyHrg==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.8.tgz", + "integrity": "sha512-dNLWCYZvXDjO3rnQfk2iuJNL4Ivwz/T2+C3+WnNfJKsNGSuOs3wAo2F6e0p946gtSAk31nZMfW+MRmYaplPKsg==", "dev": true, "dependencies": { - "@inquirer/core": "^7.0.0", - "@inquirer/type": "^1.2.0" + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/core": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-7.0.0.tgz", - "integrity": "sha512-g13W5yEt9r1sEVVriffJqQ8GWy94OnfxLCreNSOTw0HPVcszmc/If1KIf7YBmlwtX4klmvwpZHnQpl3N7VX2xA==", + "version": "10.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.9.tgz", + "integrity": "sha512-sXhVB8n20NYkUBfDYgizGHlpRVaCRjtuzNZA6xpALIUbkgfd2Hjz+DfEN6+h1BRnuxw0/P4jCIMjMsEOAMwAJw==", "dev": true, "dependencies": { - "@inquirer/type": "^1.2.0", - "@types/mute-stream": "^0.0.4", - "@types/node": "^20.11.16", - "@types/wrap-ansi": "^3.0.0", + "@inquirer/figures": "^1.0.11", + "@inquirer/type": "^3.0.5", "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "cli-spinners": "^2.9.2", "cli-width": "^4.1.0", - "figures": "^3.2.0", - "mute-stream": "^1.0.0", - "run-async": "^3.0.0", + "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/core/node_modules/ansi-escapes": { @@ -3420,31 +3430,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@inquirer/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@inquirer/core/node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/@inquirer/core/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3469,48 +3454,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/@inquirer/core/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@inquirer/core/node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@inquirer/core/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@inquirer/core/node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/@inquirer/core/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -3537,18 +3480,6 @@ "node": ">=8" } }, - "node_modules/@inquirer/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@inquirer/core/node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -3575,13 +3506,30 @@ "node": ">=8" } }, + "node_modules/@inquirer/figures": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.11.tgz", + "integrity": "sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/@inquirer/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.2.0.tgz", - "integrity": "sha512-/vvkUkYhrjbm+RolU7V1aUFDydZVKNKqKHR5TsE+j5DXgXFwrsOPcoGUJ02K0O7q7O53CU2DOTMYCHeGZ25WHA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.5.tgz", + "integrity": "sha512-ZJpeIYYueOz/i/ONzrfof8g89kNdO2hjGuvULROo3O8rlB2CRtSseE5KeirnyE4t/thAn/EwvS/vuQeJCn+NZg==", "dev": true, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@isaacs/cliui": { @@ -3884,9 +3832,9 @@ } }, "node_modules/@mswjs/interceptors": { - "version": "0.36.5", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.36.5.tgz", - "integrity": "sha512-aQ8WF5zQwOdcxLsxSEk9Jd01GgGb80xxqCaiDDlewhtwqpSm8MOvUHslwPydVirasdW09++NxDNNftm1vLY8yA==", + "version": "0.37.6", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.6.tgz", + "integrity": "sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==", "dev": true, "dependencies": { "@open-draft/deferred-promise": "^2.2.0", @@ -7176,15 +7124,6 @@ "integrity": "sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==", "dev": true }, - "node_modules/@types/mute-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node": { "version": "20.16.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.13.tgz", @@ -7254,12 +7193,6 @@ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, - "node_modules/@types/wrap-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", - "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", - "dev": true - }, "node_modules/@types/yargs": { "version": "16.0.7", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.7.tgz", @@ -8907,6 +8840,7 @@ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, + "peer": true, "engines": { "node": ">=6" }, @@ -8914,6 +8848,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -9204,9 +9147,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -15240,26 +15183,27 @@ "dev": true }, "node_modules/msw": { - "version": "2.4.12", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.12.tgz", - "integrity": "sha512-upQMKZt0fYIB0Gj6gKc5i/PK4JrICTu3ItfXiju3FTdgQLaqARv7+jugPCsOkrWpTzzjo5iLW+4F6L/mGNukbA==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.7.3.tgz", + "integrity": "sha512-+mycXv8l2fEAjFZ5sjrtjJDmm2ceKGjrNbBr1durRg6VkU9fNUE/gsmQ51hWbHqs+l35W1iM+ZsmOD9Fd6lspw==", "dev": true, "hasInstallScript": true, "dependencies": { - "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/cookie": "^2.0.1", "@bundled-es-modules/statuses": "^1.0.1", "@bundled-es-modules/tough-cookie": "^0.1.6", - "@inquirer/confirm": "^3.0.0", - "@mswjs/interceptors": "^0.36.5", + "@inquirer/confirm": "^5.0.0", + "@mswjs/interceptors": "^0.37.0", + "@open-draft/deferred-promise": "^2.2.0", "@open-draft/until": "^2.1.0", "@types/cookie": "^0.6.0", "@types/statuses": "^2.0.4", - "chalk": "^4.1.2", "graphql": "^16.8.1", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", "strict-event-emitter": "^0.5.1", "type-fest": "^4.26.1", "yargs": "^17.7.2" @@ -15282,77 +15226,25 @@ } } }, - "node_modules/msw/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/msw/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/msw/node_modules/type-fest": { + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.38.0.tgz", + "integrity": "sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/msw/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/msw/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/msw/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/msw/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", "dev": true, "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/nan": { @@ -32147,11 +32039,10 @@ } }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true, - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true }, "node_modules/picomatch": { "version": "4.0.2", @@ -36117,6 +36008,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", @@ -36586,12 +36489,12 @@ "dev": true }, "@bundled-es-modules/cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", - "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", "dev": true, "requires": { - "cookie": "^0.5.0" + "cookie": "^0.7.2" } }, "@bundled-es-modules/statuses": { @@ -38238,35 +38141,29 @@ "dev": true }, "@inquirer/confirm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.0.0.tgz", - "integrity": "sha512-LHeuYP1D8NmQra1eR4UqvZMXwxEdDXyElJmmZfU44xdNLL6+GcQBS0uE16vyfZVjH8c22p9e+DStROfE/hyHrg==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.8.tgz", + "integrity": "sha512-dNLWCYZvXDjO3rnQfk2iuJNL4Ivwz/T2+C3+WnNfJKsNGSuOs3wAo2F6e0p946gtSAk31nZMfW+MRmYaplPKsg==", "dev": true, "requires": { - "@inquirer/core": "^7.0.0", - "@inquirer/type": "^1.2.0" + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5" } }, "@inquirer/core": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-7.0.0.tgz", - "integrity": "sha512-g13W5yEt9r1sEVVriffJqQ8GWy94OnfxLCreNSOTw0HPVcszmc/If1KIf7YBmlwtX4klmvwpZHnQpl3N7VX2xA==", + "version": "10.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.9.tgz", + "integrity": "sha512-sXhVB8n20NYkUBfDYgizGHlpRVaCRjtuzNZA6xpALIUbkgfd2Hjz+DfEN6+h1BRnuxw0/P4jCIMjMsEOAMwAJw==", "dev": true, "requires": { - "@inquirer/type": "^1.2.0", - "@types/mute-stream": "^0.0.4", - "@types/node": "^20.11.16", - "@types/wrap-ansi": "^3.0.0", + "@inquirer/figures": "^1.0.11", + "@inquirer/type": "^3.0.5", "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "cli-spinners": "^2.9.2", "cli-width": "^4.1.0", - "figures": "^3.2.0", - "mute-stream": "^1.0.0", - "run-async": "^3.0.0", + "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" }, "dependencies": { "ansi-escapes": { @@ -38287,22 +38184,6 @@ "color-convert": "^2.0.1" } }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -38324,33 +38205,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true - }, - "run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -38371,15 +38225,6 @@ "ansi-regex": "^5.0.1" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -38399,12 +38244,19 @@ } } }, - "@inquirer/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.2.0.tgz", - "integrity": "sha512-/vvkUkYhrjbm+RolU7V1aUFDydZVKNKqKHR5TsE+j5DXgXFwrsOPcoGUJ02K0O7q7O53CU2DOTMYCHeGZ25WHA==", + "@inquirer/figures": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.11.tgz", + "integrity": "sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==", "dev": true }, + "@inquirer/type": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.5.tgz", + "integrity": "sha512-ZJpeIYYueOz/i/ONzrfof8g89kNdO2hjGuvULROo3O8rlB2CRtSseE5KeirnyE4t/thAn/EwvS/vuQeJCn+NZg==", + "dev": true, + "requires": {} + }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -38616,9 +38468,9 @@ } }, "@mswjs/interceptors": { - "version": "0.36.5", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.36.5.tgz", - "integrity": "sha512-aQ8WF5zQwOdcxLsxSEk9Jd01GgGb80xxqCaiDDlewhtwqpSm8MOvUHslwPydVirasdW09++NxDNNftm1vLY8yA==", + "version": "0.37.6", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.6.tgz", + "integrity": "sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==", "dev": true, "requires": { "@open-draft/deferred-promise": "^2.2.0", @@ -40884,15 +40736,6 @@ "integrity": "sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==", "dev": true }, - "@types/mute-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/node": { "version": "20.16.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.13.tgz", @@ -40962,12 +40805,6 @@ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, - "@types/wrap-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", - "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", - "dev": true - }, "@types/yargs": { "version": "16.0.7", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.7.tgz", @@ -42115,6 +41952,13 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "peer": true + }, + "cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true }, "client-only": { @@ -42361,9 +42205,9 @@ "dev": true }, "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true }, "core-util-is": { @@ -46633,81 +46477,45 @@ "dev": true }, "msw": { - "version": "2.4.12", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.4.12.tgz", - "integrity": "sha512-upQMKZt0fYIB0Gj6gKc5i/PK4JrICTu3ItfXiju3FTdgQLaqARv7+jugPCsOkrWpTzzjo5iLW+4F6L/mGNukbA==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.7.3.tgz", + "integrity": "sha512-+mycXv8l2fEAjFZ5sjrtjJDmm2ceKGjrNbBr1durRg6VkU9fNUE/gsmQ51hWbHqs+l35W1iM+ZsmOD9Fd6lspw==", "dev": true, "requires": { - "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/cookie": "^2.0.1", "@bundled-es-modules/statuses": "^1.0.1", "@bundled-es-modules/tough-cookie": "^0.1.6", - "@inquirer/confirm": "^3.0.0", - "@mswjs/interceptors": "^0.36.5", + "@inquirer/confirm": "^5.0.0", + "@mswjs/interceptors": "^0.37.0", + "@open-draft/deferred-promise": "^2.2.0", "@open-draft/until": "^2.1.0", "@types/cookie": "^0.6.0", "@types/statuses": "^2.0.4", - "chalk": "^4.1.2", "graphql": "^16.8.1", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", "strict-event-emitter": "^0.5.1", "type-fest": "^4.26.1", "yargs": "^17.7.2" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.38.0.tgz", + "integrity": "sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==", "dev": true } } }, + "mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true + }, "nan": { "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", @@ -58488,9 +58296,9 @@ "dev": true }, "picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -61228,6 +61036,12 @@ "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true }, + "yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true + }, "zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", From f978b8a3a81033e9980e620e0727149dd04f23e6 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Tue, 1 Apr 2025 11:13:59 -0400 Subject: [PATCH 03/16] chore: remove trailing slash logging (revert #2743) (#2805) --- src/run/handlers/server.ts | 2 +- src/run/headers.ts | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/run/handlers/server.ts b/src/run/handlers/server.ts index 72666dd5b3..62c7c8f8b8 100644 --- a/src/run/handlers/server.ts +++ b/src/run/handlers/server.ts @@ -131,7 +131,7 @@ export default async ( }) } - setCacheControlHeaders(response, request, requestContext, nextConfig) + setCacheControlHeaders(response, request, requestContext) setCacheTagsHeaders(response.headers, requestContext) setVaryHeaders(response.headers, request, nextConfig) setCacheStatusHeader(response.headers, nextCache) diff --git a/src/run/headers.ts b/src/run/headers.ts index bfc386506c..766e41aff7 100644 --- a/src/run/headers.ts +++ b/src/run/headers.ts @@ -3,7 +3,7 @@ import type { NextConfigComplete } from 'next/dist/server/config-shared.js' import type { NetlifyCachedRouteValue, NetlifyCacheHandlerValue } from '../shared/cache-types.cjs' -import { getLogger, RequestContext } from './handlers/request-context.cjs' +import { RequestContext } from './handlers/request-context.cjs' import { recordWarning } from './handlers/tracer.cjs' import { getMemoizedKeyValueStoreBackedByRegionalBlobStore } from './storage/storage.cjs' @@ -200,7 +200,6 @@ export const setCacheControlHeaders = ( { headers, status }: Response, request: Request, requestContext: RequestContext, - nextConfig: NextConfigComplete, ) => { if ( typeof requestContext.routeHandlerRevalidate !== 'undefined' && @@ -213,13 +212,6 @@ export const setCacheControlHeaders = ( return } - // temporary diagnostic to evaluate number of trailing slash redirects - if (status === 308 && request.url.endsWith('/') !== nextConfig.trailingSlash) { - getLogger() - .withFields({ trailingSlash: nextConfig.trailingSlash, location: headers.get('location') }) - .log('NetlifyHeadersHandler.trailingSlashRedirect') - } - const cacheControl = headers.get('cache-control') if (status === 404) { if (request.url.endsWith('.php')) { From 114945f105149b56e5de0ddc53d740a55bcc71e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 22:34:32 +0000 Subject: [PATCH 04/16] chore(deps): update dependency netlify-cli to ^19.1.5 (#2809) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- e2e-report/package-lock.json | 8 ++++---- e2e-report/package.json | 2 +- package-lock.json | 14 +++++++------- package.json | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/e2e-report/package-lock.json b/e2e-report/package-lock.json index 5963d9942a..66457f8611 100644 --- a/e2e-report/package-lock.json +++ b/e2e-report/package-lock.json @@ -18,7 +18,7 @@ "daisyui": "^4.12.2", "eslint": "^8.57.0", "eslint-config-next": "^14.2.4", - "netlify-cli": "^19.1.4", + "netlify-cli": "^19.1.5", "postcss": "^8.4.38", "sass": "^1.77.1", "tailwindcss": "^3.4.4" @@ -3623,9 +3623,9 @@ "dev": true }, "node_modules/netlify-cli": { - "version": "19.1.4", - "resolved": "https://registry.npmjs.org/netlify-cli/-/netlify-cli-19.1.4.tgz", - "integrity": "sha512-/X5gn8jO/GY4cZnEFajaUnO/4LiCLgnbumoSNvbNnY8EADqdfPiOnjz1u6gAiMlSt2DKASy7Bs6HbNM1XcXGsA==", + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/netlify-cli/-/netlify-cli-19.1.5.tgz", + "integrity": "sha512-XO8vZ/4zlVv5mHQAoqySFNVvVlvUB9UzS70Pr9fKElV/dzrgJdJp+rJgKn3F4dRK2b/B1AFzJt3NIYREWAVDmg==", "dev": true, "hasInstallScript": true, "hasShrinkwrap": true, diff --git a/e2e-report/package.json b/e2e-report/package.json index 2e946c1722..ed85303163 100644 --- a/e2e-report/package.json +++ b/e2e-report/package.json @@ -19,7 +19,7 @@ "daisyui": "^4.12.2", "eslint": "^8.57.0", "eslint-config-next": "^14.2.4", - "netlify-cli": "^19.1.4", + "netlify-cli": "^19.1.5", "postcss": "^8.4.38", "sass": "^1.77.1", "tailwindcss": "^3.4.4" diff --git a/package-lock.json b/package-lock.json index 5b0e5bbdc3..e614dcb659 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "memfs": "^4.9.2", "mock-require": "^3.0.3", "msw": "^2.0.7", - "netlify-cli": "^19.1.4", + "netlify-cli": "^19.1.5", "next": "^15.0.0-canary.28", "os": "^0.1.2", "outdent": "^0.8.0", @@ -15308,9 +15308,9 @@ } }, "node_modules/netlify-cli": { - "version": "19.1.4", - "resolved": "https://registry.npmjs.org/netlify-cli/-/netlify-cli-19.1.4.tgz", - "integrity": "sha512-/X5gn8jO/GY4cZnEFajaUnO/4LiCLgnbumoSNvbNnY8EADqdfPiOnjz1u6gAiMlSt2DKASy7Bs6HbNM1XcXGsA==", + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/netlify-cli/-/netlify-cli-19.1.5.tgz", + "integrity": "sha512-XO8vZ/4zlVv5mHQAoqySFNVvVlvUB9UzS70Pr9fKElV/dzrgJdJp+rJgKn3F4dRK2b/B1AFzJt3NIYREWAVDmg==", "dev": true, "hasInstallScript": true, "hasShrinkwrap": true, @@ -46562,9 +46562,9 @@ } }, "netlify-cli": { - "version": "19.1.4", - "resolved": "https://registry.npmjs.org/netlify-cli/-/netlify-cli-19.1.4.tgz", - "integrity": "sha512-/X5gn8jO/GY4cZnEFajaUnO/4LiCLgnbumoSNvbNnY8EADqdfPiOnjz1u6gAiMlSt2DKASy7Bs6HbNM1XcXGsA==", + "version": "19.1.5", + "resolved": "https://registry.npmjs.org/netlify-cli/-/netlify-cli-19.1.5.tgz", + "integrity": "sha512-XO8vZ/4zlVv5mHQAoqySFNVvVlvUB9UzS70Pr9fKElV/dzrgJdJp+rJgKn3F4dRK2b/B1AFzJt3NIYREWAVDmg==", "dev": true, "requires": { "@fastify/static": "7.0.4", diff --git a/package.json b/package.json index ebf8b3fc9b..3febd9822e 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "memfs": "^4.9.2", "mock-require": "^3.0.3", "msw": "^2.0.7", - "netlify-cli": "^19.1.4", + "netlify-cli": "^19.1.5", "next": "^15.0.0-canary.28", "os": "^0.1.2", "outdent": "^0.8.0", From b4f04e3c5a9c83c916f69c3e3c64e0d946ec3692 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Wed, 2 Apr 2025 11:11:08 -0400 Subject: [PATCH 05/16] fix: improved cdn cache hooks for dynamic 404 pages (#2786) * test: fixture for dynamic cms results * test: case for invalidating dynamic 404 pages * fix: wip - fix for caching issues on catch all routes * test: not all versions of next support next.config.ts * test: older versions of next have different cache headers * test: edge cache response depends on the node we hit * fix: set cache tags on 404 pages * chore: clean up variable names * chore: remove previous attempt to set cache tags on 404s * fix: also target 404 pages when purging cache * chore: remove wip check for cached api calls * chore: run format:fix --- src/run/handlers/cache.cts | 41 +++++++++---- src/run/headers.ts | 12 ++-- src/run/revalidate.ts | 4 +- tests/e2e/dynamic-cms.test.ts | 58 +++++++++++++++++++ tests/fixtures/dynamic-cms/README.md | 1 + .../dynamic-cms/netlify/functions/cms.ts | 24 ++++++++ tests/fixtures/dynamic-cms/next.config.js | 10 ++++ tests/fixtures/dynamic-cms/package.json | 24 ++++++++ tests/fixtures/dynamic-cms/pages/404.js | 3 + .../dynamic-cms/pages/api/revalidate.js | 9 +++ .../dynamic-cms/pages/content/[...slug].js | 37 ++++++++++++ tests/utils/create-e2e-fixture.ts | 1 + 12 files changed, 205 insertions(+), 19 deletions(-) create mode 100644 tests/e2e/dynamic-cms.test.ts create mode 100644 tests/fixtures/dynamic-cms/README.md create mode 100644 tests/fixtures/dynamic-cms/netlify/functions/cms.ts create mode 100644 tests/fixtures/dynamic-cms/next.config.js create mode 100644 tests/fixtures/dynamic-cms/package.json create mode 100644 tests/fixtures/dynamic-cms/pages/404.js create mode 100644 tests/fixtures/dynamic-cms/pages/api/revalidate.js create mode 100644 tests/fixtures/dynamic-cms/pages/content/[...slug].js diff --git a/src/run/handlers/cache.cts b/src/run/handlers/cache.cts index 294700901c..4e9b61ce4a 100644 --- a/src/run/handlers/cache.cts +++ b/src/run/handlers/cache.cts @@ -121,11 +121,8 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { } private captureCacheTags(cacheValue: NetlifyIncrementalCacheValue | null, key: string) { - if (!cacheValue) { - return - } - const requestContext = getRequestContext() + // Bail if we can't get request context if (!requestContext) { return @@ -141,6 +138,13 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { return } + // Set cache tags for 404 pages as well so that the content can later be purged + if (!cacheValue) { + const cacheTags = [`_N_T_${key === '/index' ? '/' : encodeURI(key)}`] + requestContext.responseCacheTags = cacheTags + return + } + if ( cacheValue.kind === 'PAGE' || cacheValue.kind === 'PAGES' || @@ -226,7 +230,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { ...args: Parameters ): ReturnType { return this.tracer.withActiveSpan('get cache key', async (span) => { - const [key, ctx = {}] = args + const [key, context = {}] = args getLogger().debug(`[NetlifyCacheHandler.get]: ${key}`) span.setAttributes({ key }) @@ -259,7 +263,11 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { return null } - const staleByTags = await this.checkCacheEntryStaleByTags(blob, ctx.tags, ctx.softTags) + const staleByTags = await this.checkCacheEntryStaleByTags( + blob, + context.tags, + context.softTags, + ) if (staleByTags) { span.addEvent('Stale', { staleByTags, key, ttl }) @@ -267,13 +275,18 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { } this.captureResponseCacheLastModified(blob, key, span) - this.captureCacheTags(blob.value, key) + + // Next sets a kind/kindHint and fetchUrl for data requests, however fetchUrl was found to be most reliable across versions + const isDataRequest = Boolean(context.fetchUrl) + if (!isDataRequest) { + this.captureCacheTags(blob.value, key) + } switch (blob.value?.kind) { case 'FETCH': span.addEvent('FETCH', { lastModified: blob.lastModified, - revalidate: ctx.revalidate, + revalidate: context.revalidate, ttl, }) return { @@ -387,13 +400,17 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { const value = this.transformToStorableObject(data, context) - // if previous CacheHandler.get call returned null (page was either never rendered or was on-demand revalidated) - // and we didn't yet capture cache tags, we try to get cache tags from freshly produced cache value - this.captureCacheTags(value, key) + // Next sets a fetchCache and fetchUrl for data requests, however fetchUrl was found to be most reliable across versions + const isDataReq = Boolean(context.fetchUrl) + if (!isDataReq) { + // if previous CacheHandler.get call returned null (page was either never rendered or was on-demand revalidated) + // and we didn't yet capture cache tags, we try to get cache tags from freshly produced cache value + this.captureCacheTags(value, key) + } await this.cacheStore.set(key, { lastModified, value }, 'blobStore.set') - if (data?.kind === 'PAGE' || data?.kind === 'PAGES') { + if ((!data && !isDataReq) || data?.kind === 'PAGE' || data?.kind === 'PAGES') { const requestContext = getRequestContext() if (requestContext?.didPagesRouterOnDemandRevalidate) { // encode here to deal with non ASCII characters in the key diff --git a/src/run/headers.ts b/src/run/headers.ts index 766e41aff7..1931f61330 100644 --- a/src/run/headers.ts +++ b/src/run/headers.ts @@ -212,7 +212,6 @@ export const setCacheControlHeaders = ( return } - const cacheControl = headers.get('cache-control') if (status === 404) { if (request.url.endsWith('.php')) { // temporary CDN Cache Control handling for bot probes on PHP files @@ -233,6 +232,8 @@ export const setCacheControlHeaders = ( } } + const cacheControl = headers.get('cache-control') + if ( cacheControl !== null && ['GET', 'HEAD'].includes(request.method) && @@ -274,10 +275,11 @@ export const setCacheControlHeaders = ( } export const setCacheTagsHeaders = (headers: Headers, requestContext: RequestContext) => { - if ( - requestContext.responseCacheTags && - (headers.has('cache-control') || headers.has('netlify-cdn-cache-control')) - ) { + if (!headers.has('cache-control') && !headers.has('netlify-cdn-cache-control')) { + return + } + + if (requestContext.responseCacheTags) { headers.set('netlify-cache-tag', requestContext.responseCacheTags.join(',')) } } diff --git a/src/run/revalidate.ts b/src/run/revalidate.ts index 25a5b86660..6789072209 100644 --- a/src/run/revalidate.ts +++ b/src/run/revalidate.ts @@ -15,8 +15,8 @@ function isRevalidateMethod( } // Needing to proxy the response object to intercept the revalidate call for on-demand revalidation on page routes -export const nextResponseProxy = (res: ServerResponse, requestContext: RequestContext) => { - return new Proxy(res, { +export const nextResponseProxy = (response: ServerResponse, requestContext: RequestContext) => { + return new Proxy(response, { get(target: ServerResponse, key: string) { const originalValue = Reflect.get(target, key) if (isRevalidateMethod(key, originalValue)) { diff --git a/tests/e2e/dynamic-cms.test.ts b/tests/e2e/dynamic-cms.test.ts new file mode 100644 index 0000000000..a157b47727 --- /dev/null +++ b/tests/e2e/dynamic-cms.test.ts @@ -0,0 +1,58 @@ +import { expect } from '@playwright/test' +import { test } from '../utils/playwright-helpers.js' + +test.describe('Dynamic CMS', () => { + test('Invalidates 404 pages from durable cache', async ({ page, dynamicCms }) => { + // 1. Verify the status and headers of the dynamic page + const response1 = await page.goto(new URL('/content/blog', dynamicCms.url).href) + const headers1 = response1?.headers() || {} + + expect(response1?.status()).toEqual(404) + expect(headers1['cache-control']).toEqual('public,max-age=0,must-revalidate') + expect(headers1['cache-status']).toEqual( + '"Next.js"; fwd=miss, "Netlify Durable"; fwd=uri-miss; stored, "Netlify Edge"; fwd=miss', + ) + expect(headers1['netlify-cache-tag']).toEqual('_n_t_/content/blog') + expect(headers1['netlify-cdn-cache-control']).toMatch( + /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, + ) + + // 2. Publish the blob, revalidate the dynamic page, and wait to regenerate + await page.goto(new URL('/cms/publish', dynamicCms.url).href) + await page.goto(new URL('/api/revalidate?path=/content/blog', dynamicCms.url).href) + await page.waitForTimeout(1000) + + // 3. Verify the status and headers of the dynamic page + const response2 = await page.goto(new URL('/content/blog', dynamicCms.url).href) + const headers2 = response2?.headers() || {} + + expect(response2?.status()).toEqual(200) + expect(headers2['cache-control']).toEqual('public,max-age=0,must-revalidate') + expect(headers2['cache-status']).toMatch( + /"Next.js"; hit, "Netlify Durable"; fwd=stale; ttl=[0-9]+; stored, "Netlify Edge"; fwd=(stale|miss)/, + ) + expect(headers2['netlify-cache-tag']).toEqual('_n_t_/content/blog') + expect(headers2['netlify-cdn-cache-control']).toMatch( + /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, + ) + + // 4. Unpublish the blob, revalidate the dynamic page, and wait to regenerate + await page.goto(new URL('/cms/unpublish', dynamicCms.url).href) + await page.goto(new URL('/api/revalidate?path=/content/blog', dynamicCms.url).href) + await page.waitForTimeout(1000) + + // 5. Verify the status and headers of the dynamic page + const response3 = await page.goto(new URL('/content/blog', dynamicCms.url).href) + const headers3 = response3?.headers() || {} + + expect(response3?.status()).toEqual(404) + expect(headers3['cache-control']).toEqual('public,max-age=0,must-revalidate') + expect(headers3['cache-status']).toMatch( + /"Next.js"; fwd=miss, "Netlify Durable"; fwd=stale; ttl=[0-9]+; stored, "Netlify Edge"; fwd=(stale|miss)/, + ) + expect(headers3['netlify-cache-tag']).toEqual('_n_t_/content/blog') + expect(headers3['netlify-cdn-cache-control']).toMatch( + /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, + ) + }) +}) diff --git a/tests/fixtures/dynamic-cms/README.md b/tests/fixtures/dynamic-cms/README.md new file mode 100644 index 0000000000..e9f8e0c8ce --- /dev/null +++ b/tests/fixtures/dynamic-cms/README.md @@ -0,0 +1 @@ +This fixture is meant to emulate dynamic content responses of a CMS-backed next site diff --git a/tests/fixtures/dynamic-cms/netlify/functions/cms.ts b/tests/fixtures/dynamic-cms/netlify/functions/cms.ts new file mode 100644 index 0000000000..243421e0be --- /dev/null +++ b/tests/fixtures/dynamic-cms/netlify/functions/cms.ts @@ -0,0 +1,24 @@ +import { getDeployStore } from '@netlify/blobs' +import { Context } from '@netlify/functions' + +// publish or unpublish "cms content" depending on the sent operation +export default async function handler(_request: Request, context: Context) { + const store = getDeployStore({ name: 'cms-content', consistency: 'strong' }) + const BLOB_KEY = 'key' + + const operation = context.params['operation'] + + if (operation === 'publish') { + await store.setJSON(BLOB_KEY, { content: true }) + } + + if (operation === 'unpublish') { + await store.delete(BLOB_KEY) + } + + return Response.json({ ok: true }) +} + +export const config = { + path: '/cms/:operation', +} diff --git a/tests/fixtures/dynamic-cms/next.config.js b/tests/fixtures/dynamic-cms/next.config.js new file mode 100644 index 0000000000..6346ab0742 --- /dev/null +++ b/tests/fixtures/dynamic-cms/next.config.js @@ -0,0 +1,10 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: 'standalone', + eslint: { + ignoreDuringBuilds: true, + }, + generateBuildId: () => 'build-id', +} + +module.exports = nextConfig diff --git a/tests/fixtures/dynamic-cms/package.json b/tests/fixtures/dynamic-cms/package.json new file mode 100644 index 0000000000..33ebc7f177 --- /dev/null +++ b/tests/fixtures/dynamic-cms/package.json @@ -0,0 +1,24 @@ +{ + "name": "dynamic-cms", + "version": "0.1.0", + "private": true, + "scripts": { + "postinstall": "next build", + "dev": "next dev", + "build": "next build" + }, + "dependencies": { + "@netlify/blobs": "^8.1.0", + "@netlify/functions": "^2.7.0", + "@netlify/plugin-nextjs": "^5.10.1", + "netlify-cli": "^19.0.3", + "next": "latest", + "react": "18.2.0", + "react-dom": "18.2.0" + }, + "devDependencies": { + "@types/node": "22.13.13", + "@types/react": "19.0.12", + "typescript": "5.8.2" + } +} diff --git a/tests/fixtures/dynamic-cms/pages/404.js b/tests/fixtures/dynamic-cms/pages/404.js new file mode 100644 index 0000000000..3c251e6665 --- /dev/null +++ b/tests/fixtures/dynamic-cms/pages/404.js @@ -0,0 +1,3 @@ +export default function NotFound() { + return

Custom 404 page

+} diff --git a/tests/fixtures/dynamic-cms/pages/api/revalidate.js b/tests/fixtures/dynamic-cms/pages/api/revalidate.js new file mode 100644 index 0000000000..e134a56577 --- /dev/null +++ b/tests/fixtures/dynamic-cms/pages/api/revalidate.js @@ -0,0 +1,9 @@ +export default async function handler(req, res) { + try { + const pathToPurge = req.query.path ?? '/static/revalidate-manual' + await res.revalidate(pathToPurge) + return res.json({ code: 200, message: 'success' }) + } catch (err) { + return res.status(500).send({ code: 500, message: err.message }) + } +} diff --git a/tests/fixtures/dynamic-cms/pages/content/[...slug].js b/tests/fixtures/dynamic-cms/pages/content/[...slug].js new file mode 100644 index 0000000000..54abf74b16 --- /dev/null +++ b/tests/fixtures/dynamic-cms/pages/content/[...slug].js @@ -0,0 +1,37 @@ +import { getDeployStore } from '@netlify/blobs' + +const Content = ({ value }) => ( +
+

+ {JSON.stringify(value)} +

+
+) + +export async function getStaticProps() { + const store = getDeployStore({ name: 'cms-content', consistency: 'strong' }) + const BLOB_KEY = 'key' + + const value = await store.get(BLOB_KEY, { type: 'json' }) + + if (!value) { + return { + notFound: true, + } + } + + return { + props: { + value: value, + }, + } +} + +export const getStaticPaths = () => { + return { + paths: [], + fallback: 'blocking', // false or "blocking" + } +} + +export default Content diff --git a/tests/utils/create-e2e-fixture.ts b/tests/utils/create-e2e-fixture.ts index b133e6bc25..a2b5c48f00 100644 --- a/tests/utils/create-e2e-fixture.ts +++ b/tests/utils/create-e2e-fixture.ts @@ -440,5 +440,6 @@ export const fixtureFactories = { publishDirectory: 'apps/site/.next', smoke: true, }), + dynamicCms: () => createE2EFixture('dynamic-cms'), after: () => createE2EFixture('after'), } From bb6b015c3936fd465f45d92bf81df8bd450b734e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 15:31:53 +0000 Subject: [PATCH 06/16] chore(deps): update dependency @netlify/build to ^30.1.1 (#2808) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index e614dcb659..951900b152 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@fastly/http-compute-js": "1.1.5", "@netlify/blobs": "^8.1.2", - "@netlify/build": "^30.1.0", + "@netlify/build": "^30.1.1", "@netlify/edge-bundler": "^12.4.0", "@netlify/edge-functions": "^2.11.1", "@netlify/eslint-config-node": "^7.0.1", @@ -3864,15 +3864,15 @@ } }, "node_modules/@netlify/build": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@netlify/build/-/build-30.1.0.tgz", - "integrity": "sha512-aVRWN4ssLR6M1eYJXbLNh/Ulw+QrJQzNv6CxCdKPhPy5Ae3Oq9bGfZP0l47XvoscvU1nLwiI+vrmuBClUnphBQ==", + "version": "30.1.1", + "resolved": "https://registry.npmjs.org/@netlify/build/-/build-30.1.1.tgz", + "integrity": "sha512-iPGaFjDOE7FDt9xskCLaYlXcbwlQuoDZ0votmr2CQWfrNSnXAP8f44kPPSEzaLqyeQwRjmsrBUKqJ0Q3NCTLPA==", "dev": true, "dependencies": { "@bugsnag/js": "^7.0.0", "@netlify/blobs": "^8.1.2", "@netlify/cache-utils": "^5.2.0", - "@netlify/config": "^21.0.5", + "@netlify/config": "^21.0.6", "@netlify/edge-bundler": "12.4.0", "@netlify/framework-info": "^9.9.2", "@netlify/functions-utils": "^5.3.13", @@ -4096,9 +4096,9 @@ } }, "node_modules/@netlify/config": { - "version": "21.0.5", - "resolved": "https://registry.npmjs.org/@netlify/config/-/config-21.0.5.tgz", - "integrity": "sha512-uKL+0rMUFx+reNRrj9m2/QUzDwiAB64wVuD6i5N7ESPQbz29uOzVXzacu7uOuBEWGEWoX/8BkvJzhNMB1g8KJA==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@netlify/config/-/config-21.0.6.tgz", + "integrity": "sha512-zie9e/lKvdZ88Heduu5X6v+CvhcU1e9notQtugc3Hg60NWfXgRr1Z11opOeD/hh2GmoLkr6f1HBjndyKEFSZJA==", "dev": true, "dependencies": { "@iarna/toml": "^2.2.5", @@ -38494,15 +38494,15 @@ "dev": true }, "@netlify/build": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@netlify/build/-/build-30.1.0.tgz", - "integrity": "sha512-aVRWN4ssLR6M1eYJXbLNh/Ulw+QrJQzNv6CxCdKPhPy5Ae3Oq9bGfZP0l47XvoscvU1nLwiI+vrmuBClUnphBQ==", + "version": "30.1.1", + "resolved": "https://registry.npmjs.org/@netlify/build/-/build-30.1.1.tgz", + "integrity": "sha512-iPGaFjDOE7FDt9xskCLaYlXcbwlQuoDZ0votmr2CQWfrNSnXAP8f44kPPSEzaLqyeQwRjmsrBUKqJ0Q3NCTLPA==", "dev": true, "requires": { "@bugsnag/js": "^7.0.0", "@netlify/blobs": "^8.1.2", "@netlify/cache-utils": "^5.2.0", - "@netlify/config": "^21.0.5", + "@netlify/config": "^21.0.6", "@netlify/edge-bundler": "12.4.0", "@netlify/framework-info": "^9.9.2", "@netlify/functions-utils": "^5.3.13", @@ -38659,9 +38659,9 @@ } }, "@netlify/config": { - "version": "21.0.5", - "resolved": "https://registry.npmjs.org/@netlify/config/-/config-21.0.5.tgz", - "integrity": "sha512-uKL+0rMUFx+reNRrj9m2/QUzDwiAB64wVuD6i5N7ESPQbz29uOzVXzacu7uOuBEWGEWoX/8BkvJzhNMB1g8KJA==", + "version": "21.0.6", + "resolved": "https://registry.npmjs.org/@netlify/config/-/config-21.0.6.tgz", + "integrity": "sha512-zie9e/lKvdZ88Heduu5X6v+CvhcU1e9notQtugc3Hg60NWfXgRr1Z11opOeD/hh2GmoLkr6f1HBjndyKEFSZJA==", "dev": true, "requires": { "@iarna/toml": "^2.2.5", diff --git a/package.json b/package.json index 3febd9822e..ed5616dd10 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "devDependencies": { "@fastly/http-compute-js": "1.1.5", "@netlify/blobs": "^8.1.2", - "@netlify/build": "^30.1.0", + "@netlify/build": "^30.1.1", "@netlify/edge-bundler": "^12.4.0", "@netlify/edge-functions": "^2.11.1", "@netlify/eslint-config-node": "^7.0.1", From f1b8509069856d7988dfe0f172c179b5a8122795 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:35:04 -0400 Subject: [PATCH 07/16] fix(deps): update dependency @netlify/plugin-nextjs to ^5.10.2 (#2793) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- e2e-report/package-lock.json | 8 ++++---- e2e-report/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/e2e-report/package-lock.json b/e2e-report/package-lock.json index 66457f8611..35c4ab9106 100644 --- a/e2e-report/package-lock.json +++ b/e2e-report/package-lock.json @@ -8,7 +8,7 @@ "name": "e2e-test-site", "version": "0.2.0", "dependencies": { - "@netlify/plugin-nextjs": "^5.8.1", + "@netlify/plugin-nextjs": "^5.10.2", "next": "^14.2.3", "react": "^18.3.1", "react-dom": "^18.3.1" @@ -263,9 +263,9 @@ } }, "node_modules/@netlify/plugin-nextjs": { - "version": "5.8.1", - "resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-5.8.1.tgz", - "integrity": "sha512-WB1N0FslhWZ1yAVYTcB6CcFrFOUSQ0O2LfavYZrbAypeNxu2I+oO+cgmhfDgZ8Eoq1g4EMeoIGMkNoZ4ogZTsg==", + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@netlify/plugin-nextjs/-/plugin-nextjs-5.10.2.tgz", + "integrity": "sha512-UWf5yA8sumJsF5XF5fvk3S4O1SN1/mEhtWR5UQgDP1kz49hSWeQrR5cdDQYjRAXTrXr/uCxchgug8h42RmSxhA==", "license": "MIT", "engines": { "node": ">=18.0.0" diff --git a/e2e-report/package.json b/e2e-report/package.json index ed85303163..bd125546be 100644 --- a/e2e-report/package.json +++ b/e2e-report/package.json @@ -9,7 +9,7 @@ "lint": "next lint" }, "dependencies": { - "@netlify/plugin-nextjs": "^5.8.1", + "@netlify/plugin-nextjs": "^5.10.2", "next": "^14.2.3", "react": "^18.3.1", "react-dom": "^18.3.1" From 0e7e3a265d253cc5ab7d03855e39bee6ebf21d47 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 2 Apr 2025 21:07:43 +0200 Subject: [PATCH 08/16] fix: don't set permanent caching header when res.revalidate() was used (#2810) * test: api route calling res.revalidate on path returning notFound: true is not cacheable * fix: don't set permanent caching header when res.revalidate() was used * test: adjust added test name, add some context, handle case of header not being set --------- Co-authored-by: Mateusz Bocian --- src/run/headers.ts | 3 ++- tests/e2e/page-router.test.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/run/headers.ts b/src/run/headers.ts index 1931f61330..35a1a4b37a 100644 --- a/src/run/headers.ts +++ b/src/run/headers.ts @@ -266,7 +266,8 @@ export const setCacheControlHeaders = ( ['GET', 'HEAD'].includes(request.method) && !headers.has('cdn-cache-control') && !headers.has('netlify-cdn-cache-control') && - requestContext.usedFsReadForNonFallback + requestContext.usedFsReadForNonFallback && + !requestContext.didPagesRouterOnDemandRevalidate ) { // handle CDN Cache Control on static files headers.set('cache-control', 'public, max-age=0, must-revalidate') diff --git a/tests/e2e/page-router.test.ts b/tests/e2e/page-router.test.ts index a2471c980a..35e9123a66 100644 --- a/tests/e2e/page-router.test.ts +++ b/tests/e2e/page-router.test.ts @@ -590,6 +590,21 @@ test.describe('Simple Page Router (no basePath, no i18n)', () => { 'getStaticProps duration should not be longer than 10 seconds', ).toBeLessThan(10_000) }) + + test('API route calling res.revalidate() on page returning notFound: true is not cacheable', async ({ + page, + pageRouter, + }) => { + // note: known conditions for problematic case is + // 1. API route needs to call res.revalidate() + // 2. revalidated page's getStaticProps must return notFound: true + const response = await page.goto( + new URL('/api/revalidate?path=/static/not-found', pageRouter.url).href, + ) + + expect(response?.status()).toEqual(200) + expect(response?.headers()['netlify-cdn-cache-control'] ?? '').not.toMatch(/(s-maxage|max-age)/) + }) }) test.describe('Page Router with basePath and i18n', () => { From 82df6daeee0a569c7facbfff8810caaeab719981 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 19:27:13 +0000 Subject: [PATCH 09/16] chore(deps): update dependency memfs to v4.17.0 (#2718) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 951900b152..23e326fcca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14595,9 +14595,9 @@ } }, "node_modules/memfs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.0.tgz", - "integrity": "sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz", + "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==", "dev": true, "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", @@ -46038,9 +46038,9 @@ "dev": true }, "memfs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.0.tgz", - "integrity": "sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz", + "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==", "dev": true, "requires": { "@jsonjoy.com/json-pack": "^1.0.3", From 9b4099ee044d21454f0d71234a7f80da37a665c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 19:49:36 +0000 Subject: [PATCH 10/16] chore(deps-dev): bump vite from 5.4.15 to 5.4.16 (#2803) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.15 to 5.4.16. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.4.16/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23e326fcca..6ce24080ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34752,9 +34752,9 @@ } }, "node_modules/vite": { - "version": "5.4.15", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.15.tgz", - "integrity": "sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==", + "version": "5.4.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.16.tgz", + "integrity": "sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==", "dev": true, "license": "MIT", "dependencies": { @@ -60290,9 +60290,9 @@ } }, "vite": { - "version": "5.4.15", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.15.tgz", - "integrity": "sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==", + "version": "5.4.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.16.tgz", + "integrity": "sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==", "dev": true, "requires": { "esbuild": "^0.21.3", From 720e20ad5800f1847694027464d50d9f28395fb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 20:16:27 +0000 Subject: [PATCH 11/16] chore(deps-dev): bump undici from 6.19.8 to 6.21.1 (#2744) Bumps [undici](https://github.com/nodejs/undici) from 6.19.8 to 6.21.1. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.19.8...v6.21.1) --- updated-dependencies: - dependency-name: undici dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ce24080ae..e36c6b8500 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34509,10 +34509,11 @@ } }, "node_modules/undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "version": "6.21.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz", + "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.17" } @@ -60113,9 +60114,9 @@ } }, "undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "version": "6.21.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz", + "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==", "dev": true }, "undici-types": { From bc3a9999d2d8f48624640f2ddf6d9237b380ecf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 17:41:19 -0400 Subject: [PATCH 12/16] chore(deps): update navikt/github-app-token-generator digest to 793caf0 (#2799) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-please.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index a63fd1aa46..9fa3ccfcfa 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -7,7 +7,7 @@ jobs: release-please: runs-on: ubuntu-latest steps: - - uses: navikt/github-app-token-generator@a8ae52448279d468cfbca5cd899f2457f0b1f643 + - uses: navikt/github-app-token-generator@793caf0d755fb4d6e88150825f680f188535cb48 id: get-token with: private-key: ${{ secrets.TOKENS_PRIVATE_KEY }} From 21e293bdeb86bd8a4cae2562bfc57c01c7d7f99b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 22:01:59 +0000 Subject: [PATCH 13/16] chore(deps): update dependency @types/picomatch to v3.0.2 (#2811) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index e36c6b8500..450e6aca6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7140,9 +7140,9 @@ "dev": true }, "node_modules/@types/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-1MRgzpzY0hOp9pW/kLRxeQhUWwil6gnrUYd3oEpeYBqp/FexhaCPv3F8LsYr47gtUU45fO2cm1dbwkSrHEo8Uw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-3.0.2.tgz", + "integrity": "sha512-n0i8TD3UDB7paoMMxA3Y65vUncFJXjcUf7lQY7YyKGl6031FNjfsLs6pdLFCy2GNFxItPJG8GvvpbZc2skH7WA==", "dev": true }, "node_modules/@types/retry": { @@ -40753,9 +40753,9 @@ "dev": true }, "@types/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-1MRgzpzY0hOp9pW/kLRxeQhUWwil6gnrUYd3oEpeYBqp/FexhaCPv3F8LsYr47gtUU45fO2cm1dbwkSrHEo8Uw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-3.0.2.tgz", + "integrity": "sha512-n0i8TD3UDB7paoMMxA3Y65vUncFJXjcUf7lQY7YyKGl6031FNjfsLs6pdLFCy2GNFxItPJG8GvvpbZc2skH7WA==", "dev": true }, "@types/retry": { From b6794be1359da578cb543c2713462e11be012b7b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 04:53:56 +0000 Subject: [PATCH 14/16] chore(deps): update dependency typescript to v5.8.2 (#2812) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 450e6aca6b..7b05c968e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34475,9 +34475,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -60090,9 +60090,9 @@ } }, "typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true }, "ufo": { From 13cb002ed2b3c020ca4c193a839459a4298945ae Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Thu, 3 Apr 2025 15:46:50 +0200 Subject: [PATCH 15/16] test: expand test fixture and cases for dynamic-cms tests with added i18n to fixture and testing i18n cases and json requests (#2813) --- tests/e2e/dynamic-cms.test.ts | 154 ++++++++++++------ .../netlify/functions/{cms.ts => cms.mts} | 12 +- tests/fixtures/dynamic-cms/next.config.js | 4 + tests/fixtures/dynamic-cms/package.json | 1 - .../dynamic-cms/pages/content/[...slug].js | 9 +- 5 files changed, 119 insertions(+), 61 deletions(-) rename tests/fixtures/dynamic-cms/netlify/functions/{cms.ts => cms.mts} (57%) diff --git a/tests/e2e/dynamic-cms.test.ts b/tests/e2e/dynamic-cms.test.ts index a157b47727..ae179c68fc 100644 --- a/tests/e2e/dynamic-cms.test.ts +++ b/tests/e2e/dynamic-cms.test.ts @@ -2,57 +2,107 @@ import { expect } from '@playwright/test' import { test } from '../utils/playwright-helpers.js' test.describe('Dynamic CMS', () => { - test('Invalidates 404 pages from durable cache', async ({ page, dynamicCms }) => { - // 1. Verify the status and headers of the dynamic page - const response1 = await page.goto(new URL('/content/blog', dynamicCms.url).href) - const headers1 = response1?.headers() || {} - - expect(response1?.status()).toEqual(404) - expect(headers1['cache-control']).toEqual('public,max-age=0,must-revalidate') - expect(headers1['cache-status']).toEqual( - '"Next.js"; fwd=miss, "Netlify Durable"; fwd=uri-miss; stored, "Netlify Edge"; fwd=miss', - ) - expect(headers1['netlify-cache-tag']).toEqual('_n_t_/content/blog') - expect(headers1['netlify-cdn-cache-control']).toMatch( - /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, - ) - - // 2. Publish the blob, revalidate the dynamic page, and wait to regenerate - await page.goto(new URL('/cms/publish', dynamicCms.url).href) - await page.goto(new URL('/api/revalidate?path=/content/blog', dynamicCms.url).href) - await page.waitForTimeout(1000) - - // 3. Verify the status and headers of the dynamic page - const response2 = await page.goto(new URL('/content/blog', dynamicCms.url).href) - const headers2 = response2?.headers() || {} - - expect(response2?.status()).toEqual(200) - expect(headers2['cache-control']).toEqual('public,max-age=0,must-revalidate') - expect(headers2['cache-status']).toMatch( - /"Next.js"; hit, "Netlify Durable"; fwd=stale; ttl=[0-9]+; stored, "Netlify Edge"; fwd=(stale|miss)/, - ) - expect(headers2['netlify-cache-tag']).toEqual('_n_t_/content/blog') - expect(headers2['netlify-cdn-cache-control']).toMatch( - /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, - ) - - // 4. Unpublish the blob, revalidate the dynamic page, and wait to regenerate - await page.goto(new URL('/cms/unpublish', dynamicCms.url).href) - await page.goto(new URL('/api/revalidate?path=/content/blog', dynamicCms.url).href) - await page.waitForTimeout(1000) - - // 5. Verify the status and headers of the dynamic page - const response3 = await page.goto(new URL('/content/blog', dynamicCms.url).href) - const headers3 = response3?.headers() || {} - - expect(response3?.status()).toEqual(404) - expect(headers3['cache-control']).toEqual('public,max-age=0,must-revalidate') - expect(headers3['cache-status']).toMatch( - /"Next.js"; fwd=miss, "Netlify Durable"; fwd=stale; ttl=[0-9]+; stored, "Netlify Edge"; fwd=(stale|miss)/, - ) - expect(headers3['netlify-cache-tag']).toEqual('_n_t_/content/blog') - expect(headers3['netlify-cdn-cache-control']).toMatch( - /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, - ) + test.describe('Invalidates 404 pages from durable cache', () => { + // using postFix allows to rerun tests without having to redeploy the app because paths/keys will be unique for each test run + const postFix = Date.now() + for (const { label, contentKey, expectedCacheTag, urlPath, pathToRevalidate } of [ + { + label: 'Invalidates 404 html from durable cache (implicit default locale)', + urlPath: `/content/html-implicit-default-locale-${postFix}`, + contentKey: `html-implicit-default-locale-${postFix}`, + expectedCacheTag: `_n_t_/en/content/html-implicit-default-locale-${postFix}`, + }, + { + label: 'Invalidates 404 html from durable cache (explicit default locale)', + urlPath: `/en/content/html-explicit-default-locale-${postFix}`, + contentKey: `html-explicit-default-locale-${postFix}`, + expectedCacheTag: `_n_t_/en/content/html-explicit-default-locale-${postFix}`, + }, + // json paths don't have implicit locale routing + { + label: 'Invalidates 404 json from durable cache (default locale)', + urlPath: `/_next/data/build-id/en/content/json-default-locale-${postFix}.json`, + // for html, we can use html path as param for revalidate, + // for json we can't use json path and instead use one of html paths + // let's use implicit default locale here, as we will have another case for + // non-default locale which will have to use explicit one + pathToRevalidate: `/content/json-default-locale-${postFix}`, + contentKey: `json-default-locale-${postFix}`, + expectedCacheTag: `_n_t_/en/content/json-default-locale-${postFix}`, + }, + { + label: 'Invalidates 404 html from durable cache (non-default locale)', + urlPath: `/fr/content/html-non-default-locale-${postFix}`, + contentKey: `html-non-default-locale-${postFix}`, + expectedCacheTag: `_n_t_/fr/content/html-non-default-locale-${postFix}`, + }, + { + label: 'Invalidates 404 json from durable cache (non-default locale)', + urlPath: `/_next/data/build-id/fr/content/json-non-default-locale-${postFix}.json`, + pathToRevalidate: `/fr/content/json-non-default-locale-${postFix}`, + contentKey: `json-non-default-locale-${postFix}`, + expectedCacheTag: `_n_t_/fr/content/json-non-default-locale-${postFix}`, + }, + ]) { + test(label, async ({ page, dynamicCms }) => { + const routeUrl = new URL(urlPath, dynamicCms.url).href + const revalidateAPiUrl = new URL( + `/api/revalidate?path=${pathToRevalidate ?? urlPath}`, + dynamicCms.url, + ).href + + // 1. Verify the status and headers of the dynamic page + const response1 = await page.goto(routeUrl) + const headers1 = response1?.headers() || {} + + expect(response1?.status()).toEqual(404) + expect(headers1['cache-control']).toEqual('public,max-age=0,must-revalidate') + expect(headers1['cache-status']).toEqual( + '"Next.js"; fwd=miss, "Netlify Durable"; fwd=uri-miss; stored, "Netlify Edge"; fwd=miss', + ) + expect(headers1['netlify-cache-tag']).toEqual(expectedCacheTag) + expect(headers1['netlify-cdn-cache-control']).toMatch( + /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, + ) + + // 2. Publish the blob, revalidate the dynamic page, and wait to regenerate + await page.goto(new URL(`/cms/publish/${contentKey}`, dynamicCms.url).href) + await page.goto(revalidateAPiUrl) + await page.waitForTimeout(1000) + + // 3. Verify the status and headers of the dynamic page + const response2 = await page.goto(routeUrl) + const headers2 = response2?.headers() || {} + + expect(response2?.status()).toEqual(200) + expect(headers2['cache-control']).toEqual('public,max-age=0,must-revalidate') + expect(headers2['cache-status']).toMatch( + /"Next.js"; hit, "Netlify Durable"; fwd=stale; ttl=[0-9]+; stored, "Netlify Edge"; fwd=(stale|miss)/, + ) + expect(headers2['netlify-cache-tag']).toEqual(expectedCacheTag) + expect(headers2['netlify-cdn-cache-control']).toMatch( + /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, + ) + + // 4. Unpublish the blob, revalidate the dynamic page, and wait to regenerate + await page.goto(new URL(`/cms/unpublish/${contentKey}`, dynamicCms.url).href) + await page.goto(revalidateAPiUrl) + await page.waitForTimeout(1000) + + // 5. Verify the status and headers of the dynamic page + const response3 = await page.goto(routeUrl) + const headers3 = response3?.headers() || {} + + expect(response3?.status()).toEqual(404) + expect(headers3['cache-control']).toEqual('public,max-age=0,must-revalidate') + expect(headers3['cache-status']).toMatch( + /"Next.js"; fwd=miss, "Netlify Durable"; fwd=stale; ttl=[0-9]+; stored, "Netlify Edge"; fwd=(stale|miss)/, + ) + expect(headers3['netlify-cache-tag']).toEqual(expectedCacheTag) + expect(headers3['netlify-cdn-cache-control']).toMatch( + /s-maxage=31536000,( stale-while-revalidate=31536000,)? durable/, + ) + }) + } }) }) diff --git a/tests/fixtures/dynamic-cms/netlify/functions/cms.ts b/tests/fixtures/dynamic-cms/netlify/functions/cms.mts similarity index 57% rename from tests/fixtures/dynamic-cms/netlify/functions/cms.ts rename to tests/fixtures/dynamic-cms/netlify/functions/cms.mts index 243421e0be..fb3a9ad2d5 100644 --- a/tests/fixtures/dynamic-cms/netlify/functions/cms.ts +++ b/tests/fixtures/dynamic-cms/netlify/functions/cms.mts @@ -4,21 +4,25 @@ import { Context } from '@netlify/functions' // publish or unpublish "cms content" depending on the sent operation export default async function handler(_request: Request, context: Context) { const store = getDeployStore({ name: 'cms-content', consistency: 'strong' }) - const BLOB_KEY = 'key' const operation = context.params['operation'] + // root of optional catch-all route in Next.js sets 'index.html' as param + // while it's undefined in the Netlify function, because we need to declare + // path without wildcard + const contentKey = context.params['0'] ?? 'index.html' + if (operation === 'publish') { - await store.setJSON(BLOB_KEY, { content: true }) + await store.setJSON(contentKey, { content: true }) } if (operation === 'unpublish') { - await store.delete(BLOB_KEY) + await store.delete(contentKey) } return Response.json({ ok: true }) } export const config = { - path: '/cms/:operation', + path: ['/cms/:operation/*', '/cms/:operation'], } diff --git a/tests/fixtures/dynamic-cms/next.config.js b/tests/fixtures/dynamic-cms/next.config.js index 6346ab0742..fb5bd7c039 100644 --- a/tests/fixtures/dynamic-cms/next.config.js +++ b/tests/fixtures/dynamic-cms/next.config.js @@ -4,6 +4,10 @@ const nextConfig = { eslint: { ignoreDuringBuilds: true, }, + i18n: { + locales: ['en', 'fr'], + defaultLocale: 'en', + }, generateBuildId: () => 'build-id', } diff --git a/tests/fixtures/dynamic-cms/package.json b/tests/fixtures/dynamic-cms/package.json index 33ebc7f177..ba2eca67e8 100644 --- a/tests/fixtures/dynamic-cms/package.json +++ b/tests/fixtures/dynamic-cms/package.json @@ -10,7 +10,6 @@ "dependencies": { "@netlify/blobs": "^8.1.0", "@netlify/functions": "^2.7.0", - "@netlify/plugin-nextjs": "^5.10.1", "netlify-cli": "^19.0.3", "next": "latest", "react": "18.2.0", diff --git a/tests/fixtures/dynamic-cms/pages/content/[...slug].js b/tests/fixtures/dynamic-cms/pages/content/[...slug].js index 54abf74b16..070d222e99 100644 --- a/tests/fixtures/dynamic-cms/pages/content/[...slug].js +++ b/tests/fixtures/dynamic-cms/pages/content/[...slug].js @@ -8,11 +8,12 @@ const Content = ({ value }) => ( ) -export async function getStaticProps() { +export async function getStaticProps({ params }) { + const contentKey = params.slug.join('/') + const store = getDeployStore({ name: 'cms-content', consistency: 'strong' }) - const BLOB_KEY = 'key' - const value = await store.get(BLOB_KEY, { type: 'json' }) + const value = await store.get(contentKey, { type: 'json' }) if (!value) { return { @@ -22,7 +23,7 @@ export async function getStaticProps() { return { props: { - value: value, + value, }, } } From 04a2c7029493d765863ce875da3f408d7c78a3e3 Mon Sep 17 00:00:00 2001 From: Mateusz Bocian Date: Thu, 3 Apr 2025 10:42:36 -0400 Subject: [PATCH 16/16] chore(main): release 5.10.3 (#2814) --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c959e3340e..b568f9c356 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.10.2" + ".": "5.10.3" } diff --git a/CHANGELOG.md b/CHANGELOG.md index e89c6e4855..db23d620df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [5.10.3](https://github.com/opennextjs/opennextjs-netlify/compare/v5.10.2...v5.10.3) (2025-04-03) + + +### Bug Fixes + +* don't set permanent caching header when res.revalidate() was used ([#2810](https://github.com/opennextjs/opennextjs-netlify/issues/2810)) ([0e7e3a2](https://github.com/opennextjs/opennextjs-netlify/commit/0e7e3a265d253cc5ab7d03855e39bee6ebf21d47)) +* improved cdn cache hooks for dynamic 404 pages ([#2786](https://github.com/opennextjs/opennextjs-netlify/issues/2786)) ([b4f04e3](https://github.com/opennextjs/opennextjs-netlify/commit/b4f04e3c5a9c83c916f69c3e3c64e0d946ec3692)) + ## [5.10.2](https://github.com/opennextjs/opennextjs-netlify/compare/v5.10.1...v5.10.2) (2025-03-31) diff --git a/package-lock.json b/package-lock.json index 7b05c968e5..bd04a964be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@netlify/plugin-nextjs", - "version": "5.10.2", + "version": "5.10.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@netlify/plugin-nextjs", - "version": "5.10.2", + "version": "5.10.3", "license": "MIT", "devDependencies": { "@fastly/http-compute-js": "1.1.5", diff --git a/package.json b/package.json index ed5616dd10..07de174715 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@netlify/plugin-nextjs", - "version": "5.10.2", + "version": "5.10.3", "description": "Run Next.js seamlessly on Netlify", "main": "./dist/index.js", "type": "module",