@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,105 +1,102 @@
1
- import type { MetadataLink } from '../../types';
2
- import { getWorkUnit } from '../../request/context';
3
- import { registerResponseFinalizers } from '../../extensions';
4
- import type { ResponseFinalizerContext } from '../../extensions';
5
- import { setResourceHintListener } from '../../render/resource-hints';
6
- import { getNextConfig } from './config-loader';
7
-
8
- const RESOURCE_HINTS_KEY = Symbol.for('pnext.compat.resourceHints');
9
- const DEFAULT_REACT_MAX_HEADERS_LENGTH = 6000;
1
+ import type { MetadataLink } from '../../types'
2
+ import { getWorkUnit } from '../../request/context'
3
+ import { registerResponseFinalizers } from '../../extensions'
4
+ import type { ResponseFinalizerContext } from '../../extensions'
5
+ import { setResourceHintListener } from '../../render/resource-hints'
6
+ import { getNextConfig } from './config-loader'
7
+
8
+ const RESOURCE_HINTS_KEY = Symbol.for('pnext.compat.resourceHints')
9
+ const DEFAULT_REACT_MAX_HEADERS_LENGTH = 6000
10
10
  // Next emits react-dom preload()/preconnect() hints as a `Link` response
11
11
  // header by default in production; nothing in the compat runtime ever called
12
12
  // enableResourceHintHeaders, so the finalizer was dead code. The finalizer is
13
13
  // only registered under next-compat, so defaulting on is scoped already.
14
- let resourceHintHeadersEnabled = true;
14
+ let resourceHintHeadersEnabled = true
15
15
 
16
16
  export type ResourceHint = MetadataLink & {
17
- rel: string;
18
- url: string;
19
- };
17
+ rel: string
18
+ url: string
19
+ }
20
20
 
21
21
  export function enableResourceHintHeaders(enabled: boolean): void {
22
- resourceHintHeadersEnabled = enabled;
22
+ resourceHintHeadersEnabled = enabled
23
23
  }
24
24
 
25
25
  export function registerResourceHintFinalizer(): void {
26
- registerResponseFinalizers(resourceHintResponseFinalizer);
26
+ registerResponseFinalizers(resourceHintResponseFinalizer)
27
27
  // Every react-dom preload()/preconnect()/preinit() during a render lands on
28
28
  // the active work unit so the finalizer (and the build prerender) can emit
29
29
  // Next's `Link` response header alongside the in-document <link> tags.
30
- setResourceHintListener(hint => recordResourceHint(hint as ResourceHint));
30
+ setResourceHintListener(hint => recordResourceHint(hint as ResourceHint))
31
31
  }
32
32
 
33
33
  export function recordResourceHint(hint: ResourceHint): void {
34
- const unit = getWorkUnit();
35
- if (!unit) return;
34
+ const unit = getWorkUnit()
35
+ if (!unit) return
36
36
 
37
- const existing = (unit.compat?.[RESOURCE_HINTS_KEY] as ResourceHint[] | undefined) ?? [];
38
- if (!unit.compat) unit.compat = {};
39
- unit.compat[RESOURCE_HINTS_KEY] = dedupeResourceHints([...existing, hint]);
37
+ const existing = (unit.compat?.[RESOURCE_HINTS_KEY] as ResourceHint[] | undefined) ?? []
38
+ if (!unit.compat) unit.compat = {}
39
+ unit.compat[RESOURCE_HINTS_KEY] = dedupeResourceHints([...existing, hint])
40
40
  }
41
41
 
42
42
  export function takeResourceHintsForResponse(): ResourceHint[] {
43
- const unit = getWorkUnit();
44
- const compat = unit?.compat;
45
- if (!compat) return [];
46
- const hints = (compat[RESOURCE_HINTS_KEY] as ResourceHint[] | undefined) ?? [];
47
- compat[RESOURCE_HINTS_KEY] = undefined;
48
- return hints;
43
+ const unit = getWorkUnit()
44
+ const compat = unit?.compat
45
+ if (!compat) return []
46
+ const hints = (compat[RESOURCE_HINTS_KEY] as ResourceHint[] | undefined) ?? []
47
+ compat[RESOURCE_HINTS_KEY] = undefined
48
+ return hints
49
49
  }
