@wular/pnext 0.0.4 → 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 -1992
  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 -1897
  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} +139 -139
  351. package/src/resolve/engine.ts +90 -77
  352. package/src/resolve/imports.ts +475 -463
  353. package/src/resolve/scan-facts.ts +318 -296
  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 +827 -815
  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,7 +1,7 @@
1
- import path from 'node:path';
2
- import { safeDecode } from '../utils/decode';
3
- import { readDirListing, toPosixPath } from '../utils/fs';
4
- import type { InterceptionMarker, RouteParamValue } from '../types';
1
+ import path from 'node:path'
2
+ import { safeDecode } from '../utils/decode'
3
+ import { readDirListing, toPosixPath } from '../utils/fs'
4
+ import type { InterceptionMarker, RouteParamValue } from '../types'
5
5
 
6
6
  // Parallel-route (@slot) and intercepting-route ((.)segment) tree matching.
7
7
  // Slot content resolves at request time against the filesystem: the app source
@@ -9,52 +9,52 @@ import type { InterceptionMarker, RouteParamValue } from '../types';
9
9
  // so matching walks directories directly instead of precomputing every slot
10
10
  // combination into the manifest.
11
11
 
12
- const pageExtensions = ['tsx', 'ts', 'jsx', 'js', 'mjs'] as const;
12
+ const pageExtensions = ['tsx', 'ts', 'jsx', 'js', 'mjs'] as const
13
13
 
14
- const interceptionMarkers: InterceptionMarker[] = ['(..)(..)', '(...)', '(..)', '(.)'];
14
+ const interceptionMarkers: InterceptionMarker[] = ['(..)(..)', '(...)', '(..)', '(.)']
15
15
  const interceptionLevels: Record<InterceptionMarker, number> = {
16
16
  '(.)': 0,
17
17
  '(..)': 1,
18
18
  '(..)(..)': 2,
19
19
  '(...)': Number.POSITIVE_INFINITY,
20
- };
20
+ }
21
21
 
22
22
  export function interceptionMarkerOf(segment: string): InterceptionMarker | undefined {
23
23
  return interceptionMarkers.find(
24
24
  marker => segment.startsWith(marker) && segment.length > marker.length,
25
- );
25
+ )
26
26
  }
27
27
 
28
28
  export function interceptionMarkerLevels(marker: InterceptionMarker) {
29
- return interceptionLevels[marker];
29
+ return interceptionLevels[marker]
30
30
  }
31
31
 
32
32
  export function isSlotSegment(name: string) {
33
- return name.startsWith('@');
33
+ return name.startsWith('@')
34
34
  }
35
35
 
36
36
  export function isGroupSegment(name: string) {
37
- return name.startsWith('(') && name.endsWith(')') && !interceptionMarkerOf(name);
37
+ return name.startsWith('(') && name.endsWith(')') && !interceptionMarkerOf(name)
38
38
  }
39
39
 
40
40
  /** Nearest existing `<base>.<ext>` convention file in `dir`. */
41
41
  export function slotConventionFile(dir: string, base: string) {
42
- const { files } = readDirListing(dir);
42
+ const { files } = readDirListing(dir)
43
43
  for (const extension of pageExtensions) {
44
- if (files.has(`${base}.${extension}`)) return path.join(dir, `${base}.${extension}`);
44
+ if (files.has(`${base}.${extension}`)) return path.join(dir, `${base}.${extension}`)
45
45
  }
46
- return undefined;
46
+ return undefined
47
47
  }
48
48
 
49
49
  function childDirectories(dir: string) {
50
- return readDirListing(dir).dirs;
50
+ return readDirListing(dir).dirs
51
51
  }
52
52
 
53
53
  /** `@slot` directories directly inside `dir`. */
54
54
  export function slotDirectoriesIn(dir: string) {
55
55
  return childDirectories(dir)
56
56
  .filter(isSlotSegment)
57
- .map(name => path.join(dir, name));
57
+ .map(name => path.join(dir, name))
58
58
  }
59
59
 
60
60
  /**
@@ -65,17 +65,17 @@ export function slotDirectoriesIn(dir: string) {
65
65
  * shift the mapping and are not supported for slot resolution below them).
66
66
  */
