@wular/pnext 0.0.3 → 0.0.6

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 (392) hide show
  1. package/README.md +11 -11
  2. package/bin/pnext +1 -1
  3. package/config/lint/base.js +7 -7
  4. package/config/ts/base.json +2 -4
  5. package/config/ts/react.json +2 -6
  6. package/package.json +23 -2
  7. package/reference/compat.md +1 -1
  8. package/reference/config.md +2 -2
  9. package/reference/css.md +13 -9
  10. package/reference/dev.md +1 -1
  11. package/reference/metadata.md +7 -7
  12. package/reference/navigation.md +35 -28
  13. package/reference/performance.md +70 -70
  14. package/reference/rendering.md +17 -17
  15. package/reference/routing.md +17 -17
  16. package/reference/typegen.md +12 -8
  17. package/src/api/cache.ts +36 -37
  18. package/src/api/client-cache.ts +2 -2
  19. package/src/api/client-navigation.ts +113 -109
  20. package/src/api/dynamic.tsx +58 -55
  21. package/src/api/link.tsx +49 -52
  22. package/src/api/navigation.ts +59 -58
  23. package/src/api/server.ts +152 -144
  24. package/src/api/suspense.ts +4 -4
  25. package/src/cli/adapters/vercel-warm.ts +126 -121
  26. package/src/cli/adapters/vercel.ts +437 -443
  27. package/src/cli/analyze.ts +333 -144
  28. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  29. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  30. package/src/cli/build.ts +976 -978
  31. package/src/cli/create.ts +71 -63
  32. package/src/cli/dev.ts +116 -116
  33. package/src/cli/index.ts +88 -85
  34. package/src/cli/migrate/package-json.ts +73 -71
  35. package/src/cli/migrate/report.ts +32 -33
  36. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  37. package/src/cli/migrate/scan.ts +46 -46
  38. package/src/cli/migrate/spinner.ts +9 -9
  39. package/src/cli/migrate/tsconfig.ts +35 -35
  40. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  41. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  42. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  43. package/src/cli/start.ts +65 -66
  44. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  45. package/src/client/build.ts +794 -768
  46. package/src/client/chunk-fold.ts +245 -240
  47. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  48. package/src/client/entry.ts +162 -147
  49. package/src/client/prebuilt.ts +231 -223
  50. package/src/client/profile.ts +29 -29
  51. package/src/client/react-compiler.ts +20 -15
  52. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  53. package/src/client/reference-stub.ts +51 -51
  54. package/src/client/reference.ts +19 -19
  55. package/src/{api → client}/router/events.ts +17 -17
  56. package/src/{api → client}/router/history.ts +16 -16
  57. package/src/{api → client}/router/hub.ts +52 -53
  58. package/src/{api/router.ts → client/router/index.ts} +61 -60
  59. package/src/{api → client}/router/policies.ts +24 -24
  60. package/src/{api → client}/router/runtime.ts +1988 -1961
  61. package/src/{api → client}/router/types.ts +93 -98
  62. package/src/compat/actions/client-plugin.ts +42 -43
  63. package/src/compat/actions/client-stub.ts +14 -14
  64. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  65. package/src/compat/actions/config.ts +63 -64
  66. package/src/compat/actions/detect.ts +68 -68
  67. package/src/compat/actions/discovery.ts +105 -105
  68. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  69. package/src/compat/actions/early-submit.ts +1 -1
  70. package/src/compat/actions/endpoint.ts +198 -198
  71. package/src/compat/actions/extensions.ts +811 -0
  72. package/src/compat/actions/flight.ts +23 -23
  73. package/src/compat/actions/form-state.ts +34 -34
  74. package/src/compat/actions/hoist.ts +382 -236
  75. package/src/compat/actions/ids.ts +7 -12
  76. package/src/compat/actions/index.ts +8 -8
  77. package/src/compat/actions/instances.ts +46 -46
  78. package/src/compat/actions/origin.ts +47 -48
  79. package/src/compat/actions/protocol.ts +22 -22
  80. package/src/compat/actions/registry.ts +19 -19
  81. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  82. package/src/compat/actions/rewrite.ts +125 -125
  83. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  84. package/src/compat/actions/serve.ts +132 -136
  85. package/src/compat/actions/server-tag.ts +4 -4
  86. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  87. package/src/compat/actions/unrecognized-error.ts +4 -4
  88. package/src/compat/{index.ts → aliases.ts} +112 -109
  89. package/src/compat/bundler/bun-externals.ts +18 -18
  90. package/src/compat/bundler/cjs-exports.ts +271 -223
  91. package/src/compat/bundler/config.ts +116 -111
  92. package/src/compat/bundler/externals.ts +12 -12
  93. package/src/compat/bundler/import-meta-url.ts +19 -19
  94. package/src/compat/bundler/modularize-imports.ts +36 -33
  95. package/src/compat/bundler/new-url-asset.ts +22 -24
  96. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  97. package/src/compat/bundler/polyfill.ts +28 -28
  98. package/src/compat/bundler/react-compiler.ts +35 -29
  99. package/src/compat/bundler/react-profiler.tsx +11 -11
  100. package/src/compat/bundler/relay-transform.ts +48 -47
  101. package/src/compat/bundler/require-context.ts +119 -113
  102. package/src/compat/bundler/resolve-extensions.ts +19 -19
  103. package/src/compat/bundler/source-cache.ts +25 -25
  104. package/src/compat/bundler/static-imports.ts +7 -7
  105. package/src/compat/bundler/symlink-imports.ts +46 -46
  106. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  107. package/src/compat/bundler/wasm.ts +58 -60
  108. package/src/compat/bundler/webpack-loaders.ts +254 -241
  109. package/src/compat/bundler/worker.ts +101 -104
  110. package/src/compat/cache/build-flags.ts +29 -29
  111. package/src/compat/cache/build-prerender-errors.ts +40 -44
  112. package/src/compat/cache/custom-handler.ts +60 -53
  113. package/src/compat/cache/fetch-patch.ts +240 -240
  114. package/src/compat/cache/handler.ts +27 -31
  115. package/src/compat/cache/modern-handler.ts +148 -126
  116. package/src/compat/cache/resume-data-cache.ts +47 -45
  117. package/src/compat/cache/revalidate.ts +233 -232
  118. package/src/compat/cache/runtime-error.ts +35 -35
  119. package/src/compat/cache/use-cache-transform.ts +442 -417
  120. package/src/compat/cache/use-cache.ts +650 -614
  121. package/src/compat/cache-control.ts +140 -142
  122. package/src/compat/client/base-path.ts +21 -20
  123. package/src/compat/client/css-order.ts +18 -18
  124. package/src/compat/client/errors/bare-boundary.ts +11 -11
  125. package/src/compat/client/errors/control-flow.ts +23 -23
  126. package/src/compat/client/errors/error-boundary.ts +61 -61
  127. package/src/compat/client/errors/global-error.ts +101 -91
  128. package/src/compat/client/errors/install.ts +71 -72
  129. package/src/compat/client/errors/lazy.ts +23 -23
  130. package/src/compat/client/errors/primitive-throw.ts +47 -45
  131. package/src/compat/client/errors/soft-refresh.ts +4 -4
  132. package/src/compat/client/link-status.ts +33 -33
  133. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  134. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  135. package/src/compat/client/navigation-scroll.ts +63 -63
  136. package/src/compat/client/optimistic-routing.ts +93 -88
  137. package/src/compat/client/prefetch-cache.ts +23 -24
  138. package/src/compat/client/route-announcer.ts +35 -35
  139. package/src/compat/client/segment-cache-policy.ts +20 -20
  140. package/src/compat/client/segment-cache.ts +309 -315
  141. package/src/compat/client/segment-prefetch.ts +127 -132
  142. package/src/compat/client/trailing-slash.ts +5 -4
  143. package/src/compat/css/chunking.ts +113 -116
  144. package/src/compat/css/inline-css.ts +21 -21
  145. package/src/compat/css/lightningcss.ts +37 -38
  146. package/src/compat/css/modules.ts +161 -175
  147. package/src/compat/css/nonce.ts +7 -7
  148. package/src/compat/css/sass-plugin.ts +18 -21
  149. package/src/compat/css/sass.ts +150 -152
  150. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  151. package/src/compat/css/styled-jsx.ts +21 -21
  152. package/src/compat/edge-runtime.ts +27 -27
  153. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  154. package/src/compat/export/client.ts +29 -31
  155. package/src/compat/export/{index.ts → emit.ts} +111 -110
  156. package/src/compat/export/standalone.ts +62 -54
  157. package/src/compat/image-optimizer/cache.ts +51 -49
  158. package/src/compat/image-optimizer/detect.ts +52 -52
  159. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  160. package/src/compat/image-optimizer/source.ts +77 -80
  161. package/src/compat/lifecycle/after-scope.ts +26 -26
  162. package/src/compat/lifecycle/after.ts +48 -45
  163. package/src/compat/lifecycle/error-funnel.ts +98 -102
  164. package/src/compat/lifecycle/error-serialize.ts +30 -26
  165. package/src/compat/lifecycle/error-ui.ts +67 -32
  166. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  167. package/src/compat/lifecycle/instrumentation.ts +85 -85
  168. package/src/compat/lifecycle/node-console.ts +11 -11
  169. package/src/compat/lifecycle/testmode.ts +160 -132
  170. package/src/compat/mdx/compile.ts +60 -57
  171. package/src/compat/mdx/plugin.ts +11 -11
  172. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  173. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  174. package/src/compat/metadata.ts +75 -81
  175. package/src/compat/next/cache.ts +68 -69
  176. package/src/compat/next/canonical-url.ts +9 -9
  177. package/src/compat/next/client-cache.ts +19 -19
  178. package/src/compat/next/client-navigation.ts +112 -116
  179. package/src/compat/next/client-only.ts +1 -1
  180. package/src/compat/next/client-script.tsx +99 -93
  181. package/src/compat/next/client-server.ts +10 -10
  182. package/src/compat/next/config-loader.ts +176 -173
  183. package/src/compat/next/config.ts +7 -7
  184. package/src/compat/next/constants.cjs +6 -6
  185. package/src/compat/next/constants.ts +6 -6
  186. package/src/compat/next/custom-server.ts +26 -24
  187. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  188. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  189. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  190. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  191. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  192. package/src/compat/next/dynamic.tsx +21 -18
  193. package/src/compat/next/error.tsx +52 -52
  194. package/src/compat/next/font/cache.ts +74 -74
  195. package/src/compat/next/font/google.ts +2 -2
  196. package/src/compat/next/font/index.ts +1 -1
  197. package/src/compat/next/font/local.ts +3 -3
  198. package/src/compat/next/font/runtime-client.ts +17 -15
  199. package/src/compat/next/font/runtime.ts +443 -408
  200. package/src/compat/next/font/shared.ts +120 -108
  201. package/src/compat/next/form.tsx +63 -63
  202. package/src/compat/next/head.tsx +2 -2
  203. package/src/compat/next/headers.ts +103 -95
  204. package/src/compat/next/image/client.tsx +220 -0
  205. package/src/compat/next/image/config.ts +56 -58
  206. package/src/compat/next/image/optimizer.ts +40 -36
  207. package/src/compat/next/image/patterns.ts +37 -40
  208. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  209. package/src/compat/next/image/shared.ts +65 -57
  210. package/src/compat/next/image/static-metadata.ts +98 -107
  211. package/src/compat/next/image/validate.ts +79 -88
  212. package/src/compat/next/image.tsx +19 -23
  213. package/src/compat/next/index.ts +1 -1
  214. package/src/compat/next/legacy-image.tsx +59 -60
  215. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  216. package/src/compat/next/link.tsx +158 -158
  217. package/src/compat/next/navigation.cjs +12 -3
  218. package/src/compat/next/navigation.ts +48 -50
  219. package/src/compat/next/offline.ts +27 -27
  220. package/src/compat/next/og.ts +121 -124
  221. package/src/compat/next/preferred-region.ts +13 -14
  222. package/src/compat/next/redirects.ts +58 -56
  223. package/src/compat/next/resource-hints.ts +73 -76
  224. package/src/compat/next/rewrites.ts +130 -133
  225. package/src/compat/next/root-params.ts +45 -45
  226. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  227. package/src/compat/next/router.cjs +4 -2
  228. package/src/compat/next/router.ts +58 -61
  229. package/src/compat/next/script.tsx +108 -108
  230. package/src/compat/next/server-only.ts +1 -1
  231. package/src/compat/next/server.ts +19 -19
  232. package/src/compat/next/svgr.ts +18 -17
  233. package/src/compat/next/telemetry.ts +24 -24
  234. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  235. package/src/compat/next/user-agent.ts +53 -49
  236. package/src/compat/next/web-vitals.ts +22 -24
  237. package/src/compat/otel/api.ts +41 -41
  238. package/src/compat/otel/client-trace-metadata.ts +25 -27
  239. package/src/compat/otel/fetch-span.ts +29 -29
  240. package/src/compat/otel/tracer.ts +331 -331
  241. package/src/compat/pages/api.ts +456 -0
  242. package/src/compat/pages/client-plugin.ts +36 -36
  243. package/src/compat/pages/router-state.ts +34 -34
  244. package/src/compat/pages/{index.ts → router.ts} +130 -135
  245. package/src/compat/ppr/io.ts +12 -12
  246. package/src/compat/ppr/missing-root-params.ts +34 -38
  247. package/src/compat/ppr/root-params-scan.ts +66 -66
  248. package/src/compat/ppr/root-params-transform.ts +24 -26
  249. package/src/compat/ppr/root-params.ts +30 -30
  250. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  251. package/src/compat/protocol.ts +71 -70
  252. package/src/compat/react/action-state.ts +47 -48
  253. package/src/compat/react/client-lite.ts +15 -15
  254. package/src/compat/react/client.ts +4 -4
  255. package/src/compat/react/compiler-runtime.ts +11 -11
  256. package/src/compat/react/dom-client.ts +44 -44
  257. package/src/compat/react/dom-react-server.ts +10 -16
  258. package/src/compat/react/dom-server.ts +10 -10
  259. package/src/compat/react/dom.ts +52 -52
  260. package/src/compat/react/hooks-extra.ts +34 -35
  261. package/src/compat/react/parity.ts +64 -61
  262. package/src/compat/react/preact.ts +81 -82
  263. package/src/compat/react/react-server.ts +28 -28
  264. package/src/compat/react/router-shim.ts +1 -1
  265. package/src/compat/react/server-component-use.ts +8 -8
  266. package/src/compat/react/server-inserted-html.ts +30 -31
  267. package/src/compat/react/server.ts +53 -55
  268. package/src/compat/react/use.ts +32 -32
  269. package/src/compat/react/view-transition.ts +20 -20
  270. package/src/compat/register/actions.ts +35 -824
  271. package/src/compat/register/boot.ts +41 -41
  272. package/src/compat/register/build-tier.ts +5 -5
  273. package/src/compat/register/build.ts +74 -70
  274. package/src/compat/register/bundler.ts +161 -156
  275. package/src/compat/register/cache.ts +20 -20
  276. package/src/compat/register/client-errors.ts +3 -3
  277. package/src/compat/register/config.ts +6 -6
  278. package/src/compat/register/css-extras.ts +30 -34
  279. package/src/compat/register/edge-runtime.ts +3 -3
  280. package/src/compat/register/errors.ts +10 -12
  281. package/src/compat/register/export.ts +16 -16
  282. package/src/compat/register/font.ts +11 -11
  283. package/src/compat/register/hooks.ts +2 -2
  284. package/src/compat/register/image.ts +40 -40
  285. package/src/compat/register/index.ts +59 -62
  286. package/src/compat/register/instrumentation-client.ts +10 -10
  287. package/src/compat/register/lifecycle.ts +25 -28
  288. package/src/compat/register/mdx.ts +10 -10
  289. package/src/compat/register/middleware.ts +226 -16
  290. package/src/compat/register/otel.ts +80 -88
  291. package/src/compat/register/pages-api.ts +10 -463
  292. package/src/compat/register/ppr.ts +16 -16
  293. package/src/compat/register/protocol.ts +17 -18
  294. package/src/compat/register/proxy.ts +49 -51
  295. package/src/compat/register/render.ts +79 -76
  296. package/src/compat/register/routing.ts +162 -159
  297. package/src/compat/register/segment.ts +24 -1887
  298. package/src/compat/register/static-image.ts +3 -3
  299. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  300. package/src/compat/register/typed-routes.ts +14 -14
  301. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  302. package/src/compat/register/validation.ts +18 -18
  303. package/src/compat/segment/loading-boundary.ts +43 -45
  304. package/src/compat/segment/page-slot.ts +69 -69
  305. package/src/compat/segment/serve.ts +1884 -0
  306. package/src/compat/segment/tree.ts +113 -112
  307. package/src/compat/segment/vary-key.ts +38 -38
  308. package/src/compat/segment/vary-params.ts +138 -142
  309. package/src/compat/static-params.ts +14 -12
  310. package/src/compat/tsconfig-defaults.ts +87 -91
  311. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  312. package/src/compat/typecheck/worker.ts +15 -12
  313. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  314. package/src/compat/typed-routes/manifest.ts +174 -170
  315. package/src/compat/typed-routes/typegen.ts +127 -110
  316. package/src/compat/validation/errors.ts +16 -19
  317. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  318. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  319. package/src/compat-bootstrap.ts +16 -16
  320. package/src/config.ts +69 -69
  321. package/src/css/build.ts +230 -227
  322. package/src/css/postcss.ts +79 -80
  323. package/src/css/worker.ts +14 -15
  324. package/src/dev/client-actions.ts +10 -10
  325. package/src/dev/client-chunk-store.ts +27 -27
  326. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  327. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  328. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  329. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  330. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  331. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  332. package/src/dev/server.ts +804 -820
  333. package/src/env.ts +46 -43
  334. package/src/extensions.ts +491 -478
  335. package/src/index.ts +8 -8
  336. package/src/internal.ts +20 -23
  337. package/src/{islands → render}/boundary-error.ts +3 -3
  338. package/src/render/hooks.ts +71 -71
  339. package/src/render/island-context.ts +14 -14
  340. package/src/render/metadata.ts +310 -310
  341. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  342. package/src/{ppr.ts → render/ppr.ts} +244 -245
  343. package/src/render/renderer.ts +2076 -2082
  344. package/src/render/resource-hints.ts +16 -17
  345. package/src/render/slots.tsx +224 -235
  346. package/src/{islands → render}/static-children.ts +9 -12
  347. package/src/{islands → render}/static-slots.ts +37 -37
  348. package/src/{cache/context.ts → request/cache.ts} +20 -20
  349. package/src/request/context.ts +107 -107
  350. package/src/{dynamic/source.ts → resolve/dynamic.ts} +152 -143
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +442 -186
  354. package/src/resolve/source-text.ts +37 -37
  355. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  356. package/src/routing/forwarded.ts +19 -19
  357. package/src/routing/handler.ts +84 -91
  358. package/src/routing/href.ts +69 -70
  359. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  360. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  361. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  362. package/src/routing/routes.ts +833 -848
  363. package/src/routing/slots.ts +164 -160
  364. package/src/runtime/loader.ts +952 -0
  365. package/src/{dev → runtime}/module-cache.ts +309 -287
  366. package/src/{dev → runtime}/module-generations.ts +9 -9
  367. package/src/{dev → runtime}/module-transform.ts +81 -72
  368. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  369. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  370. package/src/runtime/vendor.ts +425 -404
  371. package/src/styles.d.ts +9 -0
  372. package/src/types.ts +320 -335
  373. package/src/utils/ansi.ts +5 -5
  374. package/src/utils/{source.ts → code.ts} +15 -12
  375. package/src/utils/content-type.ts +3 -3
  376. package/src/utils/decode.ts +2 -2
  377. package/src/utils/dev-profile.ts +13 -13
  378. package/src/utils/error-log.ts +6 -6
  379. package/src/utils/esbuild.ts +18 -18
  380. package/src/utils/fs-cache.ts +13 -13
  381. package/src/utils/fs.ts +57 -49
  382. package/src/utils/html.ts +20 -24
  383. package/src/utils/native-require.ts +8 -8
  384. package/src/utils/serialize.ts +139 -146
  385. package/src/utils/verbose.ts +18 -18
  386. package/src/cli/analyze-print.ts +0 -181
  387. package/src/compat/middleware/manifest.ts +0 -210
  388. package/src/compat/next/image-client.tsx +0 -215
  389. package/src/compat/next/link-usage.ts +0 -29
  390. package/src/css/index.ts +0 -2
  391. package/src/render/index.ts +0 -1
  392. package/src/style-modules.d.ts +0 -9