50
50
 
51
- const ALLOWED_ROUTE_KINDS = new Set<ResponseFinalizerContext['routeKind']>([
52
- 'html',
53
- 'data',
54
- ]);
51
+ const ALLOWED_ROUTE_KINDS = new Set<ResponseFinalizerContext['routeKind']>(['html', 'data'])
55
52
 
56
53
  function resourceHintResponseFinalizer(ctx: ResponseFinalizerContext): void {
57
- if (!shouldEmitResourceHintsHeader()) return;
58
- if (ctx.hints?.runtime === 'edge') return;
59
- if (!ALLOWED_ROUTE_KINDS.has(ctx.routeKind)) return;
60
-
61
- const value = takeResourceHintHeader();
62
- if (value === undefined) return;
63
- const existing = ctx.headers.get('link');
64
- ctx.headers.set('link', existing ? `${existing}, ${value}` : value);
54
+ if (!shouldEmitResourceHintsHeader()) return
55
+ if (ctx.hints?.runtime === 'edge') return
56
+ if (!ALLOWED_ROUTE_KINDS.has(ctx.routeKind)) return
57
+
58
+ const value = takeResourceHintHeader()
59
+ if (value === undefined) return
60
+ const existing = ctx.headers.get('link')
61
+ ctx.headers.set('link', existing ? `${existing}, ${value}` : value)
65
62
  }
66
63
 
67
64
  function shouldEmitResourceHintsHeader(): boolean {
68
- return resourceHintHeadersEnabled;
65
+ return resourceHintHeadersEnabled
69
66
  }
70
67
 
71
68
  function getReactMaxHeadersLength(): number {
72
- const configValue = getNextConfig().reactMaxHeadersLength;
69
+ const configValue = getNextConfig().reactMaxHeadersLength
73
70
  if (typeof configValue === 'number' && Number.isFinite(configValue) && configValue >= 0) {
74
- return Math.floor(configValue);
71
+ return Math.floor(configValue)
75
72
  }
76
73
  // eslint-disable-next-line turbo/no-undeclared-env-vars
77
- const envValue = process.env.TEST_REACT_MAX_HEADERS_LENGTH;
74
+ const envValue = process.env.TEST_REACT_MAX_HEADERS_LENGTH
78
75
  if (typeof envValue === 'string' && envValue.trim() !== '') {
79
- const parsed = Number.parseInt(envValue, 10);
80
- if (Number.isFinite(parsed) && parsed >= 0) return Math.floor(parsed);
76
+ const parsed = Number.parseInt(envValue, 10)
77
+ if (Number.isFinite(parsed) && parsed >= 0) return Math.floor(parsed)
81
78
  }
82
- return DEFAULT_REACT_MAX_HEADERS_LENGTH;
79
+ return DEFAULT_REACT_MAX_HEADERS_LENGTH
83
80
  }
84
81
 
85
82
  export function takeResourceHintHeader(): string | undefined {
86
- const hints = takeResourceHintsForResponse();
87
- if (hints.length === 0) return undefined;
83
+ const hints = takeResourceHintsForResponse()
84
+ if (hints.length === 0) return undefined
88
85
 
89
- const maxLength = getReactMaxHeadersLength();
90
- if (!(maxLength > 0)) return undefined;
86
+ const maxLength = getReactMaxHeadersLength()
87
+ if (!(maxLength > 0)) return undefined
91
88
 
92
- const entries = hints.map(hint => formatLinkHeaderEntry(hint)).filter(Boolean);
93
- if (entries.length === 0) return undefined;
89
+ const entries = hints.map(hint => formatLinkHeaderEntry(hint)).filter(Boolean)
90
+ if (entries.length === 0) return undefined
94
91
 
95
- const values: string[] = [];
92
+ const values: string[] = []
96
93
  for (const entry of entries) {
97
- const candidate = values.length > 0 ? `${values.join(', ')}, ${entry}` : entry;
98
- if (candidate.length > maxLength) break;
99
- values.push(entry);
94
+ const candidate = values.length > 0 ? `${values.join(', ')}, ${entry}` : entry
95
+ if (candidate.length > maxLength) break
96
+ values.push(entry)
100
97
  }
101
98
 
102
- return values.length === 0 ? undefined : values.join(', ');
99
+ return values.length === 0 ? undefined : values.join(', ')
103
100
  }
