@wular/pnext 0.1.6 → 0.1.8

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 (337) hide show
  1. package/bin/pnext +9 -2
  2. package/dist/server/_chunks/aliases-pycbtjt1.js +46 -0
  3. package/dist/server/_chunks/analyze-4d9e00g9.js +449 -0
  4. package/dist/server/_chunks/boot-bhemypxz.js +38 -0
  5. package/dist/server/_chunks/build-c991dv65.js +86 -0
  6. package/dist/server/_chunks/build-kh5e3x48.js +3341 -0
  7. package/dist/server/_chunks/build-tier-0a96kmx3.js +2456 -0
  8. package/dist/server/_chunks/compile-040r79gj.js +22 -0
  9. package/dist/server/_chunks/config-0tvz03a6.js +24 -0
  10. package/dist/server/_chunks/config-27rj7830.js +36 -0
  11. package/dist/server/_chunks/create-9rvwshsp.js +135 -0
  12. package/dist/server/_chunks/dev-ex9exynt.js +220 -0
  13. package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
  14. package/dist/server/_chunks/generate-myw9hef7.js +22 -0
  15. package/dist/server/_chunks/index-0r5eqfc7.js +279 -0
  16. package/dist/server/_chunks/index-0yjv5v47.js +105 -0
  17. package/dist/server/_chunks/index-11xpbfej.js +17 -0
  18. package/dist/server/_chunks/index-141vcwk6.js +109 -0
  19. package/dist/server/_chunks/index-1pzm1hdy.js +4130 -0
  20. package/dist/server/_chunks/index-29pq0kax.js +590 -0
  21. package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
  22. package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
  23. package/dist/server/_chunks/index-38xpdxwd.js +194 -0
  24. package/dist/server/_chunks/index-3e075kny.js +128 -0
  25. package/dist/server/_chunks/index-3ycf5ckv.js +472 -0
  26. package/dist/server/_chunks/index-4399bvd2.js +18 -0
  27. package/dist/server/_chunks/index-4da76t62.js +297 -0
  28. package/dist/server/_chunks/index-4t92hdxd.js +172 -0
  29. package/dist/server/_chunks/index-4zzebszd.js +10 -0
  30. package/dist/server/_chunks/index-52k54ykj.js +95 -0
  31. package/dist/server/_chunks/index-5hr4062s.js +70 -0
  32. package/dist/server/_chunks/index-68m3mwbd.js +84 -0
  33. package/dist/server/_chunks/index-6b009mt0.js +56 -0
  34. package/dist/server/_chunks/index-6gex3pfa.js +15 -0
  35. package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
  36. package/dist/server/_chunks/index-6q7zvrap.js +134 -0
  37. package/dist/server/_chunks/index-71885zaq.js +284 -0
  38. package/dist/server/_chunks/index-73z4esab.js +38 -0
  39. package/dist/server/_chunks/index-79ngvam8.js +60 -0
  40. package/dist/server/_chunks/index-7wc9n8be.js +25 -0
  41. package/dist/server/_chunks/index-8ct7rqy3.js +198 -0
  42. package/dist/server/_chunks/index-8kcxdfya.js +206 -0
  43. package/dist/server/_chunks/index-9ch50vtq.js +18 -0
  44. package/dist/server/_chunks/index-9f49w76j.js +213 -0
  45. package/dist/server/_chunks/index-9hz3s0m8.js +851 -0
  46. package/dist/server/_chunks/index-akkrvjn6.js +535 -0
  47. package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
  48. package/dist/server/_chunks/index-b7j671dj.js +207 -0
  49. package/dist/server/_chunks/index-bcws5eh2.js +35 -0
  50. package/dist/server/_chunks/index-bzd2ef7t.js +10 -0
  51. package/dist/server/_chunks/index-cjgqs13g.js +65 -0
  52. package/dist/server/_chunks/index-ckkdpht5.js +41 -0
  53. package/dist/server/_chunks/index-cn86z041.js +296 -0
  54. package/dist/server/_chunks/index-cvr4z22m.js +92 -0
  55. package/dist/server/_chunks/index-cyfednwb.js +87 -0
  56. package/dist/server/_chunks/index-d158y67j.js +152 -0
  57. package/dist/server/_chunks/index-d1jsmhhk.js +955 -0
  58. package/dist/server/_chunks/index-dg0f05zs.js +199 -0
  59. package/dist/server/_chunks/index-dgr390q7.js +9438 -0
  60. package/dist/server/_chunks/index-drwv61cc.js +185 -0
  61. package/dist/server/_chunks/index-e3a6yx84.js +18 -0
  62. package/dist/server/_chunks/index-e88tyv35.js +45 -0
  63. package/dist/server/_chunks/index-en7n9f7m.js +22 -0
  64. package/dist/server/_chunks/index-entm8bmz.js +28 -0
  65. package/dist/server/_chunks/index-evhd413j.js +57 -0
  66. package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
  67. package/dist/server/_chunks/index-fjv96re1.js +5295 -0
  68. package/dist/server/_chunks/index-fn1chkkd.js +214 -0
  69. package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
  70. package/dist/server/_chunks/index-gcmj16xy.js +92 -0
  71. package/dist/server/_chunks/index-gkndxkxf.js +736 -0
  72. package/dist/server/_chunks/index-grta8ap3.js +238 -0
  73. package/dist/server/_chunks/index-h2a70tg4.js +7 -0
  74. package/dist/server/_chunks/index-h4xy648y.js +51 -0
  75. package/dist/server/_chunks/index-hdbwtdv2.js +352 -0
  76. package/dist/server/_chunks/index-he6n2bvp.js +1270 -0
  77. package/dist/server/_chunks/index-j0m1jxqa.js +1253 -0
  78. package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
  79. package/dist/server/_chunks/index-j681c48a.js +2530 -0
  80. package/dist/server/_chunks/index-jbj7ehef.js +50 -0
  81. package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
  82. package/dist/server/_chunks/index-jks0x0a1.js +14 -0
  83. package/dist/server/_chunks/index-jn9rbhrx.js +1599 -0
  84. package/dist/server/_chunks/index-jt8e1pje.js +12 -0
  85. package/dist/server/_chunks/index-kdhxpwyq.js +483 -0
  86. package/dist/server/_chunks/index-knp0s912.js +7 -0
  87. package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
  88. package/dist/server/_chunks/index-kresp2n8.js +445 -0
  89. package/dist/server/_chunks/index-m63czgq5.js +590 -0
  90. package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
  91. package/dist/server/_chunks/index-n4hxpng2.js +11 -0
  92. package/dist/server/_chunks/index-n629dy38.js +1071 -0
  93. package/dist/server/_chunks/index-nf3df4jy.js +266 -0
  94. package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
  95. package/dist/server/_chunks/index-pym1cezq.js +39 -0
  96. package/dist/server/_chunks/index-q3r9z8mq.js +213 -0
  97. package/dist/server/_chunks/index-q738kkhj.js +100 -0
  98. package/dist/server/_chunks/index-qcrvt6er.js +112 -0
  99. package/dist/server/_chunks/index-qjj6gddn.js +54 -0
  100. package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
  101. package/dist/server/_chunks/index-r97ptz1q.js +97 -0
  102. package/dist/server/_chunks/index-ras0sdab.js +26 -0
  103. package/dist/server/_chunks/index-rcs322t1.js +19 -0
  104. package/dist/server/_chunks/index-rgj5mx84.js +101 -0
  105. package/dist/server/_chunks/index-rjegyfx4.js +1435 -0
  106. package/dist/server/_chunks/index-rt9qq1va.js +4 -0
  107. package/dist/server/_chunks/index-rthrsed5.js +356 -0
  108. package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
  109. package/dist/server/_chunks/index-stbk3jhn.js +31 -0
  110. package/dist/server/_chunks/index-tf4j19ge.js +130 -0
  111. package/dist/server/_chunks/index-tgcakdxc.js +125 -0
  112. package/dist/server/_chunks/index-tgsfjmep.js +74 -0
  113. package/dist/server/_chunks/index-tq1f96v7.js +51 -0
  114. package/dist/server/_chunks/index-tq3b39a5.js +107 -0
  115. package/dist/server/_chunks/index-typcbcsv.js +819 -0
  116. package/dist/server/_chunks/index-v1ags1na.js +132 -0
  117. package/dist/server/_chunks/index-vmr35jjw.js +170 -0
  118. package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
  119. package/dist/server/_chunks/index-vz0km5qk.js +33 -0
  120. package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
  121. package/dist/server/_chunks/index-web361b8.js +138 -0
  122. package/dist/server/_chunks/index-wm36rj4v.js +311 -0
  123. package/dist/server/_chunks/index-x0y005nh.js +283 -0
  124. package/dist/server/_chunks/index-x2m17v9c.js +6166 -0
  125. package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
  126. package/dist/server/_chunks/index-x9c55pzy.js +871 -0
  127. package/dist/server/_chunks/index-xh1nbk46.js +1299 -0
  128. package/dist/server/_chunks/index-xvj80c3a.js +30 -0
  129. package/dist/server/_chunks/index-xywjg2vc.js +100 -0
  130. package/dist/server/_chunks/index-y4d02znn.js +66 -0
  131. package/dist/server/_chunks/index-y7mzvq2q.js +110 -0
  132. package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
  133. package/dist/server/_chunks/index-yhxkxghe.js +56 -0
  134. package/dist/server/_chunks/index-yrjkqtfj.js +86 -0
  135. package/dist/server/_chunks/index-z88qv16t.js +11 -0
  136. package/dist/server/_chunks/index-zfrwq472.js +154 -0
  137. package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
  138. package/dist/server/_chunks/loader-5en7wpt5.js +80 -0
  139. package/dist/server/_chunks/modules-t92favpj.js +76 -0
  140. package/dist/server/_chunks/pipeline-4t9q43ht.js +836 -0
  141. package/dist/server/_chunks/production-385bw8df.js +55 -0
  142. package/dist/server/_chunks/proxy-config-60gprphe.js +23 -0
  143. package/dist/server/_chunks/proxy-gfhmktbk.js +35 -0
  144. package/dist/server/_chunks/router-xnrva921.js +501 -0
  145. package/dist/server/_chunks/routes-ht868pdc.js +66 -0
  146. package/dist/server/_chunks/run-d40d63ag.js +697 -0
  147. package/dist/server/_chunks/server-2p8fgqq2.js +1839 -0
  148. package/dist/server/_chunks/tsconfig-defaults-bcn34eqb.js +21 -0
  149. package/dist/server/_chunks/typegen-dvtcjtaw.js +37 -0
  150. package/dist/server/api/client-cache.js +14 -0
  151. package/dist/server/cli/index.js +375 -0
  152. package/dist/server/cli/start.js +158 -0
  153. package/dist/server/client/reference.js +16 -0
  154. package/dist/server/compat/next/cache.js +56 -0
  155. package/dist/server/compat/next/canonical-url.js +13 -0
  156. package/dist/server/compat/next/client-cache.js +57 -0
  157. package/dist/server/compat/next/client-navigation.js +232 -0
  158. package/dist/server/compat/next/client-only.js +1 -0
  159. package/dist/server/compat/next/client-script.js +178 -0
  160. package/dist/server/compat/next/client-server.js +34 -0
  161. package/dist/server/compat/next/config-headers.js +34 -0
  162. package/dist/server/compat/next/config-loader.js +25 -0
  163. package/dist/server/compat/next/config.js +10 -0
  164. package/dist/server/compat/next/constants.js +18 -0
  165. package/dist/server/compat/next/custom-server.js +10 -0
  166. package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
  167. package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
  168. package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
  169. package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
  170. package/dist/server/compat/next/dynamic.js +21 -0
  171. package/dist/server/compat/next/error.js +112 -0
  172. package/dist/server/compat/next/font/cache.js +16 -0
  173. package/dist/server/compat/next/font/google.js +3 -0
  174. package/dist/server/compat/next/font/index.js +1 -0
  175. package/dist/server/compat/next/font/local.js +24 -0
  176. package/dist/server/compat/next/font/runtime-client.js +33 -0
  177. package/dist/server/compat/next/font/runtime.js +43 -0
  178. package/dist/server/compat/next/font/shared.js +22 -0
  179. package/dist/server/compat/next/form.js +129 -0
  180. package/dist/server/compat/next/head.js +10 -0
  181. package/dist/server/compat/next/headers.js +30 -0
  182. package/dist/server/compat/next/image/client.js +11 -0
  183. package/dist/server/compat/next/image/config.js +18 -0
  184. package/dist/server/compat/next/image/optimizer.js +25 -0
  185. package/dist/server/compat/next/image/patterns.js +12 -0
  186. package/dist/server/compat/next/image/props.js +16 -0
  187. package/dist/server/compat/next/image/shared.js +86 -0
  188. package/dist/server/compat/next/image/static-metadata.js +32 -0
  189. package/dist/server/compat/next/image/validate.js +8 -0
  190. package/dist/server/compat/next/image.js +59 -0
  191. package/dist/server/compat/next/index.js +1 -0
  192. package/dist/server/compat/next/legacy-image.js +78 -0
  193. package/dist/server/compat/next/legacy-request-apis.js +24 -0
  194. package/dist/server/compat/next/link-transform.js +15 -0
  195. package/dist/server/compat/next/link.js +14 -0
  196. package/dist/server/compat/next/navigation.js +191 -0
  197. package/dist/server/compat/next/offline.js +45 -0
  198. package/dist/server/compat/next/og.js +8 -0
  199. package/dist/server/compat/next/preferred-region.js +8 -0
  200. package/dist/server/compat/next/redirects.js +32 -0
  201. package/dist/server/compat/next/resource-hints.js +30 -0
  202. package/dist/server/compat/next/rewrites.js +43 -0
  203. package/dist/server/compat/next/root-params.js +121 -0
  204. package/dist/server/compat/next/route-state.js +23 -0
  205. package/dist/server/compat/next/router.js +103 -0
  206. package/dist/server/compat/next/script.js +37 -0
  207. package/dist/server/compat/next/server-only.js +1 -0
  208. package/dist/server/compat/next/server.js +131 -0
  209. package/dist/server/compat/next/svgr.js +14 -0
  210. package/dist/server/compat/next/telemetry.js +10 -0
  211. package/dist/server/compat/next/usage.js +13 -0
  212. package/dist/server/compat/next/user-agent.js +12 -0
  213. package/dist/server/compat/next/web-vitals.js +35 -0
  214. package/dist/server/compat/react/action-state.js +11 -0
  215. package/dist/server/compat/react/client-lite.js +83 -0
  216. package/dist/server/compat/react/client.js +131 -0
  217. package/dist/server/compat/react/compiler-runtime.js +42 -0
  218. package/dist/server/compat/react/dom-client.js +106 -0
  219. package/dist/server/compat/react/dom-react-server.js +37 -0
  220. package/dist/server/compat/react/dom-server.js +40 -0
  221. package/dist/server/compat/react/dom.js +52 -0
  222. package/dist/server/compat/react/hooks-extra.js +12 -0
  223. package/dist/server/compat/react/internals.js +14 -0
  224. package/dist/server/compat/react/parity.js +11 -0
  225. package/dist/server/compat/react/preact.js +113 -0
  226. package/dist/server/compat/react/react-server.js +133 -0
  227. package/dist/server/compat/react/router-shim.js +8 -0
  228. package/dist/server/compat/react/server-component-use.js +14 -0
  229. package/dist/server/compat/react/server-inserted-html.js +14 -0
  230. package/dist/server/compat/react/server.js +194 -0
  231. package/dist/server/compat/react/style-values.js +10 -0
  232. package/dist/server/compat/react/use.js +10 -0
  233. package/dist/server/compat/react/view-transition.js +12 -0
  234. package/dist/server/generation.json +1 -0
  235. package/package.json +4 -1
  236. package/reference/compat.md +1 -1
  237. package/reference/config.md +2 -2
  238. package/reference/dev.md +1 -1
  239. package/reference/getting-started.md +1 -1
  240. package/reference/rendering.md +4 -4
  241. package/src/api/dynamic.tsx +86 -4
  242. package/src/api/server.ts +24 -6
  243. package/src/cli/adapters/vercel-warm.ts +327 -62
  244. package/src/cli/adapters/vercel.ts +164 -1054
  245. package/src/cli/analyze.ts +3 -2
  246. package/src/cli/build/cache.ts +6 -6
  247. package/src/cli/build.ts +78 -45
  248. package/src/cli/index.ts +21 -3
  249. package/src/cli/serve/immutable.ts +31 -0
  250. package/src/cli/serve/pipeline.ts +97 -93
  251. package/src/cli/serve/standalone-worker.ts +8 -0
  252. package/src/cli/serve/standalone.ts +703 -0
  253. package/src/cli/start.ts +31 -8
  254. package/src/client/build.ts +1 -1
  255. package/src/client/chunk-fold.ts +19 -6
  256. package/src/client/react-tier.ts +3 -2
  257. package/src/client/reference-stub.ts +23 -36
  258. package/src/compat/actions/client-plugin.ts +4 -2
  259. package/src/compat/actions/config.ts +6 -5
  260. package/src/compat/actions/extensions.ts +5 -5
  261. package/src/compat/aliases.ts +8 -1
  262. package/src/compat/bundler/config.ts +88 -0
  263. package/src/compat/bundler/optimize-package-imports.ts +86 -26
  264. package/src/compat/bundler/relay-transform.ts +15 -3
  265. package/src/compat/bundler/require-context.ts +2 -1
  266. package/src/compat/bundler/webpack-loaders.ts +3 -2
  267. package/src/compat/bundler/worker.ts +2 -2
  268. package/src/compat/cache-control.ts +16 -8
  269. package/src/compat/css/inline-css.ts +1 -1
  270. package/src/compat/css/modules.ts +18 -5
  271. package/src/compat/export/build-complete.ts +1 -1
  272. package/src/compat/export/emit.ts +4 -4
  273. package/src/compat/export/standalone.ts +30 -65
  274. package/src/compat/image-optimizer/optimize.ts +1 -1
  275. package/src/compat/lifecycle/error-funnel.ts +1 -1
  276. package/src/compat/lifecycle/instrumentation-client.ts +4 -3
  277. package/src/compat/lifecycle/instrumentation.ts +117 -24
  278. package/src/compat/lifecycle/testmode.ts +3 -2
  279. package/src/compat/metadata-artifacts.ts +1 -1
  280. package/src/compat/next/config-loader.ts +140 -13
  281. package/src/compat/next/dynamic.tsx +10 -23
  282. package/src/compat/next/font/cache.ts +2 -1
  283. package/src/compat/next/font/runtime.ts +23 -3
  284. package/src/compat/next/og.ts +3 -3
  285. package/src/compat/next/usage.ts +3 -2
  286. package/src/compat/pages/api.ts +83 -14
  287. package/src/compat/pages/router.ts +30 -14
  288. package/src/compat/register/bundler.ts +3 -1
  289. package/src/compat/register/image.ts +1 -1
  290. package/src/compat/register/middleware.ts +1 -1
  291. package/src/compat/register/otel.ts +5 -9
  292. package/src/compat/register/render.ts +3 -1
  293. package/src/compat/register/use-cache.ts +3 -1
  294. package/src/compat/release.ts +46 -0
  295. package/src/compat/segment/serve.ts +1 -1
  296. package/src/compat/typecheck/check.ts +6 -4
  297. package/src/compat/validation/validate.ts +10 -7
  298. package/src/config.ts +76 -9
  299. package/src/css/assets.ts +213 -0
  300. package/src/css/build.ts +190 -247
  301. package/src/dev/client-chunk-store.ts +2 -1
  302. package/src/dev/restart/client-key.ts +2 -1
  303. package/src/dev/restart/global-css.ts +2 -1
  304. package/src/dev/restart/route-bundle-key.ts +2 -1
  305. package/src/dev/restart/route-facts.ts +2 -1
  306. package/src/dev/server.ts +34 -14
  307. package/src/extensions.ts +4 -0
  308. package/src/out-paths.ts +10 -0
  309. package/src/render/hooks.ts +13 -0
  310. package/src/render/renderer.ts +53 -33
  311. package/src/request/context.ts +9 -0
  312. package/src/resolve/dynamic.ts +7 -1
  313. package/src/resolve/engine.ts +2 -12
  314. package/src/resolve/imports.ts +12 -52
  315. package/src/resolve/package-json.ts +56 -0
  316. package/src/resolve/scan-facts.ts +250 -1
  317. package/src/routing/href.ts +10 -3
  318. package/src/routing/match.ts +287 -0
  319. package/src/routing/metadata-files.ts +20 -6
  320. package/src/routing/proxy-config.ts +137 -0
  321. package/src/routing/proxy.ts +35 -134
  322. package/src/routing/routes.ts +22 -281
  323. package/src/runtime/fingerprint.ts +23 -8
  324. package/src/runtime/load.ts +170 -0
  325. package/src/runtime/loader.ts +218 -44
  326. package/src/runtime/module-cache.ts +15 -1
  327. package/src/runtime/modules.ts +405 -82
  328. package/src/runtime/prebundle.ts +101 -0
  329. package/src/runtime/production.ts +456 -0
  330. package/src/runtime/release-graph.ts +342 -0
  331. package/src/runtime/vendor-build.ts +750 -17
  332. package/src/runtime/vendor.ts +16 -3
  333. package/src/types.ts +4 -3
  334. package/src/utils/directive.ts +40 -0
  335. package/src/utils/fs.ts +95 -4
  336. package/src/utils/resource-query.ts +12 -0
  337. package/src/cli/serve/entry.ts +0 -45