@@ -10,42 +10,39 @@
10
10
  // own. This file re-runs that registrar (idempotent) so calling it alone still yields a fully wired
11
11
  // compat layer.
12
12
 
13
- import type { ResolvedConfig } from '../../config';
14
- import { registerCompatBootExtensions } from './boot';
15
- import type * as BuildTier from './build-tier';
16
- import { registerCacheExtensions } from './cache';
17
- import { registerActionExtensions } from './actions';
18
- import { registerRenderExtensions } from './render';
19
- import { registerProxyExtensions } from './proxy';
20
- import { registerConfigSource } from './config';
21
- import {
22
- registerProtocolExtensions,
23
- registerProtocolRequestValidation,
24
- } from './protocol';
25
- import { registerLifecycleExtensions } from './lifecycle';
26
- import { registerImageExtensions } from './image';
27
- import { registerErrorExtensions } from './errors';
28
- import { registerFontExtensions } from './font';
29
- import { registerStaticImageExtensions } from './static-image';
30
- import { registerUseCacheExtensions } from './usecache';
31
- import { registerClientErrorExtensions } from './client-errors';
32
- import { registerPprExtensions } from './ppr';
33
- import { registerMdxExtensions } from './mdx';
34
- import { registerOtelExtensions, registerOtelRootInterceptor } from './otel';
35
- import { registerInstrumentationClientExtensions } from './instrumentation-client';
36
- import { registerMiscExtensions } from './misc';
37
- import { registerCssExtrasExtensions } from './css-extras';
38
- import { registerSegmentExtensions } from './segment';
39
- import { registerBundlerExtensions } from './bundler';
40
- import { registerPagesApiExtensions } from './pages-api';
41
- import { registerEdgeRuntimeExtensions } from './edge-runtime';
13
+ import type { ResolvedConfig } from '../../config'
14
+ import { registerCompatBootExtensions } from './boot'
15
+ import type * as BuildTier from './build-tier'
16
+ import { registerCacheExtensions } from './cache'
17
+ import { registerActionExtensions } from './actions'
18
+ import { registerRenderExtensions } from './render'
19
+ import { registerProxyExtensions } from './proxy'
20
+ import { registerConfigSource } from './config'
21
+ import { registerProtocolExtensions, registerProtocolRequestValidation } from './protocol'
22
+ import { registerLifecycleExtensions } from './lifecycle'
23
+ import { registerImageExtensions } from './image'
24
+ import { registerErrorExtensions } from './errors'
25
+ import { registerFontExtensions } from './font'
26
+ import { registerStaticImageExtensions } from './static-image'
27
+ import { registerUseCacheExtensions } from './use-cache'
28
+ import { registerClientErrorExtensions } from './client-errors'
29
+ import { registerPprExtensions } from './ppr'
30
+ import { registerMdxExtensions } from './mdx'
31
+ import { registerOtelExtensions, registerOtelRootInterceptor } from './otel'
32
+ import { registerInstrumentationClientExtensions } from './instrumentation-client'
33
+ import { registerMiscExtensions } from './taint'
34
+ import { registerCssExtrasExtensions } from './css-extras'
35
+ import { registerSegmentExtensions } from './segment'
36
+ import { registerBundlerExtensions } from './bundler'
37
+ import { registerPagesApiExtensions } from './pages-api'
38
+ import { registerEdgeRuntimeExtensions } from './edge-runtime'
42
39
 