104
101
 
105
102
  // React's Link-header entry shape (ReactFizz getPreloadAsHeader): the rel is
@@ -108,29 +105,29 @@ export function takeResourceHintHeader(): string | undefined {
108
105
  // expected header lengths from React's exact per-entry size, so the format
109
106
  // must match byte-for-byte.
110
107
  function formatLinkHeaderEntry(hint: ResourceHint): string {
111
- const parts = [`<${hint.url}>`, `rel=${hint.rel}`];
112
- if (hint.as) parts.push(`as="${hint.as}"`);
108
+ const parts = [`<${hint.url}>`, `rel=${hint.rel}`]
109
+ if (hint.as) parts.push(`as="${hint.as}"`)
113
110
  if (hint.crossOrigin !== undefined)
114
- parts.push(`crossorigin="${hint.crossOrigin === 'anonymous' ? '' : hint.crossOrigin}"`);
115
- if (hint.type) parts.push(`type="${hint.type}"`);
116
- if (hint.media) parts.push(`media="${hint.media}"`);
117
- if (hint.sizes) parts.push(`sizes="${hint.sizes}"`);
118
- if (hint.title) parts.push(`title="${hint.title}"`);
119
- if (hint.hrefLang) parts.push(`hreflang="${hint.hrefLang}"`);
120
- if (hint.fetchPriority) parts.push(`fetchpriority="${hint.fetchPriority}"`);
121
- if (hint.nonce) parts.push(`nonce="${hint.nonce}"`);
122
- return parts.join('; ');
111
+ parts.push(`crossorigin="${hint.crossOrigin === 'anonymous' ? '' : hint.crossOrigin}"`)
112
+ if (hint.type) parts.push(`type="${hint.type}"`)
113
+ if (hint.media) parts.push(`media="${hint.media}"`)
114
+ if (hint.sizes) parts.push(`sizes="${hint.sizes}"`)
115
+ if (hint.title) parts.push(`title="${hint.title}"`)
116
+ if (hint.hrefLang) parts.push(`hreflang="${hint.hrefLang}"`)
117
+ if (hint.fetchPriority) parts.push(`fetchpriority="${hint.fetchPriority}"`)
118
+ if (hint.nonce) parts.push(`nonce="${hint.nonce}"`)
119
+ return parts.join('; ')
123
120
  }
124
121
 
125
122
  function dedupeResourceHints(hints: ResourceHint[]): ResourceHint[] {
126
- if (hints.length <= 1) return hints;
127
- const seen = new Set<string>();
128
- const next: ResourceHint[] = [];
123
+ if (hints.length <= 1) return hints
124
+ const seen = new Set<string>()
125
+ const next: ResourceHint[] = []
129
126
  for (const hint of hints) {
130
- const key = formatLinkHeaderEntry(hint);
131
- if (seen.has(key)) continue;
132
- seen.add(key);
133
- next.push(hint);
127
+ const key = formatLinkHeaderEntry(hint)
128
+ if (seen.has(key)) continue
129
+ seen.add(key)
130
+ next.push(hint)
134
131
  }
135
- return next;
132
+ return next
136
133
  }
@@ -17,83 +17,83 @@
17
17
  * Divergence: the render sees the destination URL (Next keeps the requested URL as canonical for
18
18
  * usePathname; recordCanonicalUrl handles that separately).
19
19
  */
20
- import { loadNextConfig, loadResolvedNextConfig } from '../actions/config';
20
+ import { loadNextConfig, loadResolvedNextConfig } from '../actions/config'
21
21
 
22
22
  export interface CompatRewrite {
23
- regex: RegExp;
24
- paramNames: string[];
25
- destination: string;
26
- has: RewriteCondition[];
27
- missing: RewriteCondition[];
23
+ regex: RegExp
24
+ paramNames: string[]
25
+ destination: string
26
+ has: RewriteCondition[]
27
+ missing: RewriteCondition[]
28
28
  /**
29
29
  * A `fallback` rewrite: Next applies it only after filesystem AND dynamic
30
30
  * routes have all missed, i.e. only on a request that would otherwise 404.
31
31
  * `beforeFiles`/`afterFiles` (and the array form, which is `afterFiles`)
32
32
  * apply ahead of routing and carry this false.
33
33
  */
34
- fallback: boolean;
34
+ fallback: boolean
35
35
  /**
36
36
  * `basePath: false` on the entry: the source is matched against the RAW
37
37
  * request path, outside the configured basePath. Core 404s such paths before
38
38
  * routing, so these rules get their turn from the outside-basePath pass
39
39
  * instead of the normal one (and never both).
40
40
  */
41
- outsideBasePath: boolean;
41
+ outsideBasePath: boolean
42
42
  }
43
43
 
44
44
  export interface RewriteCondition {
45
- type: 'host' | 'header' | 'query' | 'cookie';
46
- key?: string;
47
- value?: string;
45
+ type: 'host' | 'header' | 'query' | 'cookie'
46
+ key?: string
47
+ value?: string
48
48
  }
49
49
 
50
50
  interface RewriteEntry {
51
- source?: string;
52
- destination?: string;
53
- has?: unknown;
54
- missing?: unknown;
55
- basePath?: unknown;
51
+ source?: string
52
+ destination?: string
53
+ has?: unknown
54
+ missing?: unknown
55
+ basePath?: unknown
56
56
  }
57
57
 
58
58
  /** Request facts a rewrite's `has`/`missing` conditions are evaluated against. */
59
59
  export interface RewriteRequestContext {
60
- host: string;
61
- headers: Headers;
62
- cookies: Record<string, string>;
63
- query: URLSearchParams;
60
+ host: string
61
+ headers: Headers
62
+ cookies: Record<string, string>
63
+ query: URLSearchParams
64
64
  }
65
65
 
66
- const VALID_CONDITION_TYPES = new Set(['host', 'header', 'query', 'cookie']);
66
+ const VALID_CONDITION_TYPES = new Set(['host', 'header', 'query', 'cookie'])
67
67
 
68
68
  export async function loadCompatRewrites(root: string): Promise<CompatRewrite[]> {
69
- let config = await loadResolvedNextConfig(root);
70
- if (typeof config?.rewrites !== 'function') config = await loadNextConfig(root);
71
- const producer = config?.rewrites;
72
- if (typeof producer !== 'function') return [];
73
- let value: unknown;
69
+ let config = await loadResolvedNextConfig(root)
70
+ if (typeof config?.rewrites !== 'function') config = await loadNextConfig(root)
71
+ const producer = config?.rewrites
72
+ if (typeof producer !== 'function') return []
73
+ let value: unknown
74
74
  try {
75
- value = await producer();
75
+ value = await producer()
76
76
  } catch {
77
- return [];
77
+ return []
78
78
  }
79
79
  const entries: (RewriteEntry & { fallback: boolean })[] = Array.isArray(value)
80
80
  ? (value as RewriteEntry[]).map(entry => ({ ...entry, fallback: false }))
81
81
  : value && typeof value === 'object'
82
82
  ? (['beforeFiles', 'afterFiles', 'fallback'] as const).flatMap(key => {
83
- const list = (value as Record<string, unknown>)[key];
83
+ const list = (value as Record<string, unknown>)[key]
84
84
  return Array.isArray(list)
85
85
  ? (list as RewriteEntry[]).map(entry => ({ ...entry, fallback: key === 'fallback' }))
86
- : [];
86
+ : []
87
87
  })
88
- : [];
88
+ : []
89
89
 
90
- const rewrites: CompatRewrite[] = [];
90
+ const rewrites: CompatRewrite[] = []
91
91
  for (const entry of entries) {
92
- if (!entry?.source || !entry.destination) continue;
93
- const has = parseConditions(entry.has);
94
- const missing = parseConditions(entry.missing);
95
- if (has === null || missing === null) continue; // unsupported condition shape
96
- const compiled = compileSource(entry.source);
92
+ if (!entry?.source || !entry.destination) continue
93
+ const has = parseConditions(entry.has)
94
+ const missing = parseConditions(entry.missing)
95
+ if (has === null || missing === null) continue // unsupported condition shape
96
+ const compiled = compileSource(entry.source)
97
97
  if (compiled) {
98
98
  rewrites.push({
99
99
  ...compiled,
@@ -102,78 +102,78 @@ export async function loadCompatRewrites(root: string): Promise<CompatRewrite[]>
102
102
  missing,
103
103
  fallback: entry.fallback,
104
104
  outsideBasePath: entry.basePath === false,
105
- });
105
+ })
106
106
  }
107
107
  }
