vinext 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/README.md +93 -10
  2. package/dist/build/app-page-static-eligibility.d.ts +15 -0
  3. package/dist/build/app-page-static-eligibility.js +82 -0
  4. package/dist/build/client-build-config.d.ts +10 -0
  5. package/dist/build/client-build-config.js +18 -2
  6. package/dist/build/pages-client-assets-module.d.ts +8 -0
  7. package/dist/build/pages-client-assets-module.js +21 -1
  8. package/dist/build/prerender-paths.js +8 -81
  9. package/dist/build/prerender.js +33 -8
  10. package/dist/build/run-prerender.js +1 -1
  11. package/dist/build/server-manifest.d.ts +7 -0
  12. package/dist/build/server-manifest.js +11 -1
  13. package/dist/build/ssr-manifest.d.ts +2 -0
  14. package/dist/build/ssr-manifest.js +6 -2
  15. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  16. package/dist/cache/cache-adapters-virtual.js +3 -3
  17. package/dist/check.js +7 -6
  18. package/dist/cli.js +2 -1
  19. package/dist/client/client-redirect-matcher.d.ts +14 -0
  20. package/dist/client/client-redirect-matcher.js +37 -0
  21. package/dist/client/client-redirects.d.ts +27 -0
  22. package/dist/client/client-redirects.js +28 -0
  23. package/dist/client/client-rewrites.d.ts +2 -1
  24. package/dist/client/client-rewrites.js +1 -1
  25. package/dist/client/navigation-runtime.d.ts +11 -0
  26. package/dist/client/navigation-runtime.js +1 -1
  27. package/dist/config/config-matchers.d.ts +26 -11
  28. package/dist/config/config-matchers.js +81 -82
  29. package/dist/config/destination-params.d.ts +47 -0
  30. package/dist/config/destination-params.js +116 -0
  31. package/dist/config/next-config.d.ts +14 -0
  32. package/dist/config/next-config.js +21 -3
  33. package/dist/entries/app-rsc-entry.d.ts +6 -0
  34. package/dist/entries/app-rsc-entry.js +84 -49
  35. package/dist/entries/pages-client-entry.js +3 -1
  36. package/dist/entries/pages-server-entry.js +13 -37
  37. package/dist/index.d.ts +7 -2
  38. package/dist/index.js +193 -73
  39. package/dist/init-cloudflare.d.ts +9 -0
  40. package/dist/init-cloudflare.js +107 -31
  41. package/dist/init-platform.d.ts +4 -0
  42. package/dist/init-platform.js +27 -2
  43. package/dist/init.d.ts +1 -0
  44. package/dist/init.js +67 -3
  45. package/dist/plugins/ast-scope.d.ts +7 -0
  46. package/dist/plugins/ast-scope.js +59 -3
  47. package/dist/plugins/cache-flight-codec.d.ts +19 -0
  48. package/dist/plugins/cache-flight-codec.js +68 -0
  49. package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
  50. package/dist/plugins/commonjs-esm-facade.js +80 -0
  51. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  52. package/dist/plugins/dynamic-preload-metadata.js +9 -8
  53. package/dist/plugins/fonts.d.ts +8 -11
  54. package/dist/plugins/fonts.js +71 -34
  55. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  56. package/dist/plugins/ignore-dynamic-requests.js +3 -4
  57. package/dist/plugins/middleware-server-only.d.ts +5 -4
  58. package/dist/plugins/middleware-server-only.js +8 -5
  59. package/dist/plugins/pages-node-externals.js +1 -1
  60. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  61. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  62. package/dist/plugins/strip-server-exports.js +262 -98
  63. package/dist/plugins/transform-result.d.ts +9 -5
  64. package/dist/plugins/transitive-externals.js +1 -1
  65. package/dist/plugins/typeof-window.d.ts +2 -2
  66. package/dist/plugins/use-cache-callable.js +8 -2
  67. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  68. package/dist/plugins/worker-server-only-imports.js +31 -0
  69. package/dist/plugins/worker-use-server.d.ts +25 -0
  70. package/dist/plugins/worker-use-server.js +129 -0
  71. package/dist/routing/file-matcher.d.ts +1 -0
  72. package/dist/routing/file-matcher.js +1 -1
  73. package/dist/server/api-handler.d.ts +1 -0
  74. package/dist/server/api-handler.js +19 -8
  75. package/dist/server/app-browser-action-result.d.ts +1 -1
  76. package/dist/server/app-browser-action-result.js +9 -2
  77. package/dist/server/app-browser-entry.js +11 -7
  78. package/dist/server/app-browser-history-controller.d.ts +2 -0
  79. package/dist/server/app-browser-history-controller.js +8 -0
  80. package/dist/server/app-browser-interception-context.js +26 -2
  81. package/dist/server/app-browser-navigation-controller.d.ts +7 -1
  82. package/dist/server/app-browser-navigation-controller.js +94 -11
  83. package/dist/server/app-browser-server-action-client.js +1 -1
  84. package/dist/server/app-fallback-renderer.d.ts +2 -0
  85. package/dist/server/app-fallback-renderer.js +1 -0
  86. package/dist/server/app-history-state.d.ts +3 -0
  87. package/dist/server/app-history-state.js +7 -0
  88. package/dist/server/app-middleware.d.ts +11 -0
  89. package/dist/server/app-middleware.js +19 -3
  90. package/dist/server/app-optimistic-routing.js +1 -1
  91. package/dist/server/app-page-boundary-render.d.ts +5 -0
  92. package/dist/server/app-page-boundary-render.js +6 -4
  93. package/dist/server/app-page-cache-finalizer.d.ts +11 -0
  94. package/dist/server/app-page-cache-finalizer.js +41 -7
  95. package/dist/server/app-page-cache-render.d.ts +18 -0
  96. package/dist/server/app-page-cache-render.js +63 -43
  97. package/dist/server/app-page-cache.d.ts +6 -1
  98. package/dist/server/app-page-cache.js +28 -8
  99. package/dist/server/app-page-dispatch.d.ts +12 -2
  100. package/dist/server/app-page-dispatch.js +51 -33
  101. package/dist/server/app-page-element-builder.d.ts +7 -0
  102. package/dist/server/app-page-element-builder.js +27 -42
  103. package/dist/server/app-page-execution.d.ts +15 -12
  104. package/dist/server/app-page-execution.js +30 -40
  105. package/dist/server/app-page-head.d.ts +5 -0
  106. package/dist/server/app-page-head.js +9 -3
  107. package/dist/server/app-page-ppr-runtime.js +1 -1
  108. package/dist/server/app-page-probe.d.ts +0 -109
  109. package/dist/server/app-page-probe.js +3 -136
  110. package/dist/server/app-page-render-identity.d.ts +0 -1
  111. package/dist/server/app-page-render-identity.js +1 -1
  112. package/dist/server/app-page-render-observation.js +3 -3
  113. package/dist/server/app-page-render.d.ts +13 -5
  114. package/dist/server/app-page-render.js +219 -119
  115. package/dist/server/app-page-request.d.ts +0 -1
  116. package/dist/server/app-page-request.js +54 -17
  117. package/dist/server/app-page-response.d.ts +4 -3
  118. package/dist/server/app-page-response.js +4 -3
  119. package/dist/server/app-page-route-wiring.d.ts +17 -5
  120. package/dist/server/app-page-route-wiring.js +57 -35
  121. package/dist/server/app-page-rsc-render-status.d.ts +48 -0
  122. package/dist/server/app-page-rsc-render-status.js +54 -0
  123. package/dist/server/app-page-stream.d.ts +15 -8
  124. package/dist/server/app-page-stream.js +6 -0
  125. package/dist/server/app-pages-bridge.d.ts +1 -1
  126. package/dist/server/app-pages-bridge.js +2 -3
  127. package/dist/server/app-prerender-endpoints.js +9 -6
  128. package/dist/server/app-request-stage-dispatch.js +7 -3
  129. package/dist/server/app-request-stage-independent-entry.js +29 -9
  130. package/dist/server/app-response-header-provenance.d.ts +2 -0
  131. package/dist/server/app-response-header-provenance.js +10 -4
  132. package/dist/server/app-response-stage-entry.js +10 -2
  133. package/dist/server/app-route-handler-cache.d.ts +1 -0
  134. package/dist/server/app-route-handler-cache.js +1 -0
  135. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  136. package/dist/server/app-route-handler-dispatch.js +6 -3
  137. package/dist/server/app-route-handler-execution.d.ts +1 -0
  138. package/dist/server/app-route-handler-execution.js +1 -0
  139. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  140. package/dist/server/app-route-handler-runtime.js +45 -24
  141. package/dist/server/app-router-entry.js +27 -8
  142. package/dist/server/app-rsc-cache-busting.js +1 -1
  143. package/dist/server/app-rsc-errors.js +20 -16
  144. package/dist/server/app-rsc-handler.d.ts +11 -0
  145. package/dist/server/app-rsc-handler.js +291 -125
  146. package/dist/server/app-rsc-request-normalization.d.ts +3 -1
  147. package/dist/server/app-rsc-request-normalization.js +4 -2
  148. package/dist/server/app-rsc-response-stage.d.ts +1 -1
  149. package/dist/server/app-rsc-response-stage.js +10 -6
  150. package/dist/server/app-rsc-route-matching.d.ts +9 -1
  151. package/dist/server/app-rsc-route-matching.js +36 -19
  152. package/dist/server/app-segment-config.d.ts +2 -1
  153. package/dist/server/app-server-action-execution.d.ts +2 -1
  154. package/dist/server/app-server-action-execution.js +62 -23
  155. package/dist/server/app-ssr-entry.d.ts +3 -2
  156. package/dist/server/app-ssr-entry.js +8 -5
  157. package/dist/server/app-ssr-stream.d.ts +6 -1
  158. package/dist/server/app-ssr-stream.js +34 -15
  159. package/dist/server/app-worker-stages.d.ts +7 -2
  160. package/dist/server/app-worker-stages.js +4 -4
  161. package/dist/server/cacheability-request.js +11 -7
  162. package/dist/server/client-build-files.d.ts +16 -0
  163. package/dist/server/client-build-files.js +36 -0
  164. package/dist/server/client-reuse-manifest.js +1 -1
  165. package/dist/server/config-headers.js +2 -0
  166. package/dist/server/dev-server.js +50 -29
  167. package/dist/server/dev-stack-sourcemap.js +18 -23
  168. package/dist/server/document-initial-head.d.ts +0 -11
  169. package/dist/server/document-initial-head.js +1 -1
  170. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  171. package/dist/server/forwarded-middleware-context.js +22 -0
  172. package/dist/server/headers.d.ts +18 -1
  173. package/dist/server/headers.js +19 -2
  174. package/dist/server/http-conditional.d.ts +11 -0
  175. package/dist/server/http-conditional.js +10 -1
  176. package/dist/server/http-error-responses.d.ts +1 -1
  177. package/dist/server/image-optimization.d.ts +54 -0
  178. package/dist/server/image-optimization.js +118 -9
  179. package/dist/server/isr-cache.d.ts +10 -0
  180. package/dist/server/isr-cache.js +43 -8
  181. package/dist/server/metadata-route-response.js +9 -8
  182. package/dist/server/middleware-matcher-pattern.js +8 -4
  183. package/dist/server/middleware-matcher.d.ts +2 -0
  184. package/dist/server/middleware-matcher.js +23 -2
  185. package/dist/server/middleware-response-headers.js +2 -0
  186. package/dist/server/middleware-runtime.d.ts +13 -0
  187. package/dist/server/middleware-runtime.js +33 -20
  188. package/dist/server/middleware.d.ts +1 -1
  189. package/dist/server/middleware.js +3 -1
  190. package/dist/server/multi-stage.d.ts +19 -0
  191. package/dist/server/navigation-planner.js +1 -1
  192. package/dist/server/node-response-signal.d.ts +16 -0
  193. package/dist/server/node-response-signal.js +26 -0
  194. package/dist/server/normalize-path.d.ts +0 -13
  195. package/dist/server/normalize-path.js +1 -34
  196. package/dist/server/open-redirect.d.ts +47 -0
  197. package/dist/server/open-redirect.js +74 -1
  198. package/dist/server/pages-api-route.d.ts +3 -2
  199. package/dist/server/pages-api-route.js +4 -3
  200. package/dist/server/pages-cache-tag.d.ts +12 -0
  201. package/dist/server/pages-cache-tag.js +19 -0
  202. package/dist/server/pages-client-assets.d.ts +2 -0
  203. package/dist/server/pages-data-route.d.ts +10 -0
  204. package/dist/server/pages-data-route.js +19 -2
  205. package/dist/server/pages-document-asset-props.d.ts +5 -1
  206. package/dist/server/pages-document-asset-props.js +13 -5
  207. package/dist/server/pages-document-splice.d.ts +19 -0
  208. package/dist/server/pages-document-splice.js +55 -0
  209. package/dist/server/pages-i18n.d.ts +12 -1
  210. package/dist/server/pages-i18n.js +18 -4
  211. package/dist/server/pages-node-compat.d.ts +16 -5
  212. package/dist/server/pages-node-compat.js +20 -12
  213. package/dist/server/pages-page-data.d.ts +32 -24
  214. package/dist/server/pages-page-data.js +50 -120
  215. package/dist/server/pages-page-handler.d.ts +0 -6
  216. package/dist/server/pages-page-handler.js +209 -130
  217. package/dist/server/pages-page-response.d.ts +12 -6
  218. package/dist/server/pages-page-response.js +41 -34
  219. package/dist/server/pages-request-pipeline.d.ts +10 -2
  220. package/dist/server/pages-request-pipeline.js +37 -18
  221. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  222. package/dist/server/pages-request-stage-entry.js +79 -16
  223. package/dist/server/pages-response-stage-entry.js +4 -0
  224. package/dist/server/pages-revalidate.js +1 -1
  225. package/dist/server/pages-router-entry.js +4 -3
  226. package/dist/server/prerender-manifest.d.ts +3 -3
  227. package/dist/server/prerender-manifest.js +4 -3
  228. package/dist/server/prerender-work-unit-setup.js +4 -0
  229. package/dist/server/prod-server.d.ts +20 -7
  230. package/dist/server/prod-server.js +343 -129
  231. package/dist/server/proper-error.d.ts +4 -0
  232. package/dist/server/proper-error.js +31 -0
  233. package/dist/server/request-pipeline.d.ts +24 -9
  234. package/dist/server/request-pipeline.js +24 -9
  235. package/dist/server/response-compression.d.ts +43 -0
  236. package/dist/server/response-compression.js +111 -0
  237. package/dist/server/revalidation-request.d.ts +1 -0
  238. package/dist/server/revalidation-request.js +1 -1
  239. package/dist/server/rsc-stream-hints.js +31 -2
  240. package/dist/server/seed-cache.d.ts +1 -0
  241. package/dist/server/seed-cache.js +15 -11
  242. package/dist/server/server-reference-loader.d.ts +4 -0
  243. package/dist/server/server-reference-loader.js +29 -0
  244. package/dist/server/socket-error-backstop.d.ts +23 -1
  245. package/dist/server/socket-error-backstop.js +69 -17
  246. package/dist/server/static-file-signal.d.ts +15 -4
  247. package/dist/server/static-file-signal.js +46 -12
  248. package/dist/server/worker-image-optimization.d.ts +34 -0
  249. package/dist/server/worker-image-optimization.js +86 -0
  250. package/dist/server/worker-stages.d.ts +1 -1
  251. package/dist/server/worker-stages.js +2 -2
  252. package/dist/server/worker-utils.d.ts +8 -3
  253. package/dist/server/worker-utils.js +12 -7
  254. package/dist/shims/app-router-scroll.js +4 -1
  255. package/dist/shims/app-router-tree-context.d.ts +5 -0
  256. package/dist/shims/app-router-tree-context.js +27 -0
  257. package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
  258. package/dist/shims/cache-adapter-instantiate.js +118 -0
  259. package/dist/shims/cache-callable-runtime.d.ts +6 -42
  260. package/dist/shims/cache-callable-runtime.js +65 -174
  261. package/dist/shims/cache-flight-arguments.d.ts +22 -0
  262. package/dist/shims/cache-flight-arguments.js +56 -0
  263. package/dist/shims/cache-handler.js +1 -9
  264. package/dist/shims/cache-request-state.d.ts +15 -0
  265. package/dist/shims/cache-request-state.js +31 -8
  266. package/dist/shims/cache-runtime.d.ts +12 -20
  267. package/dist/shims/cache-runtime.js +166 -225
  268. package/dist/shims/cache.d.ts +4 -4
  269. package/dist/shims/cache.js +44 -16
  270. package/dist/shims/cacheability-classification.d.ts +7 -0
  271. package/dist/shims/cdn-cache.d.ts +8 -0
  272. package/dist/shims/cdn-cache.js +17 -1
  273. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  274. package/dist/shims/disable-smooth-scroll.js +36 -0
  275. package/dist/shims/document-placeholders.d.ts +19 -0
  276. package/dist/shims/document-placeholders.js +45 -0
  277. package/dist/shims/document.js +21 -5
  278. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  279. package/dist/shims/dynamic-preload-chunks.js +13 -9
  280. package/dist/shims/dynamic.d.ts +1 -1
  281. package/dist/shims/dynamic.js +60 -8
  282. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  283. package/dist/shims/error-boundary-navigation.js +19 -1
  284. package/dist/shims/error-boundary.d.ts +10 -10
  285. package/dist/shims/error-boundary.js +26 -7
  286. package/dist/shims/fetch-cache-state.d.ts +66 -0
  287. package/dist/shims/fetch-cache-state.js +92 -0
  288. package/dist/shims/fetch-cache.d.ts +3 -61
  289. package/dist/shims/fetch-cache.js +161 -108
  290. package/dist/shims/form.js +1 -1
  291. package/dist/shims/head.d.ts +10 -6
  292. package/dist/shims/head.js +15 -13
  293. package/dist/shims/headers.d.ts +13 -0
  294. package/dist/shims/headers.js +47 -4
  295. package/dist/shims/image.js +2 -1
  296. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
  297. package/dist/shims/internal/app-page-props-cache-key.js +24 -15
  298. package/dist/shims/internal/headers-state.d.ts +0 -1
  299. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  300. package/dist/shims/internal/work-store-scope.js +24 -0
  301. package/dist/shims/metadata.js +3 -3
  302. package/dist/shims/navigation-errors.d.ts +6 -0
  303. package/dist/shims/navigation-errors.js +11 -1
  304. package/dist/shims/navigation.d.ts +7 -0
  305. package/dist/shims/navigation.js +45 -9
  306. package/dist/shims/request-context.d.ts +11 -0
  307. package/dist/shims/request-state-types.d.ts +2 -1
  308. package/dist/shims/router.js +12 -20
  309. package/dist/shims/server.d.ts +16 -0
  310. package/dist/shims/server.js +24 -4
  311. package/dist/shims/thenable-params.d.ts +4 -0
  312. package/dist/shims/thenable-params.js +25 -3
  313. package/dist/shims/unified-request-context.d.ts +1 -1
  314. package/dist/shims/unified-request-context.js +1 -0
  315. package/dist/shims/url-utils.d.ts +2 -0
  316. package/dist/shims/url-utils.js +3 -1
  317. package/dist/utils/client-runtime-metadata.js +1 -1
  318. package/dist/utils/hash.d.ts +7 -0
  319. package/dist/utils/hash.js +11 -1
  320. package/dist/utils/mdx-scan.d.ts +5 -0
  321. package/dist/utils/mdx-scan.js +8 -1
  322. package/dist/utils/package-name.d.ts +6 -0
  323. package/dist/utils/package-name.js +12 -1
  324. package/dist/utils/plugin-rsc-version.d.ts +4 -0
  325. package/dist/utils/plugin-rsc-version.js +15 -0
  326. package/dist/utils/prerender-output-paths.js +15 -4
  327. package/dist/utils/public-file-path.d.ts +10 -2
  328. package/dist/utils/public-file-path.js +13 -9
  329. package/dist/utils/public-routes.js +2 -2
  330. package/dist/utils/react-version.d.ts +3 -0
  331. package/dist/utils/react-version.js +1 -1
  332. package/dist/utils/regex-safety.d.ts +10 -0
  333. package/dist/utils/regex-safety.js +70 -18
  334. package/package.json +9 -5