43
40
  export interface RegisterCompatOptions {
44
41
  /**
45
42
  * Serving only (the dev server). Skips the build-only domains — nothing on a
46
43
  * request path reads what they register — so their module graphs never load.
47
44
  */
48
- serve?: boolean;
45
+ serve?: boolean
49
46
  }
50
47
 
51
48
  export async function registerCompatExtensions(
@@ -56,56 +53,56 @@ export async function registerCompatExtensions(
56
53
  // outright when only serving (see RegisterCompatOptions.serve).
57
54
  const build: typeof BuildTier | undefined = options.serve
58
55
  ? undefined
59
- : await import('./build-tier');
56
+ : await import('./build-tier')
60
57
  // Route conventions, page/CSS extensions, module aliases, proxy names and the
61
58
  // lifecycle init hooks — already done when the boot tier ran first.
62
- registerCompatBootExtensions(config);
63
- build?.registerBuildCompatExtensions();
64
- registerConfigSource();
59
+ registerCompatBootExtensions(config)
60
+ build?.registerBuildCompatExtensions()
61
+ registerConfigSource()
65
62
  // The otel ROOT-span interceptor must run before every short-circuiting
66
63
  // interceptor (segment prefetch, RSC protocol, action dispatch) so those
67
64
  // responses are traced too; the rest of otel registers last (below).
68
- registerOtelRootInterceptor(config);
65
+ registerOtelRootInterceptor(config)
69
66
  // Protocol validation next: an invalid next-router-state-tree must 500 before
70
67
  // the segment/action interceptors answer the request.
71
- registerProtocolRequestValidation(config);
68
+ registerProtocolRequestValidation(config)
72
69
  // Typed-routes typegen and typecheck run before structural validation so a type error surfaces ahead of
73
70
  // runtime checks, matching `next build`, which runs tsc before its own validations. The typecheck only
74
71
  // covers .ts/.tsx pages/layouts/handlers via the generated validator, so JS-only fixtures still fall
75
72
  // through to the structural validation below with their runtime error message.
76
- build?.registerTypedRoutesExtensions(config);
73
+ build?.registerTypedRoutesExtensions(config)
77
74
  // Build validation fails fast before the remaining build steps run.
78
- build?.registerValidationExtensions(config);
79
- registerCacheExtensions(config);
75
+ build?.registerValidationExtensions(config)
76
+ registerCacheExtensions(config)
80
77
  // Before actions: the /_tree prefetch responder must intercept ahead of the
81
78
  // action dispatch interceptor.
82
- registerSegmentExtensions(config);
83
- registerActionExtensions(config);
84
- registerPagesApiExtensions(config);
85
- registerEdgeRuntimeExtensions();
86
- registerRenderExtensions(config);
87
- registerProxyExtensions(config);
88
- registerProtocolExtensions(config);
89
- registerLifecycleExtensions(config);
90
- registerImageExtensions(config);
91
- registerErrorExtensions(config);
92
- registerFontExtensions(config);
93
- build?.registerMiddlewareExtensions();
94
- build?.registerExportExtensions(config);
95
- registerStaticImageExtensions();
96
- registerUseCacheExtensions(config);
97
- registerClientErrorExtensions(config);
98
- registerPprExtensions(config);
99
- registerMiscExtensions(config);
100
- registerBundlerExtensions(config);
79
+ registerSegmentExtensions(config)
80
+ registerActionExtensions(config)
81
+ registerPagesApiExtensions(config)
82
+ registerEdgeRuntimeExtensions()
83
+ registerRenderExtensions(config)
84
+ registerProxyExtensions(config)
85
+ registerProtocolExtensions(config)
86
+ registerLifecycleExtensions(config)
87
+ registerImageExtensions(config)
88
+ registerErrorExtensions(config)
89
+ registerFontExtensions(config)
90
+ build?.registerMiddlewareExtensions()
91
+ build?.registerExportExtensions(config)
92
+ registerStaticImageExtensions()
93
+ registerUseCacheExtensions(config)
94
+ registerClientErrorExtensions(config)
95
+ registerPprExtensions(config)
96
+ registerMiscExtensions(config)
97
+ registerBundlerExtensions(config)
101
98
  // After registerActionExtensions: composes (not clobbers) clientEsbuildPlugins.
102
- registerCssExtrasExtensions(config);
99
+ registerCssExtrasExtensions(config)
103
100
  // MDX last: it composes (not clobbers) clientEsbuildPlugins, so it must
104
101
  // capture every previously-registered plugin factory.
105
- registerMdxExtensions(config);
102
+ registerMdxExtensions(config)
106
103
  // Otel after everything: its route re-stamp interceptor must observe the
107
104
  // post-rewrite request (the root span opens in the EARLY interceptor above).
108
- registerOtelExtensions(config);
105
+ registerOtelExtensions(config)
109
106
  // After otel: composes (not clobbers) the documentHeadTags extension.
110
- registerInstrumentationClientExtensions(config);
107
+ registerInstrumentationClientExtensions(config)
111
108
  }
@@ -11,25 +11,25 @@
11
11
  // The router-side hook is surfaced through the `window.__PNEXT_ON_ROUTER_TRANSITION_START__` global the
12
12
  // bundle registers; the client router calls it at the start of push/replace/traverse navigations.
13
13
 
14
- import type { ResolvedConfig } from '../../config';
15
- import { registerBuildSteps } from '../../extensions';
16
- import { getDocumentScriptExtensions, setDocumentScriptExtensions } from '../../render/hooks';
17
- import { nextCompatEnabled } from '../index';
14
+ import type { ResolvedConfig } from '../../config'
15
+ import { registerBuildSteps } from '../../extensions'
16
+ import { getDocumentScriptExtensions, setDocumentScriptExtensions } from '../../render/hooks'
17
+ import { nextCompatEnabled } from '../aliases'
18
18
  import {
19
19
  buildInstrumentationClient,
20
20
  instrumentationClientHeadTag,
21
- } from '../lifecycle/instrumentation-client';
21
+ } from '../lifecycle/instrumentation-client'
22
22
 
