@wular/pnext 0.0.4 → 0.0.7

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 (395) hide show
  1. package/README.md +22 -16
  2. package/bin/pnext +6 -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 +87 -22
  8. package/reference/config.md +40 -93
  9. package/reference/css.md +42 -33
  10. package/reference/dev.md +26 -33
  11. package/reference/env.md +18 -20
  12. package/reference/getting-started.md +132 -0
  13. package/reference/metadata.md +31 -46
  14. package/reference/navigation.md +65 -105
  15. package/reference/performance.md +21 -142
  16. package/reference/rendering.md +78 -75
  17. package/reference/routing.md +97 -107
  18. package/reference/typegen.md +27 -29
  19. package/src/api/cache.ts +36 -37
  20. package/src/api/client-cache.ts +2 -2
  21. package/src/api/client-navigation.ts +121 -114
  22. package/src/api/dynamic.tsx +58 -55
  23. package/src/api/link.tsx +52 -53
  24. package/src/api/navigation.ts +59 -58
  25. package/src/api/server.ts +152 -144
  26. package/src/api/suspense.ts +4 -4
  27. package/src/cli/adapters/vercel-warm.ts +126 -121
  28. package/src/cli/adapters/vercel.ts +437 -443
  29. package/src/cli/analyze.ts +333 -144
  30. package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
  31. package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
  32. package/src/cli/build.ts +976 -978
  33. package/src/cli/create.ts +72 -64
  34. package/src/cli/dev.ts +116 -116
  35. package/src/cli/index.ts +94 -85
  36. package/src/cli/migrate/package-json.ts +73 -71
  37. package/src/cli/migrate/report.ts +32 -33
  38. package/src/cli/migrate/{index.ts → run.ts} +48 -49
  39. package/src/cli/migrate/scan.ts +46 -46
  40. package/src/cli/migrate/spinner.ts +9 -9
  41. package/src/cli/migrate/tsconfig.ts +35 -35
  42. package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
  43. package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
  44. package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
  45. package/src/cli/start.ts +65 -66
  46. package/src/{typegen.ts → cli/typegen.ts} +59 -59
  47. package/src/client/build.ts +802 -768
  48. package/src/client/chunk-fold.ts +245 -240
  49. package/src/client/{paths.ts → chunk-name.ts} +6 -6
  50. package/src/client/entry.ts +162 -147
  51. package/src/client/prebuilt.ts +231 -223
  52. package/src/client/profile.ts +29 -29
  53. package/src/client/react-compiler.ts +20 -15
  54. package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
  55. package/src/client/reference-stub.ts +51 -51
  56. package/src/client/reference.ts +19 -19
  57. package/src/{api → client}/router/events.ts +32 -17
  58. package/src/{api → client}/router/history.ts +16 -16
  59. package/src/{api → client}/router/hub.ts +52 -53
  60. package/src/{api/router.ts → client/router/index.ts} +61 -60
  61. package/src/{api → client}/router/policies.ts +24 -24
  62. package/src/{api → client}/router/runtime.ts +2022 -1995
  63. package/src/{api → client}/router/types.ts +98 -98
  64. package/src/compat/actions/client-plugin.ts +42 -43
  65. package/src/compat/actions/client-stub.ts +14 -14
  66. package/src/compat/actions/{action-client.ts → client.ts} +194 -193
  67. package/src/compat/actions/config.ts +63 -64
  68. package/src/compat/actions/detect.ts +68 -68
  69. package/src/compat/actions/discovery.ts +105 -105
  70. package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
  71. package/src/compat/actions/early-submit.ts +1 -1
  72. package/src/compat/actions/endpoint.ts +198 -198
  73. package/src/compat/actions/extensions.ts +811 -0
  74. package/src/compat/actions/flight.ts +23 -23
  75. package/src/compat/actions/form-state.ts +34 -34
  76. package/src/compat/actions/hoist.ts +382 -236
  77. package/src/compat/actions/ids.ts +7 -12
  78. package/src/compat/actions/index.ts +8 -8
  79. package/src/compat/actions/instances.ts +46 -46
  80. package/src/compat/actions/origin.ts +47 -48
  81. package/src/compat/actions/protocol.ts +22 -22
  82. package/src/compat/actions/registry.ts +19 -19
  83. package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
  84. package/src/compat/actions/rewrite.ts +125 -125
  85. package/src/compat/actions/{action-router.ts → router.ts} +10 -10
  86. package/src/compat/actions/serve.ts +132 -136
  87. package/src/compat/actions/server-tag.ts +4 -4
  88. package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
  89. package/src/compat/actions/unrecognized-error.ts +4 -4
  90. package/src/compat/{index.ts → aliases.ts} +112 -109
  91. package/src/compat/bundler/bun-externals.ts +18 -18
  92. package/src/compat/bundler/cjs-exports.ts +271 -223
  93. package/src/compat/bundler/config.ts +116 -111
  94. package/src/compat/bundler/externals.ts +12 -12
  95. package/src/compat/bundler/import-meta-url.ts +19 -19
  96. package/src/compat/bundler/modularize-imports.ts +36 -33
  97. package/src/compat/bundler/new-url-asset.ts +22 -24
  98. package/src/compat/bundler/optimize-package-imports.ts +111 -107
  99. package/src/compat/bundler/polyfill.ts +28 -28
  100. package/src/compat/bundler/react-compiler.ts +35 -29
  101. package/src/compat/bundler/react-profiler.tsx +11 -11
  102. package/src/compat/bundler/relay-transform.ts +48 -47
  103. package/src/compat/bundler/require-context.ts +119 -113
  104. package/src/compat/bundler/resolve-extensions.ts +19 -19
  105. package/src/compat/bundler/source-cache.ts +25 -25
  106. package/src/compat/bundler/static-imports.ts +7 -7
  107. package/src/compat/bundler/symlink-imports.ts +46 -46
  108. package/src/compat/bundler/tsconfig-paths.ts +13 -15
  109. package/src/compat/bundler/wasm.ts +58 -60
  110. package/src/compat/bundler/webpack-loaders.ts +254 -241
  111. package/src/compat/bundler/worker.ts +101 -104
  112. package/src/compat/cache/build-flags.ts +29 -29
  113. package/src/compat/cache/build-prerender-errors.ts +40 -44
  114. package/src/compat/cache/custom-handler.ts +60 -53
  115. package/src/compat/cache/fetch-patch.ts +240 -240
  116. package/src/compat/cache/handler.ts +27 -31
  117. package/src/compat/cache/modern-handler.ts +148 -126
  118. package/src/compat/cache/resume-data-cache.ts +47 -45
  119. package/src/compat/cache/revalidate.ts +233 -232
  120. package/src/compat/cache/runtime-error.ts +35 -35
  121. package/src/compat/cache/use-cache-transform.ts +442 -417
  122. package/src/compat/cache/use-cache.ts +650 -614
  123. package/src/compat/cache-control.ts +140 -142
  124. package/src/compat/client/base-path.ts +21 -20
  125. package/src/compat/client/css-order.ts +18 -18
  126. package/src/compat/client/errors/bare-boundary.ts +11 -11
  127. package/src/compat/client/errors/control-flow.ts +23 -23
  128. package/src/compat/client/errors/error-boundary.ts +61 -61
  129. package/src/compat/client/errors/global-error.ts +101 -91
  130. package/src/compat/client/errors/install.ts +71 -72
  131. package/src/compat/client/errors/lazy.ts +23 -23
  132. package/src/compat/client/errors/primitive-throw.ts +47 -45
  133. package/src/compat/client/errors/soft-refresh.ts +4 -4
  134. package/src/compat/client/link-status.ts +33 -33
  135. package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
  136. package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
  137. package/src/compat/client/navigation-scroll.ts +63 -63
  138. package/src/compat/client/optimistic-routing.ts +93 -88
  139. package/src/compat/client/prefetch-cache.ts +23 -24
  140. package/src/compat/client/route-announcer.ts +35 -35
  141. package/src/compat/client/segment-cache-policy.ts +20 -20
  142. package/src/compat/client/segment-cache.ts +309 -315
  143. package/src/compat/client/segment-prefetch.ts +127 -132
  144. package/src/compat/client/trailing-slash.ts +5 -4
  145. package/src/compat/css/chunking.ts +113 -116
  146. package/src/compat/css/inline-css.ts +21 -21
  147. package/src/compat/css/lightningcss.ts +37 -38
  148. package/src/compat/css/modules.ts +161 -175
  149. package/src/compat/css/nonce.ts +7 -7
  150. package/src/compat/css/sass-plugin.ts +18 -21
  151. package/src/compat/css/sass.ts +150 -152
  152. package/src/compat/css/styled-jsx-runtime.ts +27 -27
  153. package/src/compat/css/styled-jsx.ts +21 -21
  154. package/src/compat/edge-runtime.ts +27 -27
  155. package/src/compat/{adapter → export}/build-complete.ts +72 -75
  156. package/src/compat/export/client.ts +29 -31
  157. package/src/compat/export/{index.ts → emit.ts} +111 -110
  158. package/src/compat/export/standalone.ts +62 -54
  159. package/src/compat/image-optimizer/cache.ts +51 -49
  160. package/src/compat/image-optimizer/detect.ts +52 -52
  161. package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
  162. package/src/compat/image-optimizer/source.ts +77 -80
  163. package/src/compat/lifecycle/after-scope.ts +26 -26
  164. package/src/compat/lifecycle/after.ts +48 -45
  165. package/src/compat/lifecycle/error-funnel.ts +98 -102
  166. package/src/compat/lifecycle/error-serialize.ts +30 -26
  167. package/src/compat/lifecycle/error-ui.ts +67 -32
  168. package/src/compat/lifecycle/instrumentation-client.ts +36 -38
  169. package/src/compat/lifecycle/instrumentation.ts +85 -85
  170. package/src/compat/lifecycle/node-console.ts +11 -11
  171. package/src/compat/lifecycle/testmode.ts +160 -132
  172. package/src/compat/mdx/compile.ts +60 -57
  173. package/src/compat/mdx/plugin.ts +11 -11
  174. package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
  175. package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
  176. package/src/compat/metadata.ts +75 -81
  177. package/src/compat/next/cache.ts +68 -69
  178. package/src/compat/next/canonical-url.ts +9 -9
  179. package/src/compat/next/client-cache.ts +19 -19
  180. package/src/compat/next/client-navigation.ts +112 -116
  181. package/src/compat/next/client-only.ts +1 -1
  182. package/src/compat/next/client-script.tsx +99 -93
  183. package/src/compat/next/client-server.ts +10 -10
  184. package/src/compat/next/config-loader.ts +176 -173
  185. package/src/compat/next/config.ts +7 -7
  186. package/src/compat/next/constants.cjs +6 -6
  187. package/src/compat/next/constants.ts +6 -6
  188. package/src/compat/next/custom-server.ts +26 -24
  189. package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
  190. package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
  191. package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
  192. package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
  193. package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
  194. package/src/compat/next/dynamic.tsx +21 -18
  195. package/src/compat/next/error.tsx +52 -52
  196. package/src/compat/next/font/cache.ts +74 -74
  197. package/src/compat/next/font/google.ts +2 -2
  198. package/src/compat/next/font/index.ts +1 -1
  199. package/src/compat/next/font/local.ts +3 -3
  200. package/src/compat/next/font/runtime-client.ts +17 -15
  201. package/src/compat/next/font/runtime.ts +443 -408
  202. package/src/compat/next/font/shared.ts +120 -108
  203. package/src/compat/next/form.tsx +63 -63
  204. package/src/compat/next/head.tsx +2 -2
  205. package/src/compat/next/headers.ts +103 -95
  206. package/src/compat/next/image/client.tsx +220 -0
  207. package/src/compat/next/image/config.ts +56 -58
  208. package/src/compat/next/image/optimizer.ts +40 -36
  209. package/src/compat/next/image/patterns.ts +37 -40
  210. package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
  211. package/src/compat/next/image/shared.ts +65 -57
  212. package/src/compat/next/image/static-metadata.ts +98 -107
  213. package/src/compat/next/image/validate.ts +79 -88
  214. package/src/compat/next/image.tsx +19 -23
  215. package/src/compat/next/index.ts +1 -1
  216. package/src/compat/next/legacy-image.tsx +59 -60
  217. package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
  218. package/src/compat/next/link.tsx +158 -158
  219. package/src/compat/next/navigation.cjs +12 -3
  220. package/src/compat/next/navigation.ts +48 -50
  221. package/src/compat/next/offline.ts +27 -27
  222. package/src/compat/next/og.ts +121 -124
  223. package/src/compat/next/preferred-region.ts +13 -14
  224. package/src/compat/next/redirects.ts +58 -56
  225. package/src/compat/next/resource-hints.ts +73 -76
  226. package/src/compat/next/rewrites.ts +130 -133
  227. package/src/compat/next/root-params.ts +45 -45
  228. package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
  229. package/src/compat/next/router.cjs +4 -2
  230. package/src/compat/next/router.ts +58 -61
  231. package/src/compat/next/script.tsx +108 -108
  232. package/src/compat/next/server-only.ts +1 -1
  233. package/src/compat/next/server.ts +19 -19
  234. package/src/compat/next/svgr.ts +18 -17
  235. package/src/compat/next/telemetry.ts +24 -24
  236. package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
  237. package/src/compat/next/user-agent.ts +53 -49
  238. package/src/compat/next/web-vitals.ts +22 -24
  239. package/src/compat/otel/api.ts +41 -41
  240. package/src/compat/otel/client-trace-metadata.ts +25 -27
  241. package/src/compat/otel/fetch-span.ts +29 -29
  242. package/src/compat/otel/tracer.ts +331 -331
  243. package/src/compat/pages/api.ts +456 -0
  244. package/src/compat/pages/client-plugin.ts +36 -36
  245. package/src/compat/pages/router-state.ts +34 -34
  246. package/src/compat/pages/{index.ts → router.ts} +130 -135
  247. package/src/compat/ppr/io.ts +12 -12
  248. package/src/compat/ppr/missing-root-params.ts +34 -38
  249. package/src/compat/ppr/root-params-scan.ts +66 -66
  250. package/src/compat/ppr/root-params-transform.ts +24 -26
  251. package/src/compat/ppr/root-params.ts +30 -30
  252. package/src/compat/ppr/segment-config-incompat.ts +6 -7
  253. package/src/compat/protocol.ts +71 -70
  254. package/src/compat/react/action-state.ts +47 -48
  255. package/src/compat/react/client-lite.ts +15 -15
  256. package/src/compat/react/client.ts +4 -4
  257. package/src/compat/react/compiler-runtime.ts +11 -11
  258. package/src/compat/react/dom-client.ts +44 -44
  259. package/src/compat/react/dom-react-server.ts +10 -16
  260. package/src/compat/react/dom-server.ts +10 -10
  261. package/src/compat/react/dom.ts +52 -52
  262. package/src/compat/react/hooks-extra.ts +34 -35
  263. package/src/compat/react/parity.ts +64 -61
  264. package/src/compat/react/preact.ts +81 -82
  265. package/src/compat/react/react-server.ts +28 -28
  266. package/src/compat/react/router-shim.ts +1 -1
  267. package/src/compat/react/server-component-use.ts +8 -8
  268. package/src/compat/react/server-inserted-html.ts +30 -31
  269. package/src/compat/react/server.ts +53 -55
  270. package/src/compat/react/use.ts +32 -32
  271. package/src/compat/react/view-transition.ts +20 -20
  272. package/src/compat/register/actions.ts +35 -824
  273. package/src/compat/register/boot.ts +41 -41
  274. package/src/compat/register/build-tier.ts +5 -5
  275. package/src/compat/register/build.ts +74 -70
  276. package/src/compat/register/bundler.ts +161 -156
  277. package/src/compat/register/cache.ts +20 -20
  278. package/src/compat/register/client-errors.ts +3 -3
  279. package/src/compat/register/config.ts +6 -6
  280. package/src/compat/register/css-extras.ts +30 -34
  281. package/src/compat/register/edge-runtime.ts +3 -3
  282. package/src/compat/register/errors.ts +10 -12
  283. package/src/compat/register/export.ts +16 -16
  284. package/src/compat/register/font.ts +11 -11
  285. package/src/compat/register/hooks.ts +2 -2
  286. package/src/compat/register/image.ts +40 -40
  287. package/src/compat/register/index.ts +59 -62
  288. package/src/compat/register/instrumentation-client.ts +10 -10
  289. package/src/compat/register/lifecycle.ts +25 -28
  290. package/src/compat/register/mdx.ts +10 -10
  291. package/src/compat/register/middleware.ts +226 -16
  292. package/src/compat/register/otel.ts +80 -88
  293. package/src/compat/register/pages-api.ts +10 -463
  294. package/src/compat/register/ppr.ts +16 -16
  295. package/src/compat/register/protocol.ts +17 -18
  296. package/src/compat/register/proxy.ts +49 -51
  297. package/src/compat/register/render.ts +79 -76
  298. package/src/compat/register/routing.ts +162 -159
  299. package/src/compat/register/segment.ts +24 -1897
  300. package/src/compat/register/static-image.ts +3 -3
  301. package/src/compat/register/{misc.ts → taint.ts} +9 -9
  302. package/src/compat/register/typed-routes.ts +14 -14
  303. package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
  304. package/src/compat/register/validation.ts +18 -18
  305. package/src/compat/segment/loading-boundary.ts +43 -45
  306. package/src/compat/segment/page-slot.ts +69 -69
  307. package/src/compat/segment/serve.ts +1884 -0
  308. package/src/compat/segment/tree.ts +113 -112
  309. package/src/compat/segment/vary-key.ts +38 -38
  310. package/src/compat/segment/vary-params.ts +138 -142
  311. package/src/compat/static-params.ts +14 -12
  312. package/src/compat/tsconfig-defaults.ts +87 -91
  313. package/src/compat/typecheck/{index.ts → check.ts} +234 -212
  314. package/src/compat/typecheck/worker.ts +15 -12
  315. package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
  316. package/src/compat/typed-routes/manifest.ts +174 -170
  317. package/src/compat/typed-routes/typegen.ts +127 -110
  318. package/src/compat/validation/errors.ts +16 -19
  319. package/src/compat/validation/prerender-diagnostics.ts +521 -504
  320. package/src/compat/validation/{index.ts → validate.ts} +647 -648
  321. package/src/compat-bootstrap.ts +16 -16
  322. package/src/config.ts +86 -69
  323. package/src/css/build.ts +230 -227
  324. package/src/css/postcss.ts +79 -80
  325. package/src/css/worker.ts +14 -15
  326. package/src/dev/client-actions.ts +10 -10
  327. package/src/dev/client-chunk-store.ts +27 -27
  328. package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
  329. package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
  330. package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
  331. package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
  332. package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
  333. package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
  334. package/src/dev/server.ts +804 -820
  335. package/src/env.ts +46 -43
  336. package/src/extensions.ts +491 -478
  337. package/src/index.ts +8 -8
  338. package/src/internal.ts +20 -23
  339. package/src/{islands → render}/boundary-error.ts +3 -3
  340. package/src/render/hooks.ts +71 -71
  341. package/src/render/island-context.ts +14 -14
  342. package/src/render/metadata.ts +310 -310
  343. package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
  344. package/src/{ppr.ts → render/ppr.ts} +244 -245
  345. package/src/render/renderer.ts +2087 -2082
  346. package/src/render/resource-hints.ts +16 -17
  347. package/src/render/slots.tsx +224 -235
  348. package/src/{islands → render}/static-children.ts +9 -12
  349. package/src/{islands → render}/static-slots.ts +37 -37
  350. package/src/{cache/context.ts → request/cache.ts} +20 -20
  351. package/src/request/context.ts +107 -107
  352. package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
  353. package/src/resolve/engine.ts +90 -77
  354. package/src/resolve/imports.ts +475 -463
  355. package/src/resolve/scan-facts.ts +318 -296
  356. package/src/resolve/source-text.ts +37 -37
  357. package/src/{dynamic → resolve}/tree-shake.ts +132 -128
  358. package/src/routing/forwarded.ts +19 -19
  359. package/src/routing/handler.ts +84 -91
  360. package/src/routing/href.ts +87 -70
  361. package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
  362. package/src/{proxy.ts → routing/proxy.ts} +306 -312
  363. package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
  364. package/src/routing/routes.ts +827 -815
  365. package/src/routing/slots.ts +164 -160
  366. package/src/runtime/loader.ts +954 -0
  367. package/src/{dev → runtime}/module-cache.ts +309 -287
  368. package/src/{dev → runtime}/module-generations.ts +9 -9
  369. package/src/{dev → runtime}/module-transform.ts +81 -72
  370. package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
  371. package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
  372. package/src/runtime/vendor.ts +428 -406
  373. package/src/styles.d.ts +9 -0
  374. package/src/types.ts +324 -335
  375. package/src/utils/ansi.ts +5 -5
  376. package/src/utils/{source.ts → code.ts} +15 -12
  377. package/src/utils/content-type.ts +3 -3
  378. package/src/utils/decode.ts +2 -2
  379. package/src/utils/dev-profile.ts +13 -13
  380. package/src/utils/error-log.ts +6 -6
  381. package/src/utils/esbuild.ts +18 -18
  382. package/src/utils/fs-cache.ts +13 -13
  383. package/src/utils/fs.ts +57 -49
  384. package/src/utils/html.ts +20 -24
  385. package/src/utils/native-require.ts +8 -8
  386. package/src/utils/serialize.ts +139 -146
  387. package/src/utils/verbose.ts +18 -18
  388. package/reference/overview.md +0 -35
  389. package/src/cli/analyze-print.ts +0 -181
  390. package/src/compat/middleware/manifest.ts +0 -210
  391. package/src/compat/next/image-client.tsx +0 -215
  392. package/src/compat/next/link-usage.ts +0 -29
  393. package/src/css/index.ts +0 -2
  394. package/src/render/index.ts +0 -1
  395. 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
  }