package/dist/index.js CHANGED
@@ -14,8 +14,8 @@ import { matchesRewriteSource, proxyExternalRequest } from "./config/config-matc
14
14
  import { omitUnusedBuildSourcemap } from "./plugins/transform-result.js";
15
15
  import { assetPrefixPathname, isNextStaticPath, resolveAssetsDir } from "./utils/asset-prefix.js";
16
16
  import { RESOLVED_VIRTUAL_GOOGLE_FONTS, VIRTUAL_GOOGLE_FONTS, createGoogleFontsPlugin, createLocalFontsPlugin, generateGoogleFontsVirtualModule, parseStaticObjectLiteral } from "./plugins/fonts.js";
17
- import { VINEXT_NEXT_CONFIG_PLUGIN_PROPERTY, createRscCompatibilityId, findNextConfigPath, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "./config/next-config.js";
18
- import { normalizePathnameForRouteMatchStrict } from "./routing/utils.js";
17
+ import { VINEXT_NEXT_CONFIG_PLUGIN_PROPERTY, createRscCompatibilityId, findNextConfigPath, lightningCssFeatureNamesToMask, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "./config/next-config.js";
18
+ import { normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict } from "./routing/utils.js";
19
19
  import { hasBasePath, stripBasePath } from "./utils/base-path.js";
20
20
  import { appRouteGraph, appRouter, invalidateAppRouteCache, matchAppRoute } from "./routing/app-router.js";
21
21
  import { generateRouteTypes } from "./typegen.js";
@@ -25,24 +25,25 @@ import { INTERNAL_HEADERS, NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_INTERNAL_HEADERS,
25
25
  import { normalizePath as normalizePath$1 } from "./server/normalize-path.js";
26
26
  import { validateMiddlewareMatcherPatterns } from "./server/middleware-matcher-pattern.js";
27
27
  import { methodNotAllowedResponse, notFoundStaticAssetResponse } from "./server/http-error-responses.js";
28
- import { isOpenRedirectShaped } from "./server/open-redirect.js";
28
+ import { isOpenRedirectShaped, sendRepeatedSlashRedirect } from "./server/open-redirect.js";
29
29
  import { canonicalizeRequestUrlPathname, filterInternalHeaders, normalizeTrailingSlash } from "./server/request-pipeline.js";
30
30
  import { resolvePagesI18nRequest, stripI18nLocaleForApiRoute } from "./server/pages-i18n.js";
31
+ import { encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./server/pages-data-route.js";
31
32
  import { findInstrumentationClientFile, findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
32
33
  import { findMiddlewareFile, isProxyFile, runMiddleware } from "./server/middleware.js";
33
34
  import { extractMiddlewareMatcherConfig, extractMiddlewareMatcherConfigValue, hasExportedName } from "./build/report.js";
34
35
  import { generatePagesRequestEntry, generatePagesResponseEntry, generateServerEntry } from "./entries/pages-server-entry.js";
35
36
  import { compileClientMiddlewareMatchers, generateClientEntry } from "./entries/pages-client-entry.js";
37
+ import { isPathInside, isPathInsideOrEqual, stripJsExtension, stripViteModuleQuery } from "./utils/path.js";
36
38
  import { logRequest, now } from "./server/request-log.js";
37
- import { encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./server/pages-data-route.js";
38
39
  import { getPagesPreviewModeId } from "./server/pages-preview.js";
39
40
  import { createSSRHandler } from "./server/dev-server.js";
41
+ import { signalFromNodeResponse } from "./server/node-response-signal.js";
40
42
  import { handleApiRoute } from "./server/api-handler.js";
41
43
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, resolveDevImageRedirect } from "./server/image-optimization.js";
42
44
  import { CACHEABILITY_MANIFEST_MODULE, CACHEABILITY_REQUEST_PROJECTION_MODULE } from "./server/cacheability-manifest.js";
43
45
  import { PREGENERATED_CONCRETE_PATHS_MODULE } from "./server/pregenerated-concrete-paths.js";
44
46
  import { installSocketErrorBackstop } from "./server/socket-error-backstop.js";
45
- import { isPathInside, isPathInsideOrEqual, stripJsExtension, stripViteModuleQuery } from "./utils/path.js";
46
47
  import { invalidateMetadataFileCache, scanMetadataFiles } from "./server/metadata-routes.js";
47
48
  import { shouldInvalidateAppRouteFile } from "./server/dev-route-files.js";
48
49
  import { createDirectRunner } from "./server/dev-module-runner.js";
@@ -55,16 +56,19 @@ import { VIRTUAL_IMAGE_ADAPTERS, generateImageAdaptersModule } from "./image/ima
55
56
  import { generateBrowserEntry, toLinkPrefetchRoutes } from "./entries/app-browser-entry.js";
56
57
  import { collectRouteClassificationManifest } from "./build/route-classification-manifest.js";
57
58
  import { planRouteClassificationInjection } from "./build/route-classification-injector.js";
59
+ import { createRscScanGlobImportsPlugin, isRscScanGlobImportsAffected } from "./plugins/rsc-scan-glob-imports.js";
58
60
  import { findOpenTelemetryPackages, mergeServerExternalPackages } from "./config/server-external-packages.js";
59
61
  import { precompressAssets } from "./build/precompress.js";
60
62
  import { VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY, normalizeVinextPrerenderConfig } from "./config/prerender.js";
61
- import { PAGES_CLIENT_ASSETS_MODULE, buildPagesClientAssetsModule, writePagesClientAssetsModuleIfMissing } from "./build/pages-client-assets-module.js";
63
+ import { VINEXT_CLIENT_ENTRY_MANIFEST } from "./utils/client-entry-manifest.js";
64
+ import { PAGES_CLIENT_ASSETS_MODULE, buildPagesClientAssetsModule, collectClientBuildFiles, writePagesClientAssetsModuleIfMissing } from "./build/pages-client-assets-module.js";
62
65
  import { createPreviewBuildCredentials, getPreviewBuildCredentials } from "./build/preview-credentials.js";
63
66
  import { VINEXT_BUILD_LIFECYCLE_CONFIG, createBuildLifecyclePlugins } from "./build/lifecycle.js";
64
67
  import { ensureAssetsIgnore } from "./build/assets-ignore.js";
65
68
  import { emitNextClientRuntimeManifests } from "./build/next-client-runtime-manifests.js";
66
69
  import { collectInlineCssManifest, injectInlineCssManifestGlobal } from "./build/inline-css.js";
67
70
  import { readTrustedRevalidationHostname } from "./server/revalidation-host.js";
71
+ import { sealForwardedMiddlewareContext } from "./server/forwarded-middleware-context.js";
68
72
  import { installDevStackSourcemapMiddleware } from "./server/dev-stack-sourcemap.js";
69
73
  import { traceFrameworkRequest } from "./server/request-tracing.js";
70
74
  import { runPagesRequest } from "./server/pages-request-pipeline.js";
@@ -83,8 +87,8 @@ import { createScanBuildCssPlugin } from "./plugins/scan-build-css.js";
83
87
  import { createInstrumentationClientTransformPlugin, createInstrumentationServerTransformPlugin } from "./plugins/instrumentation-client.js";
84
88
  import { createStyledJsxPlugin } from "./plugins/styled-jsx.js";
85
89
  import { INSTRUMENTATION_CLIENT_EMPTY_MODULE, generateInstrumentationClientInjectModule } from "./client/instrumentation-client-inject.js";
86
- import { createMiddlewareServerOnlyPlugin } from "./plugins/middleware-server-only.js";
87
90
  import { isServerEnvironment } from "./plugins/environment.js";
91
+ import { createMiddlewareServerOnlyPlugin } from "./plugins/middleware-server-only.js";
88
92
  import { createPagesNodeExternalsPlugin } from "./plugins/pages-node-externals.js";
89
93
  import { validateMiddlewareModuleExports } from "./plugins/middleware-export-validation.js";
90
94
  import { createOptimizeImportsPlugin } from "./plugins/optimize-imports.js";
@@ -94,31 +98,35 @@ import { createTransformCache } from "./plugins/transform-cache.js";
94
98
  import { createOgHarfbuzzPlugin } from "./plugins/og-harfbuzz.js";
95
99
  import { createOgAssetsPlugin, createOgInlineFetchAssetsPlugin } from "./plugins/og-assets.js";
96
100
  import { createUseCacheCallablePlugin } from "./plugins/use-cache-callable.js";
101
+ import { cacheFlightCodecPlugin } from "./plugins/cache-flight-codec.js";
97
102
  import { SSR_EXTERNAL_REACT_ENTRIES, VINEXT_OPTIMIZE_DEPS_EXCLUDE, mergeOptimizeDepsExclude } from "./plugins/rsc-client-shim-excludes.js";
98
103
  import { createServerExternalsManifestPlugin } from "./plugins/server-externals-manifest.js";
99
104
  import { createTransitiveExternalsPlugin } from "./plugins/transitive-externals.js";
100
105
  import public_shim_map_default from "./shims/public-shim-map.json.js";
101
- import { VINEXT_CLIENT_ENTRY_MANIFEST } from "./utils/client-entry-manifest.js";
102
106
  import { computeClientRuntimeMetadata } from "./utils/client-runtime-metadata.js";
103
107
  import { readPrerenderSecret, readServerRuntimeOutputDirs } from "./build/server-manifest.js";
104
108
  import { createModuleDependencyCache } from "./build/module-dependency-cache.js";
105
109
  import { markCssUrlAssetReferences, restoreDedupedCssAssetReferences } from "./build/css-url-assets.js";
106
110
  import { buildSassPreprocessorOptions, createSassAwareFileSystemLoader, createSassCssUrlAssetImporter, createSassTildeImporter, createSassTsconfigPathImporters } from "./plugins/sass.js";
107
- import { createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createMultiStageChunkFileNames, createMultiStageCodeSplittingConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfig, withBuildBundlerOptions } from "./build/client-build-config.js";
111
+ import { assertClientOutDirIsSeparate, createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createMultiStageChunkFileNames, createMultiStageCodeSplittingConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfig, withBuildBundlerOptions } from "./build/client-build-config.js";
108
112
  import { EXPORT_ALL_CANDIDATE_FILTER, hasExportAllCandidate, stripServerExports, validatePageExports } from "./plugins/strip-server-exports.js";
109
113
  import { removeConsoleCalls } from "./plugins/remove-console.js";
110
114
  import { createImportMetaUrlPlugin } from "./plugins/import-meta-url.js";
111
115
  import { createWorkerImageImportsPlugin } from "./plugins/worker-image-imports.js";
116
+ import { SERVER_ONLY_SPECIFIER_RE, createWorkerServerOnlyImportsPlugin } from "./plugins/worker-server-only-imports.js";
117
+ import { createWorkerUseServerPlugins } from "./plugins/worker-use-server.js";
112
118
  import { createRequireContextPlugin } from "./plugins/require-context.js";
119
+ import { commonJsEsmFacadeOptimizeDepsPlugin, stripEsmCommonJsExportFacade } from "./plugins/commonjs-esm-facade.js";
113
120
  import { COMMONJS_SYNTAX_CODE_FILTER } from "./plugins/commonjs-syntax.js";
114
121
  import { createRequireConditionResolutionPlugin, isConditionalRequireScriptModuleId } from "./plugins/require-condition-resolution.js";
115
122
  import { createExtensionlessDynamicImportPlugin } from "./plugins/extensionless-dynamic-import.js";
116
123
  import { createWasmModuleImportPlugin } from "./plugins/wasm-module-import.js";
117
124
  import { consumerEnvironmentConditionFilter, getTypeofWindowReplacement, mayFoldChangeScannedImports, replaceConsumerEnvironmentConditions } from "./plugins/typeof-window.js";
118
- import { hasMdxFiles } from "./utils/mdx-scan.js";
119
- import { publicFilePathVariants } from "./utils/public-file-path.js";
125
+ import { hasMdxFiles, loadMdxEsmReader, pageExtensionsIncludeMdx } from "./utils/mdx-scan.js";
126
+ import { publicFileRouteKey } from "./utils/public-file-path.js";
120
127
  import { scanPublicFileRoutes } from "./utils/public-routes.js";
121
128
  import { createIgnoreDynamicRequestsPlugin } from "./plugins/ignore-dynamic-requests.js";
129
+ import { assertPluginRscVersion } from "./utils/plugin-rsc-version.js";
122
130
  import { assertSupportedViteVersion, getDepOptimizeNodeEnvOptions, serializeViteDefine } from "./utils/vite-version.js";
123
131
  import { staticExportApp, staticExportPages } from "./build/static-export.js";
124
132
  import { createRequire } from "node:module";
@@ -153,6 +161,17 @@ const RSC_ENVIRONMENTS = /* @__PURE__ */ new Set([
153
161
  "client"
154
162
  ]);
155
163
  const VINEXT_GENERATED_DIR_RE = /(?:^|[/\\])\.vinext(?:[/\\]|$)/;
164
+ function removeForwardedMiddlewareContext(req) {
165
+ delete req.headers[VINEXT_MW_CTX_HEADER];
166
+ const rawHeaders = req.rawHeaders;
167
+ for (let i = rawHeaders.length - 2; i >= 0; i -= 2) if (rawHeaders[i].toLowerCase() === "x-vinext-mw-ctx") rawHeaders.splice(i, 2);
168
+ }
169
+ function setForwardedMiddlewareContext(req, key, context) {
170
+ removeForwardedMiddlewareContext(req);
171
+ const value = sealForwardedMiddlewareContext(key, context);
172
+ req.headers[VINEXT_MW_CTX_HEADER] = value;
173
+ req.rawHeaders.push(VINEXT_MW_CTX_HEADER, value);
174
+ }
156
175
  function scopeRscPlugin(plugin) {
157
176
  const applyToEnvironment = plugin.applyToEnvironment;
158
177
  return {
@@ -173,6 +192,11 @@ if (earlyViteCliInvocation) {
173
192
  });
174
193
  }
175
194
  installSocketErrorBackstop();
195
+ const INVALID_SERVER_ONLY_ID_PREFIX = "\0vinext:invalid-server-only:";
196
+ const INVALID_SERVER_ONLY_ID_RE = /^\0vinext:invalid-server-only:/;
197
+ function createServerOnlyClientImportError(importer) {
198
+ return /* @__PURE__ */ new Error(`You're importing a module that depends on "server-only". This API is only available in Server Components in the App Router, but ${importer || "this module"} is reachable from a client bundle.`);
199
+ }
176
200
  function hasServerOnlyMarkerImport(code) {
177
201
  if (!code.includes("server-only")) return false;
178
202
  let ast;
@@ -900,6 +924,7 @@ function vinext(options = {}) {
900
924
  const pagesClientAssetsOutputDirs = /* @__PURE__ */ new Set();
901
925
  const resolvePagesClientAssetsOutputDir = (environmentName, outputDir) => !selectedMultiStageOutput && !hasAppDir && !hasCloudflarePlugin && environmentName === "ssr" ? path.dirname(outputDir) : outputDir;
902
926
  let pagesClientAssetsModule = internalOptions.__pagesClientAssetsModule ?? null;
927
+ let clientBuildFiles = [];
903
928
  let devPublicFileRoutes = null;
904
929
  let publicDirConflictOptions = null;
905
930
  let copyPublicDirIntoStaticExportBasePath = false;
@@ -908,6 +933,7 @@ function vinext(options = {}) {
908
933
  let draftModeSecret = getPagesPreviewModeId();
909
934
  const prerenderSecret = process.env.__VINEXT_SHARED_PRERENDER_SECRET ?? randomBytes(32).toString("hex");
910
935
  let revalidateSecret = process.env.__VINEXT_SHARED_REVALIDATE_SECRET;
936
+ const devForwardedMiddlewareContextKey = randomBytes(32).toString("hex");
911
937
  let previewBuildCredentials;
912
938
  const sassComposesLoader = createSassAwareFileSystemLoader();
913
939
  const rscClassificationManifests = /* @__PURE__ */ new Map();
@@ -996,6 +1022,7 @@ function vinext(options = {}) {
996
1022
  let rscPluginModulePromise = null;
997
1023
  resolvedReactPath = resolveOptionalDependency(earlyBaseDir, "@vitejs/plugin-react");
998
1024
  resolvedRscPath = resolveOptionalDependency(earlyBaseDir, "@vitejs/plugin-rsc");
1025
+ const rscVersion = earlyAppDirExists && resolvedRscPath ? assertPluginRscVersion(resolvedRscPath) : null;
999
1026
  let rscPluginPromise = null;
1000
1027
  let manualUseCachePluginPromise = null;
1001
1028
  if (earlyAppDirExists && autoRsc) {
@@ -1015,7 +1042,7 @@ function vinext(options = {}) {
1015
1042
  });
1016
1043
  const useServerIndex = plugins.findIndex((plugin) => plugin.name === "rsc:use-server");
1017
1044
  if (useServerIndex === -1) throw new Error("vinext: Failed to locate @vitejs/plugin-rsc use-server plugin.");
1018
- plugins.splice(useServerIndex, 0, useCachePlugin);
1045
+ plugins.splice(useServerIndex, 0, cacheFlightCodecPlugin(), useCachePlugin);
1019
1046
  return plugins.map(scopeRscPlugin);
1020
1047
  }).catch((cause) => {
1021
1048
  throw new Error("vinext: Failed to load @vitejs/plugin-rsc.", { cause });
@@ -1160,12 +1187,21 @@ function vinext(options = {}) {
1160
1187
  const previous = transformBundledCommonJsDependencies;
1161
1188
  transformProjectLocalCommonJs = projectLocal && isDev;
1162
1189
  transformBundledCommonJsDependencies = bundledDependency;
1190
+ let result;
1163
1191
  try {
1164
- return commonJsTransform.call(this, code, id, ...args);
1192
+ result = commonJsTransform.call(this, code, id, ...args);
1165
1193
  } finally {
1166
1194
  transformProjectLocalCommonJs = previousProjectLocal;
1167
1195
  transformBundledCommonJsDependencies = previous;
1168
1196
  }
1197
+ return Promise.resolve(result).then((transformed) => {
1198
+ if (typeof transformed !== "object" || typeof transformed?.code !== "string") return transformed;
1199
+ const stripped = stripEsmCommonJsExportFacade(transformed.code);
1200
+ return stripped === void 0 ? transformed : {
1201
+ ...transformed,
1202
+ code: stripped
1203
+ };
1204
+ });
1169
1205
  };
1170
1206
  commonJsPlugin.transform = {
1171
1207
  filter: { code: { include: COMMONJS_SYNTAX_CODE_FILTER } },
@@ -1313,6 +1349,7 @@ function vinext(options = {}) {
1313
1349
  buildEmptyOutDir = typeof config.build?.emptyOutDir === "boolean" ? config.build.emptyOutDir : void 0;
1314
1350
  isServeCommand = env.command === "serve";
1315
1351
  root = path.resolve(toSlash(process.cwd()), config.root ?? ".");
1352
+ if (env.command === "build") assertClientOutDirIsSeparate(root, options);
1316
1353
  const devCliLifecycleEnabled = env.command === "serve" && env.isPreview !== true && claimViteCliDevInvocation(root, config["__vinextDevRestart"] === true, reservedDevCliInvocation && config.configFile === false);
1317
1354
  buildLifecycleInvocation = config[VINEXT_BUILD_LIFECYCLE_CONFIG];
1318
1355
  buildLifecycleEnabled = env.command === "build" && !internalOptions.__skipBuildLifecycle && (buildLifecycleInvocation !== void 0 || claimViteCliBuildInvocation());
@@ -1430,6 +1467,7 @@ function vinext(options = {}) {
1430
1467
  defines["process.env.__NEXT_TEST_MODE"] = JSON.stringify(process.env.__NEXT_TEST_MODE ?? false);
1431
1468
  defines["process.env.__NEXT_SCROLL_RESTORATION"] = JSON.stringify(nextConfig.scrollRestoration ? "true" : "false");
1432
1469
  defines["process.env.__VINEXT_TRAILING_SLASH"] = JSON.stringify(nextConfig.trailingSlash ? "true" : "false");
1470
+ defines["process.env.__VINEXT_MANUAL_TRAILING_SLASH"] = JSON.stringify(nextConfig.skipTrailingSlashRedirect ? "true" : "false");
1433
1471
  defines["process.env.__NEXT_CONFIG_OUTPUT"] = JSON.stringify(nextConfig.output ?? "");
1434
1472
  defines["process.env.__VINEXT_IMAGE_REMOTE_PATTERNS"] = JSON.stringify(JSON.stringify(nextConfig.images?.remotePatterns ?? []));
1435
1473
  defines["process.env.__VINEXT_IMAGE_DOMAINS"] = JSON.stringify(JSON.stringify(nextConfig.images?.domains ?? []));
@@ -1495,6 +1533,7 @@ function vinext(options = {}) {
1495
1533
  "vinext/head-state": path.join(shimsDir, "head-state"),
1496
1534
  "vinext/i18n-state": path.join(shimsDir, "i18n-state"),
1497
1535
  "vinext/i18n-context": path.join(shimsDir, "i18n-context"),
1536
+ "vinext/document-placeholders": path.join(shimsDir, "document-placeholders"),
1498
1537
  "vinext/client": path.resolve(__dirname, "client", "index"),
1499
1538
  "vinext/cache": path.resolve(__dirname, "cache"),
1500
1539
  "vinext/instrumentation": path.resolve(__dirname, "server", "instrumentation"),
@@ -1586,7 +1625,14 @@ function vinext(options = {}) {
1586
1625
  ...!isSSR && !isMultiEnv ? { output: getClientOutputConfig(clientAssetsDir) } : {}
1587
1626
  })
1588
1627
  },
1589
- worker: { plugins: () => [createWorkerImageImportsPlugin({ deploymentId: nextConfig.deploymentId })] },
1628
+ worker: { plugins: () => [
1629
+ createWorkerImageImportsPlugin({ deploymentId: nextConfig.deploymentId }),
1630
+ createWorkerServerOnlyImportsPlugin(),
1631
+ ...rscPluginModulePromise && resolvedRscPath ? [createWorkerUseServerPlugins({
1632
+ rscPluginModule: rscPluginModulePromise,
1633
+ rscPluginPath: resolvedRscPath
1634
+ })] : []
1635
+ ] },
1590
1636
  server: {
1591
1637
  watch: config.server?.watch === null ? null : {
1592
1638
  ignored: [VINEXT_GENERATED_DIR_RE],
@@ -1643,7 +1689,8 @@ function vinext(options = {}) {
1643
1689
  transformer: "lightningcss",
1644
1690
  lightningcss: {
1645
1691
  ...nextConfig.lightningCssFeatures.include ? { include: nextConfig.lightningCssFeatures.include } : {},
1646
- ...nextConfig.lightningCssFeatures.exclude ? { exclude: nextConfig.lightningCssFeatures.exclude } : {}
1692
+ ...nextConfig.lightningCssFeatures.exclude ? { exclude: nextConfig.lightningCssFeatures.exclude } : {},
1693
+ ...(nextConfig.lightningCssFeatures.include & ~nextConfig.lightningCssFeatures.exclude & lightningCssFeatureNamesToMask(["custom-media-queries"])) !== 0 ? { drafts: { customMedia: true } } : {}
1647
1694
  }
1648
1695
  } : {},
1649
1696
  ...postcssOverride ? { postcss: postcssOverride } : {},
@@ -1693,7 +1740,7 @@ function vinext(options = {}) {
1693
1740
  ...depOptimizeNodeEnvOptions,
1694
1741
  rolldownOptions: {
1695
1742
  ...depOptimizeNodeEnvOptions.rolldownOptions,
1696
- plugins: [depOptimizeAliasPlugin]
1743
+ plugins: [depOptimizeAliasPlugin, commonJsEsmFacadeOptimizeDepsPlugin]
1697
1744
  }
1698
1745
  };
1699
1746
  pagesOptimizeEntries = !hasAppDir ? [...hasPagesDir ? [toRelativeFileEntry(root, pagesDir) + "/**/*.{tsx,ts,jsx,js}"] : [], ...[instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : [])] : [];
@@ -1822,6 +1869,7 @@ function vinext(options = {}) {
1822
1869
  ...depOptimizeNodeEnvOptions
1823
1870
  },
1824
1871
  build: {
1872
+ ...options.clientOutDir ? { outDir: options.clientOutDir } : {},
1825
1873
  manifest: true,
1826
1874
  ...hasPagesDir ? { ssrManifest: true } : {},
1827
1875
  assetsInlineLimit: clientAssetsInlineLimit,
@@ -1841,6 +1889,7 @@ function vinext(options = {}) {
1841
1889
  ...depOptimizeNodeEnvOptions
1842
1890
  },
1843
1891
  build: {
1892
+ ...options.clientOutDir ? { outDir: options.clientOutDir } : {},
1844
1893
  manifest: true,
1845
1894
  ssrManifest: true,
1846
1895
  assetsInlineLimit: clientAssetsInlineLimit,
@@ -1861,7 +1910,7 @@ function vinext(options = {}) {
1861
1910
  ...depOptimizeNodeEnvOptions
1862
1911
  },
1863
1912
  build: {
1864
- outDir: "dist/client",
1913
+ outDir: options.clientOutDir ?? "dist/client",
1865
1914
  manifest: true,
1866
1915
  ssrManifest: true,
1867
1916
  assetsInlineLimit: clientAssetsInlineLimit,
@@ -2193,12 +2242,14 @@ function vinext(options = {}) {
2193
2242
  nodeOpenTelemetryLoader: registerNodeOpenTelemetryLoader,
2194
2243
  assetPrefix: nextConfig?.assetPrefix,
2195
2244
  crossOrigin: nextConfig?.crossOrigin,
2245
+ skipTrailingSlashRedirect: nextConfig?.skipTrailingSlashRedirect,
2196
2246
  expireTime: nextConfig?.expireTime,
2197
2247
  reactMaxHeadersLength: nextConfig?.reactMaxHeadersLength,
2198
2248
  cacheMaxMemorySize: nextConfig?.cacheMaxMemorySize,
2199
2249
  inlineCss: nextConfig?.inlineCss,
2200
2250
  globalNotFound: nextConfig?.globalNotFound,
2201
2251
  cacheComponents: nextConfig?.cacheComponents,
2252
+ readMdxEsm: !nextConfig?.cacheComponents && pageExtensionsIncludeMdx(nextConfig?.pageExtensions ?? []) ? await loadMdxEsmReader(root) : null,
2202
2253
  prefetchInlining: nextConfig?.prefetchInlining,
2203
2254
  hasServerActions,
2204
2255
  actionOwners: this.environment.config.command === "build" ? void 0 : null,
@@ -2216,7 +2267,8 @@ function vinext(options = {}) {
2216
2267
  publicFiles: isServeCommand && devPublicFileRoutes ? [...devPublicFileRoutes].sort() : scanPublicFileRoutes(root, this.environment.config.publicDir === "" ? false : this.environment.config.publicDir),
2217
2268
  globalNotFoundPath,
2218
2269
  draftModeSecret,
2219
- prerenderSecret
2270
+ prerenderSecret,
2271
+ devForwardedMiddlewareContextKey: isServeCommand && this.environment.config.consumer === "server" ? devForwardedMiddlewareContextKey : void 0
2220
2272
  }, instrumentationPath);
2221
2273
  }
2222
2274
  if (id === RESOLVED_ROOT_PARAMS) return generateRootParamsModule((hasAppDir ? await appRouter(appDir, nextConfig?.pageExtensions, fileMatcher) : []).flatMap((route) => route.rootParamNames ?? []));
@@ -2581,25 +2633,13 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2581
2633
  }
2582
2634
  },
2583
2635
  configureServer(server) {
2636
+ installSocketErrorBackstop({ runningServer: true });
2584
2637
  const devBuildId = nextConfig?.buildId ?? process.env.__VINEXT_BUILD_ID ?? "development";
2585
2638
  server.middlewares.use((req, _res, next) => {
2586
2639
  req.__vinextOriginalEncodedUrl ??= req.url;
2587
- delete req.headers[VINEXT_MW_CTX_HEADER];
2640
+ removeForwardedMiddlewareContext(req);
2588
2641
  next();
2589
2642
  });
2590
- server.middlewares.use((req, _res, next) => {
2591
- try {
2592
- assertNoPublicNextRequestConflict({
2593
- root: server.config.root,
2594
- publicDir: server.config.publicDir === "" ? null : server.config.publicDir,
2595
- basePath: nextConfig.basePath ?? "",
2596
- requestUrl: req.url ?? "/"
2597
- });
2598
- next();
2599
- } catch (error) {
2600
- next(error);
2601
- }
2602
- });
2603
2643
  const pageExtensions = fileMatcher.extensionRegex;
2604
2644
  let pagesRunner = null;
2605
2645
  const getTrustedDevRevalidateOrigin = () => {
@@ -2776,7 +2816,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2776
2816
  const cleanPath = toSlash(stripViteModuleQuery(filePath));
2777
2817
  const relativePath = path.relative(devPublicDir, cleanPath);
2778
2818
  if (relativePath === "" || relativePath.startsWith("../") || path.isAbsolute(relativePath)) return null;
2779
- return publicFilePathVariants(`/${relativePath}`);
2819
+ return [publicFileRouteKey(`/${relativePath}`)];
2780
2820
  };
2781
2821
  const updatePublicFileRoute = (filePath, present) => {
2782
2822
  const routes = publicRoutesForFile(filePath);
@@ -2896,6 +2936,22 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2896
2936
  }
2897
2937
  next();
2898
2938
  });
2939
+ server.middlewares.use((req, res, next) => {
2940
+ if (!sendRepeatedSlashRedirect(req.url ?? "/", res)) next();
2941
+ });
2942
+ server.middlewares.use((req, _res, next) => {
2943
+ try {
2944
+ assertNoPublicNextRequestConflict({
2945
+ root: server.config.root,
2946
+ publicDir: server.config.publicDir === "" ? null : server.config.publicDir,
2947
+ basePath: nextConfig.basePath ?? "",
2948
+ requestUrl: req.url ?? "/"
2949
+ });
2950
+ next();
2951
+ } catch (error) {
2952
+ next(error);
2953
+ }
2954
+ });
2899
2955
  server.middlewares.use((req, res, next) => {
2900
2956
  if (!hasPagesDir || !handlePagesMiddleware || !isUnsupportedDevPublicRequest(req)) return next();
2901
2957
  handlePagesMiddleware(req, res, next).catch(next);
@@ -3055,16 +3111,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3055
3111
  }
3056
3112
  const canonicalOriginalUrl = canonicalizeRequestUrlPathname(originalEncodedUrl);
3057
3113
  url = canonicalizeRequestUrlPathname(url);
3058
- const rawPathname = url.split("?")[0];
3059
- if (rawPathname.endsWith("/index.html")) url = url.replace("/index.html", "/");
3060
- else if (rawPathname.endsWith(".html")) url = url.replace(/\.html(?=\?|$)/, "");
3061
3114
  let middlewareUrl = canonicalOriginalUrl;
3062
3115
  let routeUrl = middlewareUrl;
3063
- {
3064
- const routePathname = routeUrl.split("?")[0];
3065
- if (routePathname.endsWith("/index.html")) routeUrl = routeUrl.replace("/index.html", "/");
3066
- else if (routePathname.endsWith(".html")) routeUrl = routeUrl.replace(/\.html(?=\?|$)/, "");
3067
- }
3068
3116
  let pathname = url.split("?")[0];
3069
3117
  if (isOpenRedirectShaped(pathname)) {
3070
3118
  res.writeHead(404);
@@ -3112,7 +3160,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3112
3160
  }
3113
3161
  }
3114
3162
  let configMatchPathname = stripBasePath(middlewareUrl.split("?")[0], routingBasePath);
3115
- if (nextConfig) {
3163
+ if (nextConfig && !nextConfig.skipTrailingSlashRedirect) {
3116
3164
  const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
3117
3165
  const trailingSlashRedirect = normalizeTrailingSlash(routeUrl.split("?")[0], bp, nextConfig.trailingSlash, qs);
3118
3166
  if (trailingSlashRedirect) {
@@ -3125,18 +3173,22 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3125
3173
  if (hasCloudflarePlugin) return next();
3126
3174
  let isDataReq = false;
3127
3175
  let dataNotFoundResponse = null;
3128
- if (isNextDataPathname(pathname)) {
3129
- const dataMatch = parseNextDataPathname(pathname, devBuildId);
3130
- if (dataMatch) {
3176
+ const rawRoutePathname = routeUrl.split("?")[0];
3177
+ if (isNextDataPathname(rawRoutePathname)) {
3178
+ const rawDataMatch = parseNextDataPathname(rawRoutePathname, devBuildId);
3179
+ const dataMatch = rawDataMatch ? parseNextDataPathname(pathname, devBuildId) : null;
3180
+ if (dataMatch && rawDataMatch) {
3131
3181
  isDataReq = true;
3132
3182
  const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
3133
- const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, shouldAddTrailingSlashToPagesDataPath(capturedMiddlewarePath !== null, nextConfig?.trailingSlash === true, nextConfig?.skipProxyUrlNormalize === true));
3183
+ const addTrailingSlash = shouldAddTrailingSlashToPagesDataPath(capturedMiddlewarePath !== null, nextConfig?.trailingSlash === true, nextConfig?.skipProxyUrlNormalize === true);
3184
+ const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, addTrailingSlash);
3185
+ const rawPagePathname = normalizeNextDataPagePathname(rawDataMatch.pagePathname, addTrailingSlash);
3134
3186
  url = pagePathname + qs;
3135
- if (!nextConfig?.skipProxyUrlNormalize) middlewareUrl = url;
3136
- routeUrl = url;
3187
+ routeUrl = rawPagePathname + qs;
3188
+ if (!nextConfig?.skipProxyUrlNormalize) middlewareUrl = routeUrl;
3137
3189
  pathname = pagePathname;
3138
- configMatchPathname = pagePathname;
3139
- req.url = url;
3190
+ configMatchPathname = rawPagePathname;
3191
+ req.url = routeUrl;
3140
3192
  } else {
3141
3193
  const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
3142
3194
  const notFoundHeaders = { "Content-Type": "application/json" };
@@ -3181,9 +3233,11 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3181
3233
  const method = req.method ?? "GET";
3182
3234
  const webRequest = new Request(new URL(routeUrl, requestOrigin), {
3183
3235
  method,
3184
- headers: nodeRequestHeaders
3236
+ headers: nodeRequestHeaders,
3237
+ signal: signalFromNodeResponse(res)
3185
3238
  });
3186
3239
  const applyRequestHeadersToNodeRequest = (nextRequestHeaders) => {
3240
+ removeForwardedMiddlewareContext(req);
3187
3241
  for (const key of Object.keys(req.headers)) delete req.headers[key];
3188
3242
  for (const [key, value] of nextRequestHeaders) req.headers[key] = value;
3189
3243
  };
@@ -3192,20 +3246,22 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3192
3246
  const mwOrigin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${requestHost}`;
3193
3247
  const middlewareRequest = new Request(new URL(middlewareUrl, mwOrigin), {
3194
3248
  method: req.method,
3195
- headers: nodeRequestHeaders
3249
+ headers: nodeRequestHeaders,
3250
+ signal: webRequest.signal
3196
3251
  });
3197
- const result = await runMiddleware(getPagesRunner(), capturedMiddlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, opts.isDataRequest, pathname);
3252
+ const result = await runMiddleware(getPagesRunner(), capturedMiddlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, opts.isDataRequest, pathname, opts.isStaleDataRequest, nextConfig?.skipTrailingSlashRedirect);
3198
3253
  if (hasAppDir && result.continue) {
3199
3254
  const mwCtxEntries = [];
3200
3255
  if (result.responseHeaders) {
3201
3256
  for (const [key, value] of result.responseHeaders) if (key !== "x-middleware-next" && key !== "x-middleware-rewrite") mwCtxEntries.push([key, value]);
3202
3257
  }
3203
3258
  const mwStatus = result.status ?? result.rewriteStatus;
3204
- req.headers[VINEXT_MW_CTX_HEADER] = JSON.stringify({
3259
+ setForwardedMiddlewareContext(req, devForwardedMiddlewareContextKey, JSON.stringify({
3205
3260
  h: mwCtxEntries,
3206
3261
  s: mwStatus ?? null,
3207
- r: result.rewriteUrl ?? null
3208
- });
3262
+ r: result.rewriteUrl ?? null,
3263
+ b: result.rewriteHadBasePath ?? null
3264
+ }));
3209
3265
  }
3210
3266
  return result;
3211
3267
  } : null;
@@ -3219,6 +3275,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3219
3275
  assetPrefix: nextConfig?.assetPrefix,
3220
3276
  basePath: bp,
3221
3277
  trailingSlash: nextConfig?.trailingSlash ?? false,
3278
+ skipTrailingSlashRedirect: nextConfig?.skipTrailingSlashRedirect ?? false,
3222
3279
  i18nConfig: nextConfig?.i18n ?? null,
3223
3280
  configRedirects: nextConfig?.redirects ?? [],
3224
3281
  configRewrites: nextConfig?.rewrites ?? {
@@ -3256,7 +3313,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3256
3313
  const hasBody = externalMethod !== "GET" && externalMethod !== "HEAD";
3257
3314
  const externalInit = {
3258
3315
  method: externalMethod,
3259
- headers: currentRequest.headers
3316
+ headers: currentRequest.headers,
3317
+ signal: currentRequest.signal
3260
3318
  };
3261
3319
  if (hasBody) {
3262
3320
  const { Readable } = await import("node:stream");
@@ -3266,8 +3324,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3266
3324
  const reqWithBody = new Request(new URL(url, requestOrigin), externalInit);
3267
3325
  return proxyExternalRequest(reqWithBody, externalUrl);
3268
3326
  },
3269
- serveFilesystemRoute: async (requestPathname, stagedHeaders, phase, resolvedUrl) => {
3270
- if (isImageOptimizationPath(requestPathname)) {
3327
+ serveFilesystemRoute: async (requestPathname, stagedHeaders, phase, resolvedUrl, _request, resolvedPathnameHasBasePath) => {
3328
+ if (resolvedPathnameHasBasePath && isImageOptimizationPath(requestPathname)) {
3271
3329
  const imageRequestUrl = new URL(resolvedUrl, requestOrigin);
3272
3330
  const allowedWidths = [...nextConfig.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...nextConfig.images?.imageSizes ?? DEFAULT_IMAGE_SIZES];
3273
3331
  const encodedLocation = resolveDevImageRedirect(imageRequestUrl, allowedWidths, nextConfig.images?.qualities);
@@ -3278,7 +3336,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3278
3336
  }
3279
3337
  const isRetrievalMethod = req.method === "GET" || req.method === "HEAD";
3280
3338
  if (phase === "direct" && isRetrievalMethod || requestPathname === "/" || requestPathname === "/api" || requestPathname.startsWith("/api/")) return false;
3281
- if (!isRetrievalMethod) return isExistingDevPublicFile(requestPathname) ? methodNotAllowedResponse("GET, HEAD") : false;
3339
+ if (!isRetrievalMethod) return isExistingDevPublicFile(normalizePathnameForRouteMatch(requestPathname)) ? methodNotAllowedResponse("GET, HEAD") : false;
3282
3340
  return serveRewrittenViteFilesystemRoute(req, res, requestPathname, stagedHeaders);
3283
3341
  }
3284
3342
  };
@@ -3305,12 +3363,12 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3305
3363
  const requestHeaders = new Headers();
3306
3364
  encodeMiddlewareRequestHeaders(requestHeaders, pipelineResult.requestHeaders);
3307
3365
  flushRequestHeaders();
3308
- req.headers[VINEXT_MW_CTX_HEADER] = JSON.stringify({
3366
+ setForwardedMiddlewareContext(req, devForwardedMiddlewareContextKey, JSON.stringify({
3309
3367
  h: responseHeaders,
3310
3368
  q: [...requestHeaders],
3311
3369
  s: pipelineResult.middlewareStatus ?? null,
3312
3370
  r: apiUrl
3313
- });
3371
+ }));
3314
3372
  };
3315
3373
  if (pipelineResult.type === "api") {
3316
3374
  const devApiRoutes = await getDevApiRoutes();
@@ -3330,7 +3388,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3330
3388
  i18n: nextConfig?.i18n,
3331
3389
  trustedRevalidateOrigin: getTrustedDevRevalidateOrigin(),
3332
3390
  allowedRevalidateHeaderKeys: nextConfig?.allowedRevalidateHeaderKeys,
3333
- trailingSlash: nextConfig?.trailingSlash
3391
+ trailingSlash: nextConfig?.trailingSlash,
3392
+ skipTrailingSlashRedirect: nextConfig?.skipTrailingSlashRedirect
3334
3393
  })) return;
3335
3394
  if (hasAppDir) {
3336
3395
  if (pipelineResult.configRewriteFired) forwardInternalApiRewriteToApp(pipelineResult.apiUrl);
@@ -3478,6 +3537,25 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3478
3537
  },
3479
3538
  {
3480
3539
  name: "vinext:validate-server-only-client-imports",
3540
+ resolveId: {
3541
+ order: "pre",
3542
+ filter: { id: SERVER_ONLY_SPECIFIER_RE },
3543
+ handler(_source, importer) {
3544
+ const environment = this.environment;
3545
+ if (environment?.name !== "client" || hasAppDir) return null;
3546
+ if (environment.mode === "dev" && !(importer && environment.moduleGraph.getModuleById(importer))) return {
3547
+ id: INVALID_SERVER_ONLY_ID_PREFIX + (importer ?? ""),
3548
+ moduleSideEffects: true
3549
+ };
3550
+ throw createServerOnlyClientImportError(importer);
3551
+ }
3552
+ },
3553
+ load: {
3554
+ filter: { id: INVALID_SERVER_ONLY_ID_RE },
3555
+ handler(id) {
3556
+ throw createServerOnlyClientImportError(id.slice(28));
3557
+ }
3558
+ },
3481
3559
  transform: {
3482
3560
  filter: {
3483
3561
  id: {
@@ -3487,7 +3565,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3487
3565
  code: "server-only"
3488
3566
  },
3489
3567
  handler(code) {
3490
- if (this.environment?.name !== "client") return null;
3568
+ if (this.environment?.name !== "client" || !hasAppDir) return null;
3569
+ // @vitejs/plugin-rsc replaces a "use server" module in the client
3491
3570
  if (getLeadingReactDirective(code) === "use server") return null;
3492
3571
  if (!hasServerOnlyMarkerImport(code)) return null;
3493
3572
  throw new Error(`You're importing a module that depends on "server-only". This API is only available in Server Components in the App Router, but this module is reachable from a client bundle.`);
@@ -3715,7 +3794,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3715
3794
  createGoogleFontsPlugin(_fontGoogleShimPath, _shimsDir),
3716
3795
  createLocalFontsPlugin(_shimsDir),
3717
3796
  createOptimizeImportsPlugin(() => nextConfig, () => root),
3718
- createDynamicPreloadMetadataPlugin(),
3797
+ createDynamicPreloadMetadataPlugin(() => nextConfig?.turbopackTranspilePackages ?? []),
3719
3798
  importMetaUrlCapability.vitePlugin,
3720
3799
  createExtensionlessDynamicImportPlugin(),
3721
3800
  createRequireContextPlugin(),
@@ -3774,6 +3853,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3774
3853
  }
3775
3854
  const manifest = {
3776
3855
  prerenderSecret,
3856
+ compress: nextConfig?.compress !== false,
3777
3857
  ...serverRuntimeOutputDirs.size === 0 ? {} : { runtimeOutputDirs: [...serverRuntimeOutputDirs].map((runtimeOutputDir) => path.relative(root, runtimeOutputDir) || ".").sort() }
3778
3858
  };
3779
3859
  const source = JSON.stringify(manifest);
@@ -3920,6 +4000,10 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3920
4000
  apply: "build",
3921
4001
  enforce: "post",
3922
4002
  sharedDuringBuild: true,
4003
+ writeBundle(_options, bundle) {
4004
+ if (this.environment.name !== "client") return;
4005
+ clientBuildFiles = collectClientBuildFiles(Object.keys(bundle));
4006
+ },
3923
4007
  closeBundle: {
3924
4008
  sequential: true,
3925
4009
  order: "post",
@@ -3946,7 +4030,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3946
4030
  cssGraph: runtimeMetadata.cssGraph,
3947
4031
  lazyChunks: runtimeMetadata.lazyChunks ?? void 0,
3948
4032
  dynamicPreloads: runtimeMetadata.dynamicPreloads ?? void 0,
3949
- crossOrigin: nextConfig.crossOrigin ?? ""
4033
+ crossOrigin: nextConfig.crossOrigin ?? "",
4034
+ clientBuildFiles: clientBuildFiles.length > 0 ? clientBuildFiles : void 0
3950
4035
  });
3951
4036
  }
3952
4037
  if (pagesClientAssetsModule === null && pagesClientAssetsOutputDirs.size === 0) return;
@@ -3983,13 +4068,37 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
3983
4068
  const envConfig = this.environment?.config;
3984
4069
  if (!envConfig) return;
3985
4070
  const buildRoot = envConfig.root ?? process.cwd();
3986
- const clientDir = path.resolve(buildRoot, "dist", "client");
4071
+ const clientDir = path.resolve(buildRoot, envConfig.build.outDir);
3987
4072
  const manifest = collectInlineCssManifest(clientDir, nextConfig.assetPrefix);
3988
4073
  const rscOutDir = path.resolve(buildRoot, options.rscOutDir ?? path.join("dist", "server"));
3989
4074
  for (const entryFile of ["index.js", "index.mjs"]) if (injectInlineCssManifestGlobal(path.join(rscOutDir, entryFile), manifest)) break;
3990
4075
  }
3991
4076
  }
3992
4077
  },
4078
+ (
4079
+ // @vitejs/plugin-rsc's preview handler, and Cloudflare and Nitro builds
4080
+ {
4081
+ name: "vinext:preview-server",
4082
+ async configurePreviewServer(server) {
4083
+ if (hasAppDir || hasCloudflarePlugin || hasNitroPlugin) return;
4084
+ if (nextConfig?.output === "export") return;
4085
+ const { createPagesPreviewHandler } = await import("./server/prod-server.js");
4086
+ const { environments, preview, root } = server.config;
4087
+ const handler = await createPagesPreviewHandler({
4088
+ clientDir: path.resolve(root, environments.client?.build.outDir ?? "dist/client"),
4089
+ serverDir: path.resolve(root, environments.ssr?.build.outDir ?? "dist/server"),
4090
+ host: typeof preview.host === "string" ? preview.host : "localhost",
4091
+ port: preview.port ?? 4173
4092
+ });
4093
+ if (!handler) return;
4094
+ return () => {
4095
+ server.middlewares.use((req, res) => {
4096
+ if (nextConfig?.basePath) req.url = nextConfig.basePath + (req.url ?? "/");
4097
+ handler(req, res);
4098
+ });
4099
+ };
4100
+ }
4101
+ }),
3993
4102
  {
3994
4103
  name: "vinext:cloudflare-build",
3995
4104
  apply: "build",
@@ -4106,6 +4215,9 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
4106
4215
  }
4107
4216
  });
4108
4217
  if (rscPluginPromise) plugins.push(rscPluginPromise);
4218
+ if (rscVersion && isRscScanGlobImportsAffected(rscVersion)) plugins.push(createRscScanGlobImportsPlugin({ async getManager(config) {
4219
+ return (await rscPluginModulePromise)?.getPluginApi(config)?.manager;
4220
+ } }));
4109
4221
  if (earlyAppDirExists) {
4110
4222
  plugins.push(createActionOwnerManifestPlugin({
4111
4223
  canonicalizeModuleId: canonicalize,
@@ -4124,7 +4236,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
4124
4236
  if (rscPluginPromise) {
4125
4237
  plugins.push(createRscReferenceValidationNormalizerPlugin());
4126
4238
  plugins.push(createRscClientReferenceLoadersPlugin());
4127
- } else if (manualUseCachePluginPromise) plugins.push(manualUseCachePluginPromise);
4239
+ } else if (manualUseCachePluginPromise) plugins.push(cacheFlightCodecPlugin(), manualUseCachePluginPromise);
4128
4240
  plugins.push({
4129
4241
  name: "vinext:plain-pages-build-config",
4130
4242
  apply: "build",
@@ -4162,6 +4274,10 @@ function getNextPublicEnvDefines() {
4162
4274
  * Handles multi-value headers (Set-Cookie) correctly.
4163
4275
  */
4164
4276
  async function writeWebResponseToNodeRes(res, response) {
4277
+ if (res.destroyed) {
4278
+ response.body?.cancel().catch(() => {});
4279
+ return;
4280
+ }
4165
4281
  const nodeHeaders = {};
4166
4282
  response.headers.forEach((value, key) => {
4167
4283
  if (key === "set-cookie") return;
@@ -4174,13 +4290,17 @@ async function writeWebResponseToNodeRes(res, response) {
4174
4290
  if (response.statusText) res.writeHead(response.status, response.statusText, nodeHeaders);
4175
4291
  else res.writeHead(response.status, nodeHeaders);
4176
4292
  if (response.body) {
4177
- const { Readable } = await import("node:stream");
4293
+ const { Readable, pipeline } = await import("node:stream");
4178
4294
  const nodeStream = Readable.fromWeb(response.body);
4295
+ let clientDisconnected = false;
4296
+ res.once("close", () => {
4297
+ clientDisconnected = !res.writableFinished && !nodeStream.errored;
4298
+ });
4179
4299
  await new Promise((resolve, reject) => {
4180
- nodeStream.on("error", reject);
4181
- res.on("error", reject);
4182
- nodeStream.pipe(res);
4183
- nodeStream.on("end", resolve);
4300
+ pipeline(nodeStream, res, (error) => {
4301
+ if (error && !(clientDisconnected && error.code === "ERR_STREAM_PREMATURE_CLOSE")) reject(error);
4302
+ else resolve();
4303
+ });
4184
4304
  });
4185
4305
  } else res.end();
4186
4306
  }