@@ -0,0 +1,3341 @@
1
+ // @bun
2
+ import { join as __pnextJoin } from "node:path";
3
+ const __PNEXT_PACKAGE_ROOT__ = __pnextJoin(import.meta.dirname, "../../..");
4
+ import {
5
+ immutableAssetPath,
6
+ immutableAssetPrefixes,
7
+ immutableCacheControl
8
+ } from "./index-rcs322t1.js";
9
+ import {
10
+ buildClientEntries,
11
+ emitStaticClientChunks,
12
+ startClientSources
13
+ } from "./index-1pzm1hdy.js";
14
+ import {
15
+ writeTypegen
16
+ } from "./index-38xpdxwd.js";
17
+ import {
18
+ handleRouteModule,
19
+ staticRouteParams
20
+ } from "./index-qpwsgt3a.js";
21
+ import {
22
+ addClientEntryReason,
23
+ assertNoServerActionsWithoutCompat,
24
+ materializeRouteFacts,
25
+ scanRoutes
26
+ } from "./index-jn9rbhrx.js";
27
+ import {
28
+ devServerModuleHref,
29
+ resetModuleGraphFailure,
30
+ setEmitCompiledSpecifiersManifest,
31
+ setReleaseCompile
32
+ } from "./index-fjv96re1.js";
33
+ import"./index-n4hxpng2.js";
34
+ import"./index-x3yn4ywm.js";
35
+ import {
36
+ cacheRoot as cacheRoot2,
37
+ compiledSourceGraph,
38
+ flushDevModuleCaches,
39
+ registerServerRuntime
40
+ } from "./index-rjegyfx4.js";
41
+ import"./index-0r5eqfc7.js";
42
+ import"./index-3e075kny.js";
43
+ import {
44
+ clientEntryName,
45
+ defaultNotFoundDocument,
46
+ discoverStaticMetadataFiles,
47
+ metadataRouteHandlerModule,
48
+ pprShellPath,
49
+ pprSubShellPath,
50
+ readModuleMetadata,
51
+ readModuleViewport,
52
+ renderFallbackShell,
53
+ renderGlobalNotFoundResponse,
54
+ renderPageWithStatus,
55
+ renderPartialShell,
56
+ renderSubShell,
57
+ staticMetadataCacheControl,
58
+ staticMetadataForPathFromFiles,
59
+ staticMetadataForRouteFromFiles,
60
+ staticMetadataOutputFile,
61
+ staticParamsFor,
62
+ staticRouteMetadataKey,
63
+ withDynamicMetadataRoutes
64
+ } from "./index-x2m17v9c.js";
65
+ import {
66
+ findLayouts
67
+ } from "./index-8ct7rqy3.js";
68
+ import {
69
+ findProxyFile,
70
+ proxyExternalLoadTarget,
71
+ proxyRoutePatterns,
72
+ validateProxyFiles
73
+ } from "./index-3ycf5ckv.js";
74
+ import {
75
+ serverBundleTargetForRuntime,
76
+ throwIfModuleGraphFailed
77
+ } from "./index-0yjv5v47.js";
78
+ import"./index-yrjkqtfj.js";
79
+ import"./index-jbj7ehef.js";
80
+ import {
81
+ buildGlobalCss,
82
+ buildNotFoundCss,
83
+ buildRouteStylesheets,
84
+ globalCssSources,
85
+ prepareRouteCssChunks,
86
+ warmCssPipeline
87
+ } from "./index-n629dy38.js";
88
+ import {
89
+ createVerboseLogger
90
+ } from "./index-73z4esab.js";
91
+ import {
92
+ emittedAssetNames,
93
+ registerCssRuntime
94
+ } from "./index-d158y67j.js";
95
+ import {
96
+ nextCompatEnabled
97
+ } from "./index-web361b8.js";
98
+ import"./index-knp0s912.js";
99
+ import {
100
+ frameworkFingerprint
101
+ } from "./index-gcmj16xy.js";
102
+ import"./index-ye9hmsvf.js";
103
+ import {
104
+ setRequestRuntime
105
+ } from "./index-z88qv16t.js";
106
+ import {
107
+ beginSourceScope,
108
+ endSourceScope,
109
+ sourceCacheStats
110
+ } from "./index-fp8r0sqs.js";
111
+ import"./index-cjgqs13g.js";
112
+ import"./index-yhxkxghe.js";
113
+ import"./index-29pq0kax.js";
114
+ import {
115
+ interceptionMarkerLevels
116
+ } from "./index-cn86z041.js";
117
+ import {
118
+ ensureEmptyDir,
119
+ listFiles,
120
+ readText,
121
+ resolveManifest,
122
+ serializeBuildManifest,
123
+ toPosixPath,
124
+ writeFileAtomic,
125
+ writeText
126
+ } from "./index-4da76t62.js";
127
+ import {
128
+ cacheRoot,
129
+ namedBunBinary
130
+ } from "./index-cyfednwb.js";
131
+ import"./index-vz0km5qk.js";
132
+ import {
133
+ bootstrapCompat
134
+ } from "./index-tq3b39a5.js";
135
+ import {
136
+ devOutSegment,
137
+ frameworkRuntimeSpecifiers,
138
+ loadConfig,
139
+ pathToFileHref
140
+ } from "./index-71885zaq.js";
141
+ import {
142
+ outCachePath
143
+ } from "./index-bzd2ef7t.js";
144
+ import"./index-jcsjq3d1.js";
145
+ import {
146
+ PREBUNDLE_STAMP,
147
+ buildIndexFile,
148
+ buildManifestFile,
149
+ prebundledFile,
150
+ readBuildIndex,
151
+ readPrebundleStamp,
152
+ releaseSourceFile,
153
+ standaloneOriginsFile
154
+ } from "./index-hdbwtdv2.js";
155
+ import {
156
+ bold,
157
+ cyan,
158
+ dim,
159
+ green
160
+ } from "./index-6kp9r0d9.js";
161
+ import {
162
+ compiledClientReferenceFiles
163
+ } from "./index-ras0sdab.js";
164
+ import {
165
+ beginDynamicBailoutProbe,
166
+ endDynamicBailoutProbe,
167
+ runWithWorkUnit
168
+ } from "./index-grta8ap3.js";
169
+ import {
170
+ abortActivePrerenderScopes,
171
+ beginShellSourceTracking,
172
+ cacheComponents,
173
+ endShellSourceTracking
174
+ } from "./index-kresp2n8.js";
175
+ import"./index-e3a6yx84.js";
176
+ import {
177
+ importMetaRefs,
178
+ moduleSpecifierEdges,
179
+ scanFactsStats,
180
+ spliceSource
181
+ } from "./index-x9c55pzy.js";
182
+ import"./index-d1jsmhhk.js";
183
+ import"./index-7wc9n8be.js";
184
+ import"./index-pym1cezq.js";
185
+ import {
186
+ splitResourceQuery
187
+ } from "./index-jt8e1pje.js";
188
+ import {
189
+ buildParallelPhaseError,
190
+ clearBuildParallelPhases,
191
+ getBuildExtensions,
192
+ getCompatModeExtensions,
193
+ getRenderExtensions,
194
+ runInitHooks,
195
+ withRouteRuntime
196
+ } from "./index-zqpqyg8p.js";
197
+ import {
198
+ escapeRegex
199
+ } from "./index-qjj6gddn.js";
200
+ import"./index-4399bvd2.js";
201
+ import"./index-rt9qq1va.js";
202
+
203
+ // src/cli/build.ts
204
+ import { copyFile as copyFile3, mkdir as mkdir4, rename as rename3, writeFile as writeFile2 } from "fs/promises";
205
+ import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync as readdirSync3, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
206
+ import { createRequire } from "module";
207
+ import path5 from "path";
208
+ import { fileURLToPath as fileURLToPath3 } from "url";
209
+
210
+ // src/cli/adapters/vercel.ts
211
+ import { copyFile, cp, mkdir, readFile, readdir, rename, rm } from "fs/promises";
212
+ import { constants, existsSync, readdirSync } from "fs";
213
+ import path from "path";
214
+ var SERVER_FUNCTION = "_pnext";
215
+ var FUNCTION_PLATFORM = {
216
+ architecture: "x86_64",
217
+ os: "linux",
218
+ cpu: "x64",
219
+ libc: "glibc"
220
+ };
221
+ var functionDroppedPackages = [/^sharp$/, /^@img\/sharp-libvips/];
222
+ async function writeVercelOutput(config, manifest, options = {}) {
223
+ const log = createVerboseLogger(options.verbose ?? false, "vercel");
224
+ const outputPath = path.join(config.root, ".vercel", "output");
225
+ const staticPath = path.join(config.outPath, "static");
226
+ const staticFiles = manifest.staticFiles ?? {};
227
+ await log.step("prepare output directory", () => emptyDir(outputPath));
228
+ const functionPath = path.join(outputPath, "functions", `${SERVER_FUNCTION}.func`);
229
+ await writeServerFunction(config.outPath, manifest, functionPath, log);
230
+ await log.step("copy static files", () => copyStaticFiles(staticPath, path.join(outputPath, "static"), (relative) => !staticFiles[relative] || canServeStaticOnVercel(staticFiles[relative])));
231
+ const overrides = await staticOverrides(staticPath, staticFiles);
232
+ const routes = [
233
+ ...compatStaticRewrite(config, outputPath),
234
+ ...await immutableAssetRoutes(staticPath, manifest.publicAssets),
235
+ ...await proxyRoutes(config),
236
+ ...staticHeaderRoutes(staticFiles),
237
+ { handle: "filesystem" },
238
+ { src: "^/.*$", dest: `/${SERVER_FUNCTION}` }
239
+ ];
240
+ const vercelConfig = {
241
+ version: 3,
242
+ routes,
243
+ ...Object.keys(overrides).length > 0 ? { overrides } : {}
244
+ };
245
+ await writeText(path.join(outputPath, "config.json"), `${JSON.stringify(vercelConfig, null, 2)}
246
+ `);
247
+ }
248
+ async function emptyDir(dir) {
249
+ const parent = path.dirname(dir);
250
+ await mkdir(parent, { recursive: true });
251
+ const staleMarker = `${path.basename(dir)}.stale-`;
252
+ if (existsSync(dir)) {
253
+ await rename(dir, path.join(parent, `${staleMarker}${process.pid.toString(36)}-${Date.now().toString(36)}`));
254
+ }
255
+ const stale = readdirSync(parent).filter((entry) => entry.startsWith(staleMarker)).map((entry) => path.join(parent, entry));
256
+ await mkdir(dir, { recursive: true });
257
+ if (stale.length > 0) {
258
+ Bun.spawn(["rm", "-rf", ...stale], { stdout: "ignore", stderr: "ignore" });
259
+ }
260
+ }
261
+ function compatStaticRewrite(config, outputPath) {
262
+ if (!nextCompatEnabled(config))
263
+ return [];
264
+ const staticDir = path.join(outputPath, "static");
265
+ const names = readdirSyncSafe(path.join(staticDir, "assets")).filter((name) => !existsSync(path.join(staticDir, "_next", "static", name)));
266
+ if (names.length === 0)
267
+ return [];
268
+ const alternation = names.map((name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
269
+ return [{ src: `^/_next/static/(${alternation})(/.*)?$`, dest: "/assets/$1$2", continue: true }];
270
+ }
271
+ function readdirSyncSafe(dir) {
272
+ return existsSync(dir) ? readdirSync(dir) : [];
273
+ }
274
+ async function proxyRoutes(config) {
275
+ const proxyFile = findProxyFile(config);
276
+ if (!proxyFile)
277
+ return [];
278
+ const proxyModule = await import(pathToFileHref(proxyFile));
279
+ return [...proxyRoutePatterns(proxyModule.config), "^.*(?:%|//).*$"].map((src) => ({
280
+ src,
281
+ dest: `/${SERVER_FUNCTION}`
282
+ }));
283
+ }
284
+ async function writeServerFunction(standalonePath, manifest, functionPath, log) {
285
+ await mkdir(path.dirname(functionPath), { recursive: true });
286
+ await log.step("copy standalone", () => cp(standalonePath, functionPath, { recursive: true, verbatimSymlinks: true }));
287
+ const modules = path.join(functionPath, "node_modules");
288
+ const packages = await packageDirs(modules);
289
+ await Promise.all([...packages].filter(([name]) => functionDroppedPackages.some((pattern) => pattern.test(name))).map(([, dirs]) => Promise.all(dirs.map((dir) => rm(dir, { recursive: true, force: true })))));
290
+ await log.step("platform natives", () => replaceHostNatives(packages, log));
291
+ await writeText(path.join(functionPath, "index.mjs"), `import { createRequestHandler } from './server/entry.js';
292
+
293
+ const handlerPromise = createRequestHandler({ root: import.meta.dirname });
294
+
295
+ async function handler(request) {
296
+ return (await handlerPromise)(request);
297
+ }
298
+
299
+ // Callable for the Node-style launcher, \`fetch\` for the Bun runtime.
300
+ export default Object.assign(handler, { fetch: handler });
301
+ `);
302
+ const maxDuration = manifest.routes.reduce((max, route) => route.maxDuration ? Math.max(max ?? 0, route.maxDuration) : max, undefined);
303
+ await writeText(path.join(functionPath, ".vc-config.json"), `${JSON.stringify({
304
+ runtime: "bun1.4.x",
305
+ handler: "index.mjs",
306
+ launcherType: "Nodejs",
307
+ architecture: FUNCTION_PLATFORM.architecture,
308
+ useWebApi: true,
309
+ supportsResponseStreaming: true,
310
+ ...maxDuration ? { maxDuration } : {}
311
+ }, null, 2)}
312
+ `);
313
+ }
314
+ async function packageDirs(modules) {
315
+ const found = new Map;
316
+ const visit = async (dir, depth) => {
317
+ const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
318
+ for (const entry of entries) {
319
+ if (!entry.isDirectory())
320
+ continue;
321
+ const full = path.join(dir, entry.name);
322
+ if (entry.name === ".bun" || entry.name === ".pnpm") {
323
+ for (const store of await readdir(full, { withFileTypes: true }).catch(() => []))
324
+ if (store.isDirectory())
325
+ await visit(path.join(full, store.name, "node_modules"), 0);
326
+ } else if (entry.name.startsWith("@") && depth === 0) {
327
+ await visit(full, 1);
328
+ } else if (existsSync(path.join(full, "package.json"))) {
329
+ const name = depth === 1 ? `${path.basename(dir)}/${entry.name}` : entry.name;
330
+ found.set(name, [...found.get(name) ?? [], full]);
331
+ await visit(path.join(full, "node_modules"), 0);
332
+ }
333
+ }
334
+ };
335
+ await visit(modules, 0);
336
+ return found;
337
+ }
338
+ async function readPackageJson(dir) {
339
+ try {
340
+ return JSON.parse(await readFile(path.join(dir, "package.json"), "utf8"));
341
+ } catch {
342
+ return;
343
+ }
344
+ }
345
+ async function replaceHostNatives(packages, log) {
346
+ const manifests = new Map;
347
+ for (const [name, dirs] of packages) {
348
+ const json = await readPackageJson(dirs[0]);
349
+ if (json)
350
+ manifests.set(name, json);
351
+ }
352
+ const hostNatives = new Map;
353
+ for (const [name, json] of manifests) {
354
+ if (!(json.os ?? json.cpu) || matchesFunctionPlatform(json))
355
+ continue;
356
+ const owner = [...manifests].find(([, candidate]) => candidate.optionalDependencies?.[name]);
357
+ hostNatives.set(name, {
358
+ dirs: packages.get(name),
359
+ owner: owner && { name: owner[0], version: owner[1].version ?? "" }
360
+ });
361
+ }
362
+ if (hostNatives.size === 0)
363
+ return;
364
+ const targets = await platformNativePackages(hostNatives, manifests, log);
365
+ for (const [name, dir] of targets) {
366
+ for (const host of hostNatives.get(name)?.dirs ?? []) {
367
+ const target = path.join(path.dirname(host), name.split("/").at(-1));
368
+ await rm(host, { recursive: true, force: true });
369
+ await cp(dir, target, { recursive: true, dereference: true });
370
+ }
371
+ }
372
+ }
373
+ async function platformNativePackages(hostNatives, manifests, log) {
374
+ const owners = new Map;
375
+ for (const [name, { owner }] of hostNatives) {
376
+ const spec = owner ?? { name, version: manifests.get(name)?.version ?? "" };
377
+ if (spec.version)
378
+ owners.set(spec.name, spec.version);
379
+ }
380
+ const specs = [...owners].map(([name, version]) => `${name}@${version}`).sort();
381
+ if (specs.length === 0)
382
+ return new Map;
383
+ try {
384
+ const installed = await crossPlatformInstall(specs);
385
+ const matches = new Map;
386
+ for (const [name, dir] of installed) {
387
+ const json = await readPackageJson(dir);
388
+ if (json && (json.os ?? json.cpu) && matchesFunctionPlatform(json))
389
+ matches.set(name, dir);
390
+ }
391
+ if (matches.size === 0)
392
+ throw new Error(`no ${FUNCTION_PLATFORM.os} builds in ${specs.join(" ")}`);
393
+ return matches;
394
+ } catch (error) {
395
+ console.warn(`vercel adapter: could not fetch ${FUNCTION_PLATFORM.os}-${FUNCTION_PLATFORM.cpu} native packages; the function will carry this machine's builds and fail at runtime:`, error);
396
+ log.log("falling back to host native packages");
397
+ return new Map;
398
+ }
399
+ }
400
+ function matchesFunctionPlatform(packageJson) {
401
+ const matches = (declared, value) => {
402
+ if (!declared?.length)
403
+ return true;
404
+ if (declared.every((entry) => entry.startsWith("!")))
405
+ return !declared.includes(`!${value}`);
406
+ return declared.includes(value);
407
+ };
408
+ return matches(packageJson.os, FUNCTION_PLATFORM.os) && matches(packageJson.cpu, FUNCTION_PLATFORM.cpu) && matches(packageJson.libc, FUNCTION_PLATFORM.libc);
409
+ }
410
+ async function crossPlatformInstall(specs) {
411
+ const key = Bun.hash.xxHash3(`${FUNCTION_PLATFORM.os}-${FUNCTION_PLATFORM.cpu}\x00${specs.join("\x00")}`).toString(16);
412
+ const dir = path.join(cacheRoot(), "vercel-natives", key);
413
+ const modules = path.join(dir, "node_modules");
414
+ if (!existsSync(modules)) {
415
+ const staging = `${dir}.${process.pid.toString(36)}`;
416
+ await rm(staging, { recursive: true, force: true });
417
+ await mkdir(staging, { recursive: true });
418
+ await writeText(path.join(staging, "package.json"), `{"name":"pnext-natives"}
419
+ `);
420
+ const install = Bun.spawn([
421
+ "bun",
422
+ "add",
423
+ "--no-save",
424
+ "--ignore-scripts",
425
+ "--silent",
426
+ `--os=${FUNCTION_PLATFORM.os}`,
427
+ `--cpu=${FUNCTION_PLATFORM.cpu}`,
428
+ ...specs
429
+ ], { cwd: staging, stdout: "ignore", stderr: "pipe" });
430
+ if (await install.exited !== 0) {
431
+ const stderr = await new Response(install.stderr).text();
432
+ await rm(staging, { recursive: true, force: true });
433
+ throw new Error(stderr.trim() || "bun add failed");
434
+ }
435
+ await rm(dir, { recursive: true, force: true });
436
+ await rename(staging, dir);
437
+ }
438
+ const installed = new Map;
439
+ for (const entry of readdirSync(modules)) {
440
+ if (entry.startsWith("."))
441
+ continue;
442
+ if (!entry.startsWith("@")) {
443
+ installed.set(entry, path.join(modules, entry));
444
+ continue;
445
+ }
446
+ for (const scoped of readdirSync(path.join(modules, entry))) {
447
+ installed.set(`${entry}/${scoped}`, path.join(modules, entry, scoped));
448
+ }
449
+ }
450
+ return installed;
451
+ }
452
+ async function copyStaticFiles(from, to, shouldCopy = () => true) {
453
+ const files = (await listFiles(from)).filter((file) => shouldCopy(toPosixPath(path.relative(from, file))));
454
+ const directories = new Set(files.map((file) => path.dirname(path.join(to, path.relative(from, file)))));
455
+ await Promise.all([...directories].map((dir) => mkdir(dir, { recursive: true })));
456
+ await Promise.all(files.map((file) => copyFile(file, path.join(to, path.relative(from, file)), constants.COPYFILE_FICLONE)));
457
+ }
458
+ async function staticOverrides(publicPath, staticFiles) {
459
+ const overrides = {};
460
+ for (const file of await listFiles(publicPath)) {
461
+ const relative = toPosixPath(path.relative(publicPath, file));
462
+ if (!relative.endsWith("/index.html"))
463
+ continue;
464
+ overrides[relative] = { path: relative.replace(/\/index\.html$/, "") };
465
+ }
466
+ for (const [relative, metadata] of Object.entries(staticFiles)) {
467
+ if (!canServeStaticOnVercel(metadata))
468
+ continue;
469
+ const contentType = metadata.headers.find(([name]) => name.toLowerCase() === "content-type")?.[1];
470
+ if (contentType)
471
+ overrides[relative] = { ...overrides[relative], contentType };
472
+ }
473
+ return overrides;
474
+ }
475
+ async function immutableAssetRoutes(publicDir, publicAssets = []) {
476
+ const app = new Set(publicAssets);
477
+ const built = publicAssets.length > 0 ? (await listFiles(publicDir)).map((file) => toPosixPath(path.relative(publicDir, file))).filter((relative) => !app.has(relative) && immutableAssetPath(relative)) : [];
478
+ const patterns = immutableAssetPatterns(built, publicAssets);
479
+ return routeSources(patterns, (source) => `^/(?:${source})`).map((src) => ({
480
+ src,
481
+ headers: { "cache-control": immutableCacheControl },
482
+ continue: true,
483
+ important: true
484
+ }));
485
+ }
486
+ function immutableAssetPatterns(built, publicAssets) {
487
+ const appDirs = new Set(publicAssets.flatMap(ancestorDirs));
488
+ const prefixes = [...new Set(immutableAssetPrefixes())];
489
+ const patterns = prefixes.filter((prefix) => !appDirs.has(prefix)).map(escapeRegex);
490
+ for (const relative of built) {
491
+ const prefix = prefixes.find((prefix2) => relative.startsWith(prefix2));
492
+ if (!prefix || !appDirs.has(prefix))
493
+ continue;
494
+ const dir = ancestorDirs(relative).find((dir2) => dir2.length > prefix.length && !appDirs.has(dir2));
495
+ patterns.push(dir ? escapeRegex(requestPath(dir)) : `${escapeRegex(requestPath(relative))}$`);
496
+ }
497
+ return [...new Set(patterns)];
498
+ }
499
+ function requestPath(relative) {
500
+ return relative.replace(/[\0-\x20"#<>?`{}\x7f-\u{10ffff}]/gu, (char) => encodeURIComponent(char));
501
+ }
502
+ function ancestorDirs(relative) {
503
+ const parts = relative.split("/").slice(0, -1);
504
+ return parts.map((_, index) => `${parts.slice(0, index + 1).join("/")}/`);
505
+ }
506
+ var functionOnlyHeaders = new Set([
507
+ "content-length",
508
+ "content-encoding",
509
+ "transfer-encoding",
510
+ "connection",
511
+ "set-cookie"
512
+ ]);
513
+ function canServeStaticOnVercel(metadata) {
514
+ if (metadata.status !== 200)
515
+ return false;
516
+ const headers = routeHeaders(metadata);
517
+ if (headers.length === 0)
518
+ return true;
519
+ return metadata.revalidateSeconds === undefined && metadata.expireSeconds === undefined && !metadata.tags?.length && headers.every(([name]) => !functionOnlyHeaders.has(name.toLowerCase()));
520
+ }
521
+ function routeHeaders(metadata) {
522
+ return metadata.headers.filter(([name]) => name.toLowerCase() !== "content-type");
523
+ }
524
+ var maxRouteSourceLength = 2000;
525
+ function staticHeaderRoutes(staticFiles) {
526
+ const groups = new Map;
527
+ for (const [relative, metadata] of Object.entries(staticFiles)) {
528
+ const extra = routeHeaders(metadata);
529
+ if (extra.length === 0 || !canServeStaticOnVercel(metadata))
530
+ continue;
531
+ const headers = Object.fromEntries(new Headers(extra));
532
+ const key = JSON.stringify(headers);
533
+ const group = groups.get(key) ?? { headers, patterns: [] };
534
+ groups.set(key, group);
535
+ group.patterns.push(servedPathPattern(relative));
536
+ }
537
+ return [...groups.values()].flatMap(({ headers, patterns }) => routeSources(patterns, (source) => `^/(?:${source})$`).map((src) => ({
538
+ src,
539
+ methods: ["GET", "HEAD"],
540
+ headers,
541
+ continue: true,
542
+ important: true
543
+ })));
544
+ }
545
+ function routeSources(patterns, wrap) {
546
+ const sources = [];
547
+ for (const pattern of patterns) {
548
+ const last = sources.length - 1;
549
+ if (last >= 0 && wrap(`${sources[last]}|${pattern}`).length <= maxRouteSourceLength) {
550
+ sources[last] += `|${pattern}`;
551
+ } else {
552
+ sources.push(pattern);
553
+ }
554
+ }
555
+ return sources.map(wrap);
556
+ }
557
+ function servedPathPattern(relative) {
558
+ if (relative === "index.html")
559
+ return "(?:index\\.html)?";
560
+ if (!relative.endsWith("/index.html"))
561
+ return escapeRegex(relative);
562
+ return `${escapeRegex(relative.slice(0, -"/index.html".length))}(?:/|/index\\.html)?`;
563
+ }
564
+
565
+ // src/cli/adapters/vercel-warm.ts
566
+ import { fileURLToPath } from "url";
567
+
568
+ // src/runtime/release-graph.ts
569
+ import { existsSync as existsSync2, readFileSync, realpathSync } from "fs";
570
+ import path2 from "path";
571
+ var layerDirs = {
572
+ "server:server": "rsc",
573
+ "client:client": "ssr"
574
+ };
575
+ var layers = Object.keys(layerDirs);
576
+ var frameworkRoot = realpathSync(path2.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/runtime", "..", ".."));
577
+
578
+ // src/cli/adapters/vercel-warm.ts
579
+ var DONE_MARKER = "pnext-warm-done:";
580
+ var COMPILED_MARKER = "pnext-warm-compiled";
581
+ var ATTEMPT_TIMEOUT_MS = 10 * 60000;
582
+ var MAX_ATTEMPTS = 3;
583
+ var FULL_MODE_FLAG = "--full";
584
+ function startWarmChild(config, mode = "full") {
585
+ const children = new Set;
586
+ let disposed = false;
587
+ const spawn = () => {
588
+ if (disposed)
589
+ return;
590
+ const child = spawnWarmProcess(config, mode);
591
+ if (!child)
592
+ return;
593
+ children.add(child);
594
+ child.exited.finally(() => children.delete(child));
595
+ forwardWarmStderr(child);
596
+ return child;
597
+ };
598
+ const killOnExit = () => kill();
599
+ const kill = () => {
600
+ if (disposed)
601
+ return;
602
+ disposed = true;
603
+ process.off("exit", killOnExit);
604
+ for (const child of children)
605
+ child.kill();
606
+ children.clear();
607
+ };
608
+ process.once("exit", killOnExit);
609
+ const first = spawn();
610
+ return {
611
+ prewarm(files) {
612
+ if (!first || files.length === 0)
613
+ return;
614
+ try {
615
+ first.stdin.write(`${JSON.stringify({ prewarm: files })}
616
+ `);
617
+ first.stdin.flush();
618
+ } catch {}
619
+ },
620
+ finish: (log, onCompiled, facts = { clientReferences: [] }) => warmWithRestarts(first, spawn, mode, log, facts, onCompiled).finally(kill),
621
+ kill
622
+ };
623
+ }
624
+ async function forwardWarmStderr(child) {
625
+ try {
626
+ const reader = child.stderr.getReader();
627
+ for (;; ) {
628
+ const { done, value } = await reader.read();
629
+ if (done)
630
+ return;
631
+ process.stderr.write(value);
632
+ }
633
+ } catch {}
634
+ }
635
+ function spawnWarmProcess(config, mode) {
636
+ const entry = fileURLToPath(new URL(Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/adapters/vercel-warm.ts").href));
637
+ const argv = mode === "full" ? [config.root, FULL_MODE_FLAG] : [config.root];
638
+ try {
639
+ return Bun.spawn([namedBunBinary("pnext-warm"), "--conditions=react-server", entry, ...argv], {
640
+ cwd: config.root,
641
+ stdin: "pipe",
642
+ stdout: "pipe",
643
+ stderr: "pipe",
644
+ env: process.env
645
+ });
646
+ } catch {
647
+ return;
648
+ }
649
+ }
650
+ async function warmWithRestarts(first, spawn, mode, log, facts, onCompiled) {
651
+ const finished = new Map;
652
+ const compiled = () => [...finished.values()].filter((file) => Boolean(file));
653
+ let fired = false;
654
+ const fireOnCompiled = onCompiled ? () => {
655
+ if (fired)
656
+ return;
657
+ fired = true;
658
+ onCompiled(compiled());
659
+ } : undefined;
660
+ let child = first;
661
+ for (let attempt = 1;attempt <= MAX_ATTEMPTS && child; attempt++) {
662
+ const before = finished.size;
663
+ const failure = await runAttempt(child, {
664
+ skip: [...finished.keys()],
665
+ compiled: Object.fromEntries([...finished].filter((entry) => Boolean(entry[1]))),
666
+ ...facts
667
+ }, finished, fireOnCompiled);
668
+ if (!failure) {
669
+ log.log(`warmed ${compiled().length} modules`);
670
+ return compiled();
671
+ }
672
+ child = finished.size > before && attempt < MAX_ATTEMPTS ? spawn() : undefined;
673
+ if (child)
674
+ log.log(`warm-up ${failure} after ${finished.size} files; restarting past them`);
675
+ else
676
+ warmIncomplete(failure, finished.size, mode);
677
+ }
678
+ fireOnCompiled?.();
679
+ return compiled();
680
+ }
681
+ async function runAttempt(child, request, finished, onCompiled) {
682
+ try {
683
+ child.stdin.write(`${JSON.stringify(request)}
684
+ `);
685
+ child.stdin.end();
686
+ } catch {}
687
+ const timeout = setTimeout(() => child.kill("SIGKILL"), ATTEMPT_TIMEOUT_MS);
688
+ timeout.unref?.();
689
+ const processLine = (line) => {
690
+ if (!line)
691
+ return;
692
+ if (line === COMPILED_MARKER) {
693
+ onCompiled?.();
694
+ return;
695
+ }
696
+ if (!line.startsWith(DONE_MARKER)) {
697
+ console.log(line);
698
+ return;
699
+ }
700
+ const [source, artifact] = line.slice(DONE_MARKER.length).split("\t");
701
+ if (source)
702
+ finished.set(source, artifact || undefined);
703
+ };
704
+ const reader = child.stdout.getReader();
705
+ const decoder = new TextDecoder;
706
+ let buffer = "";
707
+ for (;; ) {
708
+ const { done, value } = await reader.read();
709
+ if (done)
710
+ break;
711
+ buffer += decoder.decode(value, { stream: true });
712
+ let newline;
713
+ while ((newline = buffer.indexOf(`
714
+ `)) >= 0) {
715
+ processLine(buffer.slice(0, newline));
716
+ buffer = buffer.slice(newline + 1);
717
+ }
718
+ }
719
+ if (buffer)
720
+ processLine(buffer);
721
+ const code = await child.exited.finally(() => clearTimeout(timeout));
722
+ if (code === 0)
723
+ return;
724
+ return child.signalCode ? `was killed by ${child.signalCode}` : `exited with code ${code}`;
725
+ }
726
+ function warmIncomplete(failure, done, mode) {
727
+ console.warn(`pnext build: module warm-up ${failure} after warming ${done} file(s). ` + (mode === "full" ? "The function ships without the rest of its module cache and may fail to render those " + "routes at request time, where Vercel's filesystem is read-only." : "The production server compiles the rest on the first request that needs them."));
728
+ }
729
+ if (false) {}
730
+
731
+ // src/cli/build.ts
732
+ import { runWithCacheScope } from "../../../src/request/cache.ts";
733
+
734
+ // src/cli/build/cache.ts
735
+ import { createHash } from "crypto";
736
+ import { existsSync as existsSync3 } from "fs";
737
+ import { lstat, mkdir as mkdir2, readFile as readFile2, readdir as readdir2, readlink } from "fs/promises";
738
+ import path3 from "path";
739
+ var CACHE_VERSION = 2;
740
+ var CACHE_SEGMENTS = ["build"];
741
+ var SKIP_INPUT_DIRS = new Set([
742
+ ".claude",
743
+ ".git",
744
+ ".husky",
745
+ ".next",
746
+ ".pnext",
747
+ ".tmp",
748
+ ".turbo",
749
+ ".vercel",
750
+ ".vscode",
751
+ "node_modules"
752
+ ]);
753
+ var SKIP_INPUT_FILE = /(?:^\.DS_Store$|\.(?:log|pid)$)/i;
754
+ var LOCK_FILES = [
755
+ "bun.lock",
756
+ "bun.lockb",
757
+ "package-lock.json",
758
+ "npm-shrinkwrap.json",
759
+ "pnpm-lock.yaml",
760
+ "yarn.lock"
761
+ ];
762
+ async function lookupBuildCache(config, options) {
763
+ if (!cacheEnabled(options))
764
+ return { enabled: false };
765
+ const record = await readRecord(config.outPath);
766
+ const inputs = await inputRecords(config, record?.inputs);
767
+ const context = buildContext();
768
+ const key = buildKey(context, inputs);
769
+ if (record?.key !== key)
770
+ return { enabled: true, context, inputs, reason: "inputs" };
771
+ const output = await outputSnapshot(config.outPath);
772
+ if (output.hash !== record.outputHash) {
773
+ const changed = changedFiles(record.outputs, output.files).slice(0, 3).join(", ");
774
+ return { enabled: true, context, inputs, reason: `output (${changed || "unknown"})` };
775
+ }
776
+ try {
777
+ const manifest = resolveManifest(JSON.parse(await readFile2(buildManifestFile(config.outPath), "utf8")), config.outPath, config.root);
778
+ return { enabled: true, context, inputs, manifest, reason: "hit" };
779
+ } catch {
780
+ return { enabled: true, context, inputs, reason: "manifest" };
781
+ }
782
+ }
783
+ async function writeBuildCache(config, options, session) {
784
+ if (!session.enabled || !session.context || !cacheEnabled(options))
785
+ return;
786
+ const inputs = await inputRecords(config, session.inputs);
787
+ const output = await outputSnapshot(config.outPath);
788
+ const record = {
789
+ version: CACHE_VERSION,
790
+ key: buildKey(session.context, inputs),
791
+ inputs,
792
+ outputHash: output.hash,
793
+ outputs: output.files
794
+ };
795
+ await mkdir2(cacheDir(config.outPath), { recursive: true });
796
+ await writeFileAtomic(recordFile(config.outPath), JSON.stringify(record));
797
+ }
798
+ function cacheEnabled(options) {
799
+ if (process.env.PNEXT_BUILD_CACHE !== "1")
800
+ return false;
801
+ return options.adapter === undefined && options.debugBuildPaths === undefined && options.buildMode === undefined && options.debugPrerender !== true;
802
+ }
803
+ function cacheDir(outPath) {
804
+ return path3.join(outCachePath(outPath), ...CACHE_SEGMENTS);
805
+ }
806
+ function recordFile(outPath) {
807
+ return path3.join(cacheDir(outPath), "result.json");
808
+ }
809
+ async function readRecord(outPath) {
810
+ try {
811
+ const parsed = JSON.parse(await readFile2(recordFile(outPath), "utf8"));
812
+ if (parsed.version === CACHE_VERSION && parsed.key && parsed.inputs && parsed.outputHash && parsed.outputs) {
813
+ return parsed;
814
+ }
815
+ } catch {}
816
+ return;
817
+ }
818
+ function buildContext() {
819
+ const hash = createHash("sha256");
820
+ hash.update(`pnext-build-cache:${CACHE_VERSION}\x00`);
821
+ hash.update(frameworkFingerprint());
822
+ hash.update(`\x00bun:${Bun.version}\x00`);
823
+ for (const [name, value] of Object.entries(process.env).sort(([a], [b]) => a.localeCompare(b))) {
824
+ hash.update(`${name}=${value ?? ""}\x00`);
825
+ }
826
+ return hash.digest("hex");
827
+ }
828
+ function buildKey(context, inputs) {
829
+ const hash = createHash("sha256");
830
+ hash.update(context);
831
+ for (const [file, record] of Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b))) {
832
+ hash.update(`${file}\x00${record[2]}\x00`);
833
+ }
834
+ return hash.digest("hex");
835
+ }
836
+ async function inputRecords(config, previous) {
837
+ const files = new Map;
838
+ await collectTree(config.root, "root", files, config.outPath);
839
+ await collectModuleGraphInputs(config, files);
840
+ for (const [prefix, root] of [
841
+ ["root-deps", config.root],
842
+ ["workspace-deps", config.workspaceRoot]
843
+ ]) {
844
+ for (const name of LOCK_FILES)
845
+ addFile(files, `${prefix}:${name}`, path3.join(root, name));
846
+ addFile(files, `${prefix}:node_modules/.package-lock.json`, path3.join(root, "node_modules", ".package-lock.json"));
847
+ }
848
+ const frameworkRoot2 = path3.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/cli/build", "..", "..");
849
+ addFile(files, "framework:package.json", path3.join(frameworkRoot2, "package.json"));
850
+ for (const name of LOCK_FILES) {
851
+ addFile(files, `framework:${name}`, path3.join(frameworkRoot2, name));
852
+ addFile(files, `framework-workspace:${name}`, path3.join(frameworkRoot2, "..", name));
853
+ }
854
+ const entries = await Promise.all([...files].map(async ([key, file]) => {
855
+ const stats = await lstat(file).catch(() => {
856
+ return;
857
+ });
858
+ if (!stats?.isFile() && !stats?.isSymbolicLink())
859
+ return;
860
+ const old = previous?.[key];
861
+ if (old?.[0] === stats.mtimeMs && old[1] === stats.size)
862
+ return [key, old];
863
+ const contents = stats.isSymbolicLink() ? Buffer.from(`link:${await readlink(file)}`) : await readFile2(file);
864
+ return [key, [stats.mtimeMs, stats.size, contentHash(contents)]];
865
+ }));
866
+ return Object.fromEntries(entries.filter((entry) => Boolean(entry)));
867
+ }
868
+ async function collectModuleGraphInputs(config, files) {
869
+ let parsed;
870
+ try {
871
+ parsed = JSON.parse(await readFile2(path3.join(outCachePath(config.outPath), "server", "graph.json"), "utf8"));
872
+ } catch {
873
+ return;
874
+ }
875
+ const frameworkRoot2 = path3.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/cli/build", "..", "..");
876
+ for (const source of Object.keys(parsed.files ?? {})) {
877
+ const value = source.slice(2).split("/").join(path3.sep);
878
+ const file = source.startsWith("w:") ? path3.resolve(config.workspaceRoot, value) : source.startsWith("f:") ? path3.resolve(frameworkRoot2, value) : source.startsWith("a:") ? value : undefined;
879
+ if (file)
880
+ addFile(files, `module:${source}`, file);
881
+ }
882
+ }
883
+ async function collectTree(root, prefix, files, outPath, dir = root) {
884
+ const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
885
+ await Promise.all(entries.map(async (entry) => {
886
+ const file = path3.join(dir, entry.name);
887
+ if (file === outPath || file.startsWith(`${outPath}${path3.sep}`))
888
+ return;
889
+ if (entry.isDirectory()) {
890
+ if (!SKIP_INPUT_DIRS.has(entry.name))
891
+ await collectTree(root, prefix, files, outPath, file);
892
+ return;
893
+ }
894
+ if (!entry.isFile() && !entry.isSymbolicLink())
895
+ return;
896
+ const relative = path3.relative(root, file);
897
+ if (SKIP_INPUT_FILE.test(entry.name) || !relative.includes(path3.sep) && /\.html?$/i.test(entry.name)) {
898
+ return;
899
+ }
900
+ addFile(files, `${prefix}:${toPosix(relative)}`, file);
901
+ }));
902
+ }
903
+ function addFile(files, key, file) {
904
+ if (existsSync3(file))
905
+ files.set(key, file);
906
+ }
907
+ async function outputSnapshot(outPath) {
908
+ const files = new Map;
909
+ const entries = await readdir2(outPath, { withFileTypes: true }).catch(() => []);
910
+ await Promise.all(entries.map(async (entry) => {
911
+ if (entry.name === "cache" || entry.name === "dev")
912
+ return;
913
+ const file = path3.join(outPath, entry.name);
914
+ if (entry.isDirectory())
915
+ await collectOutputTree(outPath, file, files);
916
+ else if (entry.isFile() || entry.isSymbolicLink()) {
917
+ files.set(toPosix(entry.name), file);
918
+ }
919
+ }));
920
+ const hash = createHash("sha256");
921
+ const hashes = {};
922
+ for (const [name, file] of [...files].sort(([a], [b]) => a.localeCompare(b))) {
923
+ const stats = await lstat(file);
924
+ const contents = stats.isSymbolicLink() ? Buffer.from(`link:${await readlink(file)}`) : await readFile2(file);
925
+ const contentsHash = contentHash(contents);
926
+ hashes[name] = contentsHash;
927
+ hash.update(`${name}\x00${contentsHash}\x00`);
928
+ }
929
+ return { hash: hash.digest("hex"), files: hashes };
930
+ }
931
+ function changedFiles(before, after) {
932
+ return [...new Set([...Object.keys(before), ...Object.keys(after)])].filter((file) => before[file] !== after[file]);
933
+ }
934
+ async function collectOutputTree(root, dir, files) {
935
+ const entries = await readdir2(dir, { withFileTypes: true });
936
+ await Promise.all(entries.map(async (entry) => {
937
+ const file = path3.join(dir, entry.name);
938
+ if (entry.isDirectory())
939
+ await collectOutputTree(root, file, files);
940
+ else if (entry.isFile() || entry.isSymbolicLink()) {
941
+ files.set(toPosix(path3.relative(root, file)), file);
942
+ }
943
+ }));
944
+ }
945
+ function contentHash(contents) {
946
+ return createHash("sha256").update(contents).digest("hex");
947
+ }
948
+ function toPosix(file) {
949
+ return path3.sep === "/" ? file : file.split(path3.sep).join("/");
950
+ }
951
+
952
+ // src/cli/serve/standalone.ts
953
+ import { createHash as createHash2 } from "crypto";
954
+ import { constants as constants2, existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync2, realpathSync as realpathSync2, statSync } from "fs";
955
+ import { copyFile as copyFile2, mkdir as mkdir3, readFile as readFile3, rename as rename2, rm as rm2, writeFile } from "fs/promises";
956
+ import { builtinModules } from "module";
957
+ import path4 from "path";
958
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
959
+ var frameworkRoot2 = realpathSync2(path4.resolve(__PNEXT_PACKAGE_ROOT__ + "/src/cli/serve", "..", "..", ".."));
960
+ var frameworkPackage = JSON.parse(readFileSync2(path4.join(frameworkRoot2, "package.json"), "utf8"));
961
+ var runtimeDependencies = new Set(Object.keys(frameworkPackage.dependencies ?? {}));
962
+ var buildOnlyModule = /^(?:build|modules|loader|compile|esbuild|dev|run|typegen|analyze|create)$/;
963
+ var builtins = new Set(builtinModules);
964
+ var scriptFile = /\.(?:[cm]?[jt]sx?)$/;
965
+ function frameworkStartEntry() {
966
+ return readPrebundleStamp(frameworkRoot2, frameworkFingerprint()) ? path4.join(frameworkRoot2, "dist", "server", "cli", "start.js") : path4.join(frameworkRoot2, "src", "cli", "start.ts");
967
+ }
968
+ function startStandalone(config) {
969
+ const input = {
970
+ outPath: config.outPath,
971
+ root: config.root,
972
+ workspaceRoot: config.workspaceRoot
973
+ };
974
+ const modules = path4.join(config.workspaceRoot, "node_modules");
975
+ const cacheFile = existsSync4(modules) && path4.join(modules, ".cache", "pnext", `standalone-${frameworkTraceKey()}.json`);
976
+ if (cacheFile && existsSync4(cacheFile)) {
977
+ try {
978
+ return Promise.resolve(JSON.parse(readFileSync2(cacheFile, "utf8")));
979
+ } catch {}
980
+ }
981
+ const framework = new Promise((resolve, reject) => {
982
+ const worker = new Worker(new URL("./standalone-worker.ts", Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/serve/standalone.ts").href));
983
+ worker.unref?.();
984
+ worker.onmessage = (event) => {
985
+ resolve(event.data);
986
+ worker.terminate();
987
+ };
988
+ worker.onerror = (event) => {
989
+ reject(new Error(event.message));
990
+ worker.terminate();
991
+ };
992
+ worker.postMessage(input);
993
+ }).catch(() => traceFramework(input));
994
+ if (cacheFile)
995
+ framework.then(async (snapshot) => {
996
+ await mkdir3(path4.dirname(cacheFile), { recursive: true });
997
+ const temporary = `${cacheFile}.${process.pid}.tmp`;
998
+ await writeFile(temporary, JSON.stringify(snapshot));
999
+ await rename2(temporary, cacheFile);
1000
+ }).catch(() => {
1001
+ return;
1002
+ });
1003
+ return framework;
1004
+ }
1005
+ function frameworkTraceKey() {
1006
+ const startEntry = frameworkStartEntry();
1007
+ const packages = [...runtimeDependencies, ...frameworkRuntimeSpecifiers()].map((specifier) => {
1008
+ const file = resolveEdge(specifier, startEntry);
1009
+ return file ? `${file}\x00${statSync(file).mtimeMs}` : specifier;
1010
+ });
1011
+ return createHash2("sha256").update(JSON.stringify([frameworkFingerprint(), startEntry, packages])).digest("hex").slice(0, 16);
1012
+ }
1013
+ async function traceFramework(config) {
1014
+ const tracer = createTracer(config);
1015
+ const startEntry = frameworkStartEntry();
1016
+ await tracer.add([
1017
+ { file: startEntry, app: false },
1018
+ ...frameworkRuntimeSpecifiers().flatMap((specifier) => {
1019
+ const file = resolveEdge(specifier, startEntry);
1020
+ return file ? [{ file, app: false }] : [];
1021
+ })
1022
+ ]);
1023
+ return tracer.snapshot();
1024
+ }
1025
+ async function writeStandalone(config, framework = startStandalone(config)) {
1026
+ const outPath = config.outPath;
1027
+ const cache = cacheRoot2(outPath);
1028
+ const index = readBuildIndex(outPath);
1029
+ const manifestFile = buildManifestFile(outPath);
1030
+ const manifest = JSON.parse(await readFile3(manifestFile, "utf8"));
1031
+ const startEntry = frameworkStartEntry();
1032
+ const snapshot = await framework;
1033
+ const copier = createCopier(outPath);
1034
+ const rewrittenFramework = new Map(snapshot.rewritten);
1035
+ for (const [dest, source] of snapshot.files)
1036
+ copier.copy(dest, source, rewrittenFramework.get(dest));
1037
+ const tracer = createTracer(config, snapshot, (dest) => copier.copy(dest, tracer.trace.files.get(dest), tracer.trace.rewritten.get(dest)));
1038
+ const { trace, place } = tracer;
1039
+ await tracer.add([
1040
+ ...Object.values(index.modules),
1041
+ ...index.dependencies ?? [],
1042
+ index.nextConfig,
1043
+ index.instrumentation?.file,
1044
+ index.instrumentation?.edge,
1045
+ ...Object.values(index.compat?.cacheHandlers ?? {}),
1046
+ ...Object.values(index.fonts ?? {}).flatMap((font) => font.files),
1047
+ manifest.proxyModule,
1048
+ ...(manifest.actions ?? []).map((action) => action.modulePath)
1049
+ ].flatMap((artifact) => artifact ? [{ file: path4.resolve(outPath, artifact), app: true }] : []));
1050
+ addAppFiles(config, index, trace);
1051
+ tracer.flush();
1052
+ await copier.settle();
1053
+ const cachePrefix = `${toPosixPath(path4.relative(outPath, cache))}/`;
1054
+ const relocate = (value) => {
1055
+ if (typeof value === "string")
1056
+ return value.startsWith(cachePrefix) ? `server/${value.slice(cachePrefix.length)}` : value;
1057
+ if (Array.isArray(value))
1058
+ return value.map(relocate);
1059
+ if (value && typeof value === "object")
1060
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, relocate(item)]));
1061
+ return value;
1062
+ };
1063
+ const indexFile = buildIndexFile(outPath);
1064
+ await writeFile(indexFile, JSON.stringify(relocate(JSON.parse(await readFile3(indexFile, "utf8")))));
1065
+ const shippedManifest = relocate(JSON.parse(await readFile3(manifestFile, "utf8")));
1066
+ for (const route of shippedManifest.routes) {
1067
+ if (route.sourceFiles)
1068
+ route.sourceFiles = route.sourceFiles.filter((file) => !file.startsWith("../"));
1069
+ }
1070
+ await writeFile(manifestFile, `${JSON.stringify(shippedManifest, null, 2)}
1071
+ `);
1072
+ await writeFile(path4.join(outPath, "server", "entry.js"), `export * from ${JSON.stringify(relativeSpecifier("server", place(startEntry)))}
1073
+ `);
1074
+ await writeFile(path4.join(outPath, "package.json"), `{ "type": "module" }
1075
+ `);
1076
+ const origins = Object.fromEntries([...trace.files].filter(([dest]) => dest.startsWith("node_modules/")));
1077
+ const originsFile = standaloneOriginsFile(outPath);
1078
+ await mkdir3(path4.dirname(originsFile), { recursive: true });
1079
+ await writeFile(originsFile, JSON.stringify({ release: outPath, origins }));
1080
+ }
1081
+ function setFile(trace, dest, source) {
1082
+ if (!trace.files.has(dest))
1083
+ trace.fresh.push(dest);
1084
+ trace.files.set(dest, source);
1085
+ }
1086
+ function createTracer(config, from, onReady) {
1087
+ const outPath = config.outPath;
1088
+ const cache = cacheRoot2(outPath);
1089
+ const trace = {
1090
+ files: new Map(from?.files),
1091
+ fresh: [],
1092
+ rewritten: new Map(from?.rewritten)
1093
+ };
1094
+ const claims = new Map(from?.claims);
1095
+ const place = createPlacer(outPath, cache, claims);
1096
+ const standalones = new Set(from?.standalones);
1097
+ const shipped = (file) => installed(file) || isInside(frameworkRoot2, file) && !isInside(config.root, file);
1098
+ const seen = new Set(from?.seen);
1099
+ const reads = new Map;
1100
+ const prefetch = (file) => {
1101
+ if (scriptFile.test(file) && !reads.has(file))
1102
+ reads.set(file, readFile3(file, "utf8").catch(() => {
1103
+ return;
1104
+ }));
1105
+ };
1106
+ const queue = [];
1107
+ const enqueue = (file, app) => {
1108
+ if (seen.has(`${app}\x00${file}`))
1109
+ return;
1110
+ queue.push({ file, app });
1111
+ prefetch(file);
1112
+ };
1113
+ const flush = () => {
1114
+ for (const dest of trace.fresh.splice(0))
1115
+ onReady?.(dest);
1116
+ };
1117
+ const run = async (items) => {
1118
+ for (const item of items)
1119
+ enqueue(item.file, item.app);
1120
+ for (let item = queue.shift();item; item = queue.shift(), flush()) {
1121
+ const { file, app } = item;
1122
+ if (seen.has(`${app}\x00${file}`))
1123
+ continue;
1124
+ seen.add(`${app}\x00${file}`);
1125
+ const nested = enclosingStandalone(file, outPath);
1126
+ if (nested) {
1127
+ if (!standalones.has(nested)) {
1128
+ standalones.add(nested);
1129
+ addTree(nested, path4.posix.dirname(path4.posix.dirname(place(path4.join(nested, "server", "entry.js")))), trace);
1130
+ }
1131
+ continue;
1132
+ }
1133
+ const dest = place(file);
1134
+ setFile(trace, dest, file);
1135
+ if (!isInside(outPath, file) && !isInside(cache, file))
1136
+ addPackageFiles(file, trace, place);
1137
+ if (!scriptFile.test(file))
1138
+ continue;
1139
+ const release = isInside(outPath, file) || isInside(cache, file);
1140
+ const framework = !release && isInside(frameworkRoot2, file) && !installedIn(frameworkRoot2, file);
1141
+ prefetch(file);
1142
+ const source = await reads.get(file);
1143
+ if (source === undefined)
1144
+ continue;
1145
+ const edits = new Map;
1146
+ for (const edge of scanEdges(file, source)) {
1147
+ if (edge.url) {
1148
+ const target2 = urlTarget(edge.specifier, file);
1149
+ if (!target2)
1150
+ continue;
1151
+ const appFile = release && !isInside(outPath, target2) && !isInside(cache, target2) && !shipped(target2);
1152
+ if (appFile && scriptFile.test(target2))
1153
+ continue;
1154
+ if (!statSync(target2, { throwIfNoEntry: false })?.isFile())
1155
+ continue;
1156
+ const at = appFile ? toPosixPath(path4.join("server", "assets", path4.relative(config.workspaceRoot, target2))) : place(target2);
1157
+ if (appFile)
1158
+ setFile(trace, at, target2);
1159
+ else
1160
+ enqueue(target2, release);
1161
+ if (release) {
1162
+ const relative = relativeSpecifier(path4.dirname(dest), at);
1163
+ if (relative !== edge.specifier)
1164
+ edits.set(edge.specifier, relative);
1165
+ }
1166
+ continue;
1167
+ }
1168
+ const bare = isPackageSpecifier(edge.specifier);
1169
+ const name = bare ? packageName(edge.specifier) : undefined;
1170
+ if (bare && !name && !edge.specifier.startsWith("#"))
1171
+ continue;
1172
+ if (name && framework && !app && (edge.require || !runtimeDependencies.has(name)))
1173
+ continue;
1174
+ const target = resolveEdge(edge.specifier, file, edge.require);
1175
+ if (!target)
1176
+ continue;
1177
+ if (edge.dynamic && framework && buildOnlyModule.test(moduleName(target)))
1178
+ continue;
1179
+ enqueue(target, release);
1180
+ for (const counterpart of frameworkCounterparts(target))
1181
+ enqueue(counterpart, release);
1182
+ if (release || name && !place(target).startsWith(`node_modules/${name}/`)) {
1183
+ const relative = relativeSpecifier(path4.dirname(dest), place(target));
1184
+ if (relative !== edge.specifier)
1185
+ edits.set(edge.specifier, relative);
1186
+ }
1187
+ }
1188
+ if (edits.size > 0)
1189
+ trace.rewritten.set(dest, rewriteSpecifiers(file, source, edits));
1190
+ }
1191
+ flush();
1192
+ };
1193
+ const snapshot = () => ({
1194
+ files: [...trace.files],
1195
+ rewritten: [...trace.rewritten],
1196
+ seen: [...seen],
1197
+ claims: [...claims],
1198
+ standalones: [...standalones]
1199
+ });
1200
+ return { trace, place, add: run, snapshot, flush };
1201
+ }
1202
+ var prunedDirNames = [
1203
+ "node_modules",
1204
+ ".git",
1205
+ ".next",
1206
+ ".pnext",
1207
+ ".turbo",
1208
+ ".cache",
1209
+ ".vercel",
1210
+ ".tmp"
1211
+ ];
1212
+ var standaloneEntries = new Set(["server", "static", "node_modules", "package.json"]);
1213
+ function addAppFiles(config, index, trace) {
1214
+ const { keep = [], exclude = [] } = config.adapter ?? {};
1215
+ const named = (entries, name) => entries.some((entry) => name === entry || entry.startsWith(".") && name.endsWith(entry));
1216
+ for (const dest of trace.files.keys()) {
1217
+ const segments = dest.split("/");
1218
+ if (dest.startsWith("node_modules/") && segments.some((name) => named(exclude, name)))
1219
+ trace.files.delete(dest);
1220
+ }
1221
+ if (keep.length === 0)
1222
+ return;
1223
+ const compiled = compiledSources(config, index);
1224
+ const outTop = path4.relative(config.root, config.outRootPath).split(path4.sep)[0];
1225
+ const visit = (dir, kept) => {
1226
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
1227
+ const file = path4.join(dir, entry.name);
1228
+ if (entry.isDirectory()) {
1229
+ const pruned = prunedDirNames.includes(entry.name) && !named(keep, entry.name);
1230
+ if (pruned || dir === config.root && entry.name === outTop)
1231
+ continue;
1232
+ visit(file, kept || named(keep, entry.name));
1233
+ continue;
1234
+ }
1235
+ if (!entry.isFile() || compiled.has(file) && !named(keep, entry.name))
1236
+ continue;
1237
+ const env = entry.name.startsWith(".env");
1238
+ if (env ? !keep.includes(entry.name) : !kept && !named(keep, entry.name))
1239
+ continue;
1240
+ const relative = toPosixPath(path4.relative(config.root, file));
1241
+ if (!standaloneEntries.has(relative.split("/")[0]))
1242
+ setFile(trace, relative, file);
1243
+ }
1244
+ };
1245
+ visit(config.root, false);
1246
+ }
1247
+ function compiledSources(config, index) {
1248
+ flushDevModuleCaches();
1249
+ const graph = compiledSourceGraph(config.outPath, config.workspaceRoot);
1250
+ const queue = Object.keys(index.modules).map((key) => releaseSourceFile(key.slice(key.indexOf(":", key.indexOf(":") + 1) + 1), config.root, config.workspaceRoot));
1251
+ if (index.proxy)
1252
+ queue.push(path4.resolve(config.root, index.proxy.file));
1253
+ for (const name of readdirSync2(config.root))
1254
+ if (/^(?:pnext|next|instrumentation)\.config\.|^instrumentation\./.test(name) && scriptFile.test(name))
1255
+ queue.push(path4.join(config.root, name));
1256
+ const compiled = new Set;
1257
+ for (const file of queue) {
1258
+ if (compiled.has(file))
1259
+ continue;
1260
+ compiled.add(file);
1261
+ queue.push(...graph.get(file) ?? []);
1262
+ }
1263
+ for (const css of index.globalCss)
1264
+ compiled.add(path4.resolve(config.root, css));
1265
+ return compiled;
1266
+ }
1267
+ function createPlacer(outPath, cache, claims = new Map) {
1268
+ const packageDir = (root, name) => {
1269
+ const owner = claims.get(name);
1270
+ if (owner === undefined)
1271
+ claims.set(name, root);
1272
+ if (owner === undefined || owner === root)
1273
+ return `node_modules/${name}`;
1274
+ const key = createHash2("sha256").update(root).digest("hex").slice(0, 12);
1275
+ return `node_modules/.pnext/${key}/node_modules/${name}`;
1276
+ };
1277
+ return (file) => {
1278
+ if (isInside(cache, file))
1279
+ return toPosixPath(path4.join("server", path4.relative(cache, file)));
1280
+ if (isInside(outPath, file))
1281
+ return toPosixPath(path4.relative(outPath, file));
1282
+ const framework = !installed(frameworkRoot2) && isInside(frameworkRoot2, file) && !installedIn(frameworkRoot2, file);
1283
+ if (framework) {
1284
+ const dir = packageDir(frameworkRoot2, frameworkPackage.name);
1285
+ return `${dir}/${toPosixPath(path4.relative(frameworkRoot2, file))}`;
1286
+ }
1287
+ const posix = toPosixPath(file);
1288
+ const at = posix.lastIndexOf("/node_modules/");
1289
+ if (at !== -1) {
1290
+ const rest = posix.slice(at + "/node_modules/".length).split("/");
1291
+ const length = rest[0].startsWith("@") ? 2 : 1;
1292
+ const name2 = rest.slice(0, length).join("/");
1293
+ const root2 = `${posix.slice(0, at)}/node_modules/${name2}`;
1294
+ return [packageDir(root2, name2), ...rest.slice(length)].join("/");
1295
+ }
1296
+ const root = packageRoot(path4.dirname(file));
1297
+ const name = root && readPackageName(root);
1298
+ if (!root || !name)
1299
+ throw new Error(`pnext build: cannot place ${file} in the standalone output`);
1300
+ return `${packageDir(root, name)}/${toPosixPath(path4.relative(root, file))}`;
1301
+ };
1302
+ }
1303
+ var standaloneDirs = new Map;
1304
+ function enclosingStandalone(file, outPath) {
1305
+ const dir = path4.dirname(file);
1306
+ if (dir === path4.dirname(dir))
1307
+ return;
1308
+ if (standaloneDirs.has(dir))
1309
+ return standaloneDirs.get(dir);
1310
+ const own = dir !== outPath && existsSync4(path4.join(dir, "server", "build-index.json")) && existsSync4(path4.join(dir, "server", "entry.js"));
1311
+ const found = own ? dir : enclosingStandalone(dir, outPath);
1312
+ standaloneDirs.set(dir, found);
1313
+ return found;
1314
+ }
1315
+ function addTree(root, dest, trace) {
1316
+ const visit = (dir, seen) => {
1317
+ const real = realpathSync2(dir);
1318
+ if (seen.has(real))
1319
+ return;
1320
+ seen.add(real);
1321
+ for (const name of readdirSync2(dir)) {
1322
+ const file = path4.join(dir, name);
1323
+ const stat = statSync(file, { throwIfNoEntry: false });
1324
+ if (stat?.isDirectory())
1325
+ visit(file, seen);
1326
+ else if (stat?.isFile())
1327
+ setFile(trace, `${dest}/${toPosixPath(path4.relative(root, file))}`, realpathSync2(file));
1328
+ }
1329
+ };
1330
+ visit(root, new Set);
1331
+ }
1332
+ function installed(file) {
1333
+ return toPosixPath(file).includes("/node_modules/");
1334
+ }
1335
+ function installedIn(root, file) {
1336
+ return path4.relative(root, file).split(path4.sep).includes("node_modules");
1337
+ }
1338
+ var transpilers = new Map;
1339
+ function scanEdges(file, source) {
1340
+ const ext = path4.extname(file);
1341
+ const loader = ext === ".tsx" || ext === ".jsx" ? "tsx" : /\.[cm]?ts$/.test(ext) ? "ts" : "js";
1342
+ let transpiler = transpilers.get(loader);
1343
+ if (!transpiler) {
1344
+ transpiler = new Bun.Transpiler({
1345
+ loader,
1346
+ tsconfig: { compilerOptions: { jsx: "react-jsx", jsxImportSource: "preact" } }
1347
+ });
1348
+ transpilers.set(loader, transpiler);
1349
+ }
1350
+ let imports;
1351
+ try {
1352
+ imports = transpiler.scanImports(source);
1353
+ } catch {
1354
+ return [];
1355
+ }
1356
+ const edges = imports.map((entry) => ({
1357
+ specifier: entry.path,
1358
+ dynamic: entry.kind === "dynamic-import",
1359
+ require: entry.kind === "require-call"
1360
+ }));
1361
+ const refs = importMetaRefs(file, source);
1362
+ for (const url of refs.urls)
1363
+ edges.push({ specifier: url.specifier, dynamic: false, url: true });
1364
+ for (const ref of refs.resolves)
1365
+ edges.push({ specifier: ref.specifier, dynamic: false });
1366
+ if (loader === "tsx")
1367
+ edges.push({ specifier: "preact/jsx-runtime", dynamic: false }, { specifier: "preact/jsx-dev-runtime", dynamic: false });
1368
+ return edges;
1369
+ }
1370
+ var resolved = new Map;
1371
+ function resolveEdge(specifier, from, require2 = false) {
1372
+ if (/^(?:node:|bun:|data:|https?:)/.test(specifier) || specifier === "bun")
1373
+ return;
1374
+ const bare = require2 ? specifier : splitResourceQuery(specifier).path;
1375
+ if (builtins.has(bare))
1376
+ return;
1377
+ const dir = path4.dirname(from);
1378
+ const key = `${dir}\x00${bare}`;
1379
+ if (resolved.has(key))
1380
+ return resolved.get(key);
1381
+ let target;
1382
+ try {
1383
+ const request = bare.startsWith("file:") ? fileURLToPath2(bare) : bare;
1384
+ target = realpathSync2(Bun.resolveSync(request, dir));
1385
+ if (!statSync(target).isFile())
1386
+ target = undefined;
1387
+ } catch {
1388
+ target = undefined;
1389
+ }
1390
+ resolved.set(key, target);
1391
+ return target;
1392
+ }
1393
+ function frameworkCounterparts(file) {
1394
+ const counterpart = prebundledFile(file);
1395
+ if (counterpart === file)
1396
+ return [];
1397
+ return [counterpart, path4.join(frameworkRoot2, PREBUNDLE_STAMP)];
1398
+ }
1399
+ function moduleName(file) {
1400
+ const base = path4.basename(file, path4.extname(file));
1401
+ const chunk = path4.basename(path4.dirname(file)) === "_chunks";
1402
+ return chunk && isInside(path4.join(frameworkRoot2, "dist"), file) ? base.replace(/-[a-z0-9]{8}$/, "") : base;
1403
+ }
1404
+ function packageName(specifier) {
1405
+ if (specifier.startsWith("#"))
1406
+ return;
1407
+ const parts = specifier.split("/");
1408
+ const name = specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
1409
+ return name && !builtins.has(name) ? name : undefined;
1410
+ }
1411
+ function addPackageFiles(file, trace, place) {
1412
+ const inStore = installed(file);
1413
+ for (let dir = path4.dirname(file);dir !== path4.dirname(dir); dir = path4.dirname(dir)) {
1414
+ const manifest = path4.join(dir, "package.json");
1415
+ const found = existsSync4(manifest);
1416
+ if (found)
1417
+ setFile(trace, place(manifest), manifest);
1418
+ if (found && dir === frameworkRoot2) {
1419
+ for (const name of ["tsconfig.json", path4.join("config", "ts", "react.json")]) {
1420
+ const extra = path4.join(dir, name);
1421
+ if (existsSync4(extra))
1422
+ setFile(trace, place(extra), extra);
1423
+ }
1424
+ }
1425
+ const parent = path4.basename(path4.dirname(dir));
1426
+ const packageTop = parent === "node_modules" || parent.startsWith("@") && path4.basename(path4.dirname(path4.dirname(dir))) === "node_modules";
1427
+ if (inStore ? packageTop : found && readPackageName(dir))
1428
+ return;
1429
+ }
1430
+ }
1431
+ function packageRoot(dir) {
1432
+ for (;dir !== path4.dirname(dir); dir = path4.dirname(dir)) {
1433
+ if (existsSync4(path4.join(dir, "package.json")))
1434
+ return dir;
1435
+ }
1436
+ return;
1437
+ }
1438
+ function readPackageName(dir) {
1439
+ try {
1440
+ return JSON.parse(readFileSync2(path4.join(dir, "package.json"), "utf8")).name;
1441
+ } catch {
1442
+ return;
1443
+ }
1444
+ }
1445
+ function relativeSpecifier(fromDir, to) {
1446
+ const relative = toPosixPath(path4.relative(fromDir, to));
1447
+ return relative.startsWith(".") ? relative : `./${relative}`;
1448
+ }
1449
+ function rewriteSpecifiers(file, source, edits) {
1450
+ const refs = importMetaRefs(file, source);
1451
+ const spans = [...moduleSpecifierEdges(source, file), ...refs.urls, ...refs.resolves];
1452
+ const changes = spans.flatMap((span) => {
1453
+ const value = edits.get(span.specifier);
1454
+ return value === undefined ? [] : [{ start: span.start, end: span.end, value: JSON.stringify(value) }];
1455
+ });
1456
+ changes.sort((a, b) => a.start - b.start);
1457
+ return changes.length > 0 ? spliceSource(source, changes) : source;
1458
+ }
1459
+ function urlTarget(specifier, from) {
1460
+ try {
1461
+ const url = new URL(specifier, pathToFileURL(from));
1462
+ return url.protocol === "file:" ? fileURLToPath2(url) : undefined;
1463
+ } catch {
1464
+ return;
1465
+ }
1466
+ }
1467
+ function isPackageSpecifier(specifier) {
1468
+ if (specifier === "." || specifier === "..")
1469
+ return false;
1470
+ if (specifier.startsWith("./") || specifier.startsWith("../"))
1471
+ return false;
1472
+ return !path4.isAbsolute(specifier) && !specifier.startsWith("file:");
1473
+ }
1474
+ function createCopier(outPath) {
1475
+ const dirs = new Map;
1476
+ const copied = new Set;
1477
+ const pending = [];
1478
+ const ensureDir = (dir) => {
1479
+ let made = dirs.get(dir);
1480
+ if (!made) {
1481
+ made = mkdir3(dir, { recursive: true });
1482
+ dirs.set(dir, made);
1483
+ }
1484
+ return made;
1485
+ };
1486
+ const copy = (dest, source, contents) => {
1487
+ if (copied.has(dest))
1488
+ return;
1489
+ copied.add(dest);
1490
+ const target = path4.join(outPath, dest);
1491
+ pending.push(ensureDir(path4.dirname(target)).then(async () => {
1492
+ if (contents !== undefined) {
1493
+ if (target !== source)
1494
+ await rm2(target, { force: true });
1495
+ return writeFile(target, contents);
1496
+ }
1497
+ if (target !== source)
1498
+ await copyFile2(source, target, constants2.COPYFILE_FICLONE);
1499
+ }));
1500
+ };
1501
+ return { copy, settle: () => Promise.all(pending) };
1502
+ }
1503
+ function isInside(root, file) {
1504
+ return file === root || file.startsWith(`${root}${path4.sep}`);
1505
+ }
1506
+
1507
+ // src/cli/build.ts
1508
+ function nextCompatEnabled2(config) {
1509
+ return getCompatModeExtensions().nextEnabled(config);
1510
+ }
1511
+ function reactCompatEnabled(config) {
1512
+ return getCompatModeExtensions().reactEnabled(config);
1513
+ }
1514
+ function buildCompat() {
1515
+ return getBuildExtensions().compat;
1516
+ }
1517
+ async function buildProject(root, options = {}) {
1518
+ clearBuildParallelPhases();
1519
+ resetModuleGraphFailure();
1520
+ beginSourceScope();
1521
+ const restoreSpecifiersManifest = setEmitCompiledSpecifiersManifest(options.adapter === "vercel");
1522
+ const restoreReleaseCompile = setReleaseCompile(true);
1523
+ const lifecycle = {};
1524
+ try {
1525
+ return await runBuild(root, options, lifecycle);
1526
+ } catch (error) {
1527
+ const phaseError = buildParallelPhaseError();
1528
+ throw phaseError ?? error;
1529
+ } finally {
1530
+ lifecycle.warm?.kill();
1531
+ endSourceScope();
1532
+ restoreSpecifiersManifest();
1533
+ restoreReleaseCompile();
1534
+ flushDevModuleCaches();
1535
+ }
1536
+ }
1537
+ async function runBuild(root, options, lifecycle) {
1538
+ const verbose = options.verbose ?? false;
1539
+ const log = createVerboseLogger(verbose, "build");
1540
+ const startedAt = performance.now();
1541
+ console.log(`\u26A1 ${bold("pnext")} ${dim(`\u2014 Creating an optimized production build ...
1542
+ `)}`);
1543
+ const config = await loadConfig(root);
1544
+ const buildCache = lookupBuildCache(config, options);
1545
+ await bootstrapCompat(config);
1546
+ log.log(`config loaded \u2014 out ${path5.relative(config.root, config.outPath) || "."}`);
1547
+ runInitHooks(config, { build: true });
1548
+ const cached = await buildCache;
1549
+ log.log(`build cache ${cached.reason ?? "disabled"}`);
1550
+ if (cached.manifest) {
1551
+ printBuildSummary(config, cached.manifest.routes, cached.manifest.staticFiles ?? {}, performance.now() - startedAt, Boolean(cached.manifest.proxyModule));
1552
+ return cached.manifest;
1553
+ }
1554
+ warmCssPipeline(config);
1555
+ const warmMode = options.adapter === "vercel" ? "full" : "compile";
1556
+ const warm = startWarmChild(config, warmMode);
1557
+ lifecycle.warm = warm;
1558
+ const standalone = startStandalone(config);
1559
+ const publicFiles = await log.step("prepare output directory", async () => {
1560
+ await ensureEmptyDir(config.outRootPath, [devOutSegment, "pnext-pages-compat"]);
1561
+ return copyPublicDir(config.publicPath, path5.join(config.outPath, "static"));
1562
+ });
1563
+ const documentCss = Promise.resolve().then(() => buildGlobalCss(config, { verbose })).then(() => buildNotFoundCss(config, { verbose }));
1564
+ documentCss.catch(() => {
1565
+ return;
1566
+ });
1567
+ const partytownLib = log.step("partytown lib", () => copyPartytownLib(config));
1568
+ partytownLib.catch(() => {
1569
+ return;
1570
+ });
1571
+ let routes = await log.step("scan routes", () => scanRoutes(config.appPath, config.workspaceRoot));
1572
+ log.log(`found ${routes.length} route${routes.length === 1 ? "" : "s"}`);
1573
+ if (options.debugBuildPaths) {
1574
+ routes = filterDebugBuildRoutes(config.root, routes, options.debugBuildPaths);
1575
+ log.log(`--debug-build-paths ${options.debugBuildPaths} \u2014 ${routes.length} route${routes.length === 1 ? "" : "s"} kept`);
1576
+ }
1577
+ warm.prewarm(routes.filter((route) => route.kind === "page").map((route) => route.file));
1578
+ const buildState = { actions: [] };
1579
+ const stepContext = { config, routes, manifest: buildState, log };
1580
+ const { steps } = getBuildExtensions();
1581
+ const earlySteps = runBuildSteps(steps.filter((step) => step.early), stepContext);
1582
+ earlySteps.catch(() => {
1583
+ return;
1584
+ });
1585
+ const clientSources = startClientSources(config);
1586
+ await log.step("scan route facts", async () => materializeRouteFacts(routes, (route) => clientSources.warmRoutes([route])));
1587
+ assertNoServerActionsWithoutCompat(routes, nextCompatEnabled2(config), config.root);
1588
+ setRequestRuntime({ config, routes, dev: false });
1589
+ prepareRouteCssChunks(routes);
1590
+ const routeStylesheets = buildRouteStylesheets(config, routes.filter((route) => route.kind !== "handler" && !route.dynamicErrorApi), documentCss, { verbose });
1591
+ const flatExportLayout = nextCompatEnabled2(config) && buildCompat().nextOutputExport() && config.trailingSlash !== true;
1592
+ const proxyBuild = log.step("proxy module", () => buildProxyModule(config));
1593
+ proxyBuild.catch(() => {
1594
+ return;
1595
+ });
1596
+ await runBuildSteps(steps.filter((step) => !step.early && step.gate), stepContext);
1597
+ const staticFiles = {};
1598
+ const staticMetadata = (async () => {
1599
+ const files = await log.step("discover static metadata files", () => Promise.resolve(discoverStaticMetadataFiles(config.appPath)));
1600
+ await log.step("static metadata files", () => copyStaticMetadataFiles(config, staticFiles, files));
1601
+ return files;
1602
+ })();
1603
+ staticMetadata.catch(() => {
1604
+ return;
1605
+ });
1606
+ await earlySteps;
1607
+ const deferredSteps = buildState.deferred ?? Promise.resolve();
1608
+ deferredSteps.catch(() => {
1609
+ return;
1610
+ });
1611
+ const staticMetadataFiles = await staticMetadata;
1612
+ const metadataWarnings = nextCompatEnabled2(config) ? log.step("next metadata warnings", () => buildCompat().warnMetadataIssues({
1613
+ appPath: config.appPath,
1614
+ routes,
1615
+ staticMetadataFiles
1616
+ })) : undefined;
1617
+ metadataWarnings?.catch(() => {
1618
+ return;
1619
+ });
1620
+ const moduleMetadata = log.step("core module metadata", () => collectStaticModuleMetadata(config, routes));
1621
+ moduleMetadata.catch(() => {
1622
+ return;
1623
+ });
1624
+ const actionSources = buildState.actionSources ?? buildState.actions.map((a) => a.sourceKey);
1625
+ const actionFiles = new Set(actionSources.map((source) => realFilePath(path5.resolve(config.root, source))));
1626
+ const actionImporters = new Set((buildState.actionImporters ?? []).map(realFilePath));
1627
+ const realFiles = new Map;
1628
+ const reachesAction = (file) => {
1629
+ let real = realFiles.get(file);
1630
+ if (real === undefined)
1631
+ realFiles.set(file, real = realFilePath(file));
1632
+ return actionFiles.has(real) || actionImporters.has(real);
1633
+ };
1634
+ for (const route of routes) {
1635
+ if (route.kind === "page" && (actionFiles.size > 0 || actionImporters.size > 0) && route.sourceFiles.some(reachesAction)) {
1636
+ addClientEntryReason(route, "actions");
1637
+ }
1638
+ }
1639
+ const clientRoutes = routes.filter((route) => route.kind !== "handler" && (route.client || route.clientReferences.length > 0 || route.needsRouterEntry));
1640
+ for (const route of clientRoutes)
1641
+ route.clientEntry = `assets/${clientEntryName(route)}.js`;
1642
+ const clientBundles = log.step(`client bundles (${clientRoutes.length} route${clientRoutes.length === 1 ? "" : "s"})`, () => buildClientEntries({
1643
+ config,
1644
+ routes: clientRoutes,
1645
+ outDir: path5.join(config.outPath, "static", "assets"),
1646
+ verbose,
1647
+ hasServerActions: actionSources.length > 0,
1648
+ pipeline: clientSources
1649
+ }));
1650
+ clientBundles.catch(() => {
1651
+ return;
1652
+ });
1653
+ const notFoundDocuments = clientBundles.then(async () => renderNotFoundDocuments({
1654
+ config,
1655
+ log,
1656
+ skip: options.buildMode === "compile",
1657
+ documentCss,
1658
+ staticMetadataFiles,
1659
+ staticModuleMetadata: await moduleMetadata
1660
+ }));
1661
+ notFoundDocuments.catch(() => {
1662
+ return;
1663
+ });
1664
+ const remainingSteps = runBuildSteps(steps.filter((step) => !step.early && !step.gate), stepContext).then(() => log.step("typegen", () => writeTypegen(config, routes)));
1665
+ remainingSteps.catch(() => {
1666
+ return;
1667
+ });
1668
+ await remainingSteps;
1669
+ const staticModuleMetadata = await moduleMetadata;
1670
+ await clientBundles;
1671
+ const proxyModule = await proxyBuild;
1672
+ await partytownLib;
1673
+ await emitStaticClientChunks(config, path5.join(config.outPath, "static", "assets"));
1674
+ if (verbose) {
1675
+ const sources = sourceCacheStats();
1676
+ log.log(`source cache \u2014 ${sources.reads} reads, ${sources.hits} shared, ${sources.files} files \xB7 parses ${JSON.stringify(scanFactsStats())}`);
1677
+ }
1678
+ await metadataWarnings;
1679
+ let hadAfterPrerenderError = false;
1680
+ let hadDynamicErrorFailure = false;
1681
+ const descendantHandlerIds = collectDescendantHandlerIds(routes);
1682
+ const isCompile = options.buildMode === "compile";
1683
+ const isGenerate = options.buildMode === "generate";
1684
+ const debugPrerender = options.debugPrerender ?? false;
1685
+ buildCompat().recordBuildFlags(config.outPath, debugPrerender);
1686
+ const generateRouteLines = [];
1687
+ const partialPrerenders = new Set;
1688
+ const generateFailures = [];
1689
+ if (isGenerate)
1690
+ console.log(" Collecting page data ...");
1691
+ await documentCss;
1692
+ for (const route of routes) {
1693
+ if (route.dynamicErrorApi) {
1694
+ console.error(`Error: Route ${toNextRoutePattern(route.route || "/")} with \`dynamic = "error"\` ` + `couldn't be rendered statically because it used ${route.dynamicErrorApi}. ` + `See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`);
1695
+ hadDynamicErrorFailure = true;
1696
+ continue;
1697
+ }
1698
+ if (route.kind === "handler") {
1699
+ if (isCompile)
1700
+ continue;
1701
+ if (!await staticRouteHandlerCandidate(route))
1702
+ continue;
1703
+ const dynamicUsage = await staticHandlerDynamicUsage(route);
1704
+ if (dynamicUsage) {
1705
+ console.log(`Caught Error: Dynamic server usage: Route ${route.route || "/"} couldn't be rendered statically because it used \`${dynamicUsage}\`.`);
1706
+ continue;
1707
+ }
1708
+ try {
1709
+ Object.assign(staticFiles, await log.step(`route handler ${route.route}`, () => buildStaticRouteHandler(config, route, {
1710
+ skipPhysicalWrite: descendantHandlerIds.has(route.id)
1711
+ })));
1712
+ } catch (error) {
1713
+ rethrowIfProgrammingError(error);
1714
+ if (isAfterPrerenderError(error))
1715
+ hadAfterPrerenderError = true;
1716
+ warnSkippedStatic(route.route, error instanceof Error ? error.message : String(error));
1717
+ }
1718
+ continue;
1719
+ }
1720
+ await routeStylesheets.get(route)?.();
1721
+ if (isCompile)
1722
+ continue;
1723
+ if (isGenerate && cacheComponents() && !route.client && !route.interception) {
1724
+ const diagnosticRoute = toNextRoutePattern(route.route || "/");
1725
+ const diagnostic = buildCompat().diagnoseCacheComponentsPrerender({
1726
+ route: diagnosticRoute,
1727
+ pageFile: route.file,
1728
+ appPath: config.appPath,
1729
+ debugPrerender
1730
+ });
1731
+ if (diagnostic) {
1732
+ console.error(diagnostic);
1733
+ generateFailures.push({
1734
+ route: diagnosticRoute,
1735
+ omitErrorLine: buildCompat().diagnosticLeadsWithErrorLine(diagnostic)
1736
+ });
1737
+ continue;
1738
+ }
1739
+ }
1740
+ if (route.ppr) {
1741
+ await log.step(`ppr shell ${route.route}`, () => buildPprShell(config, route));
1742
+ continue;
1743
+ }
1744
+ if (cacheComponents() && !route.interception && (!route.client || route.params.length === 0 && !route.catchAll)) {
1745
+ const built = await log.step(`cache-components shell ${route.route}`, () => buildCacheComponentsShell(config, route));
1746
+ if (built) {
1747
+ const paramFallback = (route.params.length > 0 || Boolean(route.catchAll)) && !route.hasStaticParams;
1748
+ if (paramFallback || (route.pprHoles?.length ?? 0) > 0 || route.pprMetadata) {
1749
+ partialPrerenders.add(route.id);
1750
+ }
1751
+ if (isGenerate)
1752
+ generateRouteLines.push(` \u25D0 ${route.route || "/"}`);
1753
+ continue;
1754
+ }
1755
+ }
1756
+ if (cacheComponents() && route.client && (route.params.length > 0 || route.catchAll))
1757
+ continue;
1758
+ const segmentConfig = route.segmentConfig;
1759
+ const forceStatic = segmentConfig?.dynamic === "force-static";
1760
+ if (forceStatic && segmentConfig?.runtime === "edge") {
1761
+ console.warn(`Page "${route.route}" is using runtime = 'edge' which is currently incompatible with dynamic = 'force-static'. Please remove either "runtime" or "force-static" for correct behavior`);
1762
+ }
1763
+ const configForcesDynamic = segmentConfig?.dynamic === "force-dynamic" || segmentConfig?.revalidate === 0 || segmentConfig?.fetchCache === "force-no-store" || segmentConfig?.runtime === "edge" && !forceStatic;
1764
+ let staticParams = null;
1765
+ if (!configForcesDynamic && route.hasStaticParams) {
1766
+ try {
1767
+ staticParams = await log.step(`static params ${route.route}`, () => getRenderExtensions().collectRenderMeta(() => staticParamsFor(config, route), {
1768
+ route: route.route,
1769
+ prerender: true
1770
+ }).then((result) => result.value));
1771
+ } catch (error) {
1772
+ rethrowIfProgrammingError(error);
1773
+ if (!isAfterPrerenderError(error))
1774
+ throw error;
1775
+ console.error(`Failed to collect page data for ${toNextRoutePattern(route.route)}`);
1776
+ console.error(error instanceof Error ? error.stack ?? error.message : String(error));
1777
+ hadAfterPrerenderError = true;
1778
+ continue;
1779
+ }
1780
+ }
1781
+ const validateUnstableCacheScope = !configForcesDynamic && route.usesRequest && !forceStatic && await usesUnstableCache(route);
1782
+ const paramSets = staticParams ? staticParams.paths : validateUnstableCacheScope ? [{}] : configForcesDynamic || route.usesRequest && !forceStatic ? [] : route.mode === "static" && route.params.length === 0 && !route.catchAll ? [{}] : [];
1783
+ if (staticParams)
1784
+ route.prerenderedParams = staticParams.allSets;
1785
+ if (process.env.NEXT_DEBUG_BUILD && paramSets.length === 0 && !staticParams && !configForcesDynamic && route.usesRequest && !forceStatic && route.params.length === 0 && !route.catchAll) {
1786
+ logStaticBailout(route.route || "/", await requestApiBailoutReason(route));
1787
+ }
1788
+ if (paramSets.length === 0) {
1789
+ if (!configForcesDynamic && !forceStatic && route.usesRequest && route.params.length === 0 && !route.catchAll && await schedulesDeferredWork(route)) {
1790
+ await probeDeferredDynamicUsage(config, route, staticMetadataFiles, staticModuleMetadata);
1791
+ }
1792
+ continue;
1793
+ }
1794
+ if (!forceStatic && await needsRequestOriginForMetadataImages(config.appPath, route))
1795
+ continue;
1796
+ await log.step(`prerender ${route.route} (${paramSets.length} page${paramSets.length === 1 ? "" : "s"})`, async () => {
1797
+ for (const rawParams of paramSets) {
1798
+ const params = encodeStaticRouteParams(rawParams);
1799
+ const routePath = fillRoutePath(route.route, rawParams);
1800
+ const file = staticHtmlPath(config.outPath, routePath, flatExportLayout);
1801
+ const collision = staticOutputCollision(config.outPath, file);
1802
+ if (collision) {
1803
+ warnSkippedStatic(routePath, collision);
1804
+ continue;
1805
+ }
1806
+ const url = new URL(`http://pnext.local${routePath}`);
1807
+ try {
1808
+ let cacheLife;
1809
+ let fontLinkHeader;
1810
+ let prerenderVary;
1811
+ const rendered = await runWithWorkUnit("render", async () => {
1812
+ const tracked = await buildCompat().withVaryParamsTracking(() => getRenderExtensions().collectRenderMeta(() => runWithNextBuildPhase(() => withRouteRuntime(route.segmentConfig?.runtime, () => renderPageWithStatus({
1813
+ config,
1814
+ route,
1815
+ params,
1816
+ url,
1817
+ ...route.usesRequest ? { request: new Request(url) } : {},
1818
+ staticMetadataFiles,
1819
+ staticModuleMetadata
1820
+ }))), {
1821
+ fetchCache: segmentConfig?.fetchCache,
1822
+ route: routePath || "/",
1823
+ prerender: true
1824
+ }));
1825
+ const result = tracked.value;
1826
+ prerenderVary = tracked.vary;
1827
+ cacheLife = buildCompat().takeCacheLifeStash();
1828
+ fontLinkHeader = buildCompat().takeFontLinkHeader();
1829
+ return result;
1830
+ });
1831
+ const optedStatic = forceStatic || typeof segmentConfig?.revalidate === "number" || segmentConfig?.revalidate === false;
1832
+ if (rendered.noStore && !optedStatic) {
1833
+ if (process.env.NEXT_DEBUG_BUILD)
1834
+ logStaticBailout(routePath || "/", "no-store fetch");
1835
+ continue;
1836
+ }
1837
+ await writeText(file, rendered.value.html);
1838
+ recordPrerenderVary(route, routePath || "/", prerenderVary);
1839
+ const routeLine = `${dim(" \u25CB")} ${routePath || "/"}`;
1840
+ if (isGenerate)
1841
+ generateRouteLines.push(routeLine);
1842
+ else
1843
+ console.log(routeLine);
1844
+ await emitConcreteNextPageArtifacts(config, route, routePath || "/", {
1845
+ html: rendered.value.html,
1846
+ status: rendered.value.status
1847
+ });
1848
+ const relative = toPosixPath(path5.relative(path5.join(config.outPath, "static"), file));
1849
+ const revalidateSeconds = combineRevalidate(segmentConfig?.revalidate, rendered.revalidateSeconds);
1850
+ const defaultExpireTime = buildCompat().defaultExpireTimeSeconds();
1851
+ const effectiveCacheLife = cacheLife ?? (rendered.expireSeconds !== undefined || rendered.staleSeconds !== undefined ? {
1852
+ ...revalidateSeconds !== undefined ? { revalidateSeconds } : {},
1853
+ ...rendered.expireSeconds !== undefined ? { expireSeconds: rendered.expireSeconds } : {},
1854
+ ...rendered.staleSeconds !== undefined ? { staleSeconds: rendered.staleSeconds } : {}
1855
+ } : revalidateSeconds !== undefined && defaultExpireTime !== undefined ? {
1856
+ revalidateSeconds,
1857
+ expireSeconds: defaultExpireTime
1858
+ } : undefined);
1859
+ const cacheLifeHeaders = cacheLifeResponseHeaders(effectiveCacheLife);
1860
+ const headers = [
1861
+ ...rendered.value.location ? [["location", rendered.value.location]] : [],
1862
+ ...fontLinkHeader ? [["link", fontLinkHeader]] : [],
1863
+ ...cacheLifeHeaders
1864
+ ];
1865
+ staticFiles[relative] = {
1866
+ status: rendered.value.status,
1867
+ headers,
1868
+ routeId: route.id,
1869
+ kind: "page",
1870
+ ...revalidateSeconds !== undefined ? { revalidateSeconds } : {},
1871
+ ...effectiveCacheLife?.expireSeconds !== undefined ? { expireSeconds: effectiveCacheLife.expireSeconds } : {},
1872
+ ...effectiveCacheLife?.staleSeconds !== undefined ? { staleSeconds: effectiveCacheLife.staleSeconds } : {},
1873
+ ...rendered.tags.length > 0 ? { tags: rendered.tags } : {}
1874
+ };
1875
+ } catch (error) {
1876
+ rethrowIfProgrammingError(error);
1877
+ if (isAfterPrerenderError(error))
1878
+ hadAfterPrerenderError = true;
1879
+ warnSkippedStatic(routePath, error instanceof Error ? error.message : String(error));
1880
+ }
1881
+ }
1882
+ });
1883
+ }
1884
+ if (isGenerate && generateFailures.length > 0) {
1885
+ for (const failed of generateFailures) {
1886
+ console.error(buildCompat().prerenderFailureFooter(failed.route, debugPrerender, failed.omitErrorLine));
1887
+ }
1888
+ console.error("Next.js build worker exited with code: 1 and signal: null");
1889
+ process.exit(1);
1890
+ }
1891
+ if (isGenerate) {
1892
+ console.log(`
1893
+ Route (app)`);
1894
+ for (const line of generateRouteLines)
1895
+ console.log(line);
1896
+ }
1897
+ throwIfModuleGraphFailed();
1898
+ if (hadAfterPrerenderError) {
1899
+ throw new Error("Build failed because an error was thrown inside `after()` while prerendering.");
1900
+ }
1901
+ if (hadDynamicErrorFailure) {
1902
+ throw new Error('Build failed because a route with `dynamic = "error"` read dynamic data during prerendering.');
1903
+ }
1904
+ const interceptionPrerenders = isCompile ? new Map : await logInterceptionPrerenders(config, routes);
1905
+ const fallback404 = await notFoundDocuments;
1906
+ await emitNextNotFoundArtifacts(config, fallback404);
1907
+ await emitProxyServerArtifacts(config, proxyModule);
1908
+ if (config.compat?.next) {
1909
+ const sourceApp = path5.join(config.appPath, "..", "source-app");
1910
+ const layoutRoot = existsSync5(sourceApp) ? sourceApp : config.appPath;
1911
+ const hasTopLevelRootLayout = ["tsx", "ts", "jsx", "js"].some((ext) => existsSync5(path5.join(layoutRoot, `layout.${ext}`)));
1912
+ const pseudos = hasTopLevelRootLayout ? ["_not-found.html", "_global-error.html"] : ["_not-found.html"];
1913
+ for (const pseudo of pseudos) {
1914
+ if (!(pseudo in staticFiles)) {
1915
+ staticFiles[pseudo] = { status: 200, headers: [], kind: "page" };
1916
+ }
1917
+ }
1918
+ }
1919
+ await deferredSteps;
1920
+ const actions = buildState.actions;
1921
+ const publicAssets = publicFiles.filter((relative) => immutableAssetPath(relative));
1922
+ const manifest = {
1923
+ version: 0,
1924
+ root: config.root,
1925
+ appDir: config.appPath,
1926
+ outDir: config.outPath,
1927
+ routes,
1928
+ staticFiles,
1929
+ assetNames: emittedAssetNames(config.outPath),
1930
+ ...publicAssets.length > 0 ? { publicAssets } : {},
1931
+ staticMetadataFiles,
1932
+ ...Object.keys(staticModuleMetadata).length > 0 ? { staticModuleMetadata } : {},
1933
+ ...!config.compat?.next ? {
1934
+ staticRouteMetadata: await log.step("core route metadata", () => collectStaticRouteMetadata(config, routes, staticMetadataFiles))
1935
+ } : {},
1936
+ ...proxyModule ? { proxyModule } : {},
1937
+ ...actions.length > 0 ? { actions } : {}
1938
+ };
1939
+ await writeBuildManifest(config.outPath, manifest);
1940
+ log.log(`wrote manifest.json (${routes.length} route${routes.length === 1 ? "" : "s"})`);
1941
+ for (const hook of getBuildExtensions().completeHooks) {
1942
+ await hook({ config, manifest, log });
1943
+ }
1944
+ await log.step("warm module cache", () => warm.finish(log, undefined, {
1945
+ globalCss: globalCssSources(config),
1946
+ clientReferences: [...compiledClientReferenceFiles()]
1947
+ }));
1948
+ if (!existsSync5(buildIndexFile(config.outPath))) {
1949
+ throw new Error("pnext build: the server compile did not complete (see the error above).");
1950
+ }
1951
+ await log.step("standalone output", () => writeStandalone(config, standalone));
1952
+ if (options.adapter === "vercel")
1953
+ await log.step("vercel adapter output", () => writeVercelOutput(config, manifest, { verbose }));
1954
+ throwIfModuleGraphFailed();
1955
+ const buildDurationMs = performance.now() - startedAt;
1956
+ const phases = await settleBuildParallelPhases();
1957
+ flushDevModuleCaches();
1958
+ await writeBuildCache(config, options, cached);
1959
+ printBuildSummary(config, routes, staticFiles, buildDurationMs, Boolean(proxyModule), interceptionPrerenders, partialPrerenders, phases);
1960
+ return manifest;
1961
+ }
1962
+ async function runBuildSteps(steps, ctx) {
1963
+ for (const [index, step] of steps.entries()) {
1964
+ await ctx.log.step(`build step ${step.name || index}`, () => step(ctx));
1965
+ }
1966
+ }
1967
+ async function settleBuildParallelPhases() {
1968
+ const phases = getBuildExtensions().parallelPhases;
1969
+ const timings = [];
1970
+ for (const phase of phases)
1971
+ timings.push({ name: phase.name, durationMs: await phase.run });
1972
+ return timings;
1973
+ }
1974
+ async function logInterceptionPrerenders(config, routes) {
1975
+ const prerenders = new Map;
1976
+ for (const route of routes) {
1977
+ if (route.kind !== "page" || !route.interception)
1978
+ continue;
1979
+ if (!routeFileExportsStaticParams(route.file))
1980
+ continue;
1981
+ let paths;
1982
+ try {
1983
+ const staticParams = await staticParamsFor(config, route);
1984
+ paths = staticParams.paths.map((params) => interceptionDisplayRoute(route, fillRoutePath(route.route, params)));
1985
+ } catch (error) {
1986
+ rethrowIfProgrammingError(error);
1987
+ warnSkippedStatic(route.route, error instanceof Error ? error.message : String(error));
1988
+ continue;
1989
+ }
1990
+ if (paths.length === 0)
1991
+ continue;
1992
+ prerenders.set(route.id, paths);
1993
+ for (const routePath of paths)
1994
+ console.log(`${dim(" \u25CB")} ${routePath}`);
1995
+ }
1996
+ return prerenders;
1997
+ }
1998
+ function routeFileExportsStaticParams(file) {
1999
+ if (!existsSync5(file))
2000
+ return false;
2001
+ const source = readTextSync(file);
2002
+ return /\bexport\s+(?:async\s+)?function\s+generateStaticParams\b/.test(source) || /\bexport\s+const\s+generateStaticParams\b/.test(source);
2003
+ }
2004
+ function interceptionDisplayRoute(route, filled) {
2005
+ const interception = route.interception;
2006
+ if (!interception)
2007
+ return route.route;
2008
+ const base = interception.base === "/" ? [] : interception.base.split("/").filter(Boolean);
2009
+ const levels = interceptionMarkerLevels(interception.marker);
2010
+ const target = (filled ?? toNextRoutePattern(route.route)).split("/").filter(Boolean);
2011
+ const cut = Number.isFinite(levels) ? Math.max(0, base.length - levels) : 0;
2012
+ const below = target.slice(cut);
2013
+ const segments = [...base, `${interception.marker}${below[0] ?? ""}`, ...below.slice(1)];
2014
+ return `/${segments.join("/")}`;
2015
+ }
2016
+ async function writeBuildManifest(outPath, manifest) {
2017
+ assertManifestServerArtifacts(outPath, manifest);
2018
+ const file = buildManifestFile(outPath);
2019
+ const temporary = `${file}.${process.pid}.tmp`;
2020
+ await mkdir4(path5.dirname(file), { recursive: true });
2021
+ await writeFile2(temporary, serializeBuildManifest(manifest));
2022
+ await rename3(temporary, file);
2023
+ }
2024
+ function assertManifestServerArtifacts(outPath, manifest) {
2025
+ const artifacts = [
2026
+ ...manifest.proxyModule ? [manifest.proxyModule] : [],
2027
+ ...manifest.actions?.map((action) => action.modulePath) ?? []
2028
+ ];
2029
+ const outRoot = path5.dirname(outPath);
2030
+ for (const artifact of artifacts) {
2031
+ const file = path5.resolve(outPath, artifact);
2032
+ if (!file.startsWith(`${outRoot}${path5.sep}`)) {
2033
+ throw new Error(`Build manifest server artifact escapes output directory: ${artifact}`);
2034
+ }
2035
+ if (!existsSync5(file)) {
2036
+ throw new Error(`Build manifest server artifact is missing: ${artifact}`);
2037
+ }
2038
+ }
2039
+ }
2040
+ function printBuildSummary(config, routes, staticFiles, durationMs, hasMiddleware = false, interceptionPrerenders = new Map, partialPrerenders = new Set, parallelPhases = []) {
2041
+ const pages = routes.filter((route) => route.kind !== "handler").length;
2042
+ const handlers = routes.length - pages;
2043
+ const parts = [`${pages} ${pages === 1 ? "page" : "pages"}`];
2044
+ if (handlers > 0)
2045
+ parts.push(`${handlers} ${handlers === 1 ? "route handler" : "route handlers"}`);
2046
+ const outDir = path5.relative(config.root, config.outPath) || ".";
2047
+ console.log("");
2048
+ console.log("Route (app)");
2049
+ const usedMarkers = new Set;
2050
+ for (const route of routes) {
2051
+ const intercepted = interceptionPrerenders.get(route.id);
2052
+ const marker = route.kind === "handler" ? Object.values(staticFiles).some((file) => file.routeId === route.id) ? "\u25CB" : "\u0192" : intercepted ? "\u25CF" : partialPrerenders.has(route.id) ? "\u25D0" : route.mode === "dynamic" && !route.hasStaticParams ? "\u0192" : route.hasStaticParams ? "\u25CF" : "\u25CB";
2053
+ const label = route.interception ? interceptionDisplayRoute(route) : route.route || "/";
2054
+ usedMarkers.add(marker);
2055
+ console.log(` ${marker} ${nextCompatEnabled2(config) ? toNextRoutePattern(label) : label}`);
2056
+ }
2057
+ for (const file of staticMetadataSummaryFiles(staticFiles)) {
2058
+ usedMarkers.add("\u25CB");
2059
+ console.log(` ${dim("\u25CB")} /${file}`);
2060
+ }
2061
+ if (hasMiddleware) {
2062
+ usedMarkers.add("\u0192");
2063
+ console.log("");
2064
+ console.log(` ${dim("\u0192")} Middleware`);
2065
+ }
2066
+ const legend = [
2067
+ ["\u25CB", "static"],
2068
+ ["\u25CF", "SSG"],
2069
+ ["\u25D0", "partial prerender"],
2070
+ ["\u0192", "dynamic"]
2071
+ ];
2072
+ const legendLine = legend.filter(([marker]) => usedMarkers.has(marker)).map(([marker, meaning]) => `${marker} ${meaning}`).join(" ");
2073
+ if (legendLine)
2074
+ console.log(`
2075
+ ${dim(legendLine)}`);
2076
+ console.log("");
2077
+ console.log(`${green("\u2713")} ${bold("Build complete")} ${dim(`in ${formatBuildDuration(durationMs)}`)}`);
2078
+ for (const phase of parallelPhases) {
2079
+ console.log(`${green("\u2713")} ${bold(`${phase.name} complete`)} ${dim(`in ${formatBuildDuration(phase.durationMs)}`)}`);
2080
+ }
2081
+ console.log(` ${dim(`${parts.join(", ")} \u2192 ${outDir}`)}`);
2082
+ console.log("");
2083
+ console.log(` Serve the production build: ${cyan("pnext start")}`);
2084
+ console.log(` Analyze the build: ${cyan("pnext analyze")}`);
2085
+ }
2086
+ function staticMetadataSummaryFiles(staticFiles) {
2087
+ return Object.entries(staticFiles).filter(([, metadata]) => metadata.headers.some(([name, value]) => name.toLowerCase() === "cache-control" && value === staticMetadataCacheControl)).map(([file]) => file).sort();
2088
+ }
2089
+ function formatBuildDuration(durationMs) {
2090
+ const totalSeconds = Math.max(0, durationMs) / 1000;
2091
+ if (totalSeconds < 60)
2092
+ return `${totalSeconds.toFixed(totalSeconds < 10 ? 2 : 1)}s`;
2093
+ const minutes = Math.floor(totalSeconds / 60);
2094
+ const seconds = Math.round(totalSeconds % 60);
2095
+ return `${minutes}m ${seconds}s`;
2096
+ }
2097
+ async function renderShellWithCacheMeta(config, route, render) {
2098
+ let linkHeader;
2099
+ const tracked = await buildCompat().withVaryParamsTracking(async () => runWithWorkUnit("render", async () => {
2100
+ const rendered = await getRenderExtensions().collectRenderMeta(() => runWithNextBuildPhase(render), {
2101
+ fetchCache: route.segmentConfig?.fetchCache,
2102
+ route: route.route || "/",
2103
+ prerender: true
2104
+ });
2105
+ linkHeader = buildCompat().takeFontLinkHeader();
2106
+ return rendered;
2107
+ }));
2108
+ const result = tracked.value;
2109
+ const cacheLife = result.revalidateSeconds !== undefined || result.expireSeconds !== undefined || result.staleSeconds !== undefined ? {
2110
+ ...result.revalidateSeconds !== undefined ? { revalidateSeconds: result.revalidateSeconds } : {},
2111
+ ...result.expireSeconds !== undefined ? { expireSeconds: result.expireSeconds } : {},
2112
+ ...result.staleSeconds !== undefined ? { staleSeconds: result.staleSeconds } : {}
2113
+ } : undefined;
2114
+ return {
2115
+ prebuilt: result.value,
2116
+ meta: {
2117
+ ...cacheLife ? { cacheLife } : {},
2118
+ tags: result.tags,
2119
+ ...linkHeader ? { linkHeader } : {}
2120
+ },
2121
+ vary: tracked.vary
2122
+ };
2123
+ }
2124
+ var DYNAMIC_EXPIRE_SECONDS = 300;
2125
+ function routeDeclaresShortLivedCache(route) {
2126
+ for (const file of route.sourceFiles) {
2127
+ if (!existsSync5(file))
2128
+ continue;
2129
+ const source = readTextSync(file);
2130
+ for (const literal of source.matchAll(/cacheLife\s*\(\s*\{[^}]*\bexpire\s*:\s*([^,}]+)/gs)) {
2131
+ const value = staticNumberExpression(literal[1]);
2132
+ if (value !== undefined && value < DYNAMIC_EXPIRE_SECONDS)
2133
+ return true;
2134
+ }
2135
+ for (const named of source.matchAll(/cacheLife\s*\(\s*['"]([^'"]+)['"]\s*\)/g)) {
2136
+ const expire = builtInCacheLifeExpire(named[1]);
2137
+ if (expire !== undefined && expire < DYNAMIC_EXPIRE_SECONDS)
2138
+ return true;
2139
+ }
2140
+ }
2141
+ return false;
2142
+ }
2143
+ async function renderPrefetchBody(config, route, render) {
2144
+ if (!routeDeclaresShortLivedCache(route))
2145
+ return;
2146
+ try {
2147
+ const { prebuilt, vary } = await renderShellWithCacheMeta(config, route, render);
2148
+ return prebuilt ? { prebuilt, vary } : undefined;
2149
+ } catch {
2150
+ return;
2151
+ } finally {
2152
+ abortActivePrerenderScopes();
2153
+ }
2154
+ }
2155
+ async function buildPprShell(config, route) {
2156
+ const url = new URL(`http://pnext.local${route.route}`);
2157
+ const { prebuilt, meta, vary } = await renderShellWithCacheMeta(config, route, () => renderPartialShell({ config, route, url }));
2158
+ if (!prebuilt) {
2159
+ route.ppr = false;
2160
+ return;
2161
+ }
2162
+ route.pprHoles = prebuilt.holes;
2163
+ route.pprMetadata = prebuilt.metadataDynamic || undefined;
2164
+ persistRouteCacheLife(route, meta.cacheLife);
2165
+ recordRouteCacheTags(route, meta.tags);
2166
+ if (meta.linkHeader)
2167
+ route.linkHeader = meta.linkHeader;
2168
+ const file = pprShellPath(config.outPath, route.id);
2169
+ await mkdir4(path5.dirname(file), { recursive: true });
2170
+ await writeText(file, prebuilt.shell);
2171
+ const prefetchBody = await renderPrefetchBody(config, route, () => renderPartialShell({ config, route, url, prefetchShell: true })) ?? { prebuilt, vary };
2172
+ await emitSegmentArtifacts(config, route, prefetchBody.prebuilt.shell, prefetchBody.prebuilt.holes.length > 0, meta, undefined, prefetchBody.vary, true);
2173
+ }
2174
+ function recordRouteCacheTags(route, tags) {
2175
+ if (tags.length === 0)
2176
+ return;
2177
+ route.cacheTags = [...new Set([...route.cacheTags ?? [], ...tags])];
2178
+ }
2179
+ function persistRouteCacheLife(route, life) {
2180
+ if (!life)
2181
+ return;
2182
+ route.cacheLife = {
2183
+ ...life.revalidateSeconds !== undefined ? { revalidateSeconds: life.revalidateSeconds } : {},
2184
+ ...life.expireSeconds !== undefined ? { expireSeconds: life.expireSeconds } : {},
2185
+ ...life.staleSeconds !== undefined ? { staleSeconds: life.staleSeconds } : {}
2186
+ };
2187
+ }
2188
+ async function emitSegmentArtifacts(config, route, body, postponed, cacheMeta, statusOverride, vary, fallbackParamsRender = false) {
2189
+ const isStatic = route.mode === "static" && !postponed;
2190
+ const compat = buildCompat();
2191
+ const staleTime = staleTimeFromRouteSources(route) ?? (isStatic ? compat.defaultStaticStaleTimeSeconds : compat.defaultDynamicStaleTimeSeconds);
2192
+ const bodySizeBytes = Buffer.byteLength(body);
2193
+ const tree = compat.buildRootTreePrefetch({
2194
+ pathname: route.route,
2195
+ isStatic,
2196
+ staleTimeSeconds: staleTime,
2197
+ routeId: route.id,
2198
+ bodySizeBytes,
2199
+ postponed,
2200
+ runtimePrefetch: route.segmentConfig?.prefetch === "allow-runtime",
2201
+ ...route.pprMetadata === true ? { headOutlined: true, .../[:*]/.test(route.route) ? { headFirst: true } : {} } : {}
2202
+ });
2203
+ const meta = compat.buildSegmentMeta({
2204
+ status: statusOverride ?? 200,
2205
+ staleTime,
2206
+ postponed,
2207
+ bodySizeBytes,
2208
+ prefetchHints: { [route.route]: tree.tree.prefetchHints },
2209
+ ...vary && buildVaryTrusted(route, vary, fallbackParamsRender) ? { vary } : {}
2210
+ });
2211
+ await mkdir4(compat.segmentDir(config.outPath, route.id), { recursive: true });
2212
+ await writeText(compat.treeSegmentFile(config.outPath, route.id), JSON.stringify(tree));
2213
+ await writeText(compat.bodySegmentFile(config.outPath, route.id), body);
2214
+ await writeText(compat.segmentMetaFile(config.outPath, route.id), JSON.stringify(meta));
2215
+ await emitNextSegmentArtifacts(config.root, route, body, compat.rootTreePrefetchText(tree, "flight"), meta, segmentMetaHeaders(cacheMeta));
2216
+ }
2217
+ function recordPrerenderVary(route, routePath, vary) {
2218
+ if (!vary || !buildVaryTrusted(route, vary, false))
2219
+ return;
2220
+ if (vary.params.length === 0 && !vary.search)
2221
+ return;
2222
+ route.prerenderVary ??= {};
2223
+ route.prerenderVary[routePath] = {
2224
+ vary: buildCompat().varyNamesFor(vary, "body"),
2225
+ layoutVary: buildCompat().varyNamesFor(vary, "layout"),
2226
+ pageVary: buildCompat().varyNamesFor(vary, "page")
2227
+ };
2228
+ }
2229
+ function buildVaryTrusted(route, vary, fallbackParamsRender) {
2230
+ if (vary.params.length > 0 || vary.search)
2231
+ return true;
2232
+ if (fallbackParamsRender)
2233
+ return true;
2234
+ return route.params.length === 0 && !route.catchAll;
2235
+ }
2236
+ function segmentMetaHeaders(cacheMeta) {
2237
+ const headers = {};
2238
+ if (!cacheMeta)
2239
+ return headers;
2240
+ for (const [key, value] of cacheLifeResponseHeaders(cacheMeta.cacheLife))
2241
+ headers[key] = value;
2242
+ if (cacheMeta.tags.length > 0)
2243
+ headers["x-next-cache-tags"] = cacheMeta.tags.join(",");
2244
+ return headers;
2245
+ }
2246
+ async function emitNextSegmentArtifacts(root, route, body, tree, meta, headers = {}) {
2247
+ const appPath = nextAppRoutePath(route.route);
2248
+ const appFile = path5.join(root, ".next", "server", "app", appPath);
2249
+ const segmentsDir = `${appFile}.segments`;
2250
+ const nextMeta = {
2251
+ status: meta.status,
2252
+ headers,
2253
+ staleTime: meta.staleTime,
2254
+ ...meta.postponed ? { postponed: "1" } : {},
2255
+ segmentPaths: meta.segmentPaths,
2256
+ ...meta.segmentSizes ? { segmentSizes: meta.segmentSizes } : {},
2257
+ ...meta.inlinedSegmentPaths ? { inlinedSegmentPaths: meta.inlinedSegmentPaths } : {},
2258
+ ...meta.prefetchHints ? { prefetchHints: meta.prefetchHints } : {}
2259
+ };
2260
+ await mkdir4(segmentsDir, { recursive: true });
2261
+ await writeText(`${appFile}.html`, meta.postponed ? body : `${body}
2262
+ </body></html>`);
2263
+ await writeText(`${appFile}.meta`, JSON.stringify(nextMeta));
2264
+ await writeText(path5.join(segmentsDir, "_tree.segment.rsc"), tree);
2265
+ await writeText(path5.join(segmentsDir, "_full.segment.rsc"), body);
2266
+ await writeText(path5.join(segmentsDir, "_index.segment.rsc"), body);
2267
+ const routeSegment = appPath === "index" ? "__PAGE__" : appPath;
2268
+ await writeNestedSegment(segmentsDir, `${routeSegment}.segment.rsc`, body);
2269
+ await writeNestedSegment(segmentsDir, path5.join(routeSegment, "__PAGE__.segment.rsc"), body);
2270
+ }
2271
+ async function emitConcreteNextPageArtifacts(config, route, routePath, rendered) {
2272
+ if (!config.compat?.next || !cacheComponents())
2273
+ return;
2274
+ const compat = buildCompat();
2275
+ const postponed = rendered.postponed ?? false;
2276
+ const bodySizeBytes = Buffer.byteLength(rendered.html);
2277
+ const staleTime = staleTimeFromRouteSources(route) ?? compat.defaultStaticStaleTimeSeconds;
2278
+ const tree = compat.buildRootTreePrefetch({
2279
+ pathname: routePath,
2280
+ isStatic: !postponed,
2281
+ staleTimeSeconds: staleTime,
2282
+ routeId: route.id,
2283
+ bodySizeBytes,
2284
+ postponed
2285
+ });
2286
+ const meta = compat.buildSegmentMeta({
2287
+ status: rendered.status,
2288
+ staleTime,
2289
+ postponed,
2290
+ bodySizeBytes
2291
+ });
2292
+ const appFile = path5.join(config.root, ".next", "server", "app", nextAppRoutePath(routePath));
2293
+ const segmentsDir = `${appFile}.segments`;
2294
+ await mkdir4(segmentsDir, { recursive: true });
2295
+ await writeText(`${appFile}.html`, rendered.html);
2296
+ await writeText(`${appFile}.meta`, JSON.stringify({
2297
+ status: meta.status,
2298
+ headers: {},
2299
+ staleTime: meta.staleTime,
2300
+ ...postponed ? { postponed: "1" } : {},
2301
+ segmentPaths: meta.segmentPaths,
2302
+ ...meta.segmentSizes ? { segmentSizes: meta.segmentSizes } : {}
2303
+ }));
2304
+ await writeText(path5.join(segmentsDir, "_tree.segment.rsc"), compat.rootTreePrefetchText(tree, "flight"));
2305
+ }
2306
+ function staleTimeFromRouteSources(route) {
2307
+ let found;
2308
+ for (const file of route.sourceFiles) {
2309
+ if (!existsSync5(file))
2310
+ continue;
2311
+ const source = readTextSync(file);
2312
+ for (const literal of source.matchAll(/cacheLife\s*\(\s*\{[^}]*\bstale\s*:\s*([^,}]+)/gs)) {
2313
+ const value = staticNumberExpression(literal[1]);
2314
+ if (value !== undefined)
2315
+ found = minDefined(found, value);
2316
+ }
2317
+ for (const named of source.matchAll(/cacheLife\s*\(\s*['"]([^'"]+)['"]\s*\)/g)) {
2318
+ const namedValue = builtInCacheLifeStale(named[1]);
2319
+ if (namedValue !== undefined)
2320
+ found = minDefined(found, namedValue);
2321
+ }
2322
+ }
2323
+ return found;
2324
+ }
2325
+ function readTextSync(file) {
2326
+ try {
2327
+ return existsSync5(file) && statSync2(file).isFile() ? readFileSync3(file, "utf8") : "";
2328
+ } catch {
2329
+ return "";
2330
+ }
2331
+ }
2332
+ function staticNumberExpression(expression) {
2333
+ const trimmed = expression.trim();
2334
+ if (/^\d+(?:\.\d+)?$/.test(trimmed))
2335
+ return Number(trimmed);
2336
+ const product = trimmed.split("*").map((part) => part.trim());
2337
+ if (product.length > 1 && product.every((part) => /^\d+(?:\.\d+)?$/.test(part))) {
2338
+ return product.reduce((value, part) => value * Number(part), 1);
2339
+ }
2340
+ return;
2341
+ }
2342
+ function builtInCacheLifeStale(profile) {
2343
+ switch (profile) {
2344
+ case "seconds":
2345
+ return;
2346
+ case "default":
2347
+ case "minutes":
2348
+ case "hours":
2349
+ case "days":
2350
+ case "weeks":
2351
+ case "max":
2352
+ return 300;
2353
+ default:
2354
+ return;
2355
+ }
2356
+ }
2357
+ function builtInCacheLifeExpire(profile) {
2358
+ switch (profile) {
2359
+ case "seconds":
2360
+ return 60;
2361
+ case "minutes":
2362
+ return 3600;
2363
+ case "hours":
2364
+ return 86400;
2365
+ case "days":
2366
+ return 604800;
2367
+ case "weeks":
2368
+ return 2592000;
2369
+ case "default":
2370
+ case "max":
2371
+ return 31536000;
2372
+ default:
2373
+ return;
2374
+ }
2375
+ }
2376
+ function minDefined(a, b) {
2377
+ if (a === undefined)
2378
+ return b;
2379
+ if (b === undefined)
2380
+ return a;
2381
+ return Math.min(a, b);
2382
+ }
2383
+ async function writeNestedSegment(root, relative, body) {
2384
+ const file = path5.join(root, relative);
2385
+ await mkdir4(path5.dirname(file), { recursive: true });
2386
+ await writeText(file, body);
2387
+ }
2388
+ function nextAppRoutePath(route) {
2389
+ return route.replace(/^\/+/, "") || "index";
2390
+ }
2391
+ function shellRendersContentOutsideHoles(shell) {
2392
+ const open = /<body[^>]*>/.exec(shell);
2393
+ if (!open)
2394
+ return false;
2395
+ const rest = shell.slice(open.index + open[0].length);
2396
+ const body = rest.split("</body>")[0] ?? "";
2397
+ const outside = stripBalanced(body, "pnext-suspense").replace(/<(script|template|style)[^>]*>[\s\S]*?<\/\1>/g, "").replace(/<!--[\s\S]*?-->/g, "");
2398
+ if (/<(img|svg|video|canvas|input)[\s>]/.test(outside))
2399
+ return true;
2400
+ return outside.replace(/<[^>]*>/g, "").trim().length > 0;
2401
+ }
2402
+ function shellHolesRenderFallbackContent(shell) {
2403
+ const open = /<body[^>]*>/.exec(shell);
2404
+ if (!open)
2405
+ return false;
2406
+ const body = (shell.slice(open.index + open[0].length).split("</body>")[0] ?? "").replace(/<(script|template|style)[^>]*>[\s\S]*?<\/\1>/g, "").replace(/<!--[\s\S]*?-->/g, "");
2407
+ const outside = stripBalanced(body, "pnext-suspense");
2408
+ const text = (h) => h.replace(/<[^>]*>/g, "").trim().length;
2409
+ const media = (h) => /<(img|svg|video|canvas|input)[\s>]/.test(h);
2410
+ return text(body) - text(outside) > 0 || media(body) && !media(outside);
2411
+ }
2412
+ function stripBalanced(html, tag) {
2413
+ const open = new RegExp(`<${tag}[\\s>]`, "g");
2414
+ const boundary = new RegExp(`<${tag}[\\s>]|</${tag}>`, "g");
2415
+ let out = "";
2416
+ let cursor = 0;
2417
+ for (let start = open.exec(html);start; start = open.exec(html)) {
2418
+ if (start.index < cursor)
2419
+ continue;
2420
+ out += html.slice(cursor, start.index);
2421
+ boundary.lastIndex = start.index + 1;
2422
+ let depth = 1;
2423
+ let end = html.length;
2424
+ for (let hit = boundary.exec(html);hit; hit = boundary.exec(html)) {
2425
+ depth += hit[0].startsWith("</") ? -1 : 1;
2426
+ if (depth === 0) {
2427
+ end = hit.index + hit[0].length;
2428
+ break;
2429
+ }
2430
+ }
2431
+ cursor = end;
2432
+ open.lastIndex = cursor;
2433
+ }
2434
+ return out + html.slice(cursor);
2435
+ }
2436
+ async function buildCacheComponentsShell(config, route) {
2437
+ const url = new URL(`http://pnext.local${route.route}`);
2438
+ const hasDynamicParams = route.params.length > 0 || Boolean(route.catchAll);
2439
+ beginShellSourceTracking();
2440
+ let renderResult;
2441
+ try {
2442
+ renderResult = await renderShellWithCacheMeta(config, route, () => hasDynamicParams ? renderFallbackShell({ config, route, url }) : renderPartialShell({ config, route, url }));
2443
+ } finally {
2444
+ abortActivePrerenderScopes();
2445
+ }
2446
+ const { prebuilt, meta } = renderResult;
2447
+ const shellSources = endShellSourceTracking();
2448
+ const baseShellIsEmpty = prebuilt === null || prebuilt.holes.length > 0 && !prebuilt.metadataDynamic && !shellSources.cacheIO && !shellSources.nonParamsRequest && !(meta.cacheLife === undefined && (shellRendersContentOutsideHoles(prebuilt.shell) || shellHolesRenderFallbackContent(prebuilt.shell))) && !(hasDynamicParams && routeSourcesUseRequestApi(config.root, route));
2449
+ if (!baseShellIsEmpty) {
2450
+ route.ppr = true;
2451
+ route.pprHoles = prebuilt.holes;
2452
+ route.pprMetadata = prebuilt.metadataDynamic || undefined;
2453
+ persistRouteCacheLife(route, meta.cacheLife);
2454
+ recordRouteCacheTags(route, meta.tags);
2455
+ if (meta.linkHeader)
2456
+ route.linkHeader = meta.linkHeader;
2457
+ const file = pprShellPath(config.outPath, route.id);
2458
+ await mkdir4(path5.dirname(file), { recursive: true });
2459
+ await writeText(file, prebuilt.shell);
2460
+ let fallbackStatus;
2461
+ if (!hasDynamicParams && routeSourcesUseHttpFallback(config.root, route)) {
2462
+ try {
2463
+ const probe = await runWithWorkUnit("render", () => getRenderExtensions().collectRenderMeta(() => runWithNextBuildPhase(() => renderPageWithStatus({ config, route, params: {}, url })), { route: route.route || "/", prerender: true }).then((result) => result.value));
2464
+ if (probe.status !== 200)
2465
+ fallbackStatus = probe.status;
2466
+ } catch {}
2467
+ }
2468
+ const prefetchBody = await renderPrefetchBody(config, route, () => hasDynamicParams ? renderFallbackShell({ config, route, url, prefetchShell: true }) : renderPartialShell({ config, route, url, prefetchShell: true })) ?? { prebuilt, vary: renderResult.vary };
2469
+ await emitSegmentArtifacts(config, route, prefetchBody.prebuilt.shell, prefetchBody.prebuilt.holes.length > 0, meta, fallbackStatus, prefetchBody.vary, true);
2470
+ if (hasDynamicParams && route.hasStaticParams) {
2471
+ await buildSubShells(config, route);
2472
+ }
2473
+ return true;
2474
+ }
2475
+ if (hasDynamicParams && route.hasStaticParams && (await hasPartialStaticPrefix(config, route) || cacheComponents() && routeSourcesUseRequestApi(config.root, route) && await hasFullStaticParamSet(config, route))) {
2476
+ route.ppr = true;
2477
+ route.pprMetadata = prebuilt?.metadataDynamic || undefined;
2478
+ if (prebuilt) {
2479
+ persistRouteCacheLife(route, meta.cacheLife);
2480
+ recordRouteCacheTags(route, meta.tags);
2481
+ if (meta.linkHeader)
2482
+ route.linkHeader = meta.linkHeader;
2483
+ }
2484
+ await buildSubShells(config, route);
2485
+ return true;
2486
+ }
2487
+ return false;
2488
+ }
2489
+ async function hasPartialStaticPrefix(config, route) {
2490
+ if (!route.hasStaticParams)
2491
+ return false;
2492
+ let staticParams;
2493
+ try {
2494
+ staticParams = await staticParamsFor(config, route);
2495
+ } catch {
2496
+ return false;
2497
+ }
2498
+ const paramKeys = [...route.params, ...route.catchAll ? [route.catchAll] : []];
2499
+ for (const set of staticParams.allSets) {
2500
+ let filled = 0;
2501
+ while (filled < paramKeys.length && set[paramKeys[filled]] !== undefined)
2502
+ filled++;
2503
+ if (filled > 0 && filled < paramKeys.length)
2504
+ return true;
2505
+ }
2506
+ return false;
2507
+ }
2508
+ async function hasFullStaticParamSet(config, route) {
2509
+ if (!route.hasStaticParams)
2510
+ return false;
2511
+ let staticParams;
2512
+ try {
2513
+ staticParams = await staticParamsFor(config, route);
2514
+ } catch {
2515
+ return false;
2516
+ }
2517
+ const paramKeys = [...route.params, ...route.catchAll ? [route.catchAll] : []];
2518
+ if (paramKeys.length === 0)
2519
+ return false;
2520
+ return staticParams.allSets.some((set) => paramKeys.every((key) => set[key] !== undefined));
2521
+ }
2522
+ async function buildSubShells(config, route) {
2523
+ let staticParams;
2524
+ try {
2525
+ staticParams = await staticParamsFor(config, route);
2526
+ } catch {
2527
+ return;
2528
+ }
2529
+ route.prerenderedParams = staticParams.allSets;
2530
+ const paramKeys = [...route.params, ...route.catchAll ? [route.catchAll] : []];
2531
+ const prefixes = new Map;
2532
+ for (const set of staticParams.allSets) {
2533
+ let filled = 0;
2534
+ while (filled < paramKeys.length && set[paramKeys[filled]] !== undefined)
2535
+ filled++;
2536
+ if (filled === 0)
2537
+ continue;
2538
+ const concrete = {};
2539
+ for (let i = 0;i < filled; i++)
2540
+ concrete[paramKeys[i]] = set[paramKeys[i]];
2541
+ const key = subShellKey(concrete);
2542
+ if (!prefixes.has(key))
2543
+ prefixes.set(key, concrete);
2544
+ }
2545
+ if (prefixes.size === 0)
2546
+ return;
2547
+ const subShells = [];
2548
+ for (const [key, concreteParams] of prefixes) {
2549
+ const routePath = fillRoutePath(route.route, concreteParams);
2550
+ const url = new URL(`http://pnext.local${routePath}`);
2551
+ const { value: prebuilt, tags } = await runWithWorkUnit("render", () => getRenderExtensions().collectRenderMeta(() => runWithNextBuildPhase(() => renderSubShell({ config, route, url, concreteParams, paramKeys })), { fetchCache: route.segmentConfig?.fetchCache, route: routePath || "/", prerender: true }));
2552
+ recordRouteCacheTags(route, tags);
2553
+ if (!prebuilt)
2554
+ continue;
2555
+ const file = pprSubShellPath(config.outPath, route.id, key);
2556
+ await mkdir4(path5.dirname(file), { recursive: true });
2557
+ await writeText(file, prebuilt.shell);
2558
+ subShells.push({ key, concreteParams, holes: prebuilt.holes });
2559
+ if (Object.keys(concreteParams).length === paramKeys.length) {
2560
+ try {
2561
+ const probe = await runWithWorkUnit("render", () => getRenderExtensions().collectRenderMeta(() => runWithNextBuildPhase(() => renderPageWithStatus({
2562
+ config,
2563
+ route,
2564
+ params: encodeStaticRouteParams(concreteParams),
2565
+ url
2566
+ })), { route: routePath || "/", prerender: true }).then((result) => result.value));
2567
+ const postponed = prebuilt.holes.length > 0 || prebuilt.metadataDynamic || route.pprMetadata === true || routeSourcesHaveDynamicHead(route);
2568
+ await emitConcreteNextPageArtifacts(config, route, routePath, {
2569
+ html: postponed ? prebuilt.shell : `${prebuilt.shell}
2570
+ </body></html>`,
2571
+ status: probe.status,
2572
+ postponed
2573
+ });
2574
+ } catch {}
2575
+ }
2576
+ }
2577
+ subShells.sort((a, b) => Object.keys(b.concreteParams).length - Object.keys(a.concreteParams).length);
2578
+ if (subShells.length > 0)
2579
+ route.pprSubShells = subShells;
2580
+ }
2581
+ function routeSourcesUseHttpFallback(root, route) {
2582
+ for (const file of route.sourceFiles) {
2583
+ if (!file.startsWith(root) || file.includes(`${path5.sep}node_modules${path5.sep}`))
2584
+ continue;
2585
+ if (!existsSync5(file))
2586
+ continue;
2587
+ const source = readTextSync(file);
2588
+ if (/\b(?:notFound|forbidden|unauthorized)\s*\(\s*\)/.test(source))
2589
+ return true;
2590
+ }
2591
+ return false;
2592
+ }
2593
+ function routeSourcesUseRequestApi(root, route) {
2594
+ for (const file of route.sourceFiles) {
2595
+ if (!file.startsWith(root) || file.includes(`${path5.sep}node_modules${path5.sep}`))
2596
+ continue;
2597
+ if (!existsSync5(file))
2598
+ continue;
2599
+ const source = readTextSync(file).replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
2600
+ if (/\b(?:connection|cookies|headers|draftMode)\s*\(\s*\)/.test(source))
2601
+ return true;
2602
+ }
2603
+ return false;
2604
+ }
2605
+ function routeSourcesHaveDynamicHead(route) {
2606
+ for (const file of route.sourceFiles) {
2607
+ if (!existsSync5(file))
2608
+ continue;
2609
+ const source = readTextSync(file);
2610
+ const match = /export\s+(?:async\s+)?function\s+(?:generateMetadata|generateViewport)\s*\([^)]*\)\s*(?::[^{]+)?\{/.exec(source);
2611
+ if (!match)
2612
+ continue;
2613
+ const body = source.slice(match.index + match[0].length);
2614
+ if (/\bawait\b/.test(body.split(`
2615
+ export `)[0] ?? body) && !body.includes("use cache")) {
2616
+ return true;
2617
+ }
2618
+ }
2619
+ return false;
2620
+ }
2621
+ function filterDebugBuildRoutes(root, routes, patterns) {
2622
+ const matchers = patterns.split(",").map((pattern) => pattern.trim()).filter((pattern) => pattern.length > 0 && !pattern.startsWith("!")).map(debugBuildPathMatcher);
2623
+ if (matchers.length === 0)
2624
+ return routes;
2625
+ return routes.filter((route) => {
2626
+ const relative = toPosixPath(path5.relative(root, route.file));
2627
+ return matchers.some((matcher) => matcher(relative));
2628
+ });
2629
+ }
2630
+ function debugBuildPathMatcher(pattern) {
2631
+ if (!/[*?]/.test(pattern)) {
2632
+ return (file) => file === pattern || file.endsWith(`/${pattern}`);
2633
+ }
2634
+ const regex = new RegExp(`^${pattern.split(/(\*\*\/|\*\*|\*|\?)/).map((part) => {
2635
+ if (part === "**/")
2636
+ return "(?:.*/)?";
2637
+ if (part === "**")
2638
+ return ".*";
2639
+ if (part === "*")
2640
+ return "[^/]*";
2641
+ if (part === "?")
2642
+ return "[^/]";
2643
+ return part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2644
+ }).join("")}$`);
2645
+ return (file) => regex.test(file);
2646
+ }
2647
+ function subShellKey(concrete) {
2648
+ return Object.entries(concrete).map(([k, v]) => `${k}-${(Array.isArray(v) ? v.join("_") : v).replace(/[^a-zA-Z0-9_]/g, "_")}`).join(".");
2649
+ }
2650
+ async function buildProxyModule(config) {
2651
+ await validateProxyFiles(config);
2652
+ const file = findProxyFile(config);
2653
+ if (!file)
2654
+ return;
2655
+ const href = await devServerModuleHref(config, file, "prod", {
2656
+ conditionTarget: "edge",
2657
+ externalLoadTarget: proxyExternalLoadTarget(file),
2658
+ reactServerLayer: true
2659
+ });
2660
+ const compiled = fileURLToPath3(href);
2661
+ return toPosixPath(path5.relative(config.outPath, compiled));
2662
+ }
2663
+ async function renderNotFoundDocuments({
2664
+ config,
2665
+ log,
2666
+ skip,
2667
+ documentCss,
2668
+ staticMetadataFiles,
2669
+ staticModuleMetadata
2670
+ }) {
2671
+ if (skip)
2672
+ return;
2673
+ const render = async () => {
2674
+ const response = await renderGlobalNotFoundResponse({
2675
+ config,
2676
+ url: new URL("http://pnext.local/_not-found"),
2677
+ staticMetadataFiles,
2678
+ staticModuleMetadata
2679
+ });
2680
+ return response.text();
2681
+ };
2682
+ await documentCss;
2683
+ if (await shouldBuildGlobalNotFound(config)) {
2684
+ await log.step("global not-found", async () => writeText(path5.join(config.outPath, "static", "404.html"), await render()));
2685
+ }
2686
+ if (!config.compat?.next)
2687
+ return;
2688
+ if (existsSync5(path5.join(config.outPath, "static", "404.html")))
2689
+ return;
2690
+ return defaultNotFoundDocument();
2691
+ }
2692
+ async function shouldBuildGlobalNotFound(config) {
2693
+ const file = ["tsx", "ts", "jsx", "js"].flatMap((ext) => [
2694
+ path5.join(config.appPath, `global-not-found.${ext}`),
2695
+ path5.join(config.appPath, `not-found.${ext}`)
2696
+ ]).find((candidate) => existsSync5(candidate));
2697
+ if (!file)
2698
+ return false;
2699
+ return !/\bexport\s+const\s+dynamic\s*=\s*['"]force-dynamic['"]/.test(await readText(file));
2700
+ }
2701
+ async function emitProxyServerArtifacts(config, proxyModule) {
2702
+ if (!config.compat?.next || !proxyModule)
2703
+ return;
2704
+ const compiled = path5.resolve(config.outPath, proxyModule);
2705
+ if (!existsSync5(compiled))
2706
+ return;
2707
+ const serverDir = path5.join(config.root, ".next", "server");
2708
+ await mkdir4(serverDir, { recursive: true });
2709
+ const middlewareFile = path5.join(serverDir, "middleware.js");
2710
+ await copyFile3(compiled, middlewareFile);
2711
+ const files = ["middleware.js"].filter((name) => existsSync5(path5.join(serverDir, name)));
2712
+ await writeFile2(path5.join(serverDir, "middleware.js.nft.json"), `${JSON.stringify({ version: 1, files })}
2713
+ `);
2714
+ }
2715
+ async function emitNextNotFoundArtifacts(config, fallback404) {
2716
+ if (!config.compat?.next)
2717
+ return;
2718
+ const source = path5.join(config.outPath, "static", "404.html");
2719
+ const html = existsSync5(source) ? readFileSync3(source, "utf8") : fallback404;
2720
+ if (html === undefined)
2721
+ return;
2722
+ const serverDir = path5.join(config.root, ".next", "server");
2723
+ const pagesDir = path5.join(serverDir, "pages");
2724
+ const notFoundDir = path5.join(serverDir, "app", "_not-found");
2725
+ await mkdir4(pagesDir, { recursive: true });
2726
+ await mkdir4(notFoundDir, { recursive: true });
2727
+ await writeFile2(path5.join(pagesDir, "404.html"), html);
2728
+ await writeFile2(path5.join(serverDir, "app", "_not-found.html"), html);
2729
+ await writeFile2(path5.join(serverDir, "app", "_not-found.rsc"), html);
2730
+ const pagesManifestFile = path5.join(serverDir, "pages-manifest.json");
2731
+ let pagesManifest = {};
2732
+ try {
2733
+ pagesManifest = JSON.parse(readFileSync3(pagesManifestFile, "utf8"));
2734
+ } catch {}
2735
+ pagesManifest["/404"] = "pages/404.html";
2736
+ await writeFile2(pagesManifestFile, `${JSON.stringify(pagesManifest, null, 2)}
2737
+ `);
2738
+ const clientReferenceManifest = "page_client-reference-manifest.js";
2739
+ await writeFile2(path5.join(notFoundDir, clientReferenceManifest), `self.__RSC_MANIFEST={}
2740
+ `);
2741
+ await writeFile2(path5.join(notFoundDir, "page.js.nft.json"), `${JSON.stringify({ version: 1, files: [clientReferenceManifest] }, null, 2)}
2742
+ `);
2743
+ }
2744
+ async function collectStaticModuleMetadata(config, routes) {
2745
+ const metadata = {};
2746
+ if (config.compat?.next)
2747
+ return metadata;
2748
+ const files = new Set;
2749
+ for (const route of routes) {
2750
+ if (route.kind !== "page")
2751
+ continue;
2752
+ for (const file of findLayouts(config.appPath, route.file)) {
2753
+ if (existsSync5(file))
2754
+ files.add(file);
2755
+ }
2756
+ files.add(route.file);
2757
+ }
2758
+ if (files.size === 0)
2759
+ return metadata;
2760
+ registerServerRuntime(config, [...files]);
2761
+ registerCssRuntime();
2762
+ for (const file of files) {
2763
+ const href = reactCompatEnabled(config) ? await devServerModuleHref(config, file, "build") : pathToFileHref(file);
2764
+ const module = await import(href);
2765
+ const entry = {};
2766
+ const routeMetadata = await readModuleMetadata(module);
2767
+ const viewport = await readModuleViewport(module);
2768
+ if (routeMetadata)
2769
+ entry.metadata = routeMetadata;
2770
+ if (viewport)
2771
+ entry.viewport = viewport;
2772
+ if (entry.metadata || entry.viewport)
2773
+ metadata[file] = entry;
2774
+ }
2775
+ return metadata;
2776
+ }
2777
+ async function collectStaticRouteMetadata(config, routes, staticMetadataFiles) {
2778
+ const metadata = {};
2779
+ if (config.compat?.next)
2780
+ return metadata;
2781
+ for (const route of routes) {
2782
+ if (route.kind !== "page" || route.interception)
2783
+ continue;
2784
+ const paramSets = route.prerenderedParams ?? (route.params.length === 0 ? [{}] : []);
2785
+ for (const params of paramSets) {
2786
+ const routePath = fillRoutePath(route.route, params);
2787
+ const base = route.interception ? staticMetadataForRouteFromFiles(staticMetadataFiles, config.appPath, route.file, routePath) : staticMetadataForPathFromFiles(staticMetadataFiles, routePath);
2788
+ const resolved2 = await withDynamicMetadataRoutes(base, config.appPath, route.file, routePath, (file) => importMetadataModule(config, file));
2789
+ metadata[staticRouteMetadataKey(routePath)] = resolved2;
2790
+ }
2791
+ }
2792
+ return metadata;
2793
+ }
2794
+ async function importMetadataModule(config, file) {
2795
+ const href = reactCompatEnabled(config) ? await devServerModuleHref(config, file, "build") : pathToFileHref(file);
2796
+ return import(href);
2797
+ }
2798
+ async function buildStaticRouteHandler(config, route, options = {}) {
2799
+ const skipPhysicalWrite = options.skipPhysicalWrite ?? false;
2800
+ registerServerRuntime(config, route.sourceFiles);
2801
+ const moduleHref = reactCompatEnabled(config) ? await devServerModuleHref(config, route.file, "build", {
2802
+ conditionTarget: serverBundleTargetForRuntime(route.segmentConfig?.runtime)
2803
+ }) : pathToFileHref(route.file);
2804
+ const imported = await import(moduleHref);
2805
+ const routeModule = metadataRouteHandlerModule(imported, route) ?? imported;
2806
+ const module = nextCompatEnabled2(config) ? buildCompat().normalizeStaticParamsModule(routeModule) : routeModule;
2807
+ const paramSets = await staticRouteParams(route, module);
2808
+ const staticFiles = {};
2809
+ if (route.metadataRoute?.generatedParam && paramSets.length > 0) {
2810
+ route.metadataRoute.generatedRoutes = paramSets.map((params) => fillRoutePath(route.route, params, route.metadataRoute?.generatedParam));
2811
+ }
2812
+ const requestBase = route.segmentConfig?.dynamic === "force-static" ? "http://localhost:3000" : "http://pnext.local";
2813
+ for (const params of paramSets) {
2814
+ const routePath = fillRoutePath(route.route, params, route.metadataRoute?.generatedParam);
2815
+ const file = staticRouteHandlerPath(config.outPath, routePath);
2816
+ if (!skipPhysicalWrite) {
2817
+ const collision = staticOutputCollision(config.outPath, file);
2818
+ if (collision) {
2819
+ warnSkippedStatic(routePath, collision);
2820
+ continue;
2821
+ }
2822
+ }
2823
+ const prerender = runWithWorkUnit("render", () => getRenderExtensions().collectRenderMeta(() => runWithCacheScope(() => runWithNextBuildPhase(() => withRouteRuntime(route.segmentConfig?.runtime, () => handleRouteModule(module, new Request(`${requestBase}${routePath}`), params, {
2824
+ routeFile: route.file
2825
+ })))), {
2826
+ fetchCache: route.segmentConfig?.fetchCache,
2827
+ route: routePath || "/",
2828
+ prerender: true,
2829
+ handler: true,
2830
+ dynamicError: route.segmentConfig?.dynamic === "error"
2831
+ }));
2832
+ const early = await settleBeforeNextTask(prerender);
2833
+ const completed = early ?? await prerender;
2834
+ const rendered = early ?? (route.segmentConfig?.dynamic === "force-static" || await handlerHasEntirelyCachedIo(route) ? completed : undefined);
2835
+ if (!rendered)
2836
+ continue;
2837
+ const response = rendered.value;
2838
+ if (response.status >= 500) {
2839
+ throw new Error(`route handler prerender returned ${response.status}`);
2840
+ }
2841
+ if (rendered.noStore && !staticRouteHandlerExplicitlyCached(route))
2842
+ continue;
2843
+ const body = await settleBeforeNextTask(response.clone().arrayBuffer());
2844
+ if (!body)
2845
+ continue;
2846
+ const relative = toPosixPath(path5.relative(path5.join(config.outPath, "static"), file));
2847
+ if (!skipPhysicalWrite) {
2848
+ await mkdir4(path5.dirname(file), { recursive: true });
2849
+ await writeFile2(file, new Uint8Array(body));
2850
+ }
2851
+ const revalidateSeconds = combineRevalidate(route.segmentConfig?.revalidate, rendered.revalidateSeconds);
2852
+ staticFiles[relative] = {
2853
+ status: response.status,
2854
+ headers: [...response.headers.entries()],
2855
+ routeId: route.id,
2856
+ ...revalidateSeconds !== undefined ? { revalidateSeconds } : {},
2857
+ ...rendered.tags.length > 0 ? { tags: rendered.tags } : {}
2858
+ };
2859
+ }
2860
+ return staticFiles;
2861
+ }
2862
+ function settleBeforeNextTask(value) {
2863
+ return new Promise((resolve, reject) => {
2864
+ let settled = false;
2865
+ const timer = setTimeout(() => {
2866
+ if (!settled)
2867
+ resolve(undefined);
2868
+ }, 0);
2869
+ value.then((result) => {
2870
+ settled = true;
2871
+ clearTimeout(timer);
2872
+ resolve(result);
2873
+ }, (error) => {
2874
+ settled = true;
2875
+ clearTimeout(timer);
2876
+ reject(error instanceof Error ? error : new Error(String(error)));
2877
+ });
2878
+ });
2879
+ }
2880
+ async function handlerHasEntirelyCachedIo(route) {
2881
+ if (route.synthetic || !existsSync5(route.file))
2882
+ return false;
2883
+ const source = await readText(route.file);
2884
+ if (route.metadataRoute && metadataDefaultUsesCache(source))
2885
+ return true;
2886
+ const getStart = source.search(/\bexport\s+(?:async\s+)?function\s+GET\s*\(/);
2887
+ if (getStart === -1)
2888
+ return false;
2889
+ const afterGet = source.slice(getStart);
2890
+ const nextDeclaration = afterGet.slice(1).search(/^(?:async\s+)?(?:function|const|let)\s+/m);
2891
+ const body = nextDeclaration === -1 ? afterGet : afterGet.slice(0, nextDeclaration + 1);
2892
+ if (/\bnew\s+Date\s*\(\s*\)/.test(body) || /\bDate\s*\.\s*now\s*\(/.test(body)) {
2893
+ return false;
2894
+ }
2895
+ const awaited = [...body.matchAll(/\bawait\s+([A-Za-z_$][\w$]*)\s*\(/g)].map((match) => match[1]);
2896
+ if (awaited.length === 0)
2897
+ return false;
2898
+ const cached = new Set(["import"]);
2899
+ for (const match of source.matchAll(/\bconst\s+([A-Za-z_$][\w$]*)\s*=\s*([A-Za-z_$][\w$]*)\s*\(/g)) {
2900
+ if (match[2] === "cache" || match[2] === "unstable_cache")
2901
+ cached.add(match[1]);
2902
+ }
2903
+ for (const match of source.matchAll(/\b(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\([^)]*\)\s*\{\s*['"]use cache['"]/g)) {
2904
+ cached.add(match[1]);
2905
+ }
2906
+ for (const name of awaited) {
2907
+ const start = source.search(new RegExp(`\\b(?:const\\s+${name}\\s*=|function\\s+${name}\\s*\\()`));
2908
+ if (start === -1)
2909
+ continue;
2910
+ const tail = source.slice(start);
2911
+ const next = tail.slice(1).search(/^(?:async\s+)?(?:function|const|let)\s+/m);
2912
+ const declaration = next === -1 ? tail : tail.slice(0, next + 1);
2913
+ if (/\bcache\s*:\s*['"]force-cache['"]/.test(declaration))
2914
+ cached.add(name);
2915
+ }
2916
+ return awaited.every((name) => cached.has(name));
2917
+ }
2918
+ function metadataDefaultUsesCache(source) {
2919
+ return /\bexport\s+default\s+(?:async\s+)?function\b[^(]*\([^)]*\)\s*(?::[^{]*)?\{\s*(?:\/\/[^\n]*\n\s*|\/\*[\s\S]*?\*\/\s*)*['"]use cache['"]/.test(source);
2920
+ }
2921
+ async function usesUnstableCache(route) {
2922
+ if (route.synthetic || !existsSync5(route.file))
2923
+ return false;
2924
+ const source = await readText(route.file);
2925
+ const localNames = [];
2926
+ const dynamicNames = [];
2927
+ for (const match of source.matchAll(/\bimport\s*\{([^}]*)\}\s*from\s*['"]next\/(cache|headers|server)(?:\.js)?['"]/g)) {
2928
+ for (const item of match[1].split(",")) {
2929
+ const [imported, local] = item.trim().split(/\s+as\s+/);
2930
+ if (match[2] === "cache" && imported === "unstable_cache") {
2931
+ localNames.push(local ?? imported);
2932
+ } else if (match[2] === "headers" && (imported === "cookies" || imported === "headers") || match[2] === "server" && imported === "connection") {
2933
+ dynamicNames.push(local ?? imported);
2934
+ }
2935
+ }
2936
+ }
2937
+ if (dynamicNames.length === 0)
2938
+ return false;
2939
+ const dynamicCall = dynamicNames.join("|");
2940
+ return localNames.some((name) => new RegExp(`\\b${name}\\s*\\(\\s*(?:async\\s*)?(?:\\([^)]*\\)|[A-Za-z_$][\\w$]*)?\\s*=>[\\s\\S]{0,1000}?\\b(?:${dynamicCall})\\s*\\(`).test(source));
2941
+ }
2942
+ async function staticHandlerDynamicUsage(route) {
2943
+ if (!route.usesRequest)
2944
+ return;
2945
+ if (route.segmentConfig?.dynamic === "force-static" || route.segmentConfig?.dynamic === "error") {
2946
+ return;
2947
+ }
2948
+ if (route.synthetic || !existsSync5(route.file))
2949
+ return;
2950
+ const source = await readText(route.file);
2951
+ if (/\b(?:request|req)\.url\b/.test(source))
2952
+ return "request.url";
2953
+ if (/\bnextUrl\s*\.\s*toString\s*\(/.test(source))
2954
+ return "nextUrl.toString";
2955
+ if (/\bheaders\s*\(/.test(source))
2956
+ return "headers()";
2957
+ if (/\bcookies\s*\(/.test(source))
2958
+ return "cookies()";
2959
+ if (/\bconnection\s*\(/.test(source))
2960
+ return "connection()";
2961
+ return;
2962
+ }
2963
+ function collectDescendantHandlerIds(routes) {
2964
+ const ids = new Set;
2965
+ const paths = routes.map((route) => ({ route, norm: (route.route || "/").replace(/\/+$/, "") }));
2966
+ for (const { route, norm } of paths) {
2967
+ if (route.kind !== "handler")
2968
+ continue;
2969
+ const hasAncestor = paths.some((other) => other.route !== route && other.norm.length > 0 && norm !== other.norm && norm.startsWith(`${other.norm}/`));
2970
+ if (hasAncestor)
2971
+ ids.add(route.id);
2972
+ }
2973
+ return ids;
2974
+ }
2975
+ async function staticRouteHandlerCandidate(route) {
2976
+ const config = route.segmentConfig;
2977
+ if (config?.dynamic === "force-dynamic")
2978
+ return false;
2979
+ if (config?.revalidate === 0)
2980
+ return false;
2981
+ if (config?.fetchCache === "force-no-store")
2982
+ return false;
2983
+ if (route.handlerUsesRevalidationApi)
2984
+ return false;
2985
+ if (route.metadataRoute)
2986
+ return !route.usesRequest;
2987
+ if (config?.dynamic === "error")
2988
+ return true;
2989
+ if (config?.dynamic === "force-static")
2990
+ return true;
2991
+ if (staticRouteHandlerExplicitlyCached(route) || route.hasStaticParams)
2992
+ return true;
2993
+ if (route.usesRequest)
2994
+ return false;
2995
+ if (!cacheComponents() || route.mode !== "static")
2996
+ return false;
2997
+ if (!handlerUsesUncachedIo(route))
2998
+ return true;
2999
+ return handlerHasEntirelyCachedIo(route);
3000
+ }
3001
+ function handlerUsesUncachedIo(route) {
3002
+ const source = readTextSync(route.file);
3003
+ if (!source)
3004
+ return false;
3005
+ return /\bnew Date\s*\(|\bDate\.now\s*\(|\bMath\.random\s*\(/.test(stripUseCacheBodies(source));
3006
+ }
3007
+ function stripUseCacheBodies(source) {
3008
+ let out = source;
3009
+ for (;; ) {
3010
+ const directive = /\{\s*(['"])use cache(?:\s*:\s*[\w-]+)?\1\s*;?/.exec(out);
3011
+ if (!directive)
3012
+ break;
3013
+ const bodyOpen = directive.index + 1;
3014
+ let balance = 1;
3015
+ let end = out.length;
3016
+ for (let i = bodyOpen;i < out.length; i += 1) {
3017
+ const ch = out[i];
3018
+ if (ch === "{")
3019
+ balance += 1;
3020
+ else if (ch === "}") {
3021
+ balance -= 1;
3022
+ if (balance === 0) {
3023
+ end = i;
3024
+ break;
3025
+ }
3026
+ }
3027
+ }
3028
+ out = `${out.slice(0, bodyOpen)}${out.slice(end)}`;
3029
+ }
3030
+ return out;
3031
+ }
3032
+ function staticRouteHandlerExplicitlyCached(route) {
3033
+ const config = route.segmentConfig;
3034
+ return config?.dynamic === "force-static" || config?.revalidate === false || typeof config?.revalidate === "number" && config.revalidate > 0;
3035
+ }
3036
+ async function needsRequestOriginForMetadataImages(appPath, route) {
3037
+ if (!await routeNullsMetadataBase(route))
3038
+ return false;
3039
+ return routeMetadataImageFiles(appPath, route.file);
3040
+ }
3041
+ async function routeNullsMetadataBase(route) {
3042
+ const sourceFiles = route.sourceFiles.filter((file) => /\.(tsx?|jsx?|mjs|cjs)$/.test(file));
3043
+ for (const file of sourceFiles) {
3044
+ try {
3045
+ if (/\bmetadataBase\s*:\s*null\b|\bmetadataBase\s*=\s*null\b/.test(await readText(file))) {
3046
+ return true;
3047
+ }
3048
+ } catch {}
3049
+ }
3050
+ return false;
3051
+ }
3052
+ function routeMetadataImageFiles(appPath, routeFile) {
3053
+ let dir = path5.dirname(routeFile);
3054
+ const root = path5.resolve(appPath);
3055
+ while (dir.startsWith(root)) {
3056
+ if (existsSync5(dir)) {
3057
+ for (const entry of readdirSync3(dir)) {
3058
+ if (/^(opengraph-image|twitter-image)\d*\.(tsx?|jsx?|mjs|png|jpe?g|gif|webp|svg)$/.test(entry)) {
3059
+ return true;
3060
+ }
3061
+ }
3062
+ }
3063
+ if (dir === root)
3064
+ break;
3065
+ dir = path5.dirname(dir);
3066
+ }
3067
+ return false;
3068
+ }
3069
+ async function copyStaticMetadataFiles(config, staticFiles, metadataFiles = discoverStaticMetadataFiles(config.appPath)) {
3070
+ for (const metadataFile of metadataFiles) {
3071
+ const target = staticMetadataOutputFile(config.outPath, metadataFile);
3072
+ const collision = staticOutputCollision(config.outPath, target);
3073
+ if (collision) {
3074
+ warnSkippedStatic(`/${metadataFile.outputPath}`, collision);
3075
+ continue;
3076
+ }
3077
+ await mkdir4(path5.dirname(target), { recursive: true });
3078
+ await copyFile3(metadataFile.file, target);
3079
+ staticFiles[metadataFile.outputPath] = {
3080
+ status: 200,
3081
+ headers: [
3082
+ ["content-type", metadataFile.contentType],
3083
+ ["cache-control", staticMetadataCacheControl]
3084
+ ]
3085
+ };
3086
+ }
3087
+ }
3088
+ function staticHtmlPath(outPath, routePath, flatLayout = false) {
3089
+ if (routePath === "/")
3090
+ return path5.join(outPath, "static", "index.html");
3091
+ const normalized = routePath.replace(/^\/|\/$/g, "");
3092
+ if (flatLayout)
3093
+ return safePublicPath(outPath, `${normalized}.html`);
3094
+ return safePublicPath(outPath, normalized, "index.html");
3095
+ }
3096
+ function encodeStaticRouteParams(params) {
3097
+ return Object.fromEntries(Object.entries(params).map(([key, value]) => [
3098
+ key,
3099
+ Array.isArray(value) ? value.map(encodeURIComponent) : encodeURIComponent(value)
3100
+ ]));
3101
+ }
3102
+ function fillRoutePath(route, params, generatedParam) {
3103
+ let value = route;
3104
+ for (const [key, param] of Object.entries(params)) {
3105
+ const segment = Array.isArray(param) ? param.join("/") : param;
3106
+ value = value.replace(`:${key}*`, segment).replace(`:${key}`, segment);
3107
+ }
3108
+ if (generatedParam && params[generatedParam] !== undefined) {
3109
+ const param = params[generatedParam];
3110
+ const segment = Array.isArray(param) ? param.join("/") : param;
3111
+ value = value.replace(":id", segment);
3112
+ }
3113
+ return value;
3114
+ }
3115
+ async function runWithNextBuildPhase(task) {
3116
+ const previous = process.env.NEXT_PHASE;
3117
+ process.env.NEXT_PHASE = "phase-production-build";
3118
+ try {
3119
+ return await task();
3120
+ } finally {
3121
+ if (previous === undefined)
3122
+ delete process.env.NEXT_PHASE;
3123
+ else
3124
+ process.env.NEXT_PHASE = previous;
3125
+ }
3126
+ }
3127
+ function cacheLifeResponseHeaders(life) {
3128
+ if (!life)
3129
+ return [];
3130
+ const headers = [];
3131
+ const { revalidateSeconds, expireSeconds, staleSeconds } = life;
3132
+ if (revalidateSeconds !== undefined && expireSeconds !== undefined) {
3133
+ const swr = Math.max(0, expireSeconds - revalidateSeconds);
3134
+ headers.push(["cache-control", `s-maxage=${revalidateSeconds}, stale-while-revalidate=${swr}`]);
3135
+ }
3136
+ if (staleSeconds !== undefined) {
3137
+ headers.push(["x-nextjs-stale-time", String(staleSeconds)]);
3138
+ }
3139
+ return headers;
3140
+ }
3141
+ function combineRevalidate(segmentRevalidate, collected) {
3142
+ const candidates = [
3143
+ ...typeof segmentRevalidate === "number" && segmentRevalidate > 0 ? [segmentRevalidate] : [],
3144
+ ...collected !== undefined && collected > 0 ? [collected] : []
3145
+ ];
3146
+ if (candidates.length === 0)
3147
+ return;
3148
+ return Math.min(...candidates);
3149
+ }
3150
+ function staticRouteHandlerPath(outPath, routePath) {
3151
+ return safePublicPath(outPath, routePath.replace(/^\/+/, "") || "index");
3152
+ }
3153
+ function staticOutputCollision(outPath, file) {
3154
+ const publicPath = path5.join(outPath, "static");
3155
+ if (existsSync5(file) && statSync2(file).isDirectory()) {
3156
+ return `${toPosixPath(path5.relative(publicPath, file))} already exists as a directory`;
3157
+ }
3158
+ let dir = path5.dirname(file);
3159
+ while (dir !== publicPath && dir !== path5.dirname(dir)) {
3160
+ if (existsSync5(dir)) {
3161
+ if (!statSync2(dir).isDirectory()) {
3162
+ return `${toPosixPath(path5.relative(publicPath, dir))} already exists as a file`;
3163
+ }
3164
+ break;
3165
+ }
3166
+ dir = path5.dirname(dir);
3167
+ }
3168
+ return null;
3169
+ }
3170
+ function rethrowIfProgrammingError(error) {
3171
+ if (error instanceof ReferenceError || error instanceof SyntaxError || error instanceof TypeError && isBuildInternalStack(error)) {
3172
+ throw error;
3173
+ }
3174
+ }
3175
+ function isBuildInternalStack(error) {
3176
+ const stack = error.stack ?? "";
3177
+ const firstFrame = stack.split(`
3178
+ `).find((line) => /^\s*at\s/.test(line)) ?? "";
3179
+ return /packages[/\\]pnext[/\\]src[/\\]/.test(firstFrame);
3180
+ }
3181
+ function logStaticBailout(routePath, reason) {
3182
+ console.log(`Static generation failed due to dynamic usage on ${routePath}, reason: ${reason}`);
3183
+ }
3184
+ async function requestApiBailoutReason(route) {
3185
+ for (const file of ownSourceFiles(route)) {
3186
+ let source;
3187
+ try {
3188
+ source = await readText(file);
3189
+ } catch {
3190
+ continue;
3191
+ }
3192
+ const match = /\b(headers|cookies|draftMode|connection)\s*\(/.exec(source);
3193
+ if (match?.[1])
3194
+ return match[1];
3195
+ }
3196
+ return "dynamic usage";
3197
+ }
3198
+ function ownSourceFiles(route) {
3199
+ const frameworkRoot3 = path5.resolve(fileURLToPath3(Bun.pathToFileURL(__PNEXT_PACKAGE_ROOT__ + "/src/cli/build.ts").href), "..", "..");
3200
+ return route.sourceFiles.filter((file) => {
3201
+ const resolved2 = path5.resolve(file);
3202
+ return !resolved2.includes(`${path5.sep}node_modules${path5.sep}`) && !resolved2.startsWith(frameworkRoot3 + path5.sep);
3203
+ });
3204
+ }
3205
+ async function schedulesDeferredWork(route) {
3206
+ for (const file of ownSourceFiles(route)) {
3207
+ let source;
3208
+ try {
3209
+ source = await readText(file);
3210
+ } catch {
3211
+ continue;
3212
+ }
3213
+ if (/\b(?:setTimeout|setImmediate|queueMicrotask)\s*\(/.test(source))
3214
+ return true;
3215
+ }
3216
+ return false;
3217
+ }
3218
+ function captureDeferredFailures(record) {
3219
+ const globals = globalThis;
3220
+ const originals = new Map;
3221
+ for (const name of ["setTimeout", "setImmediate", "queueMicrotask"]) {
3222
+ const original = globals[name];
3223
+ if (typeof original !== "function")
3224
+ continue;
3225
+ originals.set(name, original);
3226
+ globals[name] = function patched(callback, ...rest) {
3227
+ if (typeof callback !== "function")
3228
+ return original.call(this, callback, ...rest);
3229
+ const guarded = function guardedCallback(...args) {
3230
+ try {
3231
+ const value = callback.apply(this, args);
3232
+ if (isThenable(value))
3233
+ value.then(undefined, record);
3234
+ return value;
3235
+ } catch (error) {
3236
+ record(error);
3237
+ }
3238
+ };
3239
+ return original.call(this, guarded, ...rest);
3240
+ };
3241
+ }
3242
+ return () => {
3243
+ for (const [name, original] of originals)
3244
+ globals[name] = original;
3245
+ };
3246
+ }
3247
+ function isThenable(value) {
3248
+ return typeof value?.then === "function";
3249
+ }
3250
+ async function probeDeferredDynamicUsage(config, route, staticMetadataFiles, staticModuleMetadata) {
3251
+ const routePath = toNextRoutePattern(route.route || "/");
3252
+ const failures = [];
3253
+ const restore = captureDeferredFailures((error) => failures.push(error));
3254
+ beginDynamicBailoutProbe(routePath);
3255
+ try {
3256
+ await runWithWorkUnit("render", () => getRenderExtensions().collectRenderMeta(() => runWithNextBuildPhase(() => withRouteRuntime(route.segmentConfig?.runtime, () => renderPageWithStatus({
3257
+ config,
3258
+ route,
3259
+ params: {},
3260
+ url: new URL(`http://pnext.local${route.route || "/"}`),
3261
+ staticMetadataFiles,
3262
+ staticModuleMetadata
3263
+ }))), { route: route.route || "/", prerender: true }));
3264
+ await new Promise((resolve) => setTimeout(resolve, 0));
3265
+ } catch {
3266
+ return;
3267
+ } finally {
3268
+ endDynamicBailoutProbe();
3269
+ restore();
3270
+ }
3271
+ for (const failure of failures) {
3272
+ if (!(failure instanceof Error) || failure.name !== "DynamicServerError")
3273
+ continue;
3274
+ console.error(`Error occurred prerendering page "${routePath}". Read more: https://nextjs.org/docs/messages/prerender-error`);
3275
+ console.error(`${failure.name}: ${failure.message}`);
3276
+ }
3277
+ }
3278
+ function warnSkippedStatic(routePath, reason) {
3279
+ console.warn(`pnext build: skipping static output for ${routePath} (${reason}); the route will be served dynamically`);
3280
+ }
3281
+ function toNextRoutePattern(route) {
3282
+ return route.replace(/:\.\.\.([^/]+)/g, "[...$1]").replace(/:([^/]+)/g, "[$1]");
3283
+ }
3284
+ function isAfterPrerenderError(error) {
3285
+ return typeof error === "object" && error !== null && error[Symbol.for("pnext.afterPrerenderError")] === true;
3286
+ }
3287
+ function realFilePath(file) {
3288
+ try {
3289
+ return realpathSync3.native(file);
3290
+ } catch {
3291
+ return path5.resolve(file);
3292
+ }
3293
+ }
3294
+ function safePublicPath(outPath, ...segments) {
3295
+ const publicPath = path5.join(outPath, "static");
3296
+ const file = path5.join(publicPath, ...segments);
3297
+ const relative = path5.relative(publicPath, file);
3298
+ if (relative.startsWith("..") || path5.isAbsolute(relative)) {
3299
+ throw new Error(`Static output path escapes public directory: ${segments.join("/")}`);
3300
+ }
3301
+ return file;
3302
+ }
3303
+ async function copyPartytownLib(config) {
3304
+ if (!nextCompatEnabled2(config))
3305
+ return;
3306
+ if (!buildCompat().nextScriptWorkersEnabled())
3307
+ return;
3308
+ const libDir = resolvePartytownLibDir(config.root);
3309
+ if (!libDir) {
3310
+ console.warn("pnext build: experimental.nextScriptWorkers is enabled but no Partytown package was found (@qwik.dev/partytown or @builder.io/partytown); worker scripts will 404 the library until it is installed");
3311
+ return;
3312
+ }
3313
+ const target = path5.join(config.outPath, "static", "_next", "static", "~partytown");
3314
+ await mkdir4(target, { recursive: true });
3315
+ await copyPublicDir(libDir, target);
3316
+ }
3317
+ function resolvePartytownLibDir(root) {
3318
+ const requireFromRoot = createRequire(path5.join(root, "package.json"));
3319
+ for (const pkg of ["@qwik.dev/partytown", "@builder.io/partytown"]) {
3320
+ try {
3321
+ const pkgJson = requireFromRoot.resolve(`${pkg}/package.json`);
3322
+ const libDir = path5.join(path5.dirname(pkgJson), "lib");
3323
+ if (existsSync5(libDir) && statSync2(libDir).isDirectory())
3324
+ return libDir;
3325
+ } catch {}
3326
+ }
3327
+ return null;
3328
+ }
3329
+ async function copyPublicDir(from, to) {
3330
+ const files = (await listFiles(from)).map((file) => toPosixPath(path5.relative(from, file)));
3331
+ for (const relative of files) {
3332
+ const target = path5.join(to, relative);
3333
+ await mkdir4(path5.dirname(target), { recursive: true });
3334
+ await copyFile3(path5.join(from, relative), target);
3335
+ }
3336
+ return files;
3337
+ }
3338
+ export {
3339
+ buildProject,
3340
+ staticHtmlPath
3341
+ };