@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
@@ -1,12 +1,13 @@
1
- import { isNotFoundError, isRedirectError } from '../api/navigation';
2
- import { getWorkUnit, runWithRequest } from '../request/context';
3
- import { nextResponseMeta, toNextRequest } from '../api/server';
4
- import { reportRequestError } from '../extensions';
5
- import type { NextRequest, RouteManifestEntry, RouteParamValue } from '../types';
1
+ import { isNotFoundError, isRedirectError } from '../api/navigation'
2
+ import { getWorkUnit, runWithRequest } from '../request/context'
3
+ import { nextResponseMeta, toNextRequest } from '../api/server'
4
+ import { reportRequestError } from '../extensions'
5
+ import type { NextRequest, RouteManifestEntry, RouteParamValue } from '../types'
6
+ import { safeDecode } from '../utils/decode'
6
7
 
7
- const routeMethods = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'] as const;
8
+ const routeMethods = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'] as const
8
9
 
9
- type RouteMethod = (typeof routeMethods)[number];
10
+ type RouteMethod = (typeof routeMethods)[number]
10
11
 
11
12
  // Methods that are valid HTTP verbs but may be unimplemented on a route (405),
12
13
  // vs. tokens that are not HTTP methods at all (400). Next answers 400 for the
@@ -21,32 +22,32 @@ const httpMethods = new Set([
21
22
  'OPTIONS',
22
23
  'CONNECT',
23
24
  'TRACE',
24
- ]);
25
+ ])
25
26
 
26
27
  interface RouteHandlerContext {
27
- params?: Promise<Record<string, RouteParamValue>>;
28
+ params?: Promise<Record<string, RouteParamValue>>
28
29
  }
29
30
 
30
31
  interface HandleRouteOptions {
31
32
  /** Absolute route file path, used in the "no response returned" CLI error. */
32
- routeFile?: string;
33
+ routeFile?: string
33
34
  }
34
35
 
35
36
  export interface RouteHandlerModule {
36
- params?: () => Record<string, RouteParamValue>[] | Promise<Record<string, RouteParamValue>[]>;
37
- GET?: RouteHandler;
38
- HEAD?: RouteHandler;
39
- POST?: RouteHandler;
40
- PUT?: RouteHandler;
41
- PATCH?: RouteHandler;
42
- DELETE?: RouteHandler;
43
- OPTIONS?: RouteHandler;
37
+ params?: () => Record<string, RouteParamValue>[] | Promise<Record<string, RouteParamValue>[]>
38
+ GET?: RouteHandler
39
+ HEAD?: RouteHandler
40
+ POST?: RouteHandler
41
+ PUT?: RouteHandler
42
+ PATCH?: RouteHandler
43
+ DELETE?: RouteHandler
44
+ OPTIONS?: RouteHandler
44
45
  }
45
46
 
46
47
  type RouteHandler = (
47
48
  request: NextRequest,
48
49
  context: RouteHandlerContext,
49
- ) => Response | undefined | void | Promise<Response | undefined | void>;
50
+ ) => Response | undefined | void | Promise<Response | undefined | void>
50
51
 