23
23
  export function registerInstrumentationClientExtensions(config: ResolvedConfig): void {
24
- if (!nextCompatEnabled(config)) return;
24
+ if (!nextCompatEnabled(config)) return
25
25
 
26
26
  registerBuildSteps(async ctx => {
27
- await buildInstrumentationClient(ctx.config);
28
- });
27
+ await buildInstrumentationClient(ctx.config)
28
+ })
29
29
 
30
- const previousHeadTags = getDocumentScriptExtensions().documentHeadTags;
30
+ const previousHeadTags = getDocumentScriptExtensions().documentHeadTags
31
31
  setDocumentScriptExtensions({
32
32
  documentHeadTags: (cfg, ctx) =>
33
33
  `${previousHeadTags?.(cfg, ctx) ?? ''}${instrumentationClientHeadTag(cfg)}`,
34
- });
34
+ })
35
35
  }
@@ -14,73 +14,70 @@
14
14
  // registerLifecycleBootHooks(), while the request interceptor registers with the rest of the graph so its
15
15
  // position in the interceptor chain is unchanged.
16
16
 
17
- import type { ResolvedConfig } from '../../config';
17
+ import type { ResolvedConfig } from '../../config'
18
18
  import {
19
19
  registerInitHooks,
20
20
  registerRequestInterceptors,
21
21
  setRequestExtensions,
22
22
  type RequestInterceptor,
23
- } from '../../extensions';
24
- import { nextCompatEnabled } from '../index';
25
- import { getNextConfig } from '../next/config-loader';
26
- import { instrumentationReady, loadInstrumentation } from '../lifecycle/instrumentation';
27
- import {
28
- installUnhandledRejectionGuard,
29
- reportRequestErrorToUser,
30
- } from '../lifecycle/error-funnel';
31
- import { activateTestProxy, installTestProxyFetch } from '../lifecycle/testmode';
32
- import { recordRequestPath } from '../lifecycle/after-scope';
33
- import { installNodeConsoleFormat } from '../lifecycle/node-console';
23
+ } from '../../extensions'
24
+ import { nextCompatEnabled } from '../aliases'
25
+ import { getNextConfig } from '../next/config-loader'
26
+ import { instrumentationReady, loadInstrumentation } from '../lifecycle/instrumentation'
27
+ import { installUnhandledRejectionGuard, reportRequestErrorToUser } from '../lifecycle/error-funnel'
28
+ import { activateTestProxy, installTestProxyFetch } from '../lifecycle/testmode'
29
+ import { recordRequestPath } from '../lifecycle/after-scope'
30
+ import { installNodeConsoleFormat } from '../lifecycle/node-console'
34
31
 