108
- return rewrites;
108
+ return rewrites
109
109
  }
110
110
 
111
111
  /** Parse a has/missing list into typed conditions; null if any entry is unsupported. */
112
112
  export function parseConditions(value: unknown): RewriteCondition[] | null {
113
- if (value === undefined) return [];
114
- if (!Array.isArray(value)) return null;
115
- const conditions: RewriteCondition[] = [];
113
+ if (value === undefined) return []
114
+ if (!Array.isArray(value)) return null
115
+ const conditions: RewriteCondition[] = []
116
116
  for (const raw of value as unknown[]) {
117
- if (!raw || typeof raw !== 'object') return null;
118
- const { type, key, value: condValue } = raw as Record<string, unknown>;
119
- if (typeof type !== 'string' || !VALID_CONDITION_TYPES.has(type)) return null;
120
- if (key !== undefined && typeof key !== 'string') return null;
121
- if (condValue !== undefined && typeof condValue !== 'string') return null;
117
+ if (!raw || typeof raw !== 'object') return null
118
+ const { type, key, value: condValue } = raw as Record<string, unknown>
119
+ if (typeof type !== 'string' || !VALID_CONDITION_TYPES.has(type)) return null
120
+ if (key !== undefined && typeof key !== 'string') return null
121
+ if (condValue !== undefined && typeof condValue !== 'string') return null
122
122
  conditions.push({
123
123
  type: type as RewriteCondition['type'],
124
124
  ...(typeof key === 'string' ? { key } : {}),
125
125
  ...(typeof condValue === 'string' ? { value: condValue } : {}),
126
- });
126
+ })
127
127
  }
