@timber-js/app 0.2.0-alpha.12 → 0.2.0-alpha.120

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 (758) hide show
  1. package/dist/_chunks/actions-Cw-7NfJJ.js +1101 -0
  2. package/dist/_chunks/actions-Cw-7NfJJ.js.map +1 -0
  3. package/dist/_chunks/build-output-helper-DhxiT18k.js +61 -0
  4. package/dist/_chunks/build-output-helper-DhxiT18k.js.map +1 -0
  5. package/dist/_chunks/cli-schema-sync-XV0I47Gj.js +2 -0
  6. package/dist/_chunks/cli-schema-sync-q2wB0DyJ.js +358 -0
  7. package/dist/_chunks/cli-schema-sync-q2wB0DyJ.js.map +1 -0
  8. package/dist/_chunks/codec-registry-V7ARyeLN.js +21 -0
  9. package/dist/_chunks/codec-registry-V7ARyeLN.js.map +1 -0
  10. package/dist/_chunks/define-8zQ8Vm7x.js +195 -0
  11. package/dist/_chunks/define-8zQ8Vm7x.js.map +1 -0
  12. package/dist/_chunks/define-zQX6e1tN.js +124 -0
  13. package/dist/_chunks/define-zQX6e1tN.js.map +1 -0
  14. package/dist/_chunks/format-CR6v1pWE.js +14 -0
  15. package/dist/_chunks/format-CR6v1pWE.js.map +1 -0
  16. package/dist/_chunks/handler-store-iqnt2ghN.js +54 -0
  17. package/dist/_chunks/handler-store-iqnt2ghN.js.map +1 -0
  18. package/dist/_chunks/logger-DDmK5skc.js +291 -0
  19. package/dist/_chunks/logger-DDmK5skc.js.map +1 -0
  20. package/dist/_chunks/merge-search-params-CwxJzBLS.js +41 -0
  21. package/dist/_chunks/merge-search-params-CwxJzBLS.js.map +1 -0
  22. package/dist/_chunks/navigation-root-DKsJ5Di7.js +96 -0
  23. package/dist/_chunks/navigation-root-DKsJ5Di7.js.map +1 -0
  24. package/dist/_chunks/registry-Dp_hJL4s.js +20 -0
  25. package/dist/_chunks/registry-Dp_hJL4s.js.map +1 -0
  26. package/dist/_chunks/resolve-schema-23Mc8aLi.js +65 -0
  27. package/dist/_chunks/resolve-schema-23Mc8aLi.js.map +1 -0
  28. package/dist/_chunks/router-ref-sektkr-t.js +28 -0
  29. package/dist/_chunks/router-ref-sektkr-t.js.map +1 -0
  30. package/dist/_chunks/scanner-DmfoB7iK.js +336 -0
  31. package/dist/_chunks/scanner-DmfoB7iK.js.map +1 -0
  32. package/dist/_chunks/schema-bridge-eL5vQDSA.js +86 -0
  33. package/dist/_chunks/schema-bridge-eL5vQDSA.js.map +1 -0
  34. package/dist/_chunks/segment-classify-CnfLLvir.js +137 -0
  35. package/dist/_chunks/segment-classify-CnfLLvir.js.map +1 -0
  36. package/dist/_chunks/segment-context-Bg0pFbLT.js +34 -0
  37. package/dist/_chunks/segment-context-Bg0pFbLT.js.map +1 -0
  38. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-BO5OvEvg.js} +1 -1
  39. package/dist/_chunks/ssr-data-BO5OvEvg.js.map +1 -0
  40. package/dist/_chunks/stale-reload-BCPRG0Cv.js +64 -0
  41. package/dist/_chunks/stale-reload-BCPRG0Cv.js.map +1 -0
  42. package/dist/_chunks/tracing-DvKLzCFa.js +329 -0
  43. package/dist/_chunks/tracing-DvKLzCFa.js.map +1 -0
  44. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-D9SBlAfp.js} +7 -20
  45. package/dist/_chunks/use-query-states-D9SBlAfp.js.map +1 -0
  46. package/dist/_chunks/use-segment-params-CskiK-59.js +185 -0
  47. package/dist/_chunks/use-segment-params-CskiK-59.js.map +1 -0
  48. package/dist/_chunks/validation-Bm3Je-09.js +84 -0
  49. package/dist/_chunks/validation-Bm3Je-09.js.map +1 -0
  50. package/dist/_chunks/walkers-DgOXkTts.js +609 -0
  51. package/dist/_chunks/walkers-DgOXkTts.js.map +1 -0
  52. package/dist/_chunks/{format-DviM89f0.js → warnings-B30wpfaS.js} +6 -45
  53. package/dist/_chunks/warnings-B30wpfaS.js.map +1 -0
  54. package/dist/adapters/build-output-helper.d.ts +28 -0
  55. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  56. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  57. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  58. package/dist/adapters/cloudflare-dev.js +73 -0
  59. package/dist/adapters/cloudflare-dev.js.map +1 -0
  60. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  61. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  62. package/dist/adapters/cloudflare-kv-cache.js +95 -0
  63. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  64. package/dist/adapters/cloudflare.d.ts +148 -12
  65. package/dist/adapters/cloudflare.d.ts.map +1 -1
  66. package/dist/adapters/cloudflare.js +142 -38
  67. package/dist/adapters/cloudflare.js.map +1 -1
  68. package/dist/adapters/compress-module.d.ts.map +1 -1
  69. package/dist/adapters/nitro.d.ts +17 -1
  70. package/dist/adapters/nitro.d.ts.map +1 -1
  71. package/dist/adapters/nitro.js +143 -45
  72. package/dist/adapters/nitro.js.map +1 -1
  73. package/dist/adapters/shared.d.ts +16 -0
  74. package/dist/adapters/shared.d.ts.map +1 -0
  75. package/dist/cache/cache-api.d.ts +24 -0
  76. package/dist/cache/cache-api.d.ts.map +1 -0
  77. package/dist/cache/handler-store.d.ts +31 -0
  78. package/dist/cache/handler-store.d.ts.map +1 -0
  79. package/dist/cache/index.d.ts +23 -7
  80. package/dist/cache/index.d.ts.map +1 -1
  81. package/dist/cache/index.js +151 -81
  82. package/dist/cache/index.js.map +1 -1
  83. package/dist/cache/singleflight.d.ts +18 -1
  84. package/dist/cache/singleflight.d.ts.map +1 -1
  85. package/dist/cache/sizeof.d.ts +22 -0
  86. package/dist/cache/sizeof.d.ts.map +1 -0
  87. package/dist/cache/timber-cache.d.ts +1 -1
  88. package/dist/cache/timber-cache.d.ts.map +1 -1
  89. package/dist/cli-schema-sync.d.ts +37 -0
  90. package/dist/cli-schema-sync.d.ts.map +1 -0
  91. package/dist/cli.d.ts +14 -2
  92. package/dist/cli.d.ts.map +1 -1
  93. package/dist/cli.js +42 -6
  94. package/dist/cli.js.map +1 -1
  95. package/dist/client/browser-dev.d.ts +34 -1
  96. package/dist/client/browser-dev.d.ts.map +1 -1
  97. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  98. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  99. package/dist/client/browser-entry/hmr.d.ts +21 -0
  100. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  101. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  102. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  103. package/dist/client/browser-entry/index.d.ts +30 -0
  104. package/dist/client/browser-entry/index.d.ts.map +1 -0
  105. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  106. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  107. package/dist/client/browser-entry/router-init.d.ts +23 -0
  108. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  109. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  110. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  111. package/dist/client/browser-entry/scroll.d.ts +19 -0
  112. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  113. package/dist/client/error-boundary.d.ts +12 -5
  114. package/dist/client/error-boundary.d.ts.map +1 -1
  115. package/dist/client/error-boundary.js +29 -6
  116. package/dist/client/error-boundary.js.map +1 -1
  117. package/dist/client/error-reconstituter.d.ts +54 -0
  118. package/dist/client/error-reconstituter.d.ts.map +1 -0
  119. package/dist/client/form.d.ts +16 -27
  120. package/dist/client/form.d.ts.map +1 -1
  121. package/dist/client/history.d.ts +19 -4
  122. package/dist/client/history.d.ts.map +1 -1
  123. package/dist/client/index.d.ts +9 -24
  124. package/dist/client/index.d.ts.map +1 -1
  125. package/dist/client/index.js +172 -1100
  126. package/dist/client/index.js.map +1 -1
  127. package/dist/client/internal.d.ts +19 -0
  128. package/dist/client/internal.d.ts.map +1 -0
  129. package/dist/client/internal.js +964 -0
  130. package/dist/client/internal.js.map +1 -0
  131. package/dist/client/link-pending-store.d.ts +63 -0
  132. package/dist/client/link-pending-store.d.ts.map +1 -0
  133. package/dist/client/link.d.ts +62 -55
  134. package/dist/client/link.d.ts.map +1 -1
  135. package/dist/client/nav-link-store.d.ts +36 -0
  136. package/dist/client/nav-link-store.d.ts.map +1 -0
  137. package/dist/client/navigation-api-types.d.ts +90 -0
  138. package/dist/client/navigation-api-types.d.ts.map +1 -0
  139. package/dist/client/navigation-api.d.ts +115 -0
  140. package/dist/client/navigation-api.d.ts.map +1 -0
  141. package/dist/client/navigation-context.d.ts +13 -2
  142. package/dist/client/navigation-context.d.ts.map +1 -1
  143. package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
  144. package/dist/client/navigation-root.d.ts.map +1 -0
  145. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  146. package/dist/client/router-ref.d.ts +1 -1
  147. package/dist/client/router.d.ts +70 -4
  148. package/dist/client/router.d.ts.map +1 -1
  149. package/dist/client/rsc-fetch.d.ts +38 -3
  150. package/dist/client/rsc-fetch.d.ts.map +1 -1
  151. package/dist/client/segment-cache.d.ts +1 -1
  152. package/dist/client/segment-cache.d.ts.map +1 -1
  153. package/dist/client/segment-outlet.d.ts +63 -0
  154. package/dist/client/segment-outlet.d.ts.map +1 -0
  155. package/dist/client/ssr-data.d.ts +13 -4
  156. package/dist/client/ssr-data.d.ts.map +1 -1
  157. package/dist/client/stale-reload.d.ts +15 -0
  158. package/dist/client/stale-reload.d.ts.map +1 -1
  159. package/dist/client/state.d.ts +1 -1
  160. package/dist/client/top-loader.d.ts +5 -5
  161. package/dist/client/top-loader.d.ts.map +1 -1
  162. package/dist/client/use-cookie.d.ts +12 -0
  163. package/dist/client/use-cookie.d.ts.map +1 -1
  164. package/dist/client/use-link-status.d.ts +5 -5
  165. package/dist/client/use-link-status.d.ts.map +1 -1
  166. package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
  167. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  168. package/dist/client/use-query-states.d.ts +1 -1
  169. package/dist/client/use-query-states.d.ts.map +1 -1
  170. package/dist/client/use-router.d.ts +1 -1
  171. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +8 -6
  172. package/dist/client/use-segment-params.d.ts.map +1 -0
  173. package/dist/codec.d.ts +51 -0
  174. package/dist/codec.d.ts.map +1 -0
  175. package/dist/codec.js +46 -0
  176. package/dist/codec.js.map +1 -0
  177. package/dist/config-types.d.ts +294 -0
  178. package/dist/config-types.d.ts.map +1 -0
  179. package/dist/config-validation.d.ts +51 -0
  180. package/dist/config-validation.d.ts.map +1 -0
  181. package/dist/content/index.d.ts +1 -10
  182. package/dist/content/index.d.ts.map +1 -1
  183. package/dist/content/index.js +0 -2
  184. package/dist/cookies/define-cookie.d.ts +58 -25
  185. package/dist/cookies/define-cookie.d.ts.map +1 -1
  186. package/dist/cookies/index.d.ts +2 -1
  187. package/dist/cookies/index.d.ts.map +1 -1
  188. package/dist/cookies/index.js +251 -36
  189. package/dist/cookies/index.js.map +1 -1
  190. package/dist/cookies/json-cookie.d.ts +64 -0
  191. package/dist/cookies/json-cookie.d.ts.map +1 -0
  192. package/dist/cookies/validation.d.ts +46 -0
  193. package/dist/cookies/validation.d.ts.map +1 -0
  194. package/dist/dev-tools/404-page.d.ts +46 -0
  195. package/dist/dev-tools/404-page.d.ts.map +1 -0
  196. package/dist/dev-tools/browser-logs.d.ts +84 -0
  197. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  198. package/dist/dev-tools/error-page.d.ts +58 -0
  199. package/dist/dev-tools/error-page.d.ts.map +1 -0
  200. package/dist/dev-tools/holding-server.d.ts +54 -0
  201. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  202. package/dist/dev-tools/index.d.ts +31 -0
  203. package/dist/dev-tools/index.d.ts.map +1 -0
  204. package/dist/{server/dev-span-processor.d.ts → dev-tools/instrumentation.d.ts} +26 -6
  205. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  206. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  207. package/dist/dev-tools/logger.d.ts.map +1 -0
  208. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
  209. package/dist/dev-tools/logs.d.ts.map +1 -0
  210. package/dist/dev-tools/overlay.d.ts +91 -0
  211. package/dist/dev-tools/overlay.d.ts.map +1 -0
  212. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  213. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  214. package/dist/dev-tools/terminal.d.ts +28 -0
  215. package/dist/dev-tools/terminal.d.ts.map +1 -0
  216. package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +2 -22
  217. package/dist/dev-tools/warnings.d.ts.map +1 -0
  218. package/dist/fonts/ast.d.ts +98 -6
  219. package/dist/fonts/ast.d.ts.map +1 -1
  220. package/dist/fonts/bundle.d.ts +48 -0
  221. package/dist/fonts/bundle.d.ts.map +1 -0
  222. package/dist/fonts/dev-middleware.d.ts +22 -0
  223. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  224. package/dist/fonts/local.d.ts +1 -1
  225. package/dist/fonts/pipeline.d.ts +167 -0
  226. package/dist/fonts/pipeline.d.ts.map +1 -0
  227. package/dist/fonts/transform.d.ts +78 -0
  228. package/dist/fonts/transform.d.ts.map +1 -0
  229. package/dist/fonts/types.d.ts +45 -1
  230. package/dist/fonts/types.d.ts.map +1 -1
  231. package/dist/fonts/virtual-modules.d.ts +94 -0
  232. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  233. package/dist/index.d.ts +46 -190
  234. package/dist/index.d.ts.map +1 -1
  235. package/dist/index.js +4799 -12730
  236. package/dist/index.js.map +1 -1
  237. package/dist/params/codec-registry.d.ts +26 -0
  238. package/dist/params/codec-registry.d.ts.map +1 -0
  239. package/dist/params/define-schema.d.ts +53 -0
  240. package/dist/params/define-schema.d.ts.map +1 -0
  241. package/dist/params/index.d.ts +5 -0
  242. package/dist/params/index.d.ts.map +1 -0
  243. package/dist/params/index.js +34 -0
  244. package/dist/params/index.js.map +1 -0
  245. package/dist/params/resolve-schema.d.ts +34 -0
  246. package/dist/params/resolve-schema.d.ts.map +1 -0
  247. package/dist/plugin-context.d.ts +107 -0
  248. package/dist/plugin-context.d.ts.map +1 -0
  249. package/dist/plugins/adapter-build.d.ts +1 -1
  250. package/dist/plugins/adapter-build.d.ts.map +1 -1
  251. package/dist/plugins/build-manifest.d.ts +2 -2
  252. package/dist/plugins/build-manifest.d.ts.map +1 -1
  253. package/dist/plugins/build-report.d.ts +9 -7
  254. package/dist/plugins/build-report.d.ts.map +1 -1
  255. package/dist/plugins/client-chunks.d.ts +32 -0
  256. package/dist/plugins/client-chunks.d.ts.map +1 -0
  257. package/dist/plugins/content.d.ts +1 -1
  258. package/dist/plugins/content.d.ts.map +1 -1
  259. package/dist/plugins/dev-server.d.ts +1 -1
  260. package/dist/plugins/dev-server.d.ts.map +1 -1
  261. package/dist/plugins/entries.d.ts +1 -1
  262. package/dist/plugins/entries.d.ts.map +1 -1
  263. package/dist/plugins/fonts.d.ts +17 -73
  264. package/dist/plugins/fonts.d.ts.map +1 -1
  265. package/dist/plugins/mdx.d.ts +1 -1
  266. package/dist/plugins/mdx.d.ts.map +1 -1
  267. package/dist/plugins/routing.d.ts +1 -1
  268. package/dist/plugins/routing.d.ts.map +1 -1
  269. package/dist/plugins/server-bundle.d.ts.map +1 -1
  270. package/dist/plugins/shims.d.ts +6 -5
  271. package/dist/plugins/shims.d.ts.map +1 -1
  272. package/dist/plugins/static-build.d.ts +5 -26
  273. package/dist/plugins/static-build.d.ts.map +1 -1
  274. package/dist/routing/codegen-shared.d.ts +63 -0
  275. package/dist/routing/codegen-shared.d.ts.map +1 -0
  276. package/dist/routing/codegen-types.d.ts +60 -0
  277. package/dist/routing/codegen-types.d.ts.map +1 -0
  278. package/dist/routing/codegen.d.ts +7 -2
  279. package/dist/routing/codegen.d.ts.map +1 -1
  280. package/dist/routing/convention-lint.d.ts +41 -0
  281. package/dist/routing/convention-lint.d.ts.map +1 -0
  282. package/dist/routing/index.d.ts +5 -1
  283. package/dist/routing/index.d.ts.map +1 -1
  284. package/dist/routing/index.js +4 -2
  285. package/dist/routing/link-codegen.d.ts +90 -0
  286. package/dist/routing/link-codegen.d.ts.map +1 -0
  287. package/dist/routing/scanner.d.ts +1 -10
  288. package/dist/routing/scanner.d.ts.map +1 -1
  289. package/dist/routing/segment-classify.d.ts +75 -0
  290. package/dist/routing/segment-classify.d.ts.map +1 -0
  291. package/dist/routing/segment-codegen.d.ts +38 -0
  292. package/dist/routing/segment-codegen.d.ts.map +1 -0
  293. package/dist/routing/types.d.ts +77 -25
  294. package/dist/routing/types.d.ts.map +1 -1
  295. package/dist/routing/walkers.d.ts +51 -0
  296. package/dist/routing/walkers.d.ts.map +1 -0
  297. package/dist/rsc-runtime/rsc.d.ts +1 -1
  298. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  299. package/dist/rsc-runtime/ssr.d.ts +12 -0
  300. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  301. package/dist/schema-bridge.d.ts +76 -0
  302. package/dist/schema-bridge.d.ts.map +1 -0
  303. package/dist/search-params/define.d.ts +157 -0
  304. package/dist/search-params/define.d.ts.map +1 -0
  305. package/dist/search-params/index.d.ts +4 -7
  306. package/dist/search-params/index.d.ts.map +1 -1
  307. package/dist/search-params/index.js +34 -441
  308. package/dist/search-params/index.js.map +1 -1
  309. package/dist/search-params/registry.d.ts +2 -2
  310. package/dist/search-params/registry.d.ts.map +1 -1
  311. package/dist/search-params/wrappers.d.ts +53 -0
  312. package/dist/search-params/wrappers.d.ts.map +1 -0
  313. package/dist/segment-params/define.d.ts +95 -0
  314. package/dist/segment-params/define.d.ts.map +1 -0
  315. package/dist/segment-params/index.d.ts +3 -0
  316. package/dist/segment-params/index.d.ts.map +1 -0
  317. package/dist/segment-params/index.js +2 -0
  318. package/dist/server/access-gate.d.ts +8 -3
  319. package/dist/server/access-gate.d.ts.map +1 -1
  320. package/dist/server/action-client.d.ts +41 -6
  321. package/dist/server/action-client.d.ts.map +1 -1
  322. package/dist/server/action-encryption.d.ts +76 -0
  323. package/dist/server/action-encryption.d.ts.map +1 -0
  324. package/dist/server/action-handler.d.ts +35 -1
  325. package/dist/server/action-handler.d.ts.map +1 -1
  326. package/dist/server/actions.d.ts +3 -6
  327. package/dist/server/actions.d.ts.map +1 -1
  328. package/dist/server/als-registry.d.ts +53 -5
  329. package/dist/server/als-registry.d.ts.map +1 -1
  330. package/dist/server/asset-headers.d.ts +1 -15
  331. package/dist/server/asset-headers.d.ts.map +1 -1
  332. package/dist/server/build-manifest.d.ts +2 -2
  333. package/dist/server/build-manifest.d.ts.map +1 -1
  334. package/dist/server/coalesce-tick.d.ts +40 -0
  335. package/dist/server/coalesce-tick.d.ts.map +1 -0
  336. package/dist/server/cookie-context.d.ts +170 -0
  337. package/dist/server/cookie-context.d.ts.map +1 -0
  338. package/dist/server/cookie-parsing.d.ts +51 -0
  339. package/dist/server/cookie-parsing.d.ts.map +1 -0
  340. package/dist/server/debug.d.ts +1 -1
  341. package/dist/server/default-logger.d.ts +22 -0
  342. package/dist/server/default-logger.d.ts.map +1 -0
  343. package/dist/server/deny-boundary.d.ts +90 -0
  344. package/dist/server/deny-boundary.d.ts.map +1 -0
  345. package/dist/server/deny-renderer.d.ts.map +1 -1
  346. package/dist/server/dev-source-map.d.ts +22 -0
  347. package/dist/server/dev-source-map.d.ts.map +1 -0
  348. package/dist/server/early-hints-sender.d.ts.map +1 -1
  349. package/dist/server/early-hints.d.ts +13 -5
  350. package/dist/server/early-hints.d.ts.map +1 -1
  351. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  352. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  353. package/dist/server/fallback-error.d.ts +12 -7
  354. package/dist/server/fallback-error.d.ts.map +1 -1
  355. package/dist/server/flight-injection-state.d.ts +66 -0
  356. package/dist/server/flight-injection-state.d.ts.map +1 -0
  357. package/dist/server/flight-scripts.d.ts +42 -0
  358. package/dist/server/flight-scripts.d.ts.map +1 -0
  359. package/dist/server/flush.d.ts.map +1 -1
  360. package/dist/server/form-data.d.ts +29 -0
  361. package/dist/server/form-data.d.ts.map +1 -1
  362. package/dist/server/html-injector-core.d.ts +213 -0
  363. package/dist/server/html-injector-core.d.ts.map +1 -0
  364. package/dist/server/html-injectors.d.ts +81 -41
  365. package/dist/server/html-injectors.d.ts.map +1 -1
  366. package/dist/server/index.d.ts +10 -46
  367. package/dist/server/index.d.ts.map +1 -1
  368. package/dist/server/index.js +155 -2905
  369. package/dist/server/index.js.map +1 -1
  370. package/dist/server/internal.d.ts +48 -0
  371. package/dist/server/internal.d.ts.map +1 -0
  372. package/dist/server/internal.js +2947 -0
  373. package/dist/server/internal.js.map +1 -0
  374. package/dist/server/logger.d.ts +39 -7
  375. package/dist/server/logger.d.ts.map +1 -1
  376. package/dist/server/middleware-runner.d.ts +36 -4
  377. package/dist/server/middleware-runner.d.ts.map +1 -1
  378. package/dist/server/node-stream-transforms.d.ts +112 -0
  379. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  380. package/dist/server/param-coercion.d.ts +54 -0
  381. package/dist/server/param-coercion.d.ts.map +1 -0
  382. package/dist/server/pipeline-helpers.d.ts +95 -0
  383. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  384. package/dist/server/pipeline-interception.d.ts +1 -1
  385. package/dist/server/pipeline-interception.d.ts.map +1 -1
  386. package/dist/server/pipeline-metadata.d.ts +6 -0
  387. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  388. package/dist/server/pipeline-outcome.d.ts +49 -0
  389. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  390. package/dist/server/pipeline-phases.d.ts +52 -0
  391. package/dist/server/pipeline-phases.d.ts.map +1 -0
  392. package/dist/server/pipeline.d.ts +118 -23
  393. package/dist/server/pipeline.d.ts.map +1 -1
  394. package/dist/server/port-resolution.d.ts +117 -0
  395. package/dist/server/port-resolution.d.ts.map +1 -0
  396. package/dist/server/primitives.d.ts +69 -18
  397. package/dist/server/primitives.d.ts.map +1 -1
  398. package/dist/server/render-timeout.d.ts +51 -0
  399. package/dist/server/render-timeout.d.ts.map +1 -0
  400. package/dist/server/request-context.d.ts +62 -107
  401. package/dist/server/request-context.d.ts.map +1 -1
  402. package/dist/server/route-element-builder.d.ts +27 -1
  403. package/dist/server/route-element-builder.d.ts.map +1 -1
  404. package/dist/server/route-handler.d.ts.map +1 -1
  405. package/dist/server/route-matcher.d.ts +21 -34
  406. package/dist/server/route-matcher.d.ts.map +1 -1
  407. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  408. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  409. package/dist/server/rsc-entry/api-handler.d.ts +2 -2
  410. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  411. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  412. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  413. package/dist/server/rsc-entry/helpers.d.ts +49 -6
  414. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  415. package/dist/server/rsc-entry/index.d.ts +19 -8
  416. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  417. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  418. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  419. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  420. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  421. package/dist/server/rsc-entry/rsc-stream.d.ts +17 -1
  422. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  423. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  424. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  425. package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
  426. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  427. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  428. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  429. package/dist/server/safe-load.d.ts +46 -0
  430. package/dist/server/safe-load.d.ts.map +1 -0
  431. package/dist/server/sensitive-fields.d.ts +74 -0
  432. package/dist/server/sensitive-fields.d.ts.map +1 -0
  433. package/dist/server/sitemap-generator.d.ts +129 -0
  434. package/dist/server/sitemap-generator.d.ts.map +1 -0
  435. package/dist/server/sitemap-handler.d.ts +22 -0
  436. package/dist/server/sitemap-handler.d.ts.map +1 -0
  437. package/dist/server/slot-resolver.d.ts +1 -1
  438. package/dist/server/slot-resolver.d.ts.map +1 -1
  439. package/dist/server/ssr-entry.d.ts +30 -0
  440. package/dist/server/ssr-entry.d.ts.map +1 -1
  441. package/dist/server/ssr-render.d.ts +39 -21
  442. package/dist/server/ssr-render.d.ts.map +1 -1
  443. package/dist/server/ssr-wrappers.d.ts +50 -0
  444. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  445. package/dist/server/state-tree-diff.d.ts.map +1 -1
  446. package/dist/server/status-code-resolver.d.ts +16 -11
  447. package/dist/server/status-code-resolver.d.ts.map +1 -1
  448. package/dist/server/stream-utils.d.ts +36 -0
  449. package/dist/server/stream-utils.d.ts.map +1 -0
  450. package/dist/server/tracing.d.ts +5 -5
  451. package/dist/server/tracing.d.ts.map +1 -1
  452. package/dist/server/tree-builder.d.ts +62 -30
  453. package/dist/server/tree-builder.d.ts.map +1 -1
  454. package/dist/server/tree-match.d.ts +41 -0
  455. package/dist/server/tree-match.d.ts.map +1 -0
  456. package/dist/server/types.d.ts +49 -4
  457. package/dist/server/types.d.ts.map +1 -1
  458. package/dist/server/utils/escape-html.d.ts +14 -0
  459. package/dist/server/utils/escape-html.d.ts.map +1 -0
  460. package/dist/server/version-skew.d.ts +61 -0
  461. package/dist/server/version-skew.d.ts.map +1 -0
  462. package/dist/shared/merge-search-params.d.ts +22 -0
  463. package/dist/shared/merge-search-params.d.ts.map +1 -0
  464. package/dist/shims/font-google.d.ts +1 -1
  465. package/dist/shims/font-google.d.ts.map +1 -1
  466. package/dist/shims/font-google.js +42 -0
  467. package/dist/shims/font-google.js.map +1 -0
  468. package/dist/shims/font-local.d.ts +26 -0
  469. package/dist/shims/font-local.d.ts.map +1 -0
  470. package/dist/shims/font-local.js +20 -0
  471. package/dist/shims/font-local.js.map +1 -0
  472. package/dist/shims/headers.d.ts +2 -1
  473. package/dist/shims/headers.d.ts.map +1 -1
  474. package/dist/shims/navigation-client.d.ts +3 -1
  475. package/dist/shims/navigation-client.d.ts.map +1 -1
  476. package/dist/shims/navigation.d.ts +11 -5
  477. package/dist/shims/navigation.d.ts.map +1 -1
  478. package/dist/utils/state-machine.d.ts +80 -0
  479. package/dist/utils/state-machine.d.ts.map +1 -0
  480. package/package.json +56 -16
  481. package/src/adapters/build-output-helper.ts +77 -0
  482. package/src/adapters/cloudflare-dev.ts +177 -0
  483. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  484. package/src/adapters/cloudflare.ts +350 -76
  485. package/src/adapters/compress-module.ts +24 -4
  486. package/src/adapters/nitro.ts +142 -59
  487. package/src/adapters/shared.ts +40 -0
  488. package/src/adapters/wrangler.d.ts +7 -0
  489. package/src/cache/cache-api.ts +38 -0
  490. package/src/cache/handler-store.ts +68 -0
  491. package/src/cache/index.ts +81 -18
  492. package/src/cache/singleflight.ts +62 -4
  493. package/src/cache/sizeof.ts +33 -0
  494. package/src/cache/timber-cache.ts +25 -20
  495. package/src/cli-schema-sync.ts +207 -0
  496. package/src/cli.ts +65 -8
  497. package/src/client/browser-dev.ts +153 -1
  498. package/src/client/browser-entry/action-dispatch.ts +126 -0
  499. package/src/client/browser-entry/hmr.ts +81 -0
  500. package/src/client/browser-entry/hydrate.ts +145 -0
  501. package/src/client/browser-entry/index.ts +149 -0
  502. package/src/client/browser-entry/post-hydration.ts +119 -0
  503. package/src/client/browser-entry/router-init.ts +193 -0
  504. package/src/client/browser-entry/rsc-stream.ts +157 -0
  505. package/src/client/browser-entry/scroll.ts +27 -0
  506. package/src/client/error-boundary.tsx +99 -22
  507. package/src/client/error-reconstituter.tsx +65 -0
  508. package/src/client/form.tsx +31 -32
  509. package/src/client/history.ts +26 -4
  510. package/src/client/index.ts +69 -44
  511. package/src/client/internal.ts +58 -0
  512. package/src/client/link-pending-store.ts +111 -0
  513. package/src/client/link.tsx +366 -113
  514. package/src/client/nav-link-store.ts +47 -0
  515. package/src/client/navigation-api-types.ts +112 -0
  516. package/src/client/navigation-api.ts +332 -0
  517. package/src/client/navigation-context.ts +31 -6
  518. package/src/client/navigation-root.tsx +342 -0
  519. package/src/client/nuqs-adapter.tsx +16 -3
  520. package/src/client/router-ref.ts +1 -1
  521. package/src/client/router.ts +300 -73
  522. package/src/client/rsc-fetch.ts +112 -8
  523. package/src/client/segment-cache.ts +1 -1
  524. package/src/client/segment-outlet.tsx +86 -0
  525. package/src/client/ssr-data.ts +13 -5
  526. package/src/client/stale-reload.ts +72 -3
  527. package/src/client/state.ts +2 -2
  528. package/src/client/top-loader.tsx +18 -6
  529. package/src/client/use-cookie.ts +31 -2
  530. package/src/client/use-link-status.ts +7 -7
  531. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
  532. package/src/client/use-query-states.ts +9 -3
  533. package/src/client/use-router.ts +1 -1
  534. package/src/client/{use-params.ts → use-segment-params.ts} +8 -6
  535. package/src/codec.ts +97 -0
  536. package/src/config-types.ts +292 -0
  537. package/src/config-validation.ts +303 -0
  538. package/src/content/index.ts +5 -13
  539. package/src/cookies/define-cookie.ts +233 -53
  540. package/src/cookies/index.ts +12 -1
  541. package/src/cookies/json-cookie.ts +105 -0
  542. package/src/cookies/validation.ts +134 -0
  543. package/src/dev-tools/404-page.ts +387 -0
  544. package/src/dev-tools/browser-logs.ts +291 -0
  545. package/src/dev-tools/error-page.ts +506 -0
  546. package/src/dev-tools/holding-server.ts +187 -0
  547. package/src/dev-tools/index.ts +90 -0
  548. package/src/dev-tools/instrumentation.ts +176 -0
  549. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +9 -5
  550. package/src/dev-tools/overlay.ts +469 -0
  551. package/src/dev-tools/stack-classifier.ts +75 -0
  552. package/src/dev-tools/terminal.ts +183 -0
  553. package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +5 -50
  554. package/src/fonts/ast.ts +525 -16
  555. package/src/fonts/bundle.ts +142 -0
  556. package/src/fonts/dev-middleware.ts +74 -0
  557. package/src/fonts/local.ts +1 -1
  558. package/src/fonts/pipeline.ts +314 -0
  559. package/src/fonts/transform.ts +317 -0
  560. package/src/fonts/types.ts +50 -1
  561. package/src/fonts/virtual-modules.ts +233 -0
  562. package/src/index.ts +409 -357
  563. package/src/params/codec-registry.ts +34 -0
  564. package/src/params/define-schema.ts +73 -0
  565. package/src/params/index.ts +11 -0
  566. package/src/params/resolve-schema.ts +88 -0
  567. package/src/plugin-context.ts +240 -0
  568. package/src/plugins/adapter-build.ts +12 -4
  569. package/src/plugins/build-manifest.ts +13 -2
  570. package/src/plugins/build-report.ts +16 -25
  571. package/src/plugins/client-chunks.ts +65 -0
  572. package/src/plugins/content.ts +1 -1
  573. package/src/plugins/dev-server.ts +175 -35
  574. package/src/plugins/entries.ts +111 -9
  575. package/src/plugins/fonts.ts +157 -654
  576. package/src/plugins/mdx.ts +47 -10
  577. package/src/plugins/routing.ts +374 -45
  578. package/src/plugins/server-bundle.ts +32 -1
  579. package/src/plugins/shims.ts +136 -35
  580. package/src/plugins/static-build.ts +15 -89
  581. package/src/routing/codegen-shared.ts +109 -0
  582. package/src/routing/codegen-types.ts +61 -0
  583. package/src/routing/codegen.ts +269 -179
  584. package/src/routing/convention-lint.ts +357 -0
  585. package/src/routing/index.ts +5 -1
  586. package/src/routing/interception.ts +1 -1
  587. package/src/routing/link-codegen.ts +308 -0
  588. package/src/routing/scanner.ts +107 -110
  589. package/src/routing/segment-classify.ts +188 -0
  590. package/src/routing/segment-codegen.ts +98 -0
  591. package/src/routing/types.ts +78 -25
  592. package/src/routing/walkers.ts +90 -0
  593. package/src/rsc-runtime/rsc.ts +2 -0
  594. package/src/rsc-runtime/ssr.ts +50 -0
  595. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  596. package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
  597. package/src/search-params/define.ts +538 -0
  598. package/src/search-params/index.ts +14 -20
  599. package/src/search-params/registry.ts +2 -2
  600. package/src/search-params/wrappers.ts +92 -0
  601. package/src/segment-params/define.ts +336 -0
  602. package/src/segment-params/index.ts +9 -0
  603. package/src/server/access-gate.tsx +76 -34
  604. package/src/server/action-client.ts +88 -15
  605. package/src/server/action-encryption.ts +144 -0
  606. package/src/server/action-handler.ts +112 -14
  607. package/src/server/actions.ts +10 -9
  608. package/src/server/als-registry.ts +55 -7
  609. package/src/server/asset-headers.ts +8 -34
  610. package/src/server/build-manifest.ts +10 -4
  611. package/src/server/coalesce-tick.ts +75 -0
  612. package/src/server/compress.ts +25 -7
  613. package/src/server/cookie-context.ts +468 -0
  614. package/src/server/cookie-parsing.ts +135 -0
  615. package/src/server/debug.ts +1 -1
  616. package/src/server/default-logger.ts +99 -0
  617. package/src/server/deny-boundary.ts +218 -0
  618. package/src/server/deny-renderer.ts +31 -50
  619. package/src/server/dev-source-map.ts +31 -0
  620. package/src/server/early-hints-sender.ts +3 -2
  621. package/src/server/early-hints.ts +36 -15
  622. package/src/server/error-boundary-wrapper.ts +74 -22
  623. package/src/server/fallback-error.ts +74 -102
  624. package/src/server/flight-injection-state.ts +113 -0
  625. package/src/server/flight-scripts.ts +62 -0
  626. package/src/server/flush.ts +2 -1
  627. package/src/server/form-data.ts +76 -0
  628. package/src/server/html-injector-core.ts +417 -0
  629. package/src/server/html-injectors.ts +235 -223
  630. package/src/server/index.ts +29 -183
  631. package/src/server/internal.ts +176 -0
  632. package/src/server/logger.ts +67 -36
  633. package/src/server/middleware-runner.ts +75 -4
  634. package/src/server/node-stream-transforms.ts +361 -0
  635. package/src/server/param-coercion.ts +206 -0
  636. package/src/server/pipeline-helpers.ts +204 -0
  637. package/src/server/pipeline-interception.ts +17 -16
  638. package/src/server/pipeline-metadata.ts +13 -0
  639. package/src/server/pipeline-outcome.ts +176 -0
  640. package/src/server/pipeline-phases.ts +460 -0
  641. package/src/server/pipeline.ts +154 -394
  642. package/src/server/port-resolution.ts +215 -0
  643. package/src/server/primitives.ts +111 -28
  644. package/src/server/render-timeout.ts +108 -0
  645. package/src/server/request-context.ts +168 -333
  646. package/src/server/route-element-builder.ts +309 -195
  647. package/src/server/route-handler.ts +24 -4
  648. package/src/server/route-matcher.ts +50 -231
  649. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  650. package/src/server/rsc-entry/api-handler.ts +16 -17
  651. package/src/server/rsc-entry/error-renderer.ts +305 -89
  652. package/src/server/rsc-entry/helpers.ts +137 -12
  653. package/src/server/rsc-entry/index.ts +316 -352
  654. package/src/server/rsc-entry/render-route.ts +307 -0
  655. package/src/server/rsc-entry/rsc-payload.ts +65 -18
  656. package/src/server/rsc-entry/rsc-stream.ts +85 -13
  657. package/src/server/rsc-entry/ssr-bridge.ts +14 -5
  658. package/src/server/rsc-entry/ssr-renderer.ts +187 -38
  659. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  660. package/src/server/safe-load.ts +60 -0
  661. package/src/server/sensitive-fields.ts +230 -0
  662. package/src/server/sitemap-generator.ts +338 -0
  663. package/src/server/sitemap-handler.ts +126 -0
  664. package/src/server/slot-resolver.ts +228 -246
  665. package/src/server/ssr-entry.ts +229 -32
  666. package/src/server/ssr-render.ts +289 -67
  667. package/src/server/ssr-wrappers.tsx +139 -0
  668. package/src/server/state-tree-diff.ts +4 -1
  669. package/src/server/status-code-resolver.ts +112 -128
  670. package/src/server/stream-utils.ts +213 -0
  671. package/src/server/tracing.ts +21 -10
  672. package/src/server/tree-builder.ts +202 -90
  673. package/src/server/tree-match.ts +198 -0
  674. package/src/server/types.ts +55 -6
  675. package/src/server/utils/escape-html.ts +20 -0
  676. package/src/server/version-skew.ts +104 -0
  677. package/src/shared/merge-search-params.ts +55 -0
  678. package/src/shims/font-google.ts +1 -1
  679. package/src/shims/font-local.ts +34 -0
  680. package/src/shims/headers.ts +5 -1
  681. package/src/shims/navigation-client.ts +4 -3
  682. package/src/shims/navigation.ts +14 -7
  683. package/src/utils/state-machine.ts +111 -0
  684. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  685. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  686. package/dist/_chunks/debug-gwlJkDuf.js +0 -108
  687. package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
  688. package/dist/_chunks/format-DviM89f0.js.map +0 -1
  689. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  690. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  691. package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
  692. package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
  693. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  694. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  695. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  696. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  697. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  698. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  699. package/dist/cache/register-cached-function.d.ts +0 -17
  700. package/dist/cache/register-cached-function.d.ts.map +0 -1
  701. package/dist/client/browser-entry.d.ts +0 -21
  702. package/dist/client/browser-entry.d.ts.map +0 -1
  703. package/dist/client/link-status-provider.d.ts +0 -11
  704. package/dist/client/link-status-provider.d.ts.map +0 -1
  705. package/dist/client/transition-root.d.ts.map +0 -1
  706. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  707. package/dist/client/use-params.d.ts.map +0 -1
  708. package/dist/plugins/cache-transform.d.ts +0 -36
  709. package/dist/plugins/cache-transform.d.ts.map +0 -1
  710. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  711. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  712. package/dist/plugins/dev-logs.d.ts.map +0 -1
  713. package/dist/plugins/dynamic-transform.d.ts +0 -72
  714. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  715. package/dist/plugins/server-action-exports.d.ts +0 -26
  716. package/dist/plugins/server-action-exports.d.ts.map +0 -1
  717. package/dist/routing/status-file-lint.d.ts +0 -33
  718. package/dist/routing/status-file-lint.d.ts.map +0 -1
  719. package/dist/search-params/analyze.d.ts +0 -54
  720. package/dist/search-params/analyze.d.ts.map +0 -1
  721. package/dist/search-params/builtin-codecs.d.ts +0 -105
  722. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  723. package/dist/search-params/codecs.d.ts +0 -53
  724. package/dist/search-params/codecs.d.ts.map +0 -1
  725. package/dist/search-params/create.d.ts +0 -106
  726. package/dist/search-params/create.d.ts.map +0 -1
  727. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  728. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  729. package/dist/server/dev-logger.d.ts.map +0 -1
  730. package/dist/server/dev-span-processor.d.ts.map +0 -1
  731. package/dist/server/dev-warnings.d.ts.map +0 -1
  732. package/dist/server/manifest-status-resolver.d.ts +0 -58
  733. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  734. package/dist/server/prerender.d.ts +0 -77
  735. package/dist/server/prerender.d.ts.map +0 -1
  736. package/dist/server/response-cache.d.ts +0 -54
  737. package/dist/server/response-cache.d.ts.map +0 -1
  738. package/dist/utils/directive-parser.d.ts +0 -70
  739. package/dist/utils/directive-parser.d.ts.map +0 -1
  740. package/src/cache/register-cached-function.ts +0 -103
  741. package/src/client/browser-entry.ts +0 -678
  742. package/src/client/link-status-provider.tsx +0 -30
  743. package/src/client/transition-root.tsx +0 -166
  744. package/src/plugins/cache-transform.ts +0 -199
  745. package/src/plugins/dev-error-overlay.ts +0 -230
  746. package/src/plugins/dynamic-transform.ts +0 -161
  747. package/src/plugins/server-action-exports.ts +0 -220
  748. package/src/routing/status-file-lint.ts +0 -112
  749. package/src/search-params/analyze.ts +0 -192
  750. package/src/search-params/builtin-codecs.ts +0 -228
  751. package/src/search-params/create.ts +0 -321
  752. package/src/server/dev-fetch-instrumentation.ts +0 -96
  753. package/src/server/dev-span-processor.ts +0 -78
  754. package/src/server/manifest-status-resolver.ts +0 -215
  755. package/src/server/prerender.ts +0 -139
  756. package/src/server/response-cache.ts +0 -410
  757. package/src/utils/directive-parser.ts +0 -529
  758. /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