35
32
  /** experimental.testProxy from the loaded next.config. */
36
33
  function testProxyEnabled(): boolean {
37
- const experimental = getNextConfig().experimental as { testProxy?: boolean } | undefined;
38
- return experimental?.testProxy === true;
34
+ const experimental = getNextConfig().experimental as { testProxy?: boolean } | undefined
35
+ return experimental?.testProxy === true
39
36
  }
40
37
 
41
38
  /** Boot tier: everything that must be installed before the server starts. */
42
39
  export function registerLifecycleBootHooks(config: ResolvedConfig): void {
43
- if (!nextCompatEnabled(config)) return;
44
- installNodeConsoleFormat();
40
+ if (!nextCompatEnabled(config)) return
41
+ installNodeConsoleFormat()
45
42
 
46
43
  // The user's onRequestError hook (once instrumentation has loaded) receives
47
44
  // every real request error; control-flow errors are filtered in the funnel.
48
- setRequestExtensions({ onRequestError: reportRequestErrorToUser });
45
+ setRequestExtensions({ onRequestError: reportRequestErrorToUser })
49
46
 
50
47
  // Keep the server alive when an SSR error escapes as an unhandled rejection
51
48
  // (a client component that throws during server render — preact resolves the
52
49
  // string pass to '' and floats the rejection). Without this the process
53
50
  // crashes and every later request in the shared harness server fails.
54
- installUnhandledRejectionGuard();
51
+ installUnhandledRejectionGuard()
55
52
 
56
53
  // Load instrumentation and patch fetch at server start. The fetch patch is a no-op until a request
57
54
  // activates the test proxy. Instrumentation register() must NOT run during a build: Next only detects
58
55
  // the file at build and runs register() at server boot, so build prerenders see a noop tracer - a live
59
56
  // TracerProvider at build would bake real span ids into the static shell and 'use cache' entries.
60
57
  registerInitHooks((cfg, context) => {
61
- if (!context.build) loadInstrumentation(cfg);
62
- installTestProxyFetch();
63
- });
58
+ if (!context.build) loadInstrumentation(cfg)
59
+ installTestProxyFetch()
60
+ })
64
61
  }