51
52
  export async function handleRouteModule(
52
53
  module: RouteHandlerModule,
@@ -58,16 +59,16 @@ export async function handleRouteModule(
58
59
  // draftMode().enable() append set-cookie here while the handler runs, and
59
60
  // the headers are merged onto whatever response goes out — including the
60
61
  // synthesized redirect response when the handler throws redirect().
61
- const responseHeaders = new Headers();
62
- const method = request.method.toUpperCase();
62
+ const responseHeaders = new Headers()
63
+ const method = request.method.toUpperCase()
63
64
  try {
64
65
  // A request method that is not a valid HTTP verb is a bad request, not an
65
66
  // unimplemented one (Next returns 400 with an empty body).
66
- if (!httpMethods.has(method)) return new Response(null, { status: 400 });
67
+ if (!httpMethods.has(method)) return new Response(null, { status: 400 })
67
68
 
68
69
  const handler = routeMethods.includes(method as RouteMethod)
69
70
  ? module[method as RouteMethod]
70
- : undefined;
71
+ : undefined
71
72
 
72
73
  if (!handler) {
73
74
  if (method === 'HEAD' && module.GET) {
@@ -77,10 +78,10 @@ export async function handleRouteModule(
77
78
  request,
78
79
  responseHeaders,
79
80
  options,
80
- );
81
- return new Response(null, { status: response.status, headers: response.headers });
81
+ )
82
+ return new Response(null, { status: response.status, headers: response.headers })
82
83
  }
83
- return missingMethodResponse(module, method);
84
+ return missingMethodResponse(module, method)
84
85
  }
85
86
 
86
87
  return finalizeResponse(
@@ -88,21 +89,21 @@ export async function handleRouteModule(
88
89
  request,
89
90
  responseHeaders,
90
91
  options,
91
- );
92
+ )
92
93
  } catch (error) {
93
94
  if (isRedirectError(error)) {
94
95
  // POST submissions get a 303 (Next's behavior for redirect() and
95
96
  // permanentRedirect() thrown in route handlers): the browser follows
96
97
  // with a GET instead of replaying the POST against the target.
97
- const status = method === 'POST' ? 303 : error.status;
98
+ const status = method === 'POST' ? 303 : error.status
98
99
  return withResponseHeaders(
99
100
  new Response(null, { status, headers: { location: error.location } }),
100
101
  responseHeaders,
101
- );
102
+ )
102
103
  }
103
104
  // notFound() thrown inside a handler is a 404 with an empty body.
104
105
  if (isNotFoundError(error)) {
105
- return withResponseHeaders(new Response(null, { status: 404 }), responseHeaders);
106
+ return withResponseHeaders(new Response(null, { status: 404 }), responseHeaders)
106
107
  }
107
108
  // Any other throw is a 500 with an empty body. Report it through the error
108
109
  // funnel (onRequestError) here since core no longer sees it as uncaught.
@@ -110,9 +111,9 @@ export async function handleRouteModule(
110
111
  error,
111
112
  { method, url: request.url, headers: request.headers },
112
113
  { phase: 'handler', routeKind: 'route-handler', ...(getWorkUnit()?.responseHints ?? {}) },
113
- );
114
- console.error(error);
115
- return new Response(null, { status: 500 });
114
+ )
115
+ console.error(error)
116
+ return new Response(null, { status: 500 })
116
117
  }
117
118
  }
118
119
 
@@ -128,21 +129,21 @@ function finalizeResponse(
128
129
  responseHeaders: Headers,
129
130
  options: HandleRouteOptions,
130
131
  ) {
131
- const method = request.method.toUpperCase();
132
+ const method = request.method.toUpperCase()
132
133
  if (!response) {
133
- const file = options.routeFile ?? '<route>';
134
+ const file = options.routeFile ?? '<route>'
134
135
  console.error(
135
136
  `No response is returned from route handler '${file}'. Expected a Response object but ` +
136
137
  `received '${typeof response}' (method: ${method}, url: ${request.url}). Ensure you ` +
137
138
  'return a `Response` or a `NextResponse` in all branches of your handler.',
138
- );
139
- return new Response(null, { status: 500 });
139
+ )
140
+ return new Response(null, { status: 500 })
140
141
  }
141
142
  if (nextResponseMeta(response)?.kind === 'next') {
142
- console.error('https://nextjs.org/docs/messages/next-response-next-in-app-route-handler');
143
- return new Response(null, { status: 500 });
143
+ console.error('https://nextjs.org/docs/messages/next-response-next-in-app-route-handler')
144
+ return new Response(null, { status: 500 })
144
145
  }
145
- return withResponseHeaders(response, responseHeaders);
146
+ return withResponseHeaders(response, responseHeaders)
146
147
  }
147
148
 
148
149
  function callHandler(
@@ -151,121 +152,113 @@ function callHandler(
151
152
  params: Record<string, RouteParamValue>,
152
153
  responseHeaders: Headers,
153
154
  ) {
154
- const nextRequest = toNextRequest(request);
155
+ const nextRequest = toNextRequest(request)
155
156
  // Static routes (no dynamic segments) get no `params` in context — Next
156
157
  // omits it, so `context.params` is `undefined` rather than a promise of `{}`.
157
158
  const context: RouteHandlerContext =
158
- Object.keys(params).length > 0 ? { params: Promise.resolve(params) } : {};
159
+ Object.keys(params).length > 0 ? { params: Promise.resolve(params) } : {}
159
160
  return runWithRequest(nextRequest, () => handler(nextRequest, context), params, {
160
161
  responseHeaders,
161
- });
162
+ })
162
163
  }
