mirror of
https://github.com/civitai/civitai.git
synced 2026-09-20 22:08:18 +08:00
chore(deps): delete the inert next@16.3.1 patch and correct the comments about it (#4086)
Next 16.3.1 is the first release containing upstream's SVG-loader fix (vercel/next.js#96681) — it ships 'VipsForeignLoadSvg' in the sharp.unblock list itself, in both the CJS and ESM image-optimizer copies. Our local patch was therefore inert: the installed files are byte-identical (sha256) to the published tarball, and the patch does not even apply (its hunk context wants Png immediately followed by Tiff; 16.3.1 has Svg between them). It looked healthy because pnpm silently no-ops an already-applied patch — install exits 0, prints no warning, and still creates a patch_hash= virtual-store directory. Deletes the patch and its patchedDependencies entry (@mantine/hooks untouched), regenerates the lockfile, and corrects three comments that asserted upstream still lacked the entry. The CI guard stays: it asserts the outcome (the installed Next unblocks the SVG loader), so it keeps protecting against a future Next regressing this the way 16.3.0 did. Verified post-removal: guard green, still goes red when the loader entry is stripped from both installed copies, and /api/og renders PNGs on both paths on the preview build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-2
@@ -434,8 +434,7 @@
|
||||
"utf-8-validate"
|
||||
],
|
||||
"patchedDependencies": {
|
||||
"@mantine/hooks": "patches/@mantine__hooks.patch",
|
||||
"next@16.3.1": "patches/next@16.3.1.patch"
|
||||
"@mantine/hooks": "patches/@mantine__hooks.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
diff --git a/dist/esm/server/image-optimizer.js b/dist/esm/server/image-optimizer.js
|
||||
index 09277f1df5ed73d006e1769b405f148cab406dff..50135855db356fa22ab03b050ce24a4182c60a8d 100644
|
||||
--- a/dist/esm/server/image-optimizer.js
|
||||
+++ b/dist/esm/server/image-optimizer.js
|
||||
@@ -90,6 +90,7 @@ export function getSharp(concurrency, operationCache) {
|
||||
'VipsForeignLoadJpeg',
|
||||
'VipsForeignLoadNsgif',
|
||||
'VipsForeignLoadPng',
|
||||
+ 'VipsForeignLoadSvg',
|
||||
'VipsForeignLoadTiff',
|
||||
'VipsForeignLoadWebp'
|
||||
]
|
||||
diff --git a/dist/server/image-optimizer.js b/dist/server/image-optimizer.js
|
||||
index 9be0c9ae912f3824e9253641eee3273f17080a69..31b5c6e3e46f40a994f62c4d43df6a8bbf971869 100644
|
||||
--- a/dist/server/image-optimizer.js
|
||||
+++ b/dist/server/image-optimizer.js
|
||||
@@ -210,6 +210,7 @@ function getSharp(concurrency, operationCache) {
|
||||
'VipsForeignLoadJpeg',
|
||||
'VipsForeignLoadNsgif',
|
||||
'VipsForeignLoadPng',
|
||||
+ 'VipsForeignLoadSvg',
|
||||
'VipsForeignLoadTiff',
|
||||
'VipsForeignLoadWebp'
|
||||
]
|
||||
Generated
+14
-17
@@ -20,9 +20,6 @@ patchedDependencies:
|
||||
'@mantine/hooks':
|
||||
hash: b45a85bd4d007c796b93eb90a75d3234b81cce13964921b25721734c7ed79f64
|
||||
path: patches/@mantine__hooks.patch
|
||||
next@16.3.1:
|
||||
hash: d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6
|
||||
path: patches/next@16.3.1.patch
|
||||
|
||||
importers:
|
||||
|
||||
@@ -66,7 +63,7 @@ importers:
|
||||
version: link:packages/civitai-flipt
|
||||
'@civitai/next-axiom':
|
||||
specifier: ^0.17.0
|
||||
version: 0.17.0(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))
|
||||
version: 0.17.0(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))
|
||||
'@civitai/shared':
|
||||
specifier: workspace:*
|
||||
version: link:packages/civitai-shared
|
||||
@@ -156,7 +153,7 @@ importers:
|
||||
version: 16.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
|
||||
'@next/third-parties':
|
||||
specifier: ^15.0.3
|
||||
version: 15.4.6(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
|
||||
version: 15.4.6(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
|
||||
'@node-oauth/oauth2-server':
|
||||
specifier: ^5.3.0
|
||||
version: 5.3.0
|
||||
@@ -312,7 +309,7 @@ importers:
|
||||
version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2)
|
||||
'@trpc/next':
|
||||
specifier: ^11.17.0
|
||||
version: 11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)
|
||||
version: 11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)
|
||||
'@trpc/react-query':
|
||||
specifier: ^11.17.0
|
||||
version: 11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2)
|
||||
@@ -483,7 +480,7 @@ importers:
|
||||
version: 1.11.5
|
||||
next:
|
||||
specifier: ^16.3.1
|
||||
version: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
version: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
nodemailer:
|
||||
specifier: ^6.8.0
|
||||
version: 6.10.1
|
||||
@@ -543,7 +540,7 @@ importers:
|
||||
version: 7.12.0(algoliasearch@4.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-instantsearch-router-nextjs:
|
||||
specifier: 7.12.0
|
||||
version: 7.12.0(algoliasearch@4.25.2)(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
|
||||
version: 7.12.0(algoliasearch@4.25.2)(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)
|
||||
react-intersection-observer:
|
||||
specifier: ^9.4.0
|
||||
version: 9.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -13199,9 +13196,9 @@ snapshots:
|
||||
dependencies:
|
||||
fast-xml-parser: 5.10.1
|
||||
|
||||
'@civitai/next-axiom@0.17.0(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))':
|
||||
'@civitai/next-axiom@0.17.0(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))':
|
||||
dependencies:
|
||||
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
whatwg-fetch: 3.6.20
|
||||
|
||||
'@clavata/sdk@0.2.3':
|
||||
@@ -14423,9 +14420,9 @@ snapshots:
|
||||
'@next/swc-win32-x64-msvc@16.3.1':
|
||||
optional: true
|
||||
|
||||
'@next/third-parties@15.4.6(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)':
|
||||
'@next/third-parties@15.4.6(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1)':
|
||||
dependencies:
|
||||
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
react: 18.3.1
|
||||
third-party-capital: 1.0.20
|
||||
|
||||
@@ -16623,11 +16620,11 @@ snapshots:
|
||||
'@trpc/server': 11.17.0(typescript@5.9.2)
|
||||
typescript: 5.9.2
|
||||
|
||||
'@trpc/next@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)':
|
||||
'@trpc/next@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/react-query@11.17.0(@tanstack/react-query@5.101.0(react@18.3.1))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(react@18.3.1)(typescript@5.9.2))(@trpc/server@11.17.0(typescript@5.9.2))(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)':
|
||||
dependencies:
|
||||
'@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.2))(typescript@5.9.2)
|
||||
'@trpc/server': 11.17.0(typescript@5.9.2)
|
||||
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
typescript: 5.9.2
|
||||
@@ -21926,7 +21923,7 @@ snapshots:
|
||||
|
||||
neo-async@2.6.2: {}
|
||||
|
||||
next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0):
|
||||
next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0):
|
||||
dependencies:
|
||||
'@next/env': 16.3.1
|
||||
'@swc/helpers': 0.5.23
|
||||
@@ -23104,10 +23101,10 @@ snapshots:
|
||||
react: 18.3.1
|
||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||
|
||||
react-instantsearch-router-nextjs@7.12.0(algoliasearch@4.25.2)(next@16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1):
|
||||
react-instantsearch-router-nextjs@7.12.0(algoliasearch@4.25.2)(next@16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0))(react@18.3.1):
|
||||
dependencies:
|
||||
instantsearch.js: 4.73.0(algoliasearch@4.25.2)
|
||||
next: 16.3.1(patch_hash=d4cabfb715b050babab8b116679e9bd883334feb7bdf383883679c3cf22f94c6)(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
next: 16.3.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(@types/node@24.13.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.90.0)
|
||||
react-instantsearch-core: 7.12.0(algoliasearch@4.25.2)(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
- algoliasearch
|
||||
|
||||
@@ -12,22 +12,32 @@
|
||||
* WHAT IT ASSERTS, AND WHY THAT IS THE RIGHT INVARIANT. Next 16.3.0 applies a process-global
|
||||
* libvips block on first image-optimizer use and re-enables only six RASTER loaders; SVG is
|
||||
* not among them, so every `ImageResponse` in the process throws
|
||||
* `Input buffer contains unsupported image format` from then on. We carry upstream
|
||||
* vercel/next.js#96681 as `patches/next@16.3.1.patch` until we are on a Next that contains it.
|
||||
* `Input buffer contains unsupported image format` from then on. Upstream fixed that in
|
||||
* vercel/next.js#96681, and 16.3.1 is the first release that CONTAINS the fix: it ships
|
||||
* `'VipsForeignLoadSvg'` in the unblock list itself. We carried the one-line fix as a pnpm
|
||||
* patch only while we were on 16.3.0; there is no Next patch now, and this guard needs none.
|
||||
*
|
||||
* The assertion is deliberately "the installed Next unblocks SVG", NOT "our patch file is on
|
||||
* disk" and NOT "we are on any particular version":
|
||||
* So what this protects against today is a FUTURE Next regressing the loader entry again —
|
||||
* which is exactly why the assertion is deliberately "the installed Next unblocks SVG", NOT
|
||||
* "our patch file is on disk" and NOT "we are on any particular version":
|
||||
*
|
||||
* - reading `node_modules` rather than `patches/` is the whole point — a patch that exists
|
||||
* but did not APPLY (unregistered key, failed hunk, a stale lockfile hash) is exactly the
|
||||
* silent failure this catches, and a patch-file grep would sail through it;
|
||||
* - staying version-agnostic means the guard does not have to be retired in the same commit
|
||||
* that bumps Next. If a future Next ships the loader entry itself, this still passes with
|
||||
* the patch retired; the patch is separately version-pinned through
|
||||
* `pnpm.patchedDependencies`, so a bump fails the install rather than silently carrying a
|
||||
* stale patch. (Measured on the 16.3.0 -> 16.3.1 bump: the patch still applies, and the
|
||||
* installed 16.3.1 carries exactly ONE occurrence of the loader entry per copy — i.e. the
|
||||
* patch is what puts it there, upstream still does not.)
|
||||
* - reading `node_modules` rather than `patches/` is the whole point. It is the only form
|
||||
* that is correct both now (upstream supplies the entry, no patch exists) and in the
|
||||
* patched past (a patch that exists but did not APPLY — unregistered key, failed hunk, a
|
||||
* stale lockfile hash — is exactly the silent failure this catches, and a patch-file grep
|
||||
* would sail through it);
|
||||
* - staying version-agnostic means the guard does not have to be retired, re-pinned or
|
||||
* re-dated in the same commit that bumps Next. It keeps passing on any Next that unblocks
|
||||
* the loader, and goes red the moment one does not — whoever hits that decides between
|
||||
* re-introducing a patch and pinning back.
|
||||
*
|
||||
* 🔴 One occurrence per copy is NOT evidence about WHO supplied it. The count is the same
|
||||
* whether upstream ships the entry or a patch inserted it, so it cannot distinguish the two —
|
||||
* reading it as proof of a working patch is how the now-deleted 16.3.1 patch was carried for
|
||||
* a while after it had gone inert (pnpm silently no-ops an already-applied patch: rc=0, no
|
||||
* warning, and it still creates a `patch_hash=…` virtual-store dir, so it LOOKS applied).
|
||||
* To attribute the entry, compare the installed file against the pristine published tarball —
|
||||
* on 16.3.1 they are byte-identical, so upstream is the source.
|
||||
*
|
||||
* BOTH BUILDS, SKIPPING WHAT IS ABSENT. Next ships this module twice — `dist/server/` (CJS)
|
||||
* and `dist/esm/server/`. A full `pnpm install` has both; the production standalone image has
|
||||
@@ -115,10 +125,15 @@ function formatReport(report) {
|
||||
const FAILURE_EXPLANATION =
|
||||
`FAIL: the installed Next does not unblock the libvips SVG loader (${REQUIRED_LOADER}).\n` +
|
||||
'Every `next/og` ImageResponse — i.e. all of /api/og — will return 500 as soon as anything\n' +
|
||||
'touches the image optimizer in that process. Check that `patches/next@<version>.patch` is\n' +
|
||||
'still registered under `pnpm.patchedDependencies` in package.json and that\n' +
|
||||
'`pnpm install` applied it; this reads node_modules, so a patch file that exists but did\n' +
|
||||
'not apply fails here. See src/tests/api/og.image-optimizer-sharp.test.ts for the outage.';
|
||||
'touches the image optimizer in that process.\n' +
|
||||
'Next >= 16.3.1 ships this loader entry itself (vercel/next.js#96681), and we carry no Next\n' +
|
||||
'patch, so this failing means the Next you installed has REGRESSED it — or dependencies are\n' +
|
||||
'stale. Re-run `pnpm install` and re-check; if the installed Next genuinely lacks the entry,\n' +
|
||||
'pin Next back to a release that unblocks the loader, or re-introduce a pnpm patch adding\n' +
|
||||
`'${REQUIRED_LOADER}' to the sharp.unblock({ operation: [...] }) list in BOTH\n` +
|
||||
'dist/server/image-optimizer.js and dist/esm/server/image-optimizer.js. This reads\n' +
|
||||
'node_modules, not patches/, so it judges the artifact you actually installed however the\n' +
|
||||
'entry got there. See src/tests/api/og.image-optimizer-sharp.test.ts for the outage.';
|
||||
|
||||
const NO_COPIES_EXPLANATION =
|
||||
'FAIL: found no copy of next/dist/**/server/image-optimizer.js to read, so this check ' +
|
||||
|
||||
@@ -22,9 +22,17 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
* `Input buffer contains unsupported image format` — and `/api/og` returns 500
|
||||
* for the rest of that pod's life. Upstream: vercel/next.js#96301 introduced it,
|
||||
* vercel/next.js#96681 fixes it by adding `'VipsForeignLoadSvg'` to the unblock
|
||||
* list. We carry that one-line fix as `patches/next@16.3.1.patch` until we are on
|
||||
* a Next release that contains it — 16.3.1 still does not, so the bump to it
|
||||
* renamed the patch and kept it.
|
||||
* list. We carried that one-line fix as a pnpm patch while we were on 16.3.0.
|
||||
* 16.3.1 is the first release that CONTAINS the fix — it ships the loader entry
|
||||
* upstream — so the patch became inert on that bump and has been deleted. What
|
||||
* these cases guard now is a FUTURE Next regressing the entry again.
|
||||
*
|
||||
* 🔴 Note for whoever reads this next: "the installed file has one occurrence of
|
||||
* `'VipsForeignLoadSvg'`" does NOT tell you whether upstream or a patch put it
|
||||
* there — the count is identical either way. That ambiguity is how the inert
|
||||
* patch survived a bump (pnpm no-ops an already-applied patch with rc=0 and no
|
||||
* warning). Attribute it by diffing the installed file against the published
|
||||
* tarball; on 16.3.1 they are byte-identical.
|
||||
*
|
||||
* WHY THIS TEST IS SHAPED THE WAY IT IS. 🔴 The ordering is the whole test.
|
||||
* Rendering an `ImageResponse` in a fresh process SUCCEEDS even on a broken
|
||||
@@ -66,6 +74,22 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
* reports 1 copy read and the ESM copy as skipped.
|
||||
* - both copies absent: exits 1 rather than passing vacuously on zero reads.
|
||||
*
|
||||
* Re-watched 2026-08-18 on stock 16.3.1 with the patch DELETED — the mutations
|
||||
* above that reinstall or delete a patch no longer reproduce, since there is no
|
||||
* Next patch to remove, so the guard was driven against node_modules directly:
|
||||
* - installed copies byte-identical (sha256) to the published next-16.3.1
|
||||
* tarball, and the guard exits 0 reporting `copies read: 2`, both ok. The
|
||||
* hash equality is the part that attributes the loader entry to upstream;
|
||||
* the guard's own green cannot, since it counts rather than attributes.
|
||||
* - `'VipsForeignLoadSvg',` stripped from BOTH installed copies, leaving the
|
||||
* `unblock({ operation: [...] })` call structurally intact so the SVG branch
|
||||
* is reached rather than the no-unblock-call fallback: exits 1 reporting
|
||||
* both copies "does NOT unblock VipsForeignLoadSvg", `copies read: 2`.
|
||||
* Restored from a `cp -a` backup (never `git checkout` — node_modules is
|
||||
* untracked) and re-confirmed green.
|
||||
* - both copies moved aside: exits 1 with "this check proved nothing",
|
||||
* `copies read: 0` — still no vacuous pass.
|
||||
*
|
||||
* SCOPE / WHAT THIS DOES NOT COVER. This runs in-process, so it does not cover
|
||||
* packaging failures under `output: 'standalone'` (the OTHER way `/api/og` has
|
||||
* broken — see the `outputFileTracingIncludes['/api/og']` entry in
|
||||
|
||||
Reference in New Issue
Block a user