65
62
 
66
63
  export function registerLifecycleExtensions(config: ResolvedConfig): void {
67
- if (!nextCompatEnabled(config)) return;
64
+ if (!nextCompatEnabled(config)) return
68
65
 
69
66
  const lifecycleInterceptor: RequestInterceptor = async request => {
70
67
  // Block the very first requests until instrumentation register() settles.
71
- await instrumentationReady();
68
+ await instrumentationReady()
72
69
  // Remember the route pathname so an after() callback that runs detached
73
70
  // (after a page render) can name the route in its "used ... inside after()"
74
71
  // error, matching Next's message.
75
72
  try {
76
- recordRequestPath(new URL(request.url).pathname);
73
+ recordRequestPath(new URL(request.url).pathname)
77
74
  } catch {
78
75
  // ignore malformed URLs
79
76
  }
80
77
  // Route this request's outgoing fetch through the test proxy when it carries
81
78
  // Next-Test-* headers (gated on experimental.testProxy in next.config).
82
- if (testProxyEnabled()) activateTestProxy(request.headers);
83
- return undefined;
84
- };
85
- registerRequestInterceptors(lifecycleInterceptor);
79
+ if (testProxyEnabled()) activateTestProxy(request.headers)
80
+ return undefined
81
+ }
82
+ registerRequestInterceptors(lifecycleInterceptor)
86
83
  }
@@ -22,18 +22,18 @@
22
22
  // extensions at boot, so the registration itself lives in register-boot.ts; only the compilation
23
23
  // wiring is here.
24
24
 
25
- import type { Plugin } from 'esbuild';
26
- import type { ResolvedConfig } from '../../config';
27
- import { getBundlerExtensions, setBundlerExtensions } from '../../extensions';
28
- import { nextCompatEnabled } from '../../render/hooks';
29
- import { mdxEsbuildPlugin } from '../mdx/plugin';
25
+ import type { Plugin } from 'esbuild'
26
+ import type { ResolvedConfig } from '../../config'
27
+ import { getBundlerExtensions, setBundlerExtensions } from '../../extensions'
28
+ import { nextCompatEnabled } from '../../render/hooks'
29
+ import { mdxEsbuildPlugin } from '../mdx/plugin'
30
30
 
31
31
  export function registerMdxExtensions(config: ResolvedConfig): void {
32
- if (!nextCompatEnabled(config)) return;
32
+ if (!nextCompatEnabled(config)) return
33
33
 
34
- const existing = getBundlerExtensions();
35
- const priorClient = existing.clientEsbuildPlugins;
36
- const priorServer = existing.serverEsbuildPlugins;
34
+ const existing = getBundlerExtensions()
35
+ const priorClient = existing.clientEsbuildPlugins
36
+ const priorServer = existing.serverEsbuildPlugins
37
37
 
38
38
  setBundlerExtensions({
39
39
  clientEsbuildPlugins: (cfg: ResolvedConfig): Plugin[] => [
@@ -44,5 +44,5 @@ export function registerMdxExtensions(config: ResolvedConfig): void {
44
44
  ...priorServer(cfg, opts),
45
45
  mdxEsbuildPlugin(config.root),
46
46
  ],
47
- });
47
+ })
48
48
  }