163
164
 
164
165
  /** Merge scope-collected headers (set-cookie appends, everything else sets) onto the response. */
165
166
  function withResponseHeaders(response: Response, extra: Headers) {
166
- const withSetCookie = extra as Headers & { getSetCookie?: () => string[] };
167
- const scopeCookies = withSetCookie.getSetCookie?.() ?? [];
168
- let hasOthers = false;
167
+ const withSetCookie = extra as Headers & { getSetCookie?: () => string[] }
168
+ const scopeCookies = withSetCookie.getSetCookie?.() ?? []
169
+ let hasOthers = false
169
170
  extra.forEach((_, key) => {
170
- if (key !== 'set-cookie') hasOthers = true;
171
- });
172
- if (scopeCookies.length === 0 && !hasOthers) return response;
171
+ if (key !== 'set-cookie') hasOthers = true
172
+ })
173
+ if (scopeCookies.length === 0 && !hasOthers) return response
173
174
 
174
175
  const apply = (headers: Headers) => {
175
176
  extra.forEach((value, key) => {
176
- if (key !== 'set-cookie') headers.set(key, value);
177
- });
177
+ if (key !== 'set-cookie') headers.set(key, value)
178
+ })
178
179
  // Cookie-jar merge (Next's ResponseCookies semantics): scope cookies
179
180
  // (cookies().set during the handler) first, the response's own Set-Cookie
180
181
  // headers override same-name entries, and every cookie is normalized with
181
182
  // a default Path=/.
182
183
  const responseCookies =
183
- (headers as Headers & { getSetCookie?: () => string[] }).getSetCookie?.() ?? [];
184
- const jar = new Map<string, string>();
184
+ (headers as Headers & { getSetCookie?: () => string[] }).getSetCookie?.() ?? []
185
+ const jar = new Map<string, string>()
185
186
  for (const cookie of [...scopeCookies, ...responseCookies]) {
186
- jar.set(cookieName(cookie), normalizeSetCookie(cookie));
187
+ jar.set(cookieName(cookie), normalizeSetCookie(cookie))
187
188
  }
188
- headers.delete('set-cookie');
189
- for (const cookie of jar.values()) headers.append('set-cookie', cookie);
190
- };
189
+ headers.delete('set-cookie')
190
+ for (const cookie of jar.values()) headers.append('set-cookie', cookie)
191
+ }
191
192
  try {
192
- apply(response.headers);
193
- return response;
193
+ apply(response.headers)
194
+ return response
194
195
  } catch {
195
196
  // Immutable headers (e.g. a Response forwarded from fetch): re-wrap.
196
- const headers = new Headers(response.headers);
197
- apply(headers);
197
+ const headers = new Headers(response.headers)
198
+ apply(headers)
198
199
  return new Response(response.body, {
199
200
  status: response.status,
200
201
  statusText: response.statusText,
201
202
  headers,
202
- });
203
+ })
203
204
  }
204
205
  }
205
206
 
206
207
  function cookieName(setCookie: string) {
207
- return (setCookie.split('=')[0] ?? '').trim();
208
+ return (setCookie.split('=')[0] ?? '').trim()
208
209
  }
209
210
 
210
211
  function normalizeSetCookie(setCookie: string) {
211
- return /;\s*path=/i.test(setCookie) ? setCookie : `${setCookie}; Path=/`;
212
+ return /;\s*path=/i.test(setCookie) ? setCookie : `${setCookie}; Path=/`
212
213
  }
213
214
 