67
67
  export function consumedSegments(appPath: string, dir: string) {
68
- const relative = path.relative(appPath, dir);
69
- if (relative.startsWith('..')) return 0;
70
- let consumed = 0;
68
+ const relative = path.relative(appPath, dir)
69
+ if (relative.startsWith('..')) return 0
70
+ let consumed = 0
71
71
  for (const name of relative.split(path.sep).filter(Boolean)) {
72
- if (isGroupSegment(name) || isSlotSegment(name)) continue;
73
- const marker = interceptionMarkerOf(name);
74
- const bare = marker ? name.slice(marker.length) : name;
75
- if (/^\[\[?\.\.\./.test(bare)) return Number.POSITIVE_INFINITY;
76
- consumed += 1;
72
+ if (isGroupSegment(name) || isSlotSegment(name)) continue
73
+ const marker = interceptionMarkerOf(name)
74
+ const bare = marker ? name.slice(marker.length) : name
75
+ if (/^\[\[?\.\.\./.test(bare)) return Number.POSITIVE_INFINITY
76
+ consumed += 1
77
77
  }
78
- return consumed;
78
+ return consumed
79
79
  }
80
80
 
81
81
  export interface SegmentMatch {
@@ -83,16 +83,16 @@ export interface SegmentMatch {
83
83
  * The matched page file. Absent for a pageless match - a fully-consumed path that still has a layout or
84
84
  * parallel slots to render, Next's implicit null children inside intercepted units.
85
85
  */
86
- file?: string;
86
+ file?: string
87
87
  /** Directories entered from (excluding) the start dir to the page's dir. */
88
- dirs: string[];
88
+ dirs: string[]
89
89
  /** Params captured while matching (decoded). */
90
- params: Record<string, RouteParamValue>;
90
+ params: Record<string, RouteParamValue>
91
91
  }
92
92
 
93
93
  interface MatchOptions {
94
94
  /** Enter interception marker dirs as if they were their bare segment. */
95
- markersAsSegments?: boolean;
95
+ markersAsSegments?: boolean
96
96
  }
97
97
 
98
98
  /**
@@ -107,24 +107,24 @@ export function matchSegments(
107
107
  params: Record<string, RouteParamValue> = {},
108
108
  dirs: string[] = [],
109
109
  ): SegmentMatch | null {
110
- const children = childDirectories(dir);
111
- const groups = children.filter(isGroupSegment);
110
+ const children = childDirectories(dir)
111
+ const groups = children.filter(isGroupSegment)
112
112
 
113
113
  if (segments.length === 0) {
114
- const page = slotConventionFile(dir, 'page');
115
- if (page) return { file: page, dirs, params };
114
+ const page = slotConventionFile(dir, 'page')
115
+ if (page) return { file: page, dirs, params }
116
116
  for (const group of groups) {
117
- const match = matchSegments(path.join(dir, group), [], options, params, [...dirs, group]);
118
- if (match) return match;
117
+ const match = matchSegments(path.join(dir, group), [], options, params, [...dirs, group])
118
+ if (match) return match
119
119
  }
120
120
  for (const name of children) {
121
- const param = optionalCatchAllName(bareName(name, options));
122
- if (!param) continue;
121
+ const param = optionalCatchAllName(bareName(name, options))
122
+ if (!param) continue
123
123
  const match = matchSegments(path.join(dir, name), [], options, { ...params, [param]: [] }, [
124
124
  ...dirs,
125
125
  name,
126
- ]);
127
- if (match) return match;
126
+ ])
127
+ if (match) return match
128
128
  }
129
129
  // Inside an intercepted unit a fully-consumed path may have no page yet
130
130
  // still render: a layout (or parallel slots) with implicit null children.
@@ -132,78 +132,78 @@ export function matchSegments(
132
132
  options.markersAsSegments &&
133
133
  (slotConventionFile(dir, 'layout') || children.some(isSlotSegment))
134
134
  ) {
135
- return { dirs, params };
135
+ return { dirs, params }
136
136
  }
137
- return null;
137
+ return null
138
138
  }
139
139
 
140
- const [head, ...rest] = segments as [string, ...string[]];
140
+ const [head, ...rest] = segments as [string, ...string[]]
141
141
 
142
142
  // Literal segment.
143
143
  for (const name of children) {
144
- if (bareName(name, options) !== head) continue;
145
- const match = matchSegments(path.join(dir, name), rest, options, params, [...dirs, name]);
146
- if (match) return match;
144
+ if (bareName(name, options) !== head) continue
145
+ const match = matchSegments(path.join(dir, name), rest, options, params, [...dirs, name])
146
+ if (match) return match
147
147
  }
148
148
 
149
149
  // Route groups are transparent at this level.
150
150
  for (const group of groups) {
151
- const match = matchSegments(path.join(dir, group), segments, options, params, [...dirs, group]);
152
- if (match) return match;
151
+ const match = matchSegments(path.join(dir, group), segments, options, params, [...dirs, group])
152
+ if (match) return match
153
153
  }
154
154
 
155
155
  // Dynamic `[param]`.
156
156
  for (const name of children) {
157
- const param = dynamicParamName(bareName(name, options));
158
- if (!param) continue;
157
+ const param = dynamicParamName(bareName(name, options))
158
+ if (!param) continue
159
159
  const match = matchSegments(
160
160
  path.join(dir, name),
161
161
  rest,
162
162
  options,
163
163
  { ...params, [param]: safeDecode(head) },
164
164
  [...dirs, name],
165
- );
166
- if (match) return match;
165
+ )
166
+ if (match) return match
167
167
  }
168
168
 
169
169
  // `[...catchAll]` and `[[...opt]]` consume everything remaining.
170
170
  for (const name of children) {
171
- const bare = bareName(name, options);
172
- const param = catchAllName(bare) ?? optionalCatchAllName(bare);
173
- if (!param) continue;
171
+ const bare = bareName(name, options)
172
+ const param = catchAllName(bare) ?? optionalCatchAllName(bare)
173
+ if (!param) continue
174
174
  const match = matchSegments(
175
175
  path.join(dir, name),
176
176
  [],
177
177
  options,
178
178
  { ...params, [param]: segments.map(safeDecode) },
179
179
  [...dirs, name],
180
- );
181
- if (match) return match;
180
+ )
181
+ if (match) return match
182
182
  }
183
183
 
184
- return null;
184
+ return null
185
185
  }
186
186
 
187
187
  function bareName(name: string, options: MatchOptions) {
188
- if (isSlotSegment(name)) return '\0';
189
- const marker = interceptionMarkerOf(name);
190
- if (!marker) return name;
191
- return options.markersAsSegments ? name.slice(marker.length) : '\0';
188
+ if (isSlotSegment(name)) return '\0'
189
+ const marker = interceptionMarkerOf(name)
190
+ if (!marker) return name
191
+ return options.markersAsSegments ? name.slice(marker.length) : '\0'
192
192
  }
193
193
 
194
194
  function dynamicParamName(name: string) {
195
- const match = /^\[([^\].]+)\]$/.exec(name);
196
- return match?.[1];
195
+ const match = /^\[([^\].]+)\]$/.exec(name)
196
+ return match?.[1]
197
197
  }
198
198
 
199
199
  function catchAllName(name: string) {
200
- const match = /^\[\.\.\.([^\]]+)\]$/.exec(name);
201
- return match?.[1];
200
+ const match = /^\[\.\.\.([^\]]+)\]$/.exec(name)
201
+ return match?.[1]
202
202
  }
203
203
 
204
204
  function optionalCatchAllName(name: string) {
205
- const match = /^\[\[\.\.\.([^\]]+)\]\]$/.exec(name);
206
- return match?.[1];
205
+ const match = /^\[\[\.\.\.([^\]]+)\]\]$/.exec(name)
206
+ return match?.[1]
207
207
  }
208
208
 
209
209
  /**
@@ -213,40 +213,40 @@ function optionalCatchAllName(name: string) {
213
213
  * renders nothing (Next's implicit null default).
214
214
  */
215
215
  export function childrenDefaultFile(dir: string, segments: string[]): string | undefined {
216
- let current = dir;
217
- let best = slotConventionFile(current, 'default');
216
+ let current = dir
217
+ let best = slotConventionFile(current, 'default')
218
218
  for (const segment of segments) {
219
- const next = childSegmentDir(current, segment);
220
- if (!next) break;
221
- current = next;
222
- best = slotConventionFile(current, 'default') ?? best;
219
+ const next = childSegmentDir(current, segment)
220
+ if (!next) break
221
+ current = next
222
+ best = slotConventionFile(current, 'default') ?? best
223
223
  }
224
- return best;
224
+ return best
225
225
  }
226
226
 
227
227
  function childSegmentDir(dir: string, segment: string): string | undefined {
228
- const children = childDirectories(dir);
229
- if (children.includes(segment)) return path.join(dir, segment);
228
+ const children = childDirectories(dir)
229
+ if (children.includes(segment)) return path.join(dir, segment)
230
230
  for (const group of children.filter(isGroupSegment)) {
231
- const nested = childSegmentDir(path.join(dir, group), segment);
232
- if (nested) return nested;
231
+ const nested = childSegmentDir(path.join(dir, group), segment)
232
+ if (nested) return nested
233
233
  }
234
- const dynamic = children.find(name => dynamicParamName(name));
235
- if (dynamic) return path.join(dir, dynamic);
236
- return undefined;
234
+ const dynamic = children.find(name => dynamicParamName(name))
235
+ if (dynamic) return path.join(dir, dynamic)
236
+ return undefined
237
237
  }
238
238
 
239
239
  export interface InterceptorUnit {
240
240
  /** The marker directory (absolute). Content below renders when intercepted. */
241
- dir: string;
241
+ dir: string
242
242
  /** Route-style target prefix segments from the app root (e.g. `['groups', ':id', 'new']`). */
243
- targetSegments: string[];
243
+ targetSegments: string[]
244
244
  /** Regex source matching the target prefix (no anchors). */
245
- targetPattern: string;
245
+ targetPattern: string
246
246
  /** Params captured by targetPattern, in group order. */
247
- params: { name: string; catchAll: boolean }[];
247
+ params: { name: string; catchAll: boolean }[]
248
248
  /** The final target token is a catch-all (consumes every remaining segment). */
249
- catchAllTail: boolean;
249
+ catchAllTail: boolean
250
250
  }
251
251
 
252
252
  /**
@@ -256,18 +256,18 @@ export interface InterceptorUnit {
256
256
  * plain segments during `matchSegments({ markersAsSegments: true })`.
257
257
  */
258
258
  export function slotInterceptorUnits(appPath: string, slotDir: string): InterceptorUnit[] {
259
- const owner = routeTokensForDir(appPath, path.dirname(slotDir));
260
- if (!owner) return [];
261
- const units: InterceptorUnit[] = [];
262
- collectInterceptorUnits(slotDir, owner, [], units);
263
- return units;
259
+ const owner = routeTokensForDir(appPath, path.dirname(slotDir))
260
+ if (!owner) return []
261
+ const units: InterceptorUnit[] = []
262
+ collectInterceptorUnits(slotDir, owner, [], units)
263
+ return units
264
264
  }
265
265
 
266
266
  interface RouteToken {
267
- route: string;
268
- pattern: string;
269
- param?: string;
270
- catchAll?: boolean;
267
+ route: string
268
+ pattern: string
269
+ param?: string
270
+ catchAll?: boolean
271
271
  }
272
272
 
273
273
  function collectInterceptorUnits(
@@ -277,19 +277,21 @@ function collectInterceptorUnits(
277
277
  units: InterceptorUnit[],
278
278
  ) {
279
279
  for (const name of childDirectories(dir)) {
280
- const child = path.join(dir, name);
280
+ const child = path.join(dir, name)
281
281
  if (isSlotSegment(name) || isGroupSegment(name)) {
282
- collectInterceptorUnits(child, owner, inner, units);
283
- continue;
282
+ collectInterceptorUnits(child, owner, inner, units)
283
+ continue
284
284
  }
285
- const marker = interceptionMarkerOf(name);
285
+ const marker = interceptionMarkerOf(name)
286
286
  if (marker) {
287
- const bare = name.slice(marker.length);
288
- const levels = interceptionLevels[marker];
289
- const context = [...owner, ...inner];
287
+ const bare = name.slice(marker.length)
288
+ const levels = interceptionLevels[marker]
289
+ const context = [...owner, ...inner]
290
290
  const kept =
291
- levels === Number.POSITIVE_INFINITY ? [] : context.slice(0, Math.max(0, context.length - levels));
292
- const target = [...kept, segmentToken(bare)];
291
+ levels === Number.POSITIVE_INFINITY
292
+ ? []
293
+ : context.slice(0, Math.max(0, context.length - levels))
294
+ const target = [...kept, segmentToken(bare)]
293
295
  units.push({
294
296
  dir: child,
295
297
  targetSegments: target.map(token => token.route),
@@ -298,10 +300,10 @@ function collectInterceptorUnits(
298
300
  .filter(token => token.param)
299
301
  .map(token => ({ name: token.param!, catchAll: Boolean(token.catchAll) })),
300
302
  catchAllTail: Boolean(target[target.length - 1]?.catchAll),
301
- });
302
- continue;
303
+ })
304
+ continue
303
305
  }
304
- collectInterceptorUnits(child, owner, [...inner, segmentToken(name)], units);
306
+ collectInterceptorUnits(child, owner, [...inner, segmentToken(name)], units)
305
307
  }
306
308
  }
307
309
 
@@ -311,34 +313,34 @@ function collectInterceptorUnits(
311
313
  * Returns undefined when the dir is outside the app root.
312
314
  */
313
315
  export function routeTokensForDir(appPath: string, dir: string): RouteToken[] | undefined {
314
- const relative = path.relative(appPath, dir);
315
- if (relative.startsWith('..')) return undefined;
316
- let tokens: RouteToken[] = [];
316
+ const relative = path.relative(appPath, dir)
317
+ if (relative.startsWith('..')) return undefined
318
+ let tokens: RouteToken[] = []
317
319
  for (const name of toPosixPath(relative).split('/').filter(Boolean)) {
318
- if (isGroupSegment(name) || isSlotSegment(name)) continue;
319
- const marker = interceptionMarkerOf(name);
320
+ if (isGroupSegment(name) || isSlotSegment(name)) continue
321
+ const marker = interceptionMarkerOf(name)
320
322
  if (marker) {
321
- const levels = interceptionLevels[marker];
323
+ const levels = interceptionLevels[marker]
322
324
  tokens =
323
325
  levels === Number.POSITIVE_INFINITY
324
326
  ? []
325
- : tokens.slice(0, Math.max(0, tokens.length - levels));
326
- tokens.push(segmentToken(name.slice(marker.length)));
327
- continue;
327
+ : tokens.slice(0, Math.max(0, tokens.length - levels))
328
+ tokens.push(segmentToken(name.slice(marker.length)))
329
+ continue
328
330
  }
329
- tokens.push(segmentToken(name));
331
+ tokens.push(segmentToken(name))
330
332
  }
331
- return tokens;
333
+ return tokens
332
334
  }
333
335
 
334
336
  function segmentToken(name: string): RouteToken {
335
- const optional = optionalCatchAllName(name);
336
- if (optional) return { route: `:${optional}*`, pattern: '(.*)', param: optional, catchAll: true };
337
- const catchAll = catchAllName(name);
338
- if (catchAll) return { route: `:${catchAll}*`, pattern: '(.*)', param: catchAll, catchAll: true };
339
- const param = dynamicParamName(name);
340
- if (param) return { route: `:${param}`, pattern: '([^/]+)', param };
341
- return { route: name, pattern: escapeRegex(name) };
337
+ const optional = optionalCatchAllName(name)
338
+ if (optional) return { route: `:${optional}*`, pattern: '(.*)', param: optional, catchAll: true }
339
+ const catchAll = catchAllName(name)
340
+ if (catchAll) return { route: `:${catchAll}*`, pattern: '(.*)', param: catchAll, catchAll: true }
341
+ const param = dynamicParamName(name)
342
+ if (param) return { route: `:${param}`, pattern: '([^/]+)', param }
343
+ return { route: name, pattern: escapeRegex(name) }
342
344
  }
343
345
 
344
346
  /**
@@ -352,14 +354,14 @@ export function matchSlotInterceptor(
352
354
  slotDir: string,
353
355
  pathname: string,
354
356
  ): SegmentMatch | null {
355
- const segments = pathnameSegments(pathname);
356
- const markerOwner = markerOwnerTokens(appPath, slotDir);
357
+ const segments = pathnameSegments(pathname)
358
+ const markerOwner = markerOwnerTokens(appPath, slotDir)
357
359
  if (markerOwner) {
358
- const params = matchTargetTokens(markerOwner, pathname);
360
+ const params = matchTargetTokens(markerOwner, pathname)
359
361
  if (params) {
360
- const rest = markerOwner.at(-1)?.catchAll ? [] : segments.slice(markerOwner.length);
361
- const inner = matchSegments(slotDir, rest, { markersAsSegments: true }, params, []);
362
- if (inner) return inner;
362
+ const rest = markerOwner.at(-1)?.catchAll ? [] : segments.slice(markerOwner.length)
363
+ const inner = matchSegments(slotDir, rest, { markersAsSegments: true }, params, [])
364
+ if (inner) return inner
363
365
  }
364
366
  }
365
367
  // Specificity: non-catch-all first, deeper targets first, fewer dynamic
@@ -369,64 +371,66 @@ export function matchSlotInterceptor(
369
371
  Number(a.catchAllTail) - Number(b.catchAllTail) ||
370
372
  b.targetSegments.length - a.targetSegments.length ||
371
373
  a.params.length - b.params.length,
372
- );
374
+ )
373
375
  for (const unit of units) {
374
- const regex = new RegExp(`^/${unit.targetPattern}(?:/(.*))?$`);
375
- const match = regex.exec(pathname.replace(/\/+$/, '') || '/');
376
- if (!match) continue;
377
- const params: Record<string, RouteParamValue> = {};
376
+ const regex = new RegExp(`^/${unit.targetPattern}(?:/(.*))?$`)
377
+ const match = regex.exec(pathname.replace(/\/+$/, '') || '/')
378
+ if (!match) continue
379
+ const params: Record<string, RouteParamValue> = {}
378
380
  unit.params.forEach((param, index) => {
379
- const value = match[index + 1] ?? '';
381
+ const value = match[index + 1] ?? ''
380
382
  params[param.name] = param.catchAll
381
383
  ? value.split('/').filter(Boolean).map(safeDecode)
382
- : safeDecode(value);
383
- });
384
- const rest = unit.catchAllTail ? [] : segments.slice(unit.targetSegments.length);
385
- const inner = matchSegments(unit.dir, rest, { markersAsSegments: true }, params, []);
384
+ : safeDecode(value)
385
+ })
386
+ const rest = unit.catchAllTail ? [] : segments.slice(unit.targetSegments.length)
387
+ const inner = matchSegments(unit.dir, rest, { markersAsSegments: true }, params, [])
386
388
  if (inner) {
387
389
  return {
388
390
  file: inner.file,
389
391
  dirs: [path.basename(unit.dir), ...inner.dirs],
390
392
  params: inner.params,
391
- };
393
+ }
392
394
  }
393
395
  }
394
- return null;
396
+ return null
395
397
  }
396
398
 
397
399
  function markerOwnerTokens(appPath: string, slotDir: string): RouteToken[] | null {
398
- const relative = path.relative(appPath, slotDir);
399
- if (relative.startsWith('..')) return null;
400
- const segments = toPosixPath(relative).split('/').filter(Boolean);
401
- const markerIndex = segments.findIndex(segment => Boolean(interceptionMarkerOf(segment)));
402
- if (markerIndex === -1) return null;
403
- return routeTokensForDir(appPath, path.join(appPath, ...segments.slice(0, markerIndex + 1))) ?? null;
400
+ const relative = path.relative(appPath, slotDir)
401
+ if (relative.startsWith('..')) return null
402
+ const segments = toPosixPath(relative).split('/').filter(Boolean)
403
+ const markerIndex = segments.findIndex(segment => Boolean(interceptionMarkerOf(segment)))
404
+ if (markerIndex === -1) return null
405
+ return (
406
+ routeTokensForDir(appPath, path.join(appPath, ...segments.slice(0, markerIndex + 1))) ?? null
407
+ )
404
408
  }
405
409
 
406
410
  function matchTargetTokens(
407
411
  tokens: RouteToken[],
408
412
  pathname: string,
409
413
  ): Record<string, RouteParamValue> | null {
410
- const pattern = tokens.map(token => token.pattern).join('/');
411
- const regex = new RegExp(`^/${pattern}(?:/.*)?$`);
412
- const match = regex.exec(pathname.replace(/\/+$/, '') || '/');
413
- if (!match) return null;
414
- const params: Record<string, RouteParamValue> = {};
414
+ const pattern = tokens.map(token => token.pattern).join('/')
415
+ const regex = new RegExp(`^/${pattern}(?:/.*)?$`)
416
+ const match = regex.exec(pathname.replace(/\/+$/, '') || '/')
417
+ if (!match) return null
418
+ const params: Record<string, RouteParamValue> = {}
415
419
  tokens
416
420
  .filter(token => token.param)
417
421
  .forEach((token, index) => {
418
- const value = match[index + 1] ?? '';
422
+ const value = match[index + 1] ?? ''
419
423
  params[token.param!] = token.catchAll
420
424
  ? value.split('/').filter(Boolean).map(safeDecode)
421
- : safeDecode(value);
422
- });
423
- return params;
425
+ : safeDecode(value)
426
+ })
427
+ return params
424
428
  }
425
429
 
426
430
  export function pathnameSegments(pathname: string) {
427
- return pathname.split('?')[0]!.split('/').filter(Boolean);
431
+ return pathname.split('?')[0]!.split('/').filter(Boolean)
428
432
  }
429
433
 
430
434
  function escapeRegex(value: string) {
431
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
435
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
432
436
  }