@@ -3,21 +3,29 @@
3
3
  // functions-config-manifest.json). The middleware runtime itself is the existing proxy machinery; this
4
4
  // module owns only the build-time manifest output.
5
5
 
6
- import path from 'node:path';
7
- import { fileURLToPath } from 'node:url';
8
- import { registerBuildSteps } from '../../extensions';
9
- import { nextCompatEnabled } from '../../compat';
10
- import { findProxyFile, proxyExternalLoadTarget } from '../../proxy';
11
- import { devServerModuleHref } from '../../dev/imports';
12
- import { toPosixPath } from '../../utils/fs';
13
- import type { RouteManifestEntry } from '../../types';
14
- import { writeMiddlewareManifests } from '../middleware/manifest';
6
+ import path from 'node:path'
7
+ import { mkdir, writeFile } from 'node:fs/promises'
8
+ import { fileURLToPath } from 'node:url'
9
+ import { registerBuildSteps } from '../../extensions'
10
+ import { nextCompatEnabled } from '../../compat/aliases'
11
+ import {
12
+ findProxyFile,
13
+ proxyExternalLoadTarget,
14
+ type ProxyConfig,
15
+ type ProxyModule,
16
+ } from '../../routing/proxy'
17
+ import { devServerModuleHref } from '../../runtime/modules'
18
+ import { pathToFileHref, type ResolvedConfig } from '../../config'
19
+ import { toPosixPath } from '../../utils/fs'
20
+ import type { RouteManifestEntry } from '../../types'
21
+ import { readMiddlewareWasmBindingsForOutPath } from '../bundler/wasm'
22
+ import { preferredRegionForRoute } from '../next/preferred-region'
15
23
 
16
24
  export function registerMiddlewareExtensions(): void {
17
25
  registerBuildSteps(async ({ config, routes }) => {
18
- if (!nextCompatEnabled(config)) return;
19
- const file = findProxyFile(config);
20
- let relative: string | undefined;
26
+ if (!nextCompatEnabled(config)) return
27
+ const file = findProxyFile(config)
28
+ let relative: string | undefined
21
29
  if (file) {
22
30
  // Must name the SAME artifact buildProxyModule emits (the build copies it to
23
31
  // .next/server/middleware.js), so every option that keys the compile profile is spelled out here - a
@@ -27,10 +35,212 @@ export function registerMiddlewareExtensions(): void {
27
35
  conditionTarget: 'edge',
28
36
  externalLoadTarget: proxyExternalLoadTarget(file),
29
37
  reactServerLayer: true,
30
- });
31
- relative = toPosixPath(path.relative(config.outPath, fileURLToPath(href)));
38
+ })
39
+ relative = toPosixPath(path.relative(config.outPath, fileURLToPath(href)))
32
40
  }
33
41
  // Edge-runtime segments produce manifest entries even with no middleware.