128
- return conditions;
128
+ return conditions
129
129
  }
130
130
 
131
131
  export function compileSource(source: string): { regex: RegExp; paramNames: string[] } | null {
132
- const paramNames: string[] = [];
132
+ const paramNames: string[] = []
133
133
  // Match against the pathname. Note: the source is a path-to-regexp pattern
134
134
  // (query matching is done via `has` conditions), so it never carries a
135
135
  // literal `?query`. We must NOT split on `?` — a `?` may legitimately appear
136
136
  // inside a regex token such as `:path((?!sitemap.xml$).*)` or `(?<name>...)`.
137
- const segments = source.split('/').filter(Boolean);
138
- const parts: string[] = [];
137
+ const segments = source.split('/').filter(Boolean)
138
+ const parts: string[] = []
139
139
  for (const segment of segments) {
140
140
  // :param(customRegex) — a named param with an explicit regex body (may span
141
141
  // the whole segment, e.g. `:path((?!sitemap.xml$).*)`).
142
- const custom = /^:([A-Za-z_$][\w$]*)\((.*)\)$/.exec(segment);
142
+ const custom = /^:([A-Za-z_$][\w$]*)\((.*)\)$/.exec(segment)
143
143
  if (custom?.[1] !== undefined && custom[2] !== undefined) {
144
- paramNames.push(custom[1]);
145
- parts.push(`(${custom[2]})`);
146
- continue;
144
+ paramNames.push(custom[1])
145
+ parts.push(`(${custom[2]})`)
146
+ continue
147
147
  }
148
- const catchAll = /^:([A-Za-z_$][\w$]*)[*+]$/.exec(segment);
148
+ const catchAll = /^:([A-Za-z_$][\w$]*)[*+]$/.exec(segment)
149
149
  if (catchAll?.[1]) {
150
- paramNames.push(catchAll[1]);
151
- parts.push('(.*)');
152
- continue;
150
+ paramNames.push(catchAll[1])
151
+ parts.push('(.*)')
152
+ continue
153
153
  }
154
- const optional = /^:([A-Za-z_$][\w$]*)\?$/.exec(segment);
154
+ const optional = /^:([A-Za-z_$][\w$]*)\?$/.exec(segment)
155
155
  if (optional?.[1]) {
156
- paramNames.push(optional[1]);
157
- parts.push('([^/]*)');
158
- continue;
156
+ paramNames.push(optional[1])
157
+ parts.push('([^/]*)')
158
+ continue
159
159
  }
160
- const param = /^:([A-Za-z_$][\w$]*)$/.exec(segment);
160
+ const param = /^:([A-Za-z_$][\w$]*)$/.exec(segment)
161
161
  if (param?.[1]) {
162
- paramNames.push(param[1]);
163
- parts.push('([^/]+)');
164
- continue;
162
+ paramNames.push(param[1])
163
+ parts.push('([^/]+)')
164
+ continue
165
165
  }
166
166
  // Plain literal segments may carry regex-significant filename characters
167
167
  // (`favicon.ico`, `sitemap.xml`) — escape them. Anything with actual
168
168
  // pattern syntax beyond that is unsupported.
169
169
  if (/^[\w.\- ]+$/.test(segment)) {
170
- parts.push(segment.replace(/\./g, '\\.'));
171
- continue;
170
+ parts.push(segment.replace(/\./g, '\\.'))
171
+ continue
172
172
  }
173
- if (/[.*+?^${}()|[\]\\]/.test(segment)) return null; // unsupported literal syntax
174
- parts.push(segment.replace(/[/\\]/g, ''));
173
+ if (/[.*+?^${}()|[\]\\]/.test(segment)) return null // unsupported literal syntax
174
+ parts.push(segment.replace(/[/\\]/g, ''))
175
175
  }
176
- return { regex: new RegExp(`^/${parts.join('/')}/?$`), paramNames };
176
+ return { regex: new RegExp(`^/${parts.join('/')}/?$`), paramNames }
177
177
  }