@@ -0,0 +1,336 @@
1
+ import { r as DEFAULT_PAGE_EXTENSIONS, t as classifySegment } from "./segment-classify-CnfLLvir.js";
2
+ import { a as isDynamicMetadataExtension, n as classifyMetadataRoute } from "./metadata-routes-Cjmvi3rQ.js";
3
+ import { h as swallow } from "./logger-DDmK5skc.js";
4
+ import { basename, extname, join } from "node:path";
5
+ import { readdirSync, statSync } from "node:fs";
6
+ //#region src/routing/scanner.ts
7
+ /**
8
+ * Route discovery scanner.
9
+ *
10
+ * Pure function: (appDir, config) → RouteTree
11
+ *
12
+ * Scans the app/ directory and builds a segment tree recognizing all
13
+ * timber.js file conventions. Does NOT handle request matching — this
14
+ * is discovery only.
15
+ */
16
+ /**
17
+ * Pattern matching encoded path delimiters that must be rejected during route discovery.
18
+ * %2F / %2f (forward slash) and %5C / %5c (backslash) can cause route collisions
19
+ * when decoded. See design/13-security.md §"Encoded separators rejected".
20
+ */
21
+ var ENCODED_SEPARATOR_PATTERN = /%(?:2[fF]|5[cC])/;
22
+ /**
23
+ * Pattern matching encoded null bytes (%00) that must be rejected.
24
+ * See design/13-security.md §"Null bytes rejected".
25
+ */
26
+ var ENCODED_NULL_PATTERN = /%00/;
27
+ /**
28
+ * File convention names that use pageExtensions (can be .tsx, .ts, .jsx, .js, .mdx, etc.)
29
+ */
30
+ var PAGE_EXT_CONVENTIONS = new Set([
31
+ "page",
32
+ "layout",
33
+ "error",
34
+ "default",
35
+ "denied"
36
+ ]);
37
+ /**
38
+ * Legacy compat status-code files.
39
+ * Maps legacy file name → HTTP status code for the fallback chain.
40
+ * See design/10-error-handling.md §"Fallback Chain".
41
+ */
42
+ var LEGACY_STATUS_FILES = {
43
+ "not-found": 404,
44
+ "forbidden": 403,
45
+ "unauthorized": 401
46
+ };
47
+ /**
48
+ * File convention names that are always .ts/.tsx (never .mdx etc.)
49
+ */
50
+ var FIXED_CONVENTIONS = new Set([
51
+ "middleware",
52
+ "access",
53
+ "route",
54
+ "params"
55
+ ]);
56
+ /**
57
+ * Status-code file patterns:
58
+ * - Exact 3-digit codes: 401.tsx, 429.tsx, 503.tsx
59
+ * - Category catch-alls: 4xx.tsx, 5xx.tsx
60
+ */
61
+ var STATUS_CODE_PATTERN = /^(\d{3}|[45]xx)$/;
62
+ /**
63
+ * Scan the app/ directory and build the route tree.
64
+ *
65
+ * @param appDir - Absolute path to the app/ directory
66
+ * @param config - Scanner configuration
67
+ * @returns The complete route tree
68
+ */
69
+ function scanRoutes(appDir, config = {}) {
70
+ const pageExtensions = config.pageExtensions ?? DEFAULT_PAGE_EXTENSIONS;
71
+ const extSet = new Set(pageExtensions);
72
+ const tree = { root: createSegmentNode("", "static", "/") };
73
+ const proxyFile = findFixedFile(appDir, "proxy");
74
+ if (proxyFile) tree.proxy = proxyFile;
75
+ const globalErrorFile = findPageExtFile(appDir, "global-error", extSet);
76
+ if (globalErrorFile) tree.globalError = globalErrorFile;
77
+ scanSegmentFiles(appDir, tree.root, extSet);
78
+ scanChildren(appDir, tree.root, extSet);
79
+ validateRouteGroupCollisions(tree.root);
80
+ validateDuplicateParamNames(tree.root);
81
+ return tree;
82
+ }
83
+ /**
84
+ * Create an empty segment node.
85
+ */
86
+ function createSegmentNode(segmentName, segmentType, urlPath, paramName, interceptionMarker, interceptedSegmentName) {
87
+ return {
88
+ segmentName,
89
+ segmentType,
90
+ urlPath,
91
+ paramName,
92
+ interceptionMarker,
93
+ interceptedSegmentName,
94
+ children: [],
95
+ slots: {}
96
+ };
97
+ }
98
+ /**
99
+ * Compute the URL path for a child segment given its parent's URL path.
100
+ * Route groups, slots, and intercepting routes do NOT add URL depth.
101
+ */
102
+ function computeUrlPath(parentUrlPath, dirName, segmentType) {
103
+ if (segmentType === "group" || segmentType === "slot" || segmentType === "intercepting") return parentUrlPath;
104
+ return `${parentUrlPath === "/" ? "" : parentUrlPath}/${dirName}`;
105
+ }
106
+ /**
107
+ * Scan a directory for file conventions and populate the segment node.
108
+ */
109
+ function scanSegmentFiles(dirPath, node, extSet) {
110
+ let entries;
111
+ try {
112
+ entries = readdirSync(dirPath);
113
+ } catch (err) {
114
+ swallow(err, `scanSegmentFiles: unreadable directory ${dirPath}`, { level: "warn" });
115
+ return;
116
+ }
117
+ for (const entry of entries) {
118
+ const fullPath = join(dirPath, entry);
119
+ try {
120
+ if (statSync(fullPath).isDirectory()) continue;
121
+ } catch {
122
+ continue;
123
+ }
124
+ const ext = extname(entry).slice(1);
125
+ const name = basename(entry, `.${ext}`);
126
+ if (PAGE_EXT_CONVENTIONS.has(name) && extSet.has(ext)) {
127
+ const file = {
128
+ filePath: fullPath,
129
+ extension: ext
130
+ };
131
+ switch (name) {
132
+ case "page":
133
+ node.page = file;
134
+ break;
135
+ case "layout":
136
+ node.layout = file;
137
+ break;
138
+ case "error":
139
+ node.error = file;
140
+ break;
141
+ case "default":
142
+ node.default = file;
143
+ break;
144
+ case "denied":
145
+ node.denied = file;
146
+ break;
147
+ }
148
+ continue;
149
+ }
150
+ if (FIXED_CONVENTIONS.has(name) && /\.?[jt]sx?$/.test(ext)) {
151
+ const file = {
152
+ filePath: fullPath,
153
+ extension: ext
154
+ };
155
+ switch (name) {
156
+ case "middleware":
157
+ node.middleware = file;
158
+ break;
159
+ case "access":
160
+ node.access = file;
161
+ break;
162
+ case "route":
163
+ node.route = file;
164
+ break;
165
+ case "params":
166
+ node.params = file;
167
+ break;
168
+ }
169
+ continue;
170
+ }
171
+ if (STATUS_CODE_PATTERN.test(name) && ext === "json") {
172
+ if (!node.jsonStatusFiles) node.jsonStatusFiles = {};
173
+ node.jsonStatusFiles[name] = {
174
+ filePath: fullPath,
175
+ extension: ext
176
+ };
177
+ continue;
178
+ }
179
+ if (STATUS_CODE_PATTERN.test(name) && extSet.has(ext)) {
180
+ if (!node.statusFiles) node.statusFiles = {};
181
+ node.statusFiles[name] = {
182
+ filePath: fullPath,
183
+ extension: ext
184
+ };
185
+ continue;
186
+ }
187
+ if (name in LEGACY_STATUS_FILES && extSet.has(ext)) {
188
+ if (!node.legacyStatusFiles) node.legacyStatusFiles = {};
189
+ node.legacyStatusFiles[name] = {
190
+ filePath: fullPath,
191
+ extension: ext
192
+ };
193
+ continue;
194
+ }
195
+ if (classifyMetadataRoute(entry)) {
196
+ if (!node.metadataRoutes) node.metadataRoutes = {};
197
+ const existing = node.metadataRoutes[name];
198
+ if (existing) {
199
+ const existingIsDynamic = isDynamicMetadataExtension(name, existing.extension);
200
+ if (isDynamicMetadataExtension(name, ext) || !existingIsDynamic) node.metadataRoutes[name] = {
201
+ filePath: fullPath,
202
+ extension: ext
203
+ };
204
+ } else node.metadataRoutes[name] = {
205
+ filePath: fullPath,
206
+ extension: ext
207
+ };
208
+ }
209
+ }
210
+ if (node.route && node.page) throw new Error(`Build error: route.ts and page.* cannot coexist in the same segment.\n route.ts: ${node.route.filePath}\n page: ${node.page.filePath}\nA URL is either an API endpoint or a rendered page, not both.`);
211
+ }
212
+ /**
213
+ * Recursively scan child directories and build the segment tree.
214
+ */
215
+ function scanChildren(dirPath, parentNode, extSet) {
216
+ let entries;
217
+ try {
218
+ entries = readdirSync(dirPath);
219
+ } catch (err) {
220
+ swallow(err, `scanChildren: unreadable directory ${dirPath}`, { level: "warn" });
221
+ return;
222
+ }
223
+ for (const entry of entries) {
224
+ const fullPath = join(dirPath, entry);
225
+ try {
226
+ if (!statSync(fullPath).isDirectory()) continue;
227
+ } catch {
228
+ continue;
229
+ }
230
+ if (ENCODED_SEPARATOR_PATTERN.test(entry)) throw new Error(`Build error: directory name contains an encoded path delimiter (%%2F or %%5C).\n Directory: ${fullPath}\nEncoded separators in directory names cause route collisions when decoded. Rename the directory to remove the encoded delimiter.`);
231
+ if (ENCODED_NULL_PATTERN.test(entry)) throw new Error(`Build error: directory name contains an encoded null byte (%%00).\n Directory: ${fullPath}\nEncoded null bytes in directory names are not allowed. Rename the directory to remove the null byte encoding.`);
232
+ const { type, paramName, interceptionMarker, interceptedSegmentName } = classifySegment(entry);
233
+ if (type === "private") continue;
234
+ const childNode = createSegmentNode(entry, type, computeUrlPath(parentNode.urlPath, entry, type), paramName, interceptionMarker, interceptedSegmentName);
235
+ scanSegmentFiles(fullPath, childNode, extSet);
236
+ scanChildren(fullPath, childNode, extSet);
237
+ if (type === "slot") {
238
+ const slotName = entry.slice(1);
239
+ parentNode.slots[slotName] = childNode;
240
+ } else parentNode.children.push(childNode);
241
+ }
242
+ }
243
+ /**
244
+ * Validate that route groups don't produce conflicting pages/routes at the same URL path.
245
+ *
246
+ * Two route groups like (auth)/login/page.tsx and (marketing)/login/page.tsx both claim
247
+ * /login — the scanner must detect and reject this at build time.
248
+ *
249
+ * Parallel slots are excluded from collision detection — they intentionally coexist at
250
+ * the same URL path as their parent (that's the whole point of parallel routes).
251
+ */
252
+ function validateRouteGroupCollisions(root) {
253
+ collectRoutableLeaves(root, /* @__PURE__ */ new Map(), "", false);
254
+ }
255
+ /**
256
+ * Walk the segment tree and collect all routable leaves (page or route files),
257
+ * throwing on collision. Slots are tracked in their own collision space since
258
+ * they are parallel routes that intentionally share URL paths with their parent.
259
+ */
260
+ function collectRoutableLeaves(node, seen, segmentPath, insideSlot) {
261
+ const currentPath = segmentPath ? `${segmentPath}/${node.segmentName}` : node.segmentName || "(root)";
262
+ if (!insideSlot) {
263
+ const routableFile = node.page ?? node.route;
264
+ if (routableFile) {
265
+ const existing = seen.get(node.urlPath);
266
+ if (existing) throw new Error(`Build error: route collision — multiple route groups produce a page/route at the same URL path.\n URL path: ${node.urlPath}\n File 1: ${existing.filePath} (via ${existing.segmentPath})\n File 2: ${routableFile.filePath} (via ${currentPath})\nEach URL path must map to exactly one page or route handler. Rename or move one of the conflicting files.`);
267
+ seen.set(node.urlPath, {
268
+ filePath: routableFile.filePath,
269
+ segmentPath: currentPath
270
+ });
271
+ }
272
+ }
273
+ for (const child of node.children) collectRoutableLeaves(child, seen, currentPath, insideSlot);
274
+ for (const slotNode of Object.values(node.slots)) collectRoutableLeaves(slotNode, seen, currentPath, true);
275
+ }
276
+ /**
277
+ * Validate that no route chain contains duplicate dynamic param names.
278
+ *
279
+ * Example violation:
280
+ * app/[id]/items/[id]/page.tsx — 'id' appears twice in the ancestor chain.
281
+ *
282
+ * Route groups are transparent — params accumulate through them.
283
+ * Slots are independent — duplicate detection does NOT cross slot boundaries.
284
+ *
285
+ * See design/07-routing.md §"Duplicate Param Name Detection"
286
+ */
287
+ function validateDuplicateParamNames(root) {
288
+ walkForDuplicateParams(root, /* @__PURE__ */ new Map());
289
+ }
290
+ /**
291
+ * Recursively walk the segment tree, tracking seen param names → segment paths.
292
+ * Throws on the first duplicate found.
293
+ */
294
+ function walkForDuplicateParams(node, seen) {
295
+ if (node.paramName) {
296
+ const existing = seen.get(node.paramName);
297
+ if (existing) throw new Error(`[timber] Duplicate param name '${node.paramName}' in route chain.\n First defined at: ${existing}\n Duplicate at: ${node.urlPath || "/"}\n Rename one of the segments to avoid ambiguity.`);
298
+ seen = new Map(seen);
299
+ seen.set(node.paramName, node.urlPath || "/");
300
+ }
301
+ for (const child of node.children) walkForDuplicateParams(child, seen);
302
+ for (const slotNode of Object.values(node.slots)) walkForDuplicateParams(slotNode, new Map(seen));
303
+ }
304
+ /**
305
+ * Find a fixed-extension file (proxy.ts) in a directory.
306
+ */
307
+ function findFixedFile(dirPath, name) {
308
+ for (const ext of ["ts", "tsx"]) {
309
+ const fullPath = join(dirPath, `${name}.${ext}`);
310
+ try {
311
+ if (statSync(fullPath).isFile()) return {
312
+ filePath: fullPath,
313
+ extension: ext
314
+ };
315
+ } catch {}
316
+ }
317
+ }
318
+ /**
319
+ * Find a file using the configured page extensions (tsx, ts, jsx, js, mdx, etc.).
320
+ * Used for app-root conventions like global-error that aren't per-segment.
321
+ */
322
+ function findPageExtFile(dirPath, name, extSet) {
323
+ for (const ext of extSet) {
324
+ const fullPath = join(dirPath, `${name}.${ext}`);
325
+ try {
326
+ if (statSync(fullPath).isFile()) return {
327
+ filePath: fullPath,
328
+ extension: ext
329
+ };
330
+ } catch {}
331
+ }
332
+ }
333
+ //#endregion
334
+ export { scanRoutes as t };
335
+
336
+ //# sourceMappingURL=scanner-DmfoB7iK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner-DmfoB7iK.js","names":[],"sources":["../../src/routing/scanner.ts"],"sourcesContent":["/**\n * Route discovery scanner.\n *\n * Pure function: (appDir, config) → RouteTree\n *\n * Scans the app/ directory and builds a segment tree recognizing all\n * timber.js file conventions. Does NOT handle request matching — this\n * is discovery only.\n */\n\nimport { readdirSync, statSync } from 'node:fs';\nimport { join, extname, basename } from 'node:path';\nimport type {\n RouteTree,\n SegmentNode,\n SegmentType,\n RouteFile,\n ScannerConfig,\n InterceptionMarker,\n} from './types.js';\nimport { classifySegment } from './segment-classify.js';\nimport { DEFAULT_PAGE_EXTENSIONS } from './types.js';\nimport { classifyMetadataRoute, isDynamicMetadataExtension } from '../server/metadata-routes.js';\nimport { swallow } from '../server/logger.js';\n\n/**\n * Pattern matching encoded path delimiters that must be rejected during route discovery.\n * %2F / %2f (forward slash) and %5C / %5c (backslash) can cause route collisions\n * when decoded. See design/13-security.md §\"Encoded separators rejected\".\n */\nconst ENCODED_SEPARATOR_PATTERN = /%(?:2[fF]|5[cC])/;\n\n/**\n * Pattern matching encoded null bytes (%00) that must be rejected.\n * See design/13-security.md §\"Null bytes rejected\".\n */\nconst ENCODED_NULL_PATTERN = /%00/;\n\n/**\n * File convention names that use pageExtensions (can be .tsx, .ts, .jsx, .js, .mdx, etc.)\n */\nconst PAGE_EXT_CONVENTIONS = new Set(['page', 'layout', 'error', 'default', 'denied']);\n\n/**\n * Legacy compat status-code files.\n * Maps legacy file name → HTTP status code for the fallback chain.\n * See design/10-error-handling.md §\"Fallback Chain\".\n */\nconst LEGACY_STATUS_FILES: Record<string, number> = {\n 'not-found': 404,\n 'forbidden': 403,\n 'unauthorized': 401,\n};\n\n/**\n * File convention names that are always .ts/.tsx (never .mdx etc.)\n */\nconst FIXED_CONVENTIONS = new Set(['middleware', 'access', 'route', 'params']);\n\n/**\n * Status-code file patterns:\n * - Exact 3-digit codes: 401.tsx, 429.tsx, 503.tsx\n * - Category catch-alls: 4xx.tsx, 5xx.tsx\n */\nconst STATUS_CODE_PATTERN = /^(\\d{3}|[45]xx)$/;\n\n/**\n * Scan the app/ directory and build the route tree.\n *\n * @param appDir - Absolute path to the app/ directory\n * @param config - Scanner configuration\n * @returns The complete route tree\n */\nexport function scanRoutes(appDir: string, config: ScannerConfig = {}): RouteTree {\n const pageExtensions = config.pageExtensions ?? DEFAULT_PAGE_EXTENSIONS;\n const extSet = new Set(pageExtensions);\n\n const tree: RouteTree = {\n root: createSegmentNode('', 'static', '/'),\n };\n\n // Check for proxy.ts at app root\n const proxyFile = findFixedFile(appDir, 'proxy');\n if (proxyFile) {\n tree.proxy = proxyFile;\n }\n\n // Check for global-error.{tsx,ts,jsx,js} at app root.\n // Tier 2 error page — renders standalone (no layouts) when no segment-level\n // error file is found. See design/10-error-handling.md §\"Tier 2\".\n const globalErrorFile = findPageExtFile(appDir, 'global-error', extSet);\n if (globalErrorFile) {\n tree.globalError = globalErrorFile;\n }\n\n // Scan the root directory's files\n scanSegmentFiles(appDir, tree.root, extSet);\n\n // Scan children recursively\n scanChildren(appDir, tree.root, extSet);\n\n // Validate: detect route group collisions (different groups producing pages at the same URL)\n validateRouteGroupCollisions(tree.root);\n\n // Validate: detect duplicate param names in nested dynamic segments\n // e.g., /[id]/items/[id] — same param name in ancestor and descendant\n validateDuplicateParamNames(tree.root);\n\n return tree;\n}\n\n/**\n * Create an empty segment node.\n */\nfunction createSegmentNode(\n segmentName: string,\n segmentType: SegmentType,\n urlPath: string,\n paramName?: string,\n interceptionMarker?: InterceptionMarker,\n interceptedSegmentName?: string\n): SegmentNode {\n return {\n segmentName,\n segmentType,\n urlPath,\n paramName,\n interceptionMarker,\n interceptedSegmentName,\n children: [],\n slots: {},\n };\n}\n\n/**\n * Compute the URL path for a child segment given its parent's URL path.\n * Route groups, slots, and intercepting routes do NOT add URL depth.\n */\nfunction computeUrlPath(parentUrlPath: string, dirName: string, segmentType: SegmentType): string {\n // Groups, slots, and intercepting routes don't add to URL path\n if (segmentType === 'group' || segmentType === 'slot' || segmentType === 'intercepting') {\n return parentUrlPath;\n }\n\n const parentPath = parentUrlPath === '/' ? '' : parentUrlPath;\n return `${parentPath}/${dirName}`;\n}\n\n/**\n * Scan a directory for file conventions and populate the segment node.\n */\nfunction scanSegmentFiles(dirPath: string, node: SegmentNode, extSet: Set<string>): void {\n let entries: string[];\n try {\n entries = readdirSync(dirPath);\n } catch (err) {\n swallow(err, `scanSegmentFiles: unreadable directory ${dirPath}`, { level: 'warn' });\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n\n // Skip directories — handled by scanChildren\n try {\n if (statSync(fullPath).isDirectory()) continue;\n } catch {\n continue;\n }\n\n const ext = extname(entry).slice(1); // remove leading dot\n const name = basename(entry, `.${ext}`);\n\n // Page-extension conventions (page, layout, error, default, denied)\n if (PAGE_EXT_CONVENTIONS.has(name) && extSet.has(ext)) {\n const file: RouteFile = { filePath: fullPath, extension: ext };\n switch (name) {\n case 'page':\n node.page = file;\n break;\n case 'layout':\n node.layout = file;\n break;\n case 'error':\n node.error = file;\n break;\n case 'default':\n node.default = file;\n break;\n case 'denied':\n node.denied = file;\n break;\n }\n continue;\n }\n\n // Fixed conventions (middleware, access, route) — always .ts or .tsx\n if (FIXED_CONVENTIONS.has(name) && /\\.?[jt]sx?$/.test(ext)) {\n const file: RouteFile = { filePath: fullPath, extension: ext };\n switch (name) {\n case 'middleware':\n node.middleware = file;\n break;\n case 'access':\n node.access = file;\n break;\n case 'route':\n node.route = file;\n break;\n case 'params':\n node.params = file;\n break;\n }\n continue;\n }\n\n // JSON status-code files (401.json, 4xx.json, 503.json, 5xx.json)\n // Recognized regardless of pageExtensions — .json is a data format, not a page extension.\n if (STATUS_CODE_PATTERN.test(name) && ext === 'json') {\n if (!node.jsonStatusFiles) {\n node.jsonStatusFiles = {};\n }\n node.jsonStatusFiles[name] = { filePath: fullPath, extension: ext };\n continue;\n }\n\n // Status-code files (401.tsx, 4xx.tsx, 503.tsx, 5xx.tsx)\n if (STATUS_CODE_PATTERN.test(name) && extSet.has(ext)) {\n if (!node.statusFiles) {\n node.statusFiles = {};\n }\n node.statusFiles[name] = { filePath: fullPath, extension: ext };\n continue;\n }\n\n // Legacy compat files (not-found.tsx, forbidden.tsx, unauthorized.tsx)\n if (name in LEGACY_STATUS_FILES && extSet.has(ext)) {\n if (!node.legacyStatusFiles) {\n node.legacyStatusFiles = {};\n }\n node.legacyStatusFiles[name] = { filePath: fullPath, extension: ext };\n continue;\n }\n\n // Metadata route files (sitemap.ts, robots.ts, icon.tsx, opengraph-image.tsx, etc.)\n // Both static (.xml, .txt, .png, .ico, etc.) and dynamic (.ts, .tsx) files are recognized.\n // When both exist for the same base name, dynamic takes precedence.\n // See design/16-metadata.md §\"Metadata Routes\"\n const metaInfo = classifyMetadataRoute(entry);\n if (metaInfo) {\n if (!node.metadataRoutes) {\n node.metadataRoutes = {};\n }\n const existing = node.metadataRoutes[name];\n if (existing) {\n // Dynamic > static precedence: only overwrite if the new file is dynamic\n // or the existing file is static (dynamic always wins).\n const existingIsDynamic = isDynamicMetadataExtension(name, existing.extension);\n const newIsDynamic = isDynamicMetadataExtension(name, ext);\n if (newIsDynamic || !existingIsDynamic) {\n node.metadataRoutes[name] = { filePath: fullPath, extension: ext };\n }\n } else {\n node.metadataRoutes[name] = { filePath: fullPath, extension: ext };\n }\n }\n }\n\n // Validate: route.ts + page.* is a hard build error\n if (node.route && node.page) {\n throw new Error(\n `Build error: route.ts and page.* cannot coexist in the same segment.\\n` +\n ` route.ts: ${node.route.filePath}\\n` +\n ` page: ${node.page.filePath}\\n` +\n `A URL is either an API endpoint or a rendered page, not both.`\n );\n }\n}\n\n/**\n * Recursively scan child directories and build the segment tree.\n */\nfunction scanChildren(dirPath: string, parentNode: SegmentNode, extSet: Set<string>): void {\n let entries: string[];\n try {\n entries = readdirSync(dirPath);\n } catch (err) {\n swallow(err, `scanChildren: unreadable directory ${dirPath}`, { level: 'warn' });\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dirPath, entry);\n\n try {\n if (!statSync(fullPath).isDirectory()) continue;\n } catch {\n continue;\n }\n\n // Reject directories with encoded path delimiters or null bytes.\n // These can cause route collisions when decoded at the URL boundary.\n // See design/13-security.md §\"Encoded separators rejected\" and §\"Null bytes rejected\".\n if (ENCODED_SEPARATOR_PATTERN.test(entry)) {\n throw new Error(\n `Build error: directory name contains an encoded path delimiter (%%2F or %%5C).\\n` +\n ` Directory: ${fullPath}\\n` +\n `Encoded separators in directory names cause route collisions when decoded. ` +\n `Rename the directory to remove the encoded delimiter.`\n );\n }\n if (ENCODED_NULL_PATTERN.test(entry)) {\n throw new Error(\n `Build error: directory name contains an encoded null byte (%%00).\\n` +\n ` Directory: ${fullPath}\\n` +\n `Encoded null bytes in directory names are not allowed. ` +\n `Rename the directory to remove the null byte encoding.`\n );\n }\n\n const { type, paramName, interceptionMarker, interceptedSegmentName } = classifySegment(entry);\n\n // Skip private folders — underscore-prefixed dirs are excluded from routing\n if (type === 'private') continue;\n\n const urlPath = computeUrlPath(parentNode.urlPath, entry, type);\n const childNode = createSegmentNode(\n entry,\n type,\n urlPath,\n paramName,\n interceptionMarker,\n interceptedSegmentName\n );\n\n // Scan this segment's files\n scanSegmentFiles(fullPath, childNode, extSet);\n\n // Recurse into subdirectories\n scanChildren(fullPath, childNode, extSet);\n\n // Attach to parent: slots go into slots record, everything else is a child\n if (type === 'slot') {\n const slotName = entry.slice(1); // remove @\n parentNode.slots[slotName] = childNode;\n } else {\n parentNode.children.push(childNode);\n }\n }\n}\n\n/**\n * Validate that route groups don't produce conflicting pages/routes at the same URL path.\n *\n * Two route groups like (auth)/login/page.tsx and (marketing)/login/page.tsx both claim\n * /login — the scanner must detect and reject this at build time.\n *\n * Parallel slots are excluded from collision detection — they intentionally coexist at\n * the same URL path as their parent (that's the whole point of parallel routes).\n */\nfunction validateRouteGroupCollisions(root: SegmentNode): void {\n // Map from urlPath → { filePath, source } for the first page/route seen at that path\n const seen = new Map<string, { filePath: string; segmentPath: string }>();\n collectRoutableLeaves(root, seen, '', false);\n}\n\n/**\n * Walk the segment tree and collect all routable leaves (page or route files),\n * throwing on collision. Slots are tracked in their own collision space since\n * they are parallel routes that intentionally share URL paths with their parent.\n */\nfunction collectRoutableLeaves(\n node: SegmentNode,\n seen: Map<string, { filePath: string; segmentPath: string }>,\n segmentPath: string,\n insideSlot: boolean\n): void {\n const currentPath = segmentPath\n ? `${segmentPath}/${node.segmentName}`\n : node.segmentName || '(root)';\n\n // Only check collisions for non-slot pages — slots intentionally share URL paths\n if (!insideSlot) {\n const routableFile = node.page ?? node.route;\n if (routableFile) {\n const existing = seen.get(node.urlPath);\n if (existing) {\n throw new Error(\n `Build error: route collision — multiple route groups produce a page/route at the same URL path.\\n` +\n ` URL path: ${node.urlPath}\\n` +\n ` File 1: ${existing.filePath} (via ${existing.segmentPath})\\n` +\n ` File 2: ${routableFile.filePath} (via ${currentPath})\\n` +\n `Each URL path must map to exactly one page or route handler. ` +\n `Rename or move one of the conflicting files.`\n );\n }\n seen.set(node.urlPath, { filePath: routableFile.filePath, segmentPath: currentPath });\n }\n }\n\n // Recurse into children\n for (const child of node.children) {\n collectRoutableLeaves(child, seen, currentPath, insideSlot);\n }\n\n // Recurse into slots — each slot is its own parallel route space\n for (const slotNode of Object.values(node.slots)) {\n collectRoutableLeaves(slotNode, seen, currentPath, true);\n }\n}\n\n/**\n * Validate that no route chain contains duplicate dynamic param names.\n *\n * Example violation:\n * app/[id]/items/[id]/page.tsx — 'id' appears twice in the ancestor chain.\n *\n * Route groups are transparent — params accumulate through them.\n * Slots are independent — duplicate detection does NOT cross slot boundaries.\n *\n * See design/07-routing.md §\"Duplicate Param Name Detection\"\n */\nfunction validateDuplicateParamNames(root: SegmentNode): void {\n walkForDuplicateParams(root, new Map());\n}\n\n/**\n * Recursively walk the segment tree, tracking seen param names → segment paths.\n * Throws on the first duplicate found.\n */\nfunction walkForDuplicateParams(node: SegmentNode, seen: Map<string, string>): void {\n // If this node introduces a param name, check for duplicates\n if (node.paramName) {\n const existing = seen.get(node.paramName);\n if (existing) {\n throw new Error(\n `[timber] Duplicate param name '${node.paramName}' in route chain.\\n` +\n ` First defined at: ${existing}\\n` +\n ` Duplicate at: ${node.urlPath || '/'}\\n` +\n ` Rename one of the segments to avoid ambiguity.`\n );\n }\n // Add to seen for descendants (use a new Map to avoid polluting siblings)\n seen = new Map(seen);\n seen.set(node.paramName, node.urlPath || '/');\n }\n\n // Recurse into children (they inherit the accumulated params)\n for (const child of node.children) {\n walkForDuplicateParams(child, seen);\n }\n\n // Slots are independent parallel routes — start fresh param tracking\n // (a slot's params don't conflict with the main route's params)\n for (const slotNode of Object.values(node.slots)) {\n walkForDuplicateParams(slotNode, new Map(seen));\n }\n}\n\n/**\n * Find a fixed-extension file (proxy.ts) in a directory.\n */\nfunction findFixedFile(dirPath: string, name: string): RouteFile | undefined {\n for (const ext of ['ts', 'tsx']) {\n const fullPath = join(dirPath, `${name}.${ext}`);\n try {\n if (statSync(fullPath).isFile()) {\n return { filePath: fullPath, extension: ext };\n }\n } catch {\n // File doesn't exist\n }\n }\n return undefined;\n}\n\n/**\n * Find a file using the configured page extensions (tsx, ts, jsx, js, mdx, etc.).\n * Used for app-root conventions like global-error that aren't per-segment.\n */\nfunction findPageExtFile(\n dirPath: string,\n name: string,\n extSet: Set<string>\n): RouteFile | undefined {\n for (const ext of extSet) {\n const fullPath = join(dirPath, `${name}.${ext}`);\n try {\n if (statSync(fullPath).isFile()) {\n return { filePath: fullPath, extension: ext };\n }\n } catch {\n // File doesn't exist\n }\n }\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,4BAA4B;;;;;AAMlC,IAAM,uBAAuB;;;;AAK7B,IAAM,uBAAuB,IAAI,IAAI;CAAC;CAAQ;CAAU;CAAS;CAAW;CAAS,CAAC;;;;;;AAOtF,IAAM,sBAA8C;CAClD,aAAa;CACb,aAAa;CACb,gBAAgB;CACjB;;;;AAKD,IAAM,oBAAoB,IAAI,IAAI;CAAC;CAAc;CAAU;CAAS;CAAS,CAAC;;;;;;AAO9E,IAAM,sBAAsB;;;;;;;;AAS5B,SAAgB,WAAW,QAAgB,SAAwB,EAAE,EAAa;CAChF,MAAM,iBAAiB,OAAO,kBAAkB;CAChD,MAAM,SAAS,IAAI,IAAI,eAAe;CAEtC,MAAM,OAAkB,EACtB,MAAM,kBAAkB,IAAI,UAAU,IAAI,EAC3C;CAGD,MAAM,YAAY,cAAc,QAAQ,QAAQ;AAChD,KAAI,UACF,MAAK,QAAQ;CAMf,MAAM,kBAAkB,gBAAgB,QAAQ,gBAAgB,OAAO;AACvE,KAAI,gBACF,MAAK,cAAc;AAIrB,kBAAiB,QAAQ,KAAK,MAAM,OAAO;AAG3C,cAAa,QAAQ,KAAK,MAAM,OAAO;AAGvC,8BAA6B,KAAK,KAAK;AAIvC,6BAA4B,KAAK,KAAK;AAEtC,QAAO;;;;;AAMT,SAAS,kBACP,aACA,aACA,SACA,WACA,oBACA,wBACa;AACb,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA,UAAU,EAAE;EACZ,OAAO,EAAE;EACV;;;;;;AAOH,SAAS,eAAe,eAAuB,SAAiB,aAAkC;AAEhG,KAAI,gBAAgB,WAAW,gBAAgB,UAAU,gBAAgB,eACvE,QAAO;AAIT,QAAO,GADY,kBAAkB,MAAM,KAAK,cAC3B,GAAG;;;;;AAM1B,SAAS,iBAAiB,SAAiB,MAAmB,QAA2B;CACvF,IAAI;AACJ,KAAI;AACF,YAAU,YAAY,QAAQ;UACvB,KAAK;AACZ,UAAQ,KAAK,0CAA0C,WAAW,EAAE,OAAO,QAAQ,CAAC;AACpF;;AAGF,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,KAAK,SAAS,MAAM;AAGrC,MAAI;AACF,OAAI,SAAS,SAAS,CAAC,aAAa,CAAE;UAChC;AACN;;EAGF,MAAM,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE;EACnC,MAAM,OAAO,SAAS,OAAO,IAAI,MAAM;AAGvC,MAAI,qBAAqB,IAAI,KAAK,IAAI,OAAO,IAAI,IAAI,EAAE;GACrD,MAAM,OAAkB;IAAE,UAAU;IAAU,WAAW;IAAK;AAC9D,WAAQ,MAAR;IACE,KAAK;AACH,UAAK,OAAO;AACZ;IACF,KAAK;AACH,UAAK,SAAS;AACd;IACF,KAAK;AACH,UAAK,QAAQ;AACb;IACF,KAAK;AACH,UAAK,UAAU;AACf;IACF,KAAK;AACH,UAAK,SAAS;AACd;;AAEJ;;AAIF,MAAI,kBAAkB,IAAI,KAAK,IAAI,cAAc,KAAK,IAAI,EAAE;GAC1D,MAAM,OAAkB;IAAE,UAAU;IAAU,WAAW;IAAK;AAC9D,WAAQ,MAAR;IACE,KAAK;AACH,UAAK,aAAa;AAClB;IACF,KAAK;AACH,UAAK,SAAS;AACd;IACF,KAAK;AACH,UAAK,QAAQ;AACb;IACF,KAAK;AACH,UAAK,SAAS;AACd;;AAEJ;;AAKF,MAAI,oBAAoB,KAAK,KAAK,IAAI,QAAQ,QAAQ;AACpD,OAAI,CAAC,KAAK,gBACR,MAAK,kBAAkB,EAAE;AAE3B,QAAK,gBAAgB,QAAQ;IAAE,UAAU;IAAU,WAAW;IAAK;AACnE;;AAIF,MAAI,oBAAoB,KAAK,KAAK,IAAI,OAAO,IAAI,IAAI,EAAE;AACrD,OAAI,CAAC,KAAK,YACR,MAAK,cAAc,EAAE;AAEvB,QAAK,YAAY,QAAQ;IAAE,UAAU;IAAU,WAAW;IAAK;AAC/D;;AAIF,MAAI,QAAQ,uBAAuB,OAAO,IAAI,IAAI,EAAE;AAClD,OAAI,CAAC,KAAK,kBACR,MAAK,oBAAoB,EAAE;AAE7B,QAAK,kBAAkB,QAAQ;IAAE,UAAU;IAAU,WAAW;IAAK;AACrE;;AAQF,MADiB,sBAAsB,MAAM,EAC/B;AACZ,OAAI,CAAC,KAAK,eACR,MAAK,iBAAiB,EAAE;GAE1B,MAAM,WAAW,KAAK,eAAe;AACrC,OAAI,UAAU;IAGZ,MAAM,oBAAoB,2BAA2B,MAAM,SAAS,UAAU;AAE9E,QADqB,2BAA2B,MAAM,IAAI,IACtC,CAAC,kBACnB,MAAK,eAAe,QAAQ;KAAE,UAAU;KAAU,WAAW;KAAK;SAGpE,MAAK,eAAe,QAAQ;IAAE,UAAU;IAAU,WAAW;IAAK;;;AAMxE,KAAI,KAAK,SAAS,KAAK,KACrB,OAAM,IAAI,MACR,qFACiB,KAAK,MAAM,SAAS,gBACpB,KAAK,KAAK,SAAS,iEAErC;;;;;AAOL,SAAS,aAAa,SAAiB,YAAyB,QAA2B;CACzF,IAAI;AACJ,KAAI;AACF,YAAU,YAAY,QAAQ;UACvB,KAAK;AACZ,UAAQ,KAAK,sCAAsC,WAAW,EAAE,OAAO,QAAQ,CAAC;AAChF;;AAGF,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,WAAW,KAAK,SAAS,MAAM;AAErC,MAAI;AACF,OAAI,CAAC,SAAS,SAAS,CAAC,aAAa,CAAE;UACjC;AACN;;AAMF,MAAI,0BAA0B,KAAK,MAAM,CACvC,OAAM,IAAI,MACR,gGACkB,SAAS,oIAG5B;AAEH,MAAI,qBAAqB,KAAK,MAAM,CAClC,OAAM,IAAI,MACR,mFACkB,SAAS,iHAG5B;EAGH,MAAM,EAAE,MAAM,WAAW,oBAAoB,2BAA2B,gBAAgB,MAAM;AAG9F,MAAI,SAAS,UAAW;EAGxB,MAAM,YAAY,kBAChB,OACA,MAHc,eAAe,WAAW,SAAS,OAAO,KAAK,EAK7D,WACA,oBACA,uBACD;AAGD,mBAAiB,UAAU,WAAW,OAAO;AAG7C,eAAa,UAAU,WAAW,OAAO;AAGzC,MAAI,SAAS,QAAQ;GACnB,MAAM,WAAW,MAAM,MAAM,EAAE;AAC/B,cAAW,MAAM,YAAY;QAE7B,YAAW,SAAS,KAAK,UAAU;;;;;;;;;;;;AAczC,SAAS,6BAA6B,MAAyB;AAG7D,uBAAsB,sBADT,IAAI,KAAwD,EACvC,IAAI,MAAM;;;;;;;AAQ9C,SAAS,sBACP,MACA,MACA,aACA,YACM;CACN,MAAM,cAAc,cAChB,GAAG,YAAY,GAAG,KAAK,gBACvB,KAAK,eAAe;AAGxB,KAAI,CAAC,YAAY;EACf,MAAM,eAAe,KAAK,QAAQ,KAAK;AACvC,MAAI,cAAc;GAChB,MAAM,WAAW,KAAK,IAAI,KAAK,QAAQ;AACvC,OAAI,SACF,OAAM,IAAI,MACR,gHACiB,KAAK,QAAQ,gBACb,SAAS,SAAS,QAAQ,SAAS,YAAY,iBAC/C,aAAa,SAAS,QAAQ,YAAY,8GAG5D;AAEH,QAAK,IAAI,KAAK,SAAS;IAAE,UAAU,aAAa;IAAU,aAAa;IAAa,CAAC;;;AAKzF,MAAK,MAAM,SAAS,KAAK,SACvB,uBAAsB,OAAO,MAAM,aAAa,WAAW;AAI7D,MAAK,MAAM,YAAY,OAAO,OAAO,KAAK,MAAM,CAC9C,uBAAsB,UAAU,MAAM,aAAa,KAAK;;;;;;;;;;;;;AAe5D,SAAS,4BAA4B,MAAyB;AAC5D,wBAAuB,sBAAM,IAAI,KAAK,CAAC;;;;;;AAOzC,SAAS,uBAAuB,MAAmB,MAAiC;AAElF,KAAI,KAAK,WAAW;EAClB,MAAM,WAAW,KAAK,IAAI,KAAK,UAAU;AACzC,MAAI,SACF,OAAM,IAAI,MACR,kCAAkC,KAAK,UAAU,yCACxB,SAAS,oBACb,KAAK,WAAW,IAAI,oDAE1C;AAGH,SAAO,IAAI,IAAI,KAAK;AACpB,OAAK,IAAI,KAAK,WAAW,KAAK,WAAW,IAAI;;AAI/C,MAAK,MAAM,SAAS,KAAK,SACvB,wBAAuB,OAAO,KAAK;AAKrC,MAAK,MAAM,YAAY,OAAO,OAAO,KAAK,MAAM,CAC9C,wBAAuB,UAAU,IAAI,IAAI,KAAK,CAAC;;;;;AAOnD,SAAS,cAAc,SAAiB,MAAqC;AAC3E,MAAK,MAAM,OAAO,CAAC,MAAM,MAAM,EAAE;EAC/B,MAAM,WAAW,KAAK,SAAS,GAAG,KAAK,GAAG,MAAM;AAChD,MAAI;AACF,OAAI,SAAS,SAAS,CAAC,QAAQ,CAC7B,QAAO;IAAE,UAAU;IAAU,WAAW;IAAK;UAEzC;;;;;;;AAWZ,SAAS,gBACP,SACA,MACA,QACuB;AACvB,MAAK,MAAM,OAAO,QAAQ;EACxB,MAAM,WAAW,KAAK,SAAS,GAAG,KAAK,GAAG,MAAM;AAChD,MAAI;AACF,OAAI,SAAS,SAAS,CAAC,QAAQ,CAC7B,QAAO;IAAE,UAAU;IAAU,WAAW;IAAK;UAEzC"}
@@ -0,0 +1,86 @@
1
+ //#region src/schema-bridge.ts
2
+ /**
3
+ * Run a Standard Schema's `~standard.validate()` synchronously.
4
+ *
5
+ * Zod v4's signature includes `Promise` in the return union to satisfy the
6
+ * Standard Schema spec, but in practice Zod always validates synchronously
7
+ * for the schema types we use. We assert the result is sync and throw if
8
+ * it isn't — codec parsing must be synchronous.
9
+ */
10
+ function validateSync(schema, value) {
11
+ const result = schema["~standard"].validate(value);
12
+ if (result instanceof Promise) throw new Error("[timber] fromSchema: schema returned a Promise — only sync schemas are supported.");
13
+ return result;
14
+ }
15
+ /** Check if a value is a Standard Schema object. */
16
+ function isStandardSchema(value) {
17
+ return typeof value === "object" && value !== null && "~standard" in value && typeof value["~standard"]?.validate === "function";
18
+ }
19
+ /** Check if a value is a Codec (has parse + serialize methods). */
20
+ function isCodec(value) {
21
+ return typeof value === "object" && value !== null && typeof value.parse === "function" && typeof value.serialize === "function";
22
+ }
23
+ /**
24
+ * Bridge a Standard Schema-compatible schema (Zod, Valibot, ArkType) to a
25
+ * Codec<T>.
26
+ *
27
+ * Parse: coerces the raw string through the schema. On validation failure,
28
+ * parses `undefined` to get the schema's default value (the schema should have
29
+ * a `.default()` call). If that also fails, returns `undefined`.
30
+ *
31
+ * Serialize: uses `String()` for primitives, `null` for null/undefined.
32
+ *
33
+ * ```ts
34
+ * import { fromSchema } from '@timber-js/app/codec'
35
+ * import { z } from 'zod/v4'
36
+ *
37
+ * const pageCodec = fromSchema(z.coerce.number().int().min(1).default(1))
38
+ * ```
39
+ */
40
+ function fromSchema(schema) {
41
+ return {
42
+ parse(value) {
43
+ const result = validateSync(schema, Array.isArray(value) ? value[value.length - 1] : value);
44
+ if (!result.issues) return result.value;
45
+ const defaultResult = validateSync(schema, void 0);
46
+ if (!defaultResult.issues) return defaultResult.value;
47
+ },
48
+ serialize(value) {
49
+ if (value === null || value === void 0) return null;
50
+ return String(value);
51
+ }
52
+ };
53
+ }
54
+ /**
55
+ * Bridge a Standard Schema for array values. Handles both single strings
56
+ * and repeated query keys (`?tag=a&tag=b`).
57
+ *
58
+ * ```ts
59
+ * import { fromArraySchema } from '@timber-js/app/codec'
60
+ * import { z } from 'zod/v4'
61
+ *
62
+ * const tagsCodec = fromArraySchema(z.array(z.string()).default([]))
63
+ * ```
64
+ */
65
+ function fromArraySchema(schema) {
66
+ return {
67
+ parse(value) {
68
+ let input = value;
69
+ if (typeof value === "string") input = [value];
70
+ else if (value === void 0) input = void 0;
71
+ const result = validateSync(schema, input);
72
+ if (!result.issues) return result.value;
73
+ const defaultResult = validateSync(schema, void 0);
74
+ if (!defaultResult.issues) return defaultResult.value;
75
+ },
76
+ serialize(value) {
77
+ if (value === null || value === void 0) return null;
78
+ if (Array.isArray(value)) return value.length === 0 ? null : value.join(",");
79
+ return String(value);
80
+ }
81
+ };
82
+ }
83
+ //#endregion
84
+ export { validateSync as a, isStandardSchema as i, fromSchema as n, isCodec as r, fromArraySchema as t };
85
+
86
+ //# sourceMappingURL=schema-bridge-eL5vQDSA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-bridge-eL5vQDSA.js","names":[],"sources":["../../src/schema-bridge.ts"],"sourcesContent":["/**\n * Standard Schema bridge — shared helpers for bridging Standard Schema-compatible\n * validation libraries (Zod, Valibot, ArkType) to the Codec<T> protocol.\n *\n * This module is the single source of truth for:\n * - StandardSchemaV1 interface (subset of the Standard Schema spec)\n * - validateSync() helper\n * - fromSchema() — bridge from Standard Schema to Codec<T>\n * - fromArraySchema() — bridge for array-valued codecs\n *\n * These are re-exported from @timber-js/app/search-params, @timber-js/app/segment-params,\n * and @timber-js/app/cookies for convenience. The canonical import is\n * @timber-js/app/codec.\n *\n * Design doc: design/23a-search-params-triage.md §\"Unify Codec<T> type\"\n */\n\nimport type { Codec } from './codec.js';\n\n// ---------------------------------------------------------------------------\n// Standard Schema interface (subset)\n//\n// Standard Schema (https://github.com/standard-schema/standard-schema) defines\n// a minimal interface that Zod ≥3.24, Valibot ≥1.0, and ArkType all implement.\n// We depend only on `~standard.validate` to avoid coupling to any specific lib.\n// ---------------------------------------------------------------------------\n\n/** Minimal Standard Schema interface for auto-detection. */\nexport interface StandardSchemaV1<Output = unknown> {\n '~standard': {\n validate(value: unknown): StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;\n };\n}\n\nexport type StandardSchemaResult<Output> =\n | { value: Output; issues?: undefined }\n | { value?: undefined; issues: ReadonlyArray<{ message: string }> };\n\n// ---------------------------------------------------------------------------\n// Sync validate helper\n// ---------------------------------------------------------------------------\n\n/**\n * Run a Standard Schema's `~standard.validate()` synchronously.\n *\n * Zod v4's signature includes `Promise` in the return union to satisfy the\n * Standard Schema spec, but in practice Zod always validates synchronously\n * for the schema types we use. We assert the result is sync and throw if\n * it isn't — codec parsing must be synchronous.\n */\nexport function validateSync<Output>(\n schema: StandardSchemaV1<Output>,\n value: unknown\n): StandardSchemaResult<Output> {\n const result = schema['~standard'].validate(value);\n if (result instanceof Promise) {\n throw new Error(\n '[timber] fromSchema: schema returned a Promise — only sync schemas are supported.'\n );\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------------------\n\n/** Check if a value is a Standard Schema object. */\nexport function isStandardSchema(value: unknown): value is StandardSchemaV1 {\n return (\n typeof value === 'object' &&\n value !== null &&\n '~standard' in value &&\n typeof (value as StandardSchemaV1)['~standard']?.validate === 'function'\n );\n}\n\n/** Check if a value is a Codec (has parse + serialize methods). */\nexport function isCodec(value: unknown): value is Codec<unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Codec<unknown>).parse === 'function' &&\n typeof (value as Codec<unknown>).serialize === 'function'\n );\n}\n\n// ---------------------------------------------------------------------------\n// fromSchema — bridge from Standard Schema to Codec<T>\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge a Standard Schema-compatible schema (Zod, Valibot, ArkType) to a\n * Codec<T>.\n *\n * Parse: coerces the raw string through the schema. On validation failure,\n * parses `undefined` to get the schema's default value (the schema should have\n * a `.default()` call). If that also fails, returns `undefined`.\n *\n * Serialize: uses `String()` for primitives, `null` for null/undefined.\n *\n * ```ts\n * import { fromSchema } from '@timber-js/app/codec'\n * import { z } from 'zod/v4'\n *\n * const pageCodec = fromSchema(z.coerce.number().int().min(1).default(1))\n * ```\n */\nexport function fromSchema<T>(schema: StandardSchemaV1<T>): Codec<T> {\n return {\n parse(value: string | string[] | undefined): T {\n // For array inputs, take the last value (consistent with URLSearchParams.get())\n const input = Array.isArray(value) ? value[value.length - 1] : value;\n\n // Try parsing the raw value\n const result = validateSync(schema, input);\n if (!result.issues) {\n return result.value;\n }\n\n // On failure, try parsing undefined to get the default\n const defaultResult = validateSync(schema, undefined);\n if (!defaultResult.issues) {\n return defaultResult.value;\n }\n\n // No default available — return undefined (codec design choice)\n return undefined as T;\n },\n\n serialize(value: T): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n return String(value);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// fromArraySchema — bridge for array-valued codecs\n// ---------------------------------------------------------------------------\n\n/**\n * Bridge a Standard Schema for array values. Handles both single strings\n * and repeated query keys (`?tag=a&tag=b`).\n *\n * ```ts\n * import { fromArraySchema } from '@timber-js/app/codec'\n * import { z } from 'zod/v4'\n *\n * const tagsCodec = fromArraySchema(z.array(z.string()).default([]))\n * ```\n */\nexport function fromArraySchema<T>(schema: StandardSchemaV1<T>): Codec<T> {\n return {\n parse(value: string | string[] | undefined): T {\n // Coerce single string to array for array schemas\n let input: unknown = value;\n if (typeof value === 'string') {\n input = [value];\n } else if (value === undefined) {\n input = undefined;\n }\n\n const result = validateSync(schema, input);\n if (!result.issues) {\n return result.value;\n }\n\n // On failure, try undefined for default\n const defaultResult = validateSync(schema, undefined);\n if (!defaultResult.issues) {\n return defaultResult.value;\n }\n\n return undefined as T;\n },\n\n serialize(value: T): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n if (Array.isArray(value)) {\n return value.length === 0 ? null : value.join(',');\n }\n return String(value);\n },\n };\n}\n"],"mappings":";;;;;;;;;AAkDA,SAAgB,aACd,QACA,OAC8B;CAC9B,MAAM,SAAS,OAAO,aAAa,SAAS,MAAM;AAClD,KAAI,kBAAkB,QACpB,OAAM,IAAI,MACR,oFACD;AAEH,QAAO;;;AAQT,SAAgB,iBAAiB,OAA2C;AAC1E,QACE,OAAO,UAAU,YACjB,UAAU,QACV,eAAe,SACf,OAAQ,MAA2B,cAAc,aAAa;;;AAKlE,SAAgB,QAAQ,OAAyC;AAC/D,QACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAyB,UAAU,cAC3C,OAAQ,MAAyB,cAAc;;;;;;;;;;;;;;;;;;;AAyBnD,SAAgB,WAAc,QAAuC;AACnE,QAAO;EACL,MAAM,OAAyC;GAK7C,MAAM,SAAS,aAAa,QAHd,MAAM,QAAQ,MAAM,GAAG,MAAM,MAAM,SAAS,KAAK,MAGrB;AAC1C,OAAI,CAAC,OAAO,OACV,QAAO,OAAO;GAIhB,MAAM,gBAAgB,aAAa,QAAQ,KAAA,EAAU;AACrD,OAAI,CAAC,cAAc,OACjB,QAAO,cAAc;;EAOzB,UAAU,OAAyB;AACjC,OAAI,UAAU,QAAQ,UAAU,KAAA,EAC9B,QAAO;AAET,UAAO,OAAO,MAAM;;EAEvB;;;;;;;;;;;;;AAkBH,SAAgB,gBAAmB,QAAuC;AACxE,QAAO;EACL,MAAM,OAAyC;GAE7C,IAAI,QAAiB;AACrB,OAAI,OAAO,UAAU,SACnB,SAAQ,CAAC,MAAM;YACN,UAAU,KAAA,EACnB,SAAQ,KAAA;GAGV,MAAM,SAAS,aAAa,QAAQ,MAAM;AAC1C,OAAI,CAAC,OAAO,OACV,QAAO,OAAO;GAIhB,MAAM,gBAAgB,aAAa,QAAQ,KAAA,EAAU;AACrD,OAAI,CAAC,cAAc,OACjB,QAAO,cAAc;;EAMzB,UAAU,OAAyB;AACjC,OAAI,UAAU,QAAQ,UAAU,KAAA,EAC9B,QAAO;AAET,OAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,WAAW,IAAI,OAAO,MAAM,KAAK,IAAI;AAEpD,UAAO,OAAO,MAAM;;EAEvB"}
@@ -0,0 +1,137 @@
1
+ //#region src/routing/types.ts
2
+ /** All recognized interception markers, ordered longest-first for parsing. */
3
+ var INTERCEPTION_MARKERS = [
4
+ "(..)(..)",
5
+ "(.)",
6
+ "(..)",
7
+ "(...)"
8
+ ];
9
+ /** Default page extensions */
10
+ var DEFAULT_PAGE_EXTENSIONS = [
11
+ "tsx",
12
+ "ts",
13
+ "jsx",
14
+ "js"
15
+ ];
16
+ //#endregion
17
+ //#region src/routing/segment-classify.ts
18
+ /**
19
+ * Classify a URL path segment token.
20
+ *
21
+ * Walks the string left-to-right in one pass:
22
+ * 1. If it doesn't start with '[', it's static.
23
+ * 2. Count opening brackets (1 or 2) to detect optional.
24
+ * 3. Check for '...' to detect catch-all.
25
+ * 4. Read the param name up to the closing bracket.
26
+ * 5. Validate the expected closing sequence (']' or ']]').
27
+ * 6. Reject if there are leftover characters after the close.
28
+ *
29
+ * Any structural violation → static (safe default).
30
+ */
31
+ function classifyUrlSegment(token) {
32
+ const len = token.length;
33
+ if (len === 0 || token[0] !== "[") return {
34
+ kind: "static",
35
+ value: token
36
+ };
37
+ let i = 1;
38
+ const optional = token[i] === "[";
39
+ if (optional) i++;
40
+ const catchAll = i + 2 < len && token[i] === "." && token[i + 1] === "." && token[i + 2] === ".";
41
+ if (catchAll) i += 3;
42
+ const nameStart = i;
43
+ while (i < len && token[i] !== "]") i++;
44
+ if (i >= len || i === nameStart) return {
45
+ kind: "static",
46
+ value: token
47
+ };
48
+ const name = token.slice(nameStart, i);
49
+ i++;
50
+ if (optional) {
51
+ if (i >= len || token[i] !== "]") return {
52
+ kind: "static",
53
+ value: token
54
+ };
55
+ i++;
56
+ }
57
+ if (i !== len) return {
58
+ kind: "static",
59
+ value: token
60
+ };
61
+ if (optional && catchAll) return {
62
+ kind: "optional-catch-all",
63
+ name
64
+ };
65
+ if (catchAll) return {
66
+ kind: "catch-all",
67
+ name
68
+ };
69
+ if (optional) return {
70
+ kind: "static",
71
+ value: token
72
+ };
73
+ return {
74
+ kind: "dynamic",
75
+ name
76
+ };
77
+ }
78
+ /**
79
+ * Classify a directory name into its segment type.
80
+ *
81
+ * Recognizes all timber file-system conventions in priority order:
82
+ * 1. Private folders: `_name` (excluded from routing)
83
+ * 2. Parallel route slots: `@name`
84
+ * 3. Intercepting routes: `(.)name`, `(..)name`, `(...)name`, `(..)(..)name`
85
+ * 4. Route groups: `(name)`
86
+ * 5. Bracket syntax: `[id]`, `[...slug]`, `[[...path]]` (delegated to
87
+ * `classifyUrlSegment`)
88
+ * 6. Static: anything else
89
+ *
90
+ * If you change the bracket syntax, update only `classifyUrlSegment`.
91
+ * If you change the directory-prefix conventions, update this function.
92
+ */
93
+ function classifySegment(dirName) {
94
+ if (dirName.startsWith("_")) return { type: "private" };
95
+ if (dirName.startsWith("@")) return { type: "slot" };
96
+ const interception = parseInterceptionMarker(dirName);
97
+ if (interception) return {
98
+ type: "intercepting",
99
+ interceptionMarker: interception.marker,
100
+ interceptedSegmentName: interception.segmentName
101
+ };
102
+ if (dirName.startsWith("(") && dirName.endsWith(")")) return { type: "group" };
103
+ const urlSeg = classifyUrlSegment(dirName);
104
+ if (urlSeg.kind !== "static") return {
105
+ type: urlSeg.kind,
106
+ paramName: urlSeg.name
107
+ };
108
+ return { type: "static" };
109
+ }
110
+ /**
111
+ * Parse an interception marker from a directory name.
112
+ *
113
+ * Returns the marker and the remaining segment name, or null if not an
114
+ * intercepting route. Markers are checked longest-first to avoid `(..)`
115
+ * matching before `(..)(..)`.
116
+ *
117
+ * Examples:
118
+ * "(.)photo" → { marker: "(.)", segmentName: "photo" }
119
+ * "(..)feed" → { marker: "(..)", segmentName: "feed" }
120
+ * "(...)photos" → { marker: "(...)", segmentName: "photos" }
121
+ * "(..)(..)admin" → { marker: "(..)(..)", segmentName: "admin" }
122
+ * "(marketing)" → null (route group, not interception)
123
+ */
124
+ function parseInterceptionMarker(dirName) {
125
+ for (const marker of INTERCEPTION_MARKERS) if (dirName.startsWith(marker)) {
126
+ const rest = dirName.slice(marker.length);
127
+ if (rest.length > 0 && !rest.endsWith(")")) return {
128
+ marker,
129
+ segmentName: rest
130
+ };
131
+ }
132
+ return null;
133
+ }
134
+ //#endregion
135
+ export { INTERCEPTION_MARKERS as i, classifyUrlSegment as n, DEFAULT_PAGE_EXTENSIONS as r, classifySegment as t };
136
+
137
+ //# sourceMappingURL=segment-classify-CnfLLvir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment-classify-CnfLLvir.js","names":[],"sources":["../../src/routing/types.ts","../../src/routing/segment-classify.ts"],"sourcesContent":["/**\n * Route tree types for timber.js file-system routing.\n *\n * The route tree is built by scanning the app/ directory and recognizing\n * file conventions (page.*, layout.*, middleware.ts, access.ts, route.ts, etc.).\n *\n * **Single shape, two specializations** (TIM-848):\n *\n * `SegmentNode<TFile>` is the one canonical in-memory shape for the\n * timber route tree. The same interface is used at build time (with\n * `TFile = RouteFile`) and at request time (with `TFile = ManifestFile`,\n * see `server/route-matcher.ts`). Walkers parameterized over `TFile`\n * work on either, eliminating the previous duplication between\n * `SegmentNode` (Map-based) and `ManifestSegmentNode` (object-based).\n *\n * Keyed groups (`slots`, `statusFiles`, `jsonStatusFiles`,\n * `legacyStatusFiles`, `metadataRoutes`) are plain `Record<string, …>`\n * objects rather than `Map`s so that the build-time tree can be\n * serialized into the virtual route manifest with no shape transform.\n *\n * See design/07-routing.md §\"Route Tree Shape\" and design/18-build-system.md\n * §\"Route Manifest Shape\".\n */\n\n/** Segment type classification */\nexport type SegmentType =\n | 'static' // e.g. \"dashboard\"\n | 'dynamic' // e.g. \"[id]\"\n | 'catch-all' // e.g. \"[...slug]\"\n | 'optional-catch-all' // e.g. \"[[...slug]]\"\n | 'group' // e.g. \"(marketing)\"\n | 'slot' // e.g. \"@sidebar\"\n | 'intercepting' // e.g. \"(.)photo\", \"(..)photo\", \"(...)photo\"\n | 'private'; // e.g. \"_components\", \"_lib\" — excluded from routing\n\n/**\n * Intercepting route marker — indicates how many levels up to resolve the\n * intercepted route from the intercepting route's location.\n *\n * See design/07-routing.md §\"Intercepting Routes\"\n */\nexport type InterceptionMarker = '(.)' | '(..)' | '(...)' | '(..)(..)';\n\n/** All recognized interception markers, ordered longest-first for parsing. */\nexport const INTERCEPTION_MARKERS: InterceptionMarker[] = ['(..)(..)', '(.)', '(..)', '(...)'];\n\n/**\n * A single file discovered in a route segment at build time.\n *\n * The runtime equivalent (`ManifestFile`, defined in\n * `server/route-matcher.ts`) replaces `extension` with a lazy `load`\n * function. Walkers that only need `filePath` are parameterized over\n * `TFile` and accept either.\n */\nexport interface RouteFile {\n /** Absolute path to the file */\n filePath: string;\n /** File extension without leading dot (e.g. \"tsx\", \"ts\", \"mdx\") */\n extension: string;\n}\n\n/**\n * A node in the segment tree.\n *\n * Generic over `TFile` so the same interface describes both the\n * build-time tree (`SegmentNode<RouteFile>`, the default) and the\n * runtime manifest tree (`SegmentNode<ManifestFile>`, aliased as\n * `ManifestSegmentNode`). All keyed groups use `Record` (not `Map`)\n * so the build-time tree serializes to the virtual route manifest\n * with no shape transform.\n */\nexport interface SegmentNode<TFile = RouteFile> {\n /** The raw directory name (e.g. \"dashboard\", \"[id]\", \"(auth)\", \"@sidebar\") */\n segmentName: string;\n /** Classified segment type */\n segmentType: SegmentType;\n /** The dynamic param name, if dynamic (e.g. \"id\" for \"[id]\", \"slug\" for \"[...slug]\") */\n paramName?: string;\n /** The URL path prefix at this segment level (e.g. \"/dashboard\") */\n urlPath: string;\n /** For intercepting segments: the marker used, e.g. \"(.)\". */\n interceptionMarker?: InterceptionMarker;\n /**\n * For intercepting segments: the segment name after stripping the marker.\n * E.g., for \"(.)photo\" this is \"photo\".\n */\n interceptedSegmentName?: string;\n\n // --- File conventions ---\n page?: TFile;\n layout?: TFile;\n middleware?: TFile;\n access?: TFile;\n route?: TFile;\n /**\n * params.ts — isomorphic convention file exporting segmentParams and/or searchParams.\n * Discovered by the scanner like middleware.ts and access.ts.\n * See design/07-routing.md §\"params.ts Convention File\"\n */\n params?: TFile;\n error?: TFile;\n default?: TFile;\n /** Status-code files: 4xx.tsx, 5xx.tsx, {status}.tsx (component format) */\n statusFiles?: Record<string, TFile>;\n /** JSON status-code files: 4xx.json, 5xx.json, {status}.json */\n jsonStatusFiles?: Record<string, TFile>;\n /** denied.tsx — slot-only denial rendering */\n denied?: TFile;\n /** Legacy compat: not-found.tsx (maps to 404), forbidden.tsx (403), unauthorized.tsx (401) */\n legacyStatusFiles?: Record<string, TFile>;\n\n /** Metadata route files (sitemap.ts, robots.ts, icon.tsx, etc.) keyed by base name */\n metadataRoutes?: Record<string, TFile>;\n\n // --- Children ---\n children: SegmentNode<TFile>[];\n /** Parallel route slots (keyed by slot name without @) */\n slots: Record<string, SegmentNode<TFile>>;\n}\n\n/**\n * The full route tree output from the scanner (or the root of the\n * runtime route manifest, when `TFile = ManifestFile`).\n *\n * Generic so the same wrapper carries app-root metadata for both\n * shapes. The runtime manifest extends this with `viteRoot` (see\n * `ManifestRoot` in `server/route-matcher.ts`).\n */\nexport interface RouteTree<TFile = RouteFile> {\n /** The root segment node (representing app/) */\n root: SegmentNode<TFile>;\n /** All discovered proxy.ts files (should be at most one, in app/) */\n proxy?: TFile;\n /**\n * Global error page: app/global-error.{tsx,ts,jsx,js}\n *\n * Rendered as a standalone full-page replacement (no layout wrapping)\n * when no segment-level error file is found. SSR-only render path.\n * Must provide its own <html> and <body>.\n *\n * See design/10-error-handling.md §\"Tier 2 — Global Error Page\"\n */\n globalError?: TFile;\n}\n\n/** Configuration passed to the scanner */\nexport interface ScannerConfig {\n /** Recognized page/layout extensions (without dots). Default: ['tsx', 'ts', 'jsx', 'js'] */\n pageExtensions?: string[];\n}\n\n/** Default page extensions */\nexport const DEFAULT_PAGE_EXTENSIONS = ['tsx', 'ts', 'jsx', 'js'];\n","/**\n * Shared segment classifier — both URL tokens and filesystem directory names.\n *\n * `classifyUrlSegment(token)` is a pure single-pass character parser that\n * classifies a route segment token (e.g. \"dashboard\", \"[id]\", \"[...slug]\",\n * \"[[...path]]\") into a typed discriminated union. NO regex, NO Node.js-only\n * APIs — safe to import from browser code (used by `Link` interpolation).\n *\n * `classifySegment(dirName)` is the build-time directory-name classifier\n * used by the scanner. It recognizes timber-only conventions (private\n * `_*`, parallel `@*`, route groups `(name)`, intercepting routes\n * `(.)`/`(..)`/`(...)`/`(..)(..)`) and delegates bracket syntax to\n * `classifyUrlSegment`. It is the **single source of truth** for what\n * counts as a routing segment — there is no separate copy in the\n * scanner. (TIM-848.)\n *\n * Malformed input falls through to `{ kind: 'static' }` — the safe default.\n *\n * If you change the bracket syntax, update ONLY this file. Every\n * consumer imports from here.\n *\n * See design/07-routing.md §\"Route Segments\"\n */\n\nimport type { InterceptionMarker, SegmentType } from './types.js';\nimport { INTERCEPTION_MARKERS } from './types.js';\n\nexport type UrlSegment =\n | { kind: 'static'; value: string }\n | { kind: 'dynamic'; name: string }\n | { kind: 'catch-all'; name: string }\n | { kind: 'optional-catch-all'; name: string };\n\n/**\n * Classify a URL path segment token.\n *\n * Walks the string left-to-right in one pass:\n * 1. If it doesn't start with '[', it's static.\n * 2. Count opening brackets (1 or 2) to detect optional.\n * 3. Check for '...' to detect catch-all.\n * 4. Read the param name up to the closing bracket.\n * 5. Validate the expected closing sequence (']' or ']]').\n * 6. Reject if there are leftover characters after the close.\n *\n * Any structural violation → static (safe default).\n */\nexport function classifyUrlSegment(token: string): UrlSegment {\n const len = token.length;\n\n // Must start with '[' to be dynamic\n if (len === 0 || token[0] !== '[') {\n return { kind: 'static', value: token };\n }\n\n let i = 1;\n\n // Check for optional: '[[...'\n const optional = token[i] === '[';\n if (optional) i++;\n\n // Check for catch-all: '...'\n const catchAll = i + 2 < len && token[i] === '.' && token[i + 1] === '.' && token[i + 2] === '.';\n if (catchAll) i += 3;\n\n // Read param name — everything up to ']'\n const nameStart = i;\n while (i < len && token[i] !== ']') i++;\n\n // Must have found a ']' and name must be non-empty\n if (i >= len || i === nameStart) {\n return { kind: 'static', value: token };\n }\n\n const name = token.slice(nameStart, i);\n i++; // skip first ']'\n\n // Optional requires a second ']'\n if (optional) {\n if (i >= len || token[i] !== ']') {\n return { kind: 'static', value: token };\n }\n i++;\n }\n\n // Must be at end of string — no trailing characters\n if (i !== len) {\n return { kind: 'static', value: token };\n }\n\n if (optional && catchAll) return { kind: 'optional-catch-all', name };\n if (catchAll) return { kind: 'catch-all', name };\n if (optional) {\n // '[[name]]' without '...' is malformed — not a valid segment syntax\n return { kind: 'static', value: token };\n }\n return { kind: 'dynamic', name };\n}\n\n// ─── Directory-name classifier (build-time scanner) ─────────────────────────\n\n/** Result of classifying a filesystem directory name. */\nexport interface SegmentClassification {\n type: SegmentType;\n paramName?: string;\n interceptionMarker?: InterceptionMarker;\n interceptedSegmentName?: string;\n}\n\n/**\n * Classify a directory name into its segment type.\n *\n * Recognizes all timber file-system conventions in priority order:\n * 1. Private folders: `_name` (excluded from routing)\n * 2. Parallel route slots: `@name`\n * 3. Intercepting routes: `(.)name`, `(..)name`, `(...)name`, `(..)(..)name`\n * 4. Route groups: `(name)`\n * 5. Bracket syntax: `[id]`, `[...slug]`, `[[...path]]` (delegated to\n * `classifyUrlSegment`)\n * 6. Static: anything else\n *\n * If you change the bracket syntax, update only `classifyUrlSegment`.\n * If you change the directory-prefix conventions, update this function.\n */\nexport function classifySegment(dirName: string): SegmentClassification {\n // Private folder: _name (excluded from routing)\n if (dirName.startsWith('_')) {\n return { type: 'private' };\n }\n\n // Parallel route slot: @name\n if (dirName.startsWith('@')) {\n return { type: 'slot' };\n }\n\n // Intercepting routes: (.)name, (..)name, (...)name, (..)(..)name\n // Check before route groups since intercepting markers also start with (\n const interception = parseInterceptionMarker(dirName);\n if (interception) {\n return {\n type: 'intercepting',\n interceptionMarker: interception.marker,\n interceptedSegmentName: interception.segmentName,\n };\n }\n\n // Route group: (name)\n if (dirName.startsWith('(') && dirName.endsWith(')')) {\n return { type: 'group' };\n }\n\n // Bracket-syntax segments: [param], [...param], [[...param]]\n const urlSeg = classifyUrlSegment(dirName);\n if (urlSeg.kind !== 'static') {\n return { type: urlSeg.kind, paramName: urlSeg.name };\n }\n\n return { type: 'static' };\n}\n\n/**\n * Parse an interception marker from a directory name.\n *\n * Returns the marker and the remaining segment name, or null if not an\n * intercepting route. Markers are checked longest-first to avoid `(..)`\n * matching before `(..)(..)`.\n *\n * Examples:\n * \"(.)photo\" → { marker: \"(.)\", segmentName: \"photo\" }\n * \"(..)feed\" → { marker: \"(..)\", segmentName: \"feed\" }\n * \"(...)photos\" → { marker: \"(...)\", segmentName: \"photos\" }\n * \"(..)(..)admin\" → { marker: \"(..)(..)\", segmentName: \"admin\" }\n * \"(marketing)\" → null (route group, not interception)\n */\nfunction parseInterceptionMarker(\n dirName: string\n): { marker: InterceptionMarker; segmentName: string } | null {\n for (const marker of INTERCEPTION_MARKERS) {\n if (dirName.startsWith(marker)) {\n const rest = dirName.slice(marker.length);\n // Must have a segment name after the marker, and the rest must not\n // be empty or end with ) (which would be a route group like \"(auth)\")\n if (rest.length > 0 && !rest.endsWith(')')) {\n return { marker, segmentName: rest };\n }\n }\n }\n return null;\n}\n"],"mappings":";;AA4CA,IAAa,uBAA6C;CAAC;CAAY;CAAO;CAAQ;CAAQ;;AA4G9F,IAAa,0BAA0B;CAAC;CAAO;CAAM;CAAO;CAAK;;;;;;;;;;;;;;;;AC1GjE,SAAgB,mBAAmB,OAA2B;CAC5D,MAAM,MAAM,MAAM;AAGlB,KAAI,QAAQ,KAAK,MAAM,OAAO,IAC5B,QAAO;EAAE,MAAM;EAAU,OAAO;EAAO;CAGzC,IAAI,IAAI;CAGR,MAAM,WAAW,MAAM,OAAO;AAC9B,KAAI,SAAU;CAGd,MAAM,WAAW,IAAI,IAAI,OAAO,MAAM,OAAO,OAAO,MAAM,IAAI,OAAO,OAAO,MAAM,IAAI,OAAO;AAC7F,KAAI,SAAU,MAAK;CAGnB,MAAM,YAAY;AAClB,QAAO,IAAI,OAAO,MAAM,OAAO,IAAK;AAGpC,KAAI,KAAK,OAAO,MAAM,UACpB,QAAO;EAAE,MAAM;EAAU,OAAO;EAAO;CAGzC,MAAM,OAAO,MAAM,MAAM,WAAW,EAAE;AACtC;AAGA,KAAI,UAAU;AACZ,MAAI,KAAK,OAAO,MAAM,OAAO,IAC3B,QAAO;GAAE,MAAM;GAAU,OAAO;GAAO;AAEzC;;AAIF,KAAI,MAAM,IACR,QAAO;EAAE,MAAM;EAAU,OAAO;EAAO;AAGzC,KAAI,YAAY,SAAU,QAAO;EAAE,MAAM;EAAsB;EAAM;AACrE,KAAI,SAAU,QAAO;EAAE,MAAM;EAAa;EAAM;AAChD,KAAI,SAEF,QAAO;EAAE,MAAM;EAAU,OAAO;EAAO;AAEzC,QAAO;EAAE,MAAM;EAAW;EAAM;;;;;;;;;;;;;;;;;AA4BlC,SAAgB,gBAAgB,SAAwC;AAEtE,KAAI,QAAQ,WAAW,IAAI,CACzB,QAAO,EAAE,MAAM,WAAW;AAI5B,KAAI,QAAQ,WAAW,IAAI,CACzB,QAAO,EAAE,MAAM,QAAQ;CAKzB,MAAM,eAAe,wBAAwB,QAAQ;AACrD,KAAI,aACF,QAAO;EACL,MAAM;EACN,oBAAoB,aAAa;EACjC,wBAAwB,aAAa;EACtC;AAIH,KAAI,QAAQ,WAAW,IAAI,IAAI,QAAQ,SAAS,IAAI,CAClD,QAAO,EAAE,MAAM,SAAS;CAI1B,MAAM,SAAS,mBAAmB,QAAQ;AAC1C,KAAI,OAAO,SAAS,SAClB,QAAO;EAAE,MAAM,OAAO;EAAM,WAAW,OAAO;EAAM;AAGtD,QAAO,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;;AAiB3B,SAAS,wBACP,SAC4D;AAC5D,MAAK,MAAM,UAAU,qBACnB,KAAI,QAAQ,WAAW,OAAO,EAAE;EAC9B,MAAM,OAAO,QAAQ,MAAM,OAAO,OAAO;AAGzC,MAAI,KAAK,SAAS,KAAK,CAAC,KAAK,SAAS,IAAI,CACxC,QAAO;GAAE;GAAQ,aAAa;GAAM;;AAI1C,QAAO"}