34
- await writeMiddlewareManifests(config, relative, routes as RouteManifestEntry[]);
35
- });
42
+ await writeMiddlewareManifests(config, relative, routes as RouteManifestEntry[])
43
+ })
44
+ }
45
+
46
+ // Middleware manifest emission.
47
+ //
48
+ // Writes the two Next-shaped manifests a few suites read directly from the build output:
49
+ // - `<out>/server/middleware-manifest.json`: the edge-middleware entry with its compiled matchers,
50
+ // entrypoint and files list.
51
+ // - `<out>/server/functions-config-manifest.json`: the node-runtime variant, when the middleware opts
52
+ // into `runtime: 'nodejs'`.
53
+ //
54
+ // Only the fields the tests read are populated. A pure-core app writes neither.
55
+
56
+ interface ManifestMatcher {
57
+ regexp: string
58
+ originalSource: string
59
+ }
60
+
61
+ interface MiddlewareEntry {
62
+ name: string
63
+ page: string
64
+ matchers: ManifestMatcher[]
65
+ wasm: { name: string; filePath: string }[]
66
+ assets: never[]
67
+ files: string[]
68
+ entrypoint: string
69
+ env: Record<string, string>
70
+ }
71
+
72
+ interface MiddlewareManifest {
73
+ version: number
74
+ sortedMiddleware: string[]
75
+ middleware: Record<string, MiddlewareEntry>
76
+ functions: Record<string, unknown>
77
+ }
78
+
79
+ interface FunctionsConfigManifest {
80
+ version: number
81
+ functions: Record<string, { runtime: string; matchers: ManifestMatcher[] }>
82
+ }
83
+
84
+ /**
85
+ * Emit the middleware manifests for the resolved proxy file, if any. `entryFile`
86
+ * is the compiled proxy module path (relative to `outPath`, posix) produced by
87
+ * the build; it is recorded as the manifest `entrypoint` under `server/`.
88
+ */
89
+ export async function writeMiddlewareManifests(
90
+ config: ResolvedConfig,
91
+ entryFile: string | undefined,
92
+ routes: RouteManifestEntry[] = [],
93
+ ): Promise<void> {
94
+ const source = findProxyFile(config)
95
+ // Edge-runtime app segments are manifest `functions` entries alongside the
96
+ // middleware, keyed by their app path (route groups included) — an app with
97
+ // an edge page and no middleware still writes the manifest for them.
98
+ const functions = edgeFunctionEntries(config, routes)
99
+ if (!source || !entryFile) {
100
+ if (Object.keys(functions).length === 0) return
101
+ const serverDir = path.join(config.outPath, 'server')
102
+ await mkdir(serverDir, { recursive: true })
103
+ await writeFile(
104
+ path.join(serverDir, 'middleware-manifest.json'),
105
+ `${JSON.stringify({ ...emptyMiddlewareManifest(), functions }, null, 2)}\n`,
106
+ )
107
+ return
108
+ }
109
+
110
+ const moduleFile = path.resolve(config.outPath, entryFile)
111
+ const module = (await import(pathToFileHref(moduleFile))) as ProxyModule
112
+ const matchers = manifestMatchers(module.config)
113
+ const runtime = proxyRuntime(module.config)
114
+ const entrypoint = toServerEntrypoint(entryFile)
115
+
116
+ const serverDir = path.join(config.outPath, 'server')
117
+ await mkdir(serverDir, { recursive: true })
118
+
119
+ if (runtime === 'nodejs') {
120
+ const functionsConfig: FunctionsConfigManifest = {
121
+ version: 1,
122
+ functions: { '/_middleware': { runtime: 'nodejs', matchers } },
123
+ }
124
+ await writeFile(
125
+ path.join(serverDir, 'functions-config-manifest.json'),
126
+ `${JSON.stringify(functionsConfig, null, 2)}\n`,
127
+ )
128
+ // A node-runtime middleware still lists an empty edge middleware manifest so
129
+ // consumers that always read it find a valid (empty) shape.
130
+ await writeFile(
131
+ path.join(serverDir, 'middleware-manifest.json'),
132
+ `${JSON.stringify({ ...emptyMiddlewareManifest(), functions }, null, 2)}\n`,
133
+ )
134
+ return
135
+ }
136
+
137
+ const entry: MiddlewareEntry = {
138
+ name: 'middleware',
139
+ page: '/',
140
+ matchers,
141
+ wasm: readMiddlewareWasmBindingsForOutPath(config.outPath),
142
+ assets: [],
143
+ files: [entrypoint],
144
+ entrypoint,
145
+ env: {},
146
+ }
147
+ const manifest: MiddlewareManifest = {
148
+ version: 3,
149
+ sortedMiddleware: ['/'],
150
+ middleware: { '/': entry },
151
+ functions,
152
+ }
153
+ await writeFile(
154
+ path.join(serverDir, 'middleware-manifest.json'),
155
+ `${JSON.stringify(manifest, null, 2)}\n`,
156
+ )
157
+ }
158
+
159
+ function emptyMiddlewareManifest(): MiddlewareManifest {
160
+ return { version: 3, sortedMiddleware: [], middleware: {}, functions: {} }
161
+ }
162
+
163
+ /**
164
+ * Manifest `functions` entries for app segments that declared
165
+ * `export const runtime = 'edge'`. Next keys them by the segment's app path
166
+ * (route groups kept, e.g. `/(group)/group/page`) and records the URL the
167
+ * segment answers as its matcher.
168
+ */
169
+ function edgeFunctionEntries(
170
+ config: ResolvedConfig,
171
+ routes: RouteManifestEntry[],
172
+ ): Record<string, unknown> {
173
+ const entries: Record<string, unknown> = {}
174
+ if (!config.appPath) return entries
175
+ for (const route of routes) {
176
+ const runtime = route.segmentConfig?.runtime
177
+ if (runtime !== 'edge' && runtime !== 'experimental-edge') continue
178
+ const page = appManifestKey(config.appPath, route.file)
179
+ if (!page) continue
180
+ const regions = preferredRegionForRoute(route)
181
+ entries[page] = {
182
+ files: [],
183
+ name: `app${page}`,
184
+ page,
185
+ matchers: [{ regexp: `^${routeMatcherRegexp(route.route)}$`, originalSource: route.route }],
186
+ wasm: [],
187
+ assets: [],
188
+ env: {},
189
+ ...(regions ? { regions } : {}),
190
+ }
191
+ }
192
+ return entries
193
+ }
194
+
195
+ // `<app>/(group)/group/page.tsx` → `/(group)/group/page`.
196
+ function appManifestKey(appPath: string, file: string): string | undefined {
197
+ const relative = toPosixPath(path.relative(appPath, file))
198
+ if (!relative || relative.startsWith('..')) return undefined
199
+ return `/${relative.replace(/\.[^./]+$/, '')}`
200
+ }
201
+
202
+ // The URL regexp Next records for a segment: literal path with each dynamic
203
+ // segment widened to a single path part.
204
+ function routeMatcherRegexp(route: string): string {
205
+ return route.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/:([^/\\]+)/g, '[^/]+')
206
+ }
207
+
208
+ // Compile config.matcher entries into { regexp, originalSource } pairs. With no
209
+ // matcher, the middleware runs on every path: Next records the `/:path*` source
210
+ // and its `^/.*$` regexp.
211
+ function manifestMatchers(config: ProxyConfig | undefined): ManifestMatcher[] {
212
+ const matcher = config?.matcher
213
+ if (!matcher) return [{ regexp: '^/.*$', originalSource: '/:path*' }]
214
+ const list = Array.isArray(matcher) ? matcher : [matcher]
215
+ return list.map(item => {
216
+ const originalSource = typeof item === 'string' ? item : item.source
217
+ return { regexp: `^${matcherRegexp(originalSource)}$`, originalSource }
218
+ })
219
+ }
220
+
221
+ // Mirror src/proxy.ts matcherPattern for the manifest regexp string (kept in
222
+ // sync with the runtime matcher). Raw regex sources pass through unchanged.
223
+ function matcherRegexp(matcher: string): string {
224
+ if (matcher.includes('(')) return matcher
225
+ if (matcher === '/') return '/'
226
+ let source = ''
227
+ for (const segment of matcher.split('/').filter(Boolean)) {
228
+ if (/^:[^/]+\*$/.test(segment)) source += '(?:/.*)?'
229
+ else if (/^:[^/]+$/.test(segment)) source += '/[^/]+'
230
+ else source += `/${segment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`
231
+ }
232
+ return source || '/'
233
+ }
234
+
235
+ function proxyRuntime(config: ProxyConfig | undefined): 'edge' | 'nodejs' {
236
+ const runtime = (config as { runtime?: unknown } | undefined)?.runtime
237
+ return runtime === 'nodejs' ? 'nodejs' : 'edge'
238
+ }
239
+
240
+ // Record the compiled entry under the `server/` prefix Next uses, forcing a
241
+ // `.js` extension (the manifest tests assert `^server/.+\.(js|mjs|cjs)$`).
242
+ function toServerEntrypoint(entryFile: string): string {
243
+ const posix = toPosixPath(entryFile).replace(/^\.?\//, '')
244
+ const withinServer = posix.startsWith('server/') ? posix : `server/${path.posix.basename(posix)}`
245
+ return withinServer.replace(/\.[^./]+$/, '.js')
36
246
  }