214
215
  export async function staticRouteParams(route: RouteManifestEntry, module: RouteHandlerModule) {
215
- if (typeof module.GET !== 'function') return [];
216
+ if (typeof module.GET !== 'function') return []
216
217
  // `dynamic = 'force-static'` and `dynamic = 'error'` both evaluate a static
217
218
  // request; the latter lets request APIs fail at their call sites. A
218
219
  // `revalidate` export opts a request-independent GET into static/ISR output.
219
- const config = route.segmentConfig;
220
+ const config = route.segmentConfig
220
221
  const optedStatic =
221
222
  config?.dynamic === 'force-static' ||
222
223
  config?.dynamic === 'error' ||
223
224
  config?.revalidate === false ||
224
- (typeof config?.revalidate === 'number' && config.revalidate > 0);
225
- if (route.hasStaticParams) return module.params?.() ?? [];
226
- if (route.usesRequest && !optedStatic) return [];
227
- return route.mode === 'static' || optedStatic ? [{}] : [];
225
+ (typeof config?.revalidate === 'number' && config.revalidate > 0)
226
+ if (route.hasStaticParams) return module.params?.() ?? []
227
+ if (route.usesRequest && !optedStatic) return []
228
+ return route.mode === 'static' || optedStatic ? [{}] : []
228
229
  }
229
230
 
230
231
  export function routeParamsFromPath(
231
232
  route: Pick<RouteManifestEntry, 'catchAll' | 'params' | 'pattern'>,
232
233
  pathname: string,
233
234
  ) {
234
- const match = new RegExp(`^${route.pattern}$`).exec(pathname);
235
- const params: Record<string, RouteParamValue> = {};
236
- if (!match) return params;
235
+ const match = new RegExp(`^${route.pattern}$`).exec(pathname)
236
+ const params: Record<string, RouteParamValue> = {}
237
+ if (!match) return params
237
238
 
238
239
  for (let index = 0; index < route.params.length; index += 1) {
239
- params[route.params[index]!] = safeDecode(match[index + 1] ?? '');
240
+ params[route.params[index]!] = safeDecode(match[index + 1] ?? '')
240
241
  }
241
242
  if (route.catchAll) {
242
243
  params[route.catchAll] = (match[route.params.length + 1] ?? '')
243
244
  .split('/')
244
245
  .filter(Boolean)
245
- .map(safeDecode);
246
+ .map(safeDecode)
246
247
  }
247
- return params;
248
+ return params
248
249
  }
249
250
 
250
251
  function missingMethodResponse(module: RouteHandlerModule, method: string) {
251
- const headers = { Allow: allowedMethods(module).join(', ') };
252
- if (method === 'OPTIONS') return new Response(null, { status: 204, headers });
253
- return new Response(null, { status: 405, headers });
252
+ const headers = { Allow: allowedMethods(module).join(', ') }
253
+ if (method === 'OPTIONS') return new Response(null, { status: 204, headers })
254
+ return new Response(null, { status: 405, headers })
254
255
  }
255
256
 
256
257
  function allowedMethods(module: RouteHandlerModule) {
257
- const allowed = new Set(routeMethods.filter(method => typeof module[method] === 'function'));
258
+ const allowed = new Set(routeMethods.filter(method => typeof module[method] === 'function'))
258
259
  // GET implies auto-HEAD; every route gets auto-OPTIONS. The Allow header is
259
260
  // sorted (Next emits e.g. `OPTIONS, POST`).
260
- if (allowed.has('GET')) allowed.add('HEAD');
261
- allowed.add('OPTIONS');
262
- return [...allowed].sort();
263
- }
264
-
265
- function safeDecode(value: string) {
266
- try {
267
- return decodeURIComponent(value);
268
- } catch {
269
- return value;
270
- }
261
+ if (allowed.has('GET')) allowed.add('HEAD')
262
+ allowed.add('OPTIONS')
263
+ return [...allowed].sort()
271
264
  }
@@ -1,26 +1,26 @@
1
- import type { RouteParamValue } from '../types';
1
+ import type { RouteParamValue } from '../types'
2
2
 
3
- export type SearchValue = string | number | boolean | null | undefined;
4
- export type SearchInput = URLSearchParams | Record<string, SearchValue | SearchValue[]>;
3
+ export type SearchValue = string | number | boolean | null | undefined
4
+ export type SearchInput = URLSearchParams | Record<string, SearchValue | SearchValue[]>
5
5
 