178
178
 
179
179
  /** Evaluate a single has/missing condition, returning captured params or null (no match). */
@@ -181,14 +181,14 @@ function evaluateCondition(
181
181
  condition: RewriteCondition,
182
182
  ctx: RewriteRequestContext,
183
183
  ): Record<string, string> | null {
184
- const target = conditionTarget(condition, ctx);
185
- if (target === undefined) return null;
186
- if (condition.value === undefined) return {}; // presence-only match
184
+ const target = conditionTarget(condition, ctx)
185
+ if (target === undefined) return null
186
+ if (condition.value === undefined) return {} // presence-only match
187
187
  // Anchor the value regex the way Next does (full-value match).
188
- const regex = new RegExp(`^(?:${condition.value})$`);
189
- const match = regex.exec(target);
190
- if (!match) return null;
191
- return match.groups ? { ...match.groups } : {};
188
+ const regex = new RegExp(`^(?:${condition.value})$`)
189
+ const match = regex.exec(target)
190
+ if (!match) return null
191
+ return match.groups ? { ...match.groups } : {}
192
192
  }
193
193
 
194
194
  function conditionTarget(
@@ -197,24 +197,24 @@ function conditionTarget(
197
197
  ): string | undefined {
198
198
  switch (condition.type) {
199
199
  case 'host':
200
- return ctx.host;
200
+ return ctx.host
201
201
  case 'header':
202
- return condition.key ? (ctx.headers.get(condition.key) ?? undefined) : undefined;
202
+ return condition.key ? (ctx.headers.get(condition.key) ?? undefined) : undefined
203
203
  case 'cookie':
204
- return condition.key ? ctx.cookies[condition.key] : undefined;
204
+ return condition.key ? ctx.cookies[condition.key] : undefined
205
205
  case 'query':
206
- return condition.key ? (ctx.query.get(condition.key) ?? undefined) : undefined;
206
+ return condition.key ? (ctx.query.get(condition.key) ?? undefined) : undefined
207
207
  default:
208
- return undefined;
208
+ return undefined
209
209
  }
210
210
  }
211
211
 
212
212
  export interface RewriteResult {
213
- pathname: string;
213
+ pathname: string
214
214
  /** Search params after the rewrite (original query + any auto-appended params). */
215
- search: URLSearchParams;
215
+ search: URLSearchParams
216
216
  /** Fully-qualified destination for external rewrites (`https://...`). */
217
- destination?: string;
217
+ destination?: string
218
218
  }
219
219
 
220
220
  /**
@@ -228,7 +228,7 @@ export function applyCompatRewrites(
228
228
  pathname: string,
229
229
  ctx?: RewriteRequestContext,
230
230
  ): string | undefined {
231
- return resolveCompatRewrite(rewrites, pathname, ctx)?.pathname;
231
+ return resolveCompatRewrite(rewrites, pathname, ctx)?.pathname
232
232
  }
233
233
 
234
234
  /**
@@ -246,42 +246,42 @@ export function resolveCompatRewrite(
246
246
  headers: new Headers(),
247
247
  cookies: {},
248
248
  query: new URLSearchParams(),
249
- };
249
+ }
250
250
  for (const rewrite of rewrites) {
251
- const match = rewrite.regex.exec(pathname);
252
- if (!match) continue;
251
+ const match = rewrite.regex.exec(pathname)
252
+ if (!match) continue
253
253
 
254
254
  // Collect all params: source captures first, then has/missing captures.
255
- const params: Record<string, string> = {};
255
+ const params: Record<string, string> = {}
256
256
  rewrite.paramNames.forEach((name, index) => {
257
- params[name] = match[index + 1] ?? '';
258
- });
257
+ params[name] = match[index + 1] ?? ''
258
+ })
259
259
 
260
- const conditionParams = evaluateConditions(rewrite, context);
261
- if (conditionParams === null) continue; // has/missing gate failed
262
- Object.assign(params, conditionParams);
260
+ const conditionParams = evaluateConditions(rewrite, context)
261
+ if (conditionParams === null) continue // has/missing gate failed
262
+ Object.assign(params, conditionParams)
263
263
 
264
- const [destPath, destQuery] = splitDestination(rewrite.destination);
265
- const { pathname: newPath, used: usedInPath } = substitute(destPath, params);
266
- const search = new URLSearchParams(context.query);
264
+ const [destPath, destQuery] = splitDestination(rewrite.destination)
265
+ const { pathname: newPath, used: usedInPath } = substitute(destPath, params)
266
+ const search = new URLSearchParams(context.query)
267
267
 
268
268
  // Destination-declared query params (?key=:val) are always applied.
269
- let usedInQuery = false;
269
+ let usedInQuery = false
270
270
  if (destQuery) {
271
- const destParams = new URLSearchParams(destQuery);
271
+ const destParams = new URLSearchParams(destQuery)
272
272
  for (const [key, rawValue] of destParams.entries()) {
273
- const { pathname: value, used } = substitute(rawValue, params);
274
- if (used) usedInQuery = true;
275
- search.set(key, value);
273
+ const { pathname: value, used } = substitute(rawValue, params)
274
+ if (used) usedInQuery = true
275
+ search.set(key, value)
276
276
  }
277
277
  }
278
278
 
279
279
  // Next rule: only auto-append unused params to the query when NONE of the
280
280
  // params were used in the destination. If any param is used, nothing leaks.
281
- const anyUsed = usedInPath.size > 0 || usedInQuery;
281
+ const anyUsed = usedInPath.size > 0 || usedInQuery
282
282
  if (!anyUsed) {
283
283
  for (const [name, value] of Object.entries(params)) {
284
- if (!search.has(name)) search.append(name, value);
284
+ if (!search.has(name)) search.append(name, value)
285
285
  }
286
286
  }
287
287
 
@@ -289,23 +289,20 @@ export function resolveCompatRewrite(
289
289
  pathname: newPath,
290
290
  search,
291
291
  destination: /^https?:/.test(newPath) ? normalizeDestination(newPath, search) : undefined,
292
- };
292
+ }
293
293
  }
294
- return undefined;
294
+ return undefined
295
295
  }
296
296
 
297
- function normalizeDestination(
298
- pathname: string,
299
- search: URLSearchParams,
300
- ): string | undefined {
297
+ function normalizeDestination(pathname: string, search: URLSearchParams): string | undefined {
301
298
  try {
302
- const destination = new URL(pathname);
299
+ const destination = new URL(pathname)
303
300
  for (const [key, value] of search.entries()) {
304
- destination.searchParams.set(key, value);
301
+ destination.searchParams.set(key, value)
305
302
  }
306
- return destination.toString();
303
+ return destination.toString()
307
304
  } catch {
308
- return undefined;
305
+ return undefined
309
306
  }
310
307
  }
311
308
 
@@ -314,22 +311,22 @@ export function evaluateConditions(
314
311
  rule: { has: RewriteCondition[]; missing: RewriteCondition[] },
315
312
  ctx: RewriteRequestContext,
316
313
  ): Record<string, string> | null {
317
- const params: Record<string, string> = {};
314
+ const params: Record<string, string> = {}
318
315
  for (const condition of rule.has) {
319
- const captured = evaluateCondition(condition, ctx);
320
- if (captured === null) return null;
321
- Object.assign(params, captured);
316
+ const captured = evaluateCondition(condition, ctx)
317
+ if (captured === null) return null
318
+ Object.assign(params, captured)
322
319
  }
323
320
  for (const condition of rule.missing) {
324
- if (evaluateCondition(condition, ctx) !== null) return null;
321
+ if (evaluateCondition(condition, ctx) !== null) return null
325
322
  }
326
- return params;
323
+ return params
327
324
  }
328
325
 
329
326
  export function splitDestination(destination: string): [string, string | undefined] {
330
- const index = destination.indexOf('?');
331
- if (index === -1) return [destination, undefined];
332
- return [destination.slice(0, index), destination.slice(index + 1)];
327
+ const index = destination.indexOf('?')
328
+ if (index === -1) return [destination, undefined]
329
+ return [destination.slice(0, index), destination.slice(index + 1)]
333
330
  }
334
331
 
335
332
  /**
@@ -340,11 +337,11 @@ export function substitute(
340
337
  template: string,
341
338
  params: Record<string, string>,
342
339
  ): { pathname: string; used: Set<string> } {
343
- const used = new Set<string>();
340
+ const used = new Set<string>()
344
341
  const result = template.replace(/:([A-Za-z_$][\w$]*)(\*|\+|\?)?/g, (whole, name: string) => {
345
- if (!(name in params)) return whole;
346
- used.add(name);
347
- return params[name] ?? '';
348
- });
349
- return { pathname: result, used };
342
+ if (!(name in params)) return whole
343
+ used.add(name)
344
+ return params[name] ?? ''
345
+ })
346
+ return { pathname: result, used }
350
347
  }