6
6
  export interface HrefParts {
7
- params?: Record<string, RouteParamValue>;
8
- search?: SearchInput;
9
- hash?: string;
7
+ params?: Record<string, RouteParamValue>
8
+ search?: SearchInput
9
+ hash?: string
10
10
  }
11
11
 
12
12
  export function routeHref(route: string, options: HrefParts = {}) {
13
- const path = applyTrailingSlash(fillParams(route, options.params ?? {}));
14
- const search = searchString(options.search);
15
- const hash = hashString(options.hash);
16
- return `${path}${search}${hash}`;
13
+ const path = applyTrailingSlash(fillParams(route, options.params ?? {}))
14
+ const search = searchString(options.search)
15
+ const hash = hashString(options.hash)
16
+ return `${path}${search}${hash}`
17
17
  }
18
18
 
19
19
  declare global {
20
20
  interface Window {
21
- __PNEXT_TRAILING_SLASH__?: boolean;
21
+ __PNEXT_TRAILING_SLASH__?: boolean
22
22
  }
23
- var __PNEXT_TRAILING_SLASH__: boolean | undefined;
23
+ var __PNEXT_TRAILING_SLASH__: boolean | undefined
24
24
  }
25
25
 
26
26
  // With `trailingSlash: true` the server 308s bare page URLs to their slashed
@@ -31,16 +31,17 @@ declare global {
31
31
  // Anchored on globalThis, not a module local: this module is dual-copied into
32
32
  // the client/prebundled bundles, where setTrailingSlashUrls never runs.
33
33
  export function setTrailingSlashUrls(enabled: boolean) {
34
- globalThis.__PNEXT_TRAILING_SLASH__ = enabled;
34
+ globalThis.__PNEXT_TRAILING_SLASH__ = enabled
35
35
  }
36
36
 
37
37
  function isTrailingSlashEnabled(): boolean {
38
- if (process.browser || typeof window !== 'undefined') return window.__PNEXT_TRAILING_SLASH__ === true;
39
- return globalThis.__PNEXT_TRAILING_SLASH__ === true;
38
+ if (process.browser || typeof window !== 'undefined')
39
+ return window.__PNEXT_TRAILING_SLASH__ === true
40
+ return globalThis.__PNEXT_TRAILING_SLASH__ === true
40
41
  }
41
42
 
42
43
  export function getTrailingSlashUrls() {
43
- return isTrailingSlashEnabled();
44
+ return isTrailingSlashEnabled()
44
45
  }
45
46
 
46
47
  // The configured basePath ('' when unset). Set once per process by the server
@@ -48,14 +49,14 @@ export function getTrailingSlashUrls() {
48
49
  // trailing-slash seam. Core render code (metadata) reads it through
49
50
  // withBasePath so file-convention asset hrefs (og-image, manifest) carry the
50
51
  // prefix without a compat/next.config import in core.
51
- let basePathPrefix = '';
52
+ let basePathPrefix = ''
52
53
 
53
54
  export function setBasePathPrefix(value: string) {
54
- basePathPrefix = value;
55
+ basePathPrefix = value
55
56
  }
56
57
 
57
58
  export function getBasePathPrefix() {
58
- return basePathPrefix;
59
+ return basePathPrefix
59
60
  }
60
61
 
61
62
  /**
@@ -65,26 +66,26 @@ export function getBasePathPrefix() {
65
66
  * always a no-op. Any query/hash on the path rides along untouched.
66
67
  */
67
68
  export function withBasePath(path: string) {
68
- const base = basePathPrefix;
69
- if (!base) return path;
70
- if (!path.startsWith('/') || path.startsWith('//')) return path;
71
- if (path === base || path.startsWith(`${base}/`)) return path;
72
- return `${base}${path}`;
69
+ const base = basePathPrefix
70
+ if (!base) return path
71
+ if (!path.startsWith('/') || path.startsWith('//')) return path
72
+ if (path === base || path.startsWith(`${base}/`)) return path
73
+ return `${base}${path}`
73
74
  }
74
75
 
75
76
  export function applyTrailingSlash(pathname: string) {
76
- const [, path = '', rest = ''] = /^([^?#]*)([\s\S]*)$/.exec(pathname) ?? [];
77
- if (!path.startsWith('/')) return pathname;
77
+ const [, path = '', rest = ''] = /^([^?#]*)([\s\S]*)$/.exec(pathname) ?? []
78
+ if (!path.startsWith('/')) return pathname
78
79
  if (isTrailingSlashEnabled()) {
79
80
  // Add the canonical trailing slash (skip root, already-slashed, and files).
80
- if (path === '/' || path.endsWith('/') || /\.[^/]+$/.test(path)) return pathname;
81
- return `${path}/${rest}`;
81
+ if (path === '/' || path.endsWith('/') || /\.[^/]+$/.test(path)) return pathname
82
+ return `${path}/${rest}`
82
83
  }
83
84
  // trailingSlash:false — Next strips a trailing slash from hrefs so the anchor
84
85
  // matches the canonical (unslashed) form and avoids a 308 on click. Root and
85
86
  // file paths (`/a.txt/` is not a thing) are left alone.
86
- if (path === '/' || !path.endsWith('/') || /\.[^/]+\/$/.test(path)) return pathname;
87
- return `${path.replace(/\/+$/, '')}${rest}`;
87
+ if (path === '/' || !path.endsWith('/') || /\.[^/]+\/$/.test(path)) return pathname
88
+ return `${path.replace(/\/+$/, '')}${rest}`
88
89
  }
89
90
 
90
91
  function fillParams(route: string, params: Record<string, RouteParamValue>) {
@@ -93,47 +94,47 @@ function fillParams(route: string, params: Record<string, RouteParamValue>) {
93
94
  // catch-all form so its doubled brackets aren't mis-parsed.
94
95
  .replace(/\[\[\.\.\.([^\]]+)\]\]/g, (_match, key: string) => encodeParam(params[key], true))
95
96
  .replace(/\[\.\.\.([^\]]+)\]/g, (_match, key: string) => encodeParam(params[key], true))
96
- .replace(/\[([^\]]+)\]/g, (_match, key: string) => encodeParam(params[key], false));
97
+ .replace(/\[([^\]]+)\]/g, (_match, key: string) => encodeParam(params[key], false))
97
98
  // An absent optional catch-all (`[[...slug]]`) leaves a dangling `/`; drop it
98
99
  // so /docs/:slug* with no params yields /docs, not /docs/.
99
- return collapseTrailingSlash(filled);
100
+ return collapseTrailingSlash(filled)
100
101
  }
101
102
 
102
103
  function collapseTrailingSlash(pathname: string) {
103
- if (pathname.length <= 1) return pathname;
104
- return pathname.replace(/\/+$/, '') || '/';
104
+ if (pathname.length <= 1) return pathname
105
+ return pathname.replace(/\/+$/, '') || '/'
105
106
  }
106
107
 
107
108
  function encodeParam(value: RouteParamValue | undefined, catchAll: boolean) {
108
109
  if (Array.isArray(value)) {
109
- const encoded = value.map(segment => encodeURIComponent(segment));
110
- return catchAll ? encoded.join('/') : encoded[0] ?? '';
110
+ const encoded = value.map(segment => encodeURIComponent(segment))
111
+ return catchAll ? encoded.join('/') : (encoded[0] ?? '')
111
112
  }
112
- return encodeURIComponent(value ?? '');
113
+ return encodeURIComponent(value ?? '')
113
114
  }
114
115
 
115
116
  function searchString(search: SearchInput | undefined) {
116
- if (!search) return '';
117
- const params = search instanceof URLSearchParams ? search : objectSearchParams(search);
118
- const value = params.toString();
119
- return value ? `?${value}` : '';
117
+ if (!search) return ''
118
+ const params = search instanceof URLSearchParams ? search : objectSearchParams(search)
119
+ const value = params.toString()
120
+ return value ? `?${value}` : ''
120
121
  }
121
122
 
122
123
  function objectSearchParams(search: Record<string, SearchValue | SearchValue[]>) {
123
- const params = new URLSearchParams();
124
+ const params = new URLSearchParams()
124
125
  for (const [key, value] of Object.entries(search)) {
125
- const values = Array.isArray(value) ? value : [value];
126
+ const values = Array.isArray(value) ? value : [value]
126
127
  for (const item of values) {
127
- if (item == null) continue;
128
- params.append(key, String(item));
128
+ if (item == null) continue
129
+ params.append(key, String(item))
129
130
  }
130
131
  }
131
- return params;
132
+ return params
132
133
  }
133
134
 
134
135
  function hashString(hash: string | undefined) {
135
- if (!hash) return '';
136
- return hash.startsWith('#') ? hash : `#${hash}`;
136
+ if (!hash) return ''
137
+ return hash.startsWith('#') ? hash : `#${hash}`
137
138
  }
138
139
 
139
140
  /**
@@ -142,18 +143,18 @@ function hashString(hash: string | undefined) {
142
143
  * Next. Returns the response when the path cannot be decoded, else null.
143
144
  */
144
145
  export function malformedUrlResponse(request: Request): Response | null {
145
- let pathname: string;
146
+ let pathname: string
146
147
  try {
147
- pathname = new URL(request.url).pathname;
148
+ pathname = new URL(request.url).pathname
148
149
  } catch {
149
- return new Response('Bad Request', { status: 400 });
150
+ return new Response('Bad Request', { status: 400 })
150
151
  }
151
- if (!pathname.includes('%')) return null;
152
+ if (!pathname.includes('%')) return null
152
153
  try {
153
- decodeURIComponent(pathname);
154
- return null;
154
+ decodeURIComponent(pathname)
155
+ return null
155
156
  } catch {
156
- return new Response('Bad Request', { status: 400 });
157
+ return new Response('Bad Request', { status: 400 })
157
158
  }
158
159
  }
159
160
 
@@ -165,13 +166,11 @@ export function malformedUrlResponse(request: Request): Response | null {
165
166
  * already canonical.
166
167
  */
167
168
  export function canonicalTrailingSlashPath(pathname: string, trailingSlash: boolean): string {
168
- if (pathname === '/' || pathname === '') return pathname;
169
- if (/\.[^/]+$/.test(pathname)) return pathname;
170
- const slashed = pathname.endsWith('/');
171
- if (trailingSlash ? slashed : !slashed) return pathname;
172
- return trailingSlash
173
- ? `${pathname.replace(/\/+$/, '')}/`
174
- : pathname.replace(/\/+$/, '') || '/';
169
+ if (pathname === '/' || pathname === '') return pathname
170
+ if (/\.[^/]+$/.test(pathname)) return pathname
171
+ const slashed = pathname.endsWith('/')
172
+ if (trailingSlash ? slashed : !slashed) return pathname
173
+ return trailingSlash ? `${pathname.replace(/\/+$/, '')}/` : pathname.replace(/\/+$/, '') || '/'
175
174
  }
176
175
 
177
176
  /**
@@ -188,15 +187,15 @@ export function trailingSlashRedirect(
188
187
  // skipTrailingSlashRedirect: the app serves both slashed and unslashed URLs
189
188
  // as-is, so no canonical redirect is ever emitted (route matching already
190
189
  // tolerates a trailing slash via normalizePathname).
191
- if (config.skipTrailingSlashRedirect) return null;
192
- if (method !== 'GET' && method !== 'HEAD') return null;
193
- const pathname = url.pathname;
194
- if (pathname === '/' || pathname === '') return null;
195
- if (pathname.startsWith('/__pnext') || pathname.startsWith('/assets/')) return null;
196
- const target = canonicalTrailingSlashPath(pathname, Boolean(config.trailingSlash));
197
- if (target === pathname) return null;
190
+ if (config.skipTrailingSlashRedirect) return null
191
+ if (method !== 'GET' && method !== 'HEAD') return null
192
+ const pathname = url.pathname
193
+ if (pathname === '/' || pathname === '') return null
194
+ if (pathname.startsWith('/__pnext') || pathname.startsWith('/assets/')) return null
195
+ const target = canonicalTrailingSlashPath(pathname, Boolean(config.trailingSlash))
196
+ if (target === pathname) return null
198
197
  return new Response(null, {
199
198
  status: 308,
200
199
  headers: { location: `${target}${url.search}` },
201
- });
200
+ })
202
201
  }