@farm.js/core 0.1.34 → 0.1.35

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 (261) hide show
  1. package/dist/agent-runtime.cjs +3 -3
  2. package/dist/agent-runtime.d.mts +4 -5
  3. package/dist/agent-runtime.d.ts +4 -5
  4. package/dist/agent-runtime.mjs +2 -2
  5. package/dist/api/route-manager.cjs +5 -5
  6. package/dist/api/route-manager.d.mts +6 -7
  7. package/dist/api/route-manager.d.ts +6 -7
  8. package/dist/api/route-manager.mjs +4 -4
  9. package/dist/api/runtime.cjs +6 -4
  10. package/dist/api/runtime.d.mts +4 -5
  11. package/dist/api/runtime.d.ts +4 -5
  12. package/dist/api/runtime.mjs +6 -4
  13. package/dist/api.cjs +6 -6
  14. package/dist/api.d.mts +7 -8
  15. package/dist/api.d.ts +7 -8
  16. package/dist/api.mjs +5 -5
  17. package/dist/{app-DgotYGbq.d.ts → app-BXB3JZYc.d.ts} +38 -12
  18. package/dist/{app-q4rmZlXK.d.mts → app-D_j9AAVL.d.mts} +38 -12
  19. package/dist/app-markdown.cjs +5 -5
  20. package/dist/app-markdown.d.mts +5 -6
  21. package/dist/app-markdown.d.ts +5 -6
  22. package/dist/app-markdown.mjs +4 -4
  23. package/dist/{chunk-LMJ7VRHZ.mjs → chunk-22LTEMGQ.mjs} +1 -1
  24. package/dist/{chunk-AQZFOP7S.mjs → chunk-2G2NNLE2.mjs} +1 -1
  25. package/dist/{chunk-QJ3J6MZT.cjs → chunk-3BHT4WMP.cjs} +2 -2
  26. package/dist/{chunk-X242HVD5.mjs → chunk-3PXS2MHU.mjs} +1 -1
  27. package/dist/{chunk-A5FGU2WU.cjs → chunk-3UH7MRCP.cjs} +19 -23
  28. package/dist/{chunk-AGC75XAE.mjs → chunk-4JHOT46A.mjs} +1 -1
  29. package/dist/{chunk-XV5DJTBX.mjs → chunk-4KU5Q7C2.mjs} +424 -230
  30. package/dist/{chunk-TA5G2HWD.cjs → chunk-4MMGO7YW.cjs} +21 -21
  31. package/dist/{chunk-7BT4H4P7.cjs → chunk-62XKI4Z3.cjs} +2 -2
  32. package/dist/{chunk-ZKP7C2B6.mjs → chunk-6DU6UFUE.mjs} +12 -11
  33. package/dist/{chunk-GOABMOX3.mjs → chunk-6ETPZTJI.mjs} +366 -4
  34. package/dist/{chunk-7Y6ZNFPX.mjs → chunk-6TJOML4E.mjs} +13 -3
  35. package/dist/{chunk-3ATMYLLJ.mjs → chunk-6WCPV6G2.mjs} +1 -1
  36. package/dist/{chunk-BTAG7LI7.cjs → chunk-73MC7ZL6.cjs} +2 -2
  37. package/dist/chunk-75RZHGLS.cjs +135 -0
  38. package/dist/{chunk-VKNHTSAP.cjs → chunk-7GLPRTTF.cjs} +2 -2
  39. package/dist/{chunk-7M52YUMY.cjs → chunk-7L5V3KQO.cjs} +2 -2
  40. package/dist/{chunk-LI2LMOLR.mjs → chunk-C35ZBVRD.mjs} +12 -3
  41. package/dist/{chunk-YQVSHTMR.mjs → chunk-CP6X4AEU.mjs} +1 -1
  42. package/dist/{chunk-QZCT2CQ4.mjs → chunk-CXEN47J3.mjs} +64 -2
  43. package/dist/{chunk-ATK2R4CH.cjs → chunk-D227TIEN.cjs} +14 -4
  44. package/dist/{chunk-ROUTX2E5.cjs → chunk-DBNKI4NF.cjs} +12 -3
  45. package/dist/{chunk-UX5S4JEO.cjs → chunk-EFCQPQMG.cjs} +3 -3
  46. package/dist/{chunk-K3F2E6GS.cjs → chunk-EJQT6KZN.cjs} +2 -2
  47. package/dist/{chunk-3LUF2PE2.cjs → chunk-EK4QAEFZ.cjs} +67 -5
  48. package/dist/{chunk-VVBO3QH7.mjs → chunk-ENLZ4R3Y.mjs} +10 -1
  49. package/dist/{chunk-XXJU7FCC.cjs → chunk-EUV4YR3V.cjs} +2 -2
  50. package/dist/{chunk-WNNYOOIB.mjs → chunk-F6Z3Y5KL.mjs} +1 -1
  51. package/dist/{chunk-PQDFUSXD.cjs → chunk-F7JZENPF.cjs} +33 -32
  52. package/dist/{chunk-TDFPACVX.cjs → chunk-FTFYRMQQ.cjs} +18 -18
  53. package/dist/{chunk-657WJNRY.mjs → chunk-G5RT7EXW.mjs} +1 -1
  54. package/dist/{chunk-MOKLYNHV.cjs → chunk-GFHLGIYC.cjs} +6 -6
  55. package/dist/{chunk-AWC4VUZL.cjs → chunk-GQ3Z3IZI.cjs} +14 -14
  56. package/dist/{chunk-75WGQVQA.cjs → chunk-HITLGIAO.cjs} +10 -1
  57. package/dist/{chunk-GNSDTTWZ.mjs → chunk-HMIJDL7S.mjs} +1 -1
  58. package/dist/{chunk-PXKIEXZD.mjs → chunk-HUMR6LSU.mjs} +1 -1
  59. package/dist/{chunk-SJVKK4JE.cjs → chunk-ICUQICNC.cjs} +912 -718
  60. package/dist/{chunk-P64MIF5B.cjs → chunk-IPXLADVO.cjs} +387 -25
  61. package/dist/{chunk-KROWKCUH.cjs → chunk-JGLC4TO3.cjs} +8 -1
  62. package/dist/{chunk-2NQQ5H5G.cjs → chunk-M7MKQXAF.cjs} +2 -1
  63. package/dist/chunk-NRDBW4MP.mjs +45 -0
  64. package/dist/chunk-OFZUJMCU.mjs +601 -0
  65. package/dist/{chunk-VCCUOMQN.mjs → chunk-OKZUAXHF.mjs} +1 -1
  66. package/dist/{chunk-EM6SBQKM.cjs → chunk-OMVAU7NT.cjs} +27 -2
  67. package/dist/{chunk-O27L4YAA.mjs → chunk-PDOCJ6RY.mjs} +2 -2
  68. package/dist/{chunk-36MK5YCW.cjs → chunk-PFQKNERH.cjs} +346 -206
  69. package/dist/{chunk-HR5KPHC2.mjs → chunk-Q3VLETLE.mjs} +1 -1
  70. package/dist/{chunk-LR5QSC2P.mjs → chunk-QAU5JD57.mjs} +211 -71
  71. package/dist/{chunk-LHODW25H.mjs → chunk-QORUJDIV.mjs} +2 -2
  72. package/dist/{chunk-UBO4SGH4.mjs → chunk-RHAZ22ZN.mjs} +2 -1
  73. package/dist/{chunk-ZHPHJPQP.cjs → chunk-RU3M2FIK.cjs} +18 -14
  74. package/dist/{chunk-JDPAKVS4.mjs → chunk-SAZVVAJH.mjs} +3 -3
  75. package/dist/{chunk-6VVL3MHY.mjs → chunk-SC2WYWPF.mjs} +1 -1
  76. package/dist/{chunk-QCFFHV5H.mjs → chunk-SMHH4VDG.mjs} +1 -1
  77. package/dist/{chunk-U4PTAHW3.mjs → chunk-SOMHP6GF.mjs} +7 -11
  78. package/dist/{chunk-VHANUNEG.mjs → chunk-UAORZ7QA.mjs} +2 -2
  79. package/dist/{chunk-NGVORZVZ.mjs → chunk-UJD4PHYB.mjs} +15 -11
  80. package/dist/{chunk-U74I55WB.cjs → chunk-ULAWS2PA.cjs} +13 -3
  81. package/dist/{chunk-MPEYMSCF.cjs → chunk-VFQT3LAO.cjs} +5 -5
  82. package/dist/{chunk-Z2YLTERK.cjs → chunk-VZJR7UTG.cjs} +6 -6
  83. package/dist/chunk-WWFTAUFG.cjs +45 -0
  84. package/dist/{chunk-ZUSJDQ2Q.mjs → chunk-WWIKMBRN.mjs} +1 -1
  85. package/dist/{chunk-QGYRXFU2.cjs → chunk-X6W5FFH6.cjs} +8 -8
  86. package/dist/{chunk-MIDIZJZC.cjs → chunk-XBML5KMG.cjs} +8 -8
  87. package/dist/{chunk-G26MUMKL.cjs → chunk-XCACDAZZ.cjs} +4 -4
  88. package/dist/{chunk-CLJYVZAD.mjs → chunk-XCMCS4DA.mjs} +11 -1
  89. package/dist/{chunk-XF7Q24PF.mjs → chunk-Y7RKTKYI.mjs} +25 -0
  90. package/dist/{chunk-ODBZYBAB.cjs → chunk-YC6V7PWE.cjs} +1 -1
  91. package/dist/{chunk-F6OHXPWR.mjs → chunk-YFILVET3.mjs} +8 -1
  92. package/dist/{chunk-DZ4DTRJ5.cjs → chunk-YKX5BK66.cjs} +7 -7
  93. package/dist/chunk-YSLWRWWP.cjs +601 -0
  94. package/dist/{chunk-3VSKDFAT.mjs → chunk-YULD7ICZ.mjs} +1 -1
  95. package/dist/chunk-ZLAT2CWY.mjs +135 -0
  96. package/dist/{chunk-T5CERMEH.cjs → chunk-ZXGAFZDO.cjs} +2 -2
  97. package/dist/{client-plugins-CLObcuCq.d.mts → client-plugins-CvIslxWi.d.mts} +207 -7
  98. package/dist/{client-plugins-DZjHC4Mi.d.ts → client-plugins-HIyulDym.d.ts} +207 -7
  99. package/dist/client-plugins.d.mts +4 -5
  100. package/dist/client-plugins.d.ts +4 -5
  101. package/dist/client.cjs +5 -5
  102. package/dist/client.d.mts +8 -9
  103. package/dist/client.d.ts +8 -9
  104. package/dist/client.mjs +4 -4
  105. package/dist/config.d.mts +4 -5
  106. package/dist/config.d.ts +4 -5
  107. package/dist/{devtools-HU6Y2MNV.cjs → devtools-EAUY43BS.cjs} +9 -9
  108. package/dist/{devtools-RNXCTS4R.mjs → devtools-EE5RIBTH.mjs} +8 -8
  109. package/dist/docs.cjs +12 -12
  110. package/dist/docs.d.mts +41 -4
  111. package/dist/docs.d.ts +41 -4
  112. package/dist/docs.mjs +11 -11
  113. package/dist/i18n/client.d.mts +2 -2
  114. package/dist/i18n/client.d.ts +2 -2
  115. package/dist/i18n/index.d.mts +3 -3
  116. package/dist/i18n/index.d.ts +3 -3
  117. package/dist/i18n/server.d.mts +5 -5
  118. package/dist/i18n/server.d.ts +5 -5
  119. package/dist/image/server.cjs +3 -3
  120. package/dist/image/server.mjs +2 -2
  121. package/dist/image/sharp.cjs +10 -10
  122. package/dist/image/sharp.mjs +2 -2
  123. package/dist/{index-a-8Z5kZU.d.mts → index-BJJfLxJo.d.mts} +2 -2
  124. package/dist/{index-BWVfxIsO.d.ts → index-CwoOP-MW.d.ts} +2 -2
  125. package/dist/index.cjs +38 -35
  126. package/dist/index.d.mts +19 -20
  127. package/dist/index.d.ts +19 -20
  128. package/dist/index.mjs +37 -34
  129. package/dist/integrations.cjs +3 -3
  130. package/dist/integrations.d.mts +4 -5
  131. package/dist/integrations.d.ts +4 -5
  132. package/dist/integrations.mjs +2 -2
  133. package/dist/internal/app-markdown-runtime.cjs +4 -4
  134. package/dist/internal/app-markdown-runtime.d.mts +5 -6
  135. package/dist/internal/app-markdown-runtime.d.ts +5 -6
  136. package/dist/internal/app-markdown-runtime.mjs +3 -3
  137. package/dist/internal/build-runtime.cjs +26 -26
  138. package/dist/internal/build-runtime.d.mts +6 -7
  139. package/dist/internal/build-runtime.d.ts +6 -7
  140. package/dist/internal/build-runtime.mjs +25 -25
  141. package/dist/internal/cli-runtime.cjs +13 -13
  142. package/dist/internal/cli-runtime.mjs +12 -12
  143. package/dist/internal/client-error-overlay.cjs +6 -6
  144. package/dist/internal/client-error-overlay.mjs +2 -2
  145. package/dist/internal/client-runtime.cjs +2 -2
  146. package/dist/internal/client-runtime.mjs +1 -1
  147. package/dist/internal/compression-runtime.d.mts +4 -5
  148. package/dist/internal/compression-runtime.d.ts +4 -5
  149. package/dist/internal/config-runtime.cjs +9 -9
  150. package/dist/internal/config-runtime.d.mts +5 -6
  151. package/dist/internal/config-runtime.d.ts +5 -6
  152. package/dist/internal/config-runtime.mjs +8 -8
  153. package/dist/internal/isolated-boundary.cjs +3 -2
  154. package/dist/internal/isolated-boundary.d.mts +1 -0
  155. package/dist/internal/isolated-boundary.d.ts +1 -0
  156. package/dist/internal/isolated-boundary.mjs +2 -1
  157. package/dist/internal/metadata-image-runtime.cjs +3 -3
  158. package/dist/internal/metadata-image-runtime.mjs +2 -2
  159. package/dist/internal/product-telemetry-runtime.cjs +2 -2
  160. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  161. package/dist/internal/production-runtime.cjs +47 -23
  162. package/dist/internal/production-runtime.d.mts +58 -18
  163. package/dist/internal/production-runtime.d.ts +58 -18
  164. package/dist/internal/production-runtime.mjs +43 -19
  165. package/dist/internal/server-tree.cjs +12 -0
  166. package/dist/internal/server-tree.d.mts +27 -0
  167. package/dist/internal/server-tree.d.ts +27 -0
  168. package/dist/internal/server-tree.mjs +12 -0
  169. package/dist/markdown.cjs +3 -3
  170. package/dist/markdown.d.mts +4 -5
  171. package/dist/markdown.d.ts +4 -5
  172. package/dist/markdown.mjs +2 -2
  173. package/dist/{metadata-Cjs8JMRM.d.ts → metadata-BnLDsUOS.d.ts} +16 -2
  174. package/dist/{metadata-2HSU2i_w.d.mts → metadata-WGpBYcGn.d.mts} +16 -2
  175. package/dist/middleware.cjs +4 -4
  176. package/dist/middleware.d.mts +6 -7
  177. package/dist/middleware.d.ts +6 -7
  178. package/dist/middleware.mjs +3 -3
  179. package/dist/navigation.cjs +5 -5
  180. package/dist/navigation.d.mts +7 -8
  181. package/dist/navigation.d.ts +7 -8
  182. package/dist/navigation.mjs +4 -4
  183. package/dist/{nitro-4XGPNIK4.mjs → nitro-MXRDCXWZ.mjs} +2 -2
  184. package/dist/{nitro-HSAQFXSS.cjs → nitro-OVPLKPE2.cjs} +3 -3
  185. package/dist/{observability-BupkiN0m.d.mts → observability-CoXunYhS.d.mts} +4 -3
  186. package/dist/{observability-BupkiN0m.d.ts → observability-CoXunYhS.d.ts} +4 -3
  187. package/dist/observability.d.mts +1 -1
  188. package/dist/observability.d.ts +1 -1
  189. package/dist/plugin.cjs +22 -22
  190. package/dist/plugin.d.mts +4 -5
  191. package/dist/plugin.d.ts +4 -5
  192. package/dist/plugin.mjs +21 -21
  193. package/dist/{production-runtime-CysZl3EV.d.mts → production-runtime-0sRnuYc-.d.mts} +4 -4
  194. package/dist/{production-runtime-BU5ETAK9.d.ts → production-runtime-Crq6CJ-2.d.ts} +4 -4
  195. package/dist/query/client.cjs +6 -6
  196. package/dist/query/client.mjs +2 -2
  197. package/dist/{render-plan-D72O1qm4.d.ts → render-plan-8ozZh2Qv.d.ts} +1 -1
  198. package/dist/{render-plan-CKr4ltOd.d.mts → render-plan-gs9GGPzw.d.mts} +1 -1
  199. package/dist/renderer/react/server.cjs +10 -4
  200. package/dist/renderer/react/server.d.mts +2 -1
  201. package/dist/renderer/react/server.d.ts +2 -1
  202. package/dist/renderer/react/server.mjs +7 -1
  203. package/dist/renderer-client.cjs +5 -5
  204. package/dist/renderer-client.d.mts +6 -7
  205. package/dist/renderer-client.d.ts +6 -7
  206. package/dist/renderer-client.mjs +2 -2
  207. package/dist/renderer.d.mts +2 -0
  208. package/dist/renderer.d.ts +2 -0
  209. package/dist/{request-DbyOYI2j.d.ts → request-B5G8rLBH.d.ts} +1 -1
  210. package/dist/{request-Be83WafN.d.mts → request-fkhiynXe.d.mts} +1 -1
  211. package/dist/request.d.mts +5 -6
  212. package/dist/request.d.ts +5 -6
  213. package/dist/{resolver-PPEeiJ6M.d.ts → resolver-DadfRL6F.d.ts} +1 -1
  214. package/dist/{resolver-DhW0CqZN.d.mts → resolver-khasx3fU.d.mts} +1 -1
  215. package/dist/{route-rendering-BG56SzvJ.d.mts → route-rendering-CLnS7AZj.d.mts} +1 -1
  216. package/dist/{route-rendering-CtVMpV-k.d.ts → route-rendering-lS5nUMua.d.ts} +1 -1
  217. package/dist/{router-D94-SDlW.d.ts → router-4iuiYnOW.d.ts} +1 -1
  218. package/dist/{router-ALUvm8gC.d.mts → router-ifU8Dui1.d.mts} +1 -1
  219. package/dist/routes.d.mts +4 -5
  220. package/dist/routes.d.ts +4 -5
  221. package/dist/{runtime-BirxPwbZ.d.ts → runtime-BgDQzBiu.d.ts} +2 -2
  222. package/dist/{runtime-AOJge4vQ.d.mts → runtime-CV2UCV-5.d.mts} +2 -2
  223. package/dist/server-action-security.cjs +3 -3
  224. package/dist/server-action-security.mjs +2 -2
  225. package/dist/server-fn.cjs +4 -4
  226. package/dist/server-fn.mjs +3 -3
  227. package/dist/server-plugins.d.mts +5 -6
  228. package/dist/server-plugins.d.ts +5 -6
  229. package/dist/server-query.cjs +5 -5
  230. package/dist/server-query.mjs +4 -4
  231. package/dist/server.cjs +41 -41
  232. package/dist/server.d.mts +13 -14
  233. package/dist/server.d.ts +13 -14
  234. package/dist/server.mjs +24 -24
  235. package/dist/{spa-router-DbxNRKOB.d.mts → spa-router-Bq7VCOwx.d.mts} +3 -3
  236. package/dist/{spa-router-CxK3USIz.d.ts → spa-router-DaJk5Re4.d.ts} +3 -3
  237. package/dist/testing.cjs +7 -7
  238. package/dist/testing.d.mts +4 -5
  239. package/dist/testing.d.ts +4 -5
  240. package/dist/testing.mjs +5 -5
  241. package/dist/{types-Z0aotQ8w.d.mts → types-CnH8DOqo.d.mts} +1 -1
  242. package/dist/{types-Z0aotQ8w.d.ts → types-CnH8DOqo.d.ts} +1 -1
  243. package/dist/{utils-311Y8eoK.d.ts → utils-BXLmFsVR.d.ts} +1 -1
  244. package/dist/{utils-4wVRcpOw.d.mts → utils-XJn0c9bj.d.mts} +1 -1
  245. package/dist/version.cjs +2 -2
  246. package/dist/version.mjs +1 -1
  247. package/dist/vite.cjs +22 -22
  248. package/dist/vite.d.mts +4 -5
  249. package/dist/vite.d.ts +4 -5
  250. package/dist/vite.mjs +21 -21
  251. package/dist/{workflows-CR9ex-gz.d.ts → workflows-jZ4BcdoZ.d.mts} +1 -1
  252. package/dist/{workflows-CR9ex-gz.d.mts → workflows-jZ4BcdoZ.d.ts} +1 -1
  253. package/dist/workflows.cjs +3 -3
  254. package/dist/workflows.d.mts +1 -1
  255. package/dist/workflows.d.ts +1 -1
  256. package/dist/workflows.mjs +2 -2
  257. package/package.json +9 -1
  258. package/dist/chunk-M64YUMA4.cjs +0 -58
  259. package/dist/chunk-QLQ32WC4.mjs +0 -58
  260. package/dist/types-DFbjpjXX.d.mts +0 -105
  261. package/dist/types-DFbjpjXX.d.ts +0 -105
@@ -4,7 +4,7 @@ import {
4
4
  matchSSGPage,
5
5
  resolveRouteRenderingConfig,
6
6
  resolveRouteRenderingConfigFromFile
7
- } from "./chunk-AQZFOP7S.mjs";
7
+ } from "./chunk-2G2NNLE2.mjs";
8
8
  import {
9
9
  collectSchemaExtensions,
10
10
  declareSchemaTables,
@@ -16,28 +16,41 @@ import {
16
16
  import {
17
17
  FARM_API_CATALOG_PATH,
18
18
  FARM_APP_MANIFEST_PATH,
19
+ classifyFarmDocumentPrefix,
20
+ composeFarmFullDocument,
19
21
  createDefaultErrorMarkup,
22
+ createFarmAiCatalogResponse,
20
23
  createFarmApiCatalogResponse,
21
24
  createFarmAppManifestResponse,
22
25
  createFarmMetadataRouteResponse,
23
26
  createFarmThemeDocumentParts,
24
27
  createLateNotFoundRecovery,
25
28
  createLateRedirectRecovery,
29
+ createRouteDirectoryPattern,
30
+ extractFarmFullDocument,
31
+ formatRouteSegment,
26
32
  getDefaultErrorStatusText,
33
+ getRouteDirectoryDepth,
34
+ getRouteGroupScope,
35
+ isInRouteGroupScope,
36
+ listFarmMCPLlmsTxtLinks,
37
+ removeFarmDocumentTitles,
27
38
  renderFarmLocaleAlternateLinks,
28
39
  resolveDefaultErrorStatus,
29
40
  resolveFarmApiCatalogInput,
30
- resolveFarmAppManifestInput
31
- } from "./chunk-GOABMOX3.mjs";
41
+ resolveFarmAppManifestInput,
42
+ routeBoundaryCoversDirectory,
43
+ stripRouteGroups
44
+ } from "./chunk-6ETPZTJI.mjs";
32
45
  import {
33
46
  isFarmPreviewDeploymentEnvironment
34
47
  } from "./chunk-BOYNDCZL.mjs";
35
48
  import {
36
49
  createFarmMetadataImageResponse
37
- } from "./chunk-YQVSHTMR.mjs";
50
+ } from "./chunk-CP6X4AEU.mjs";
38
51
  import {
39
52
  createFarmImageHandler
40
- } from "./chunk-PXKIEXZD.mjs";
53
+ } from "./chunk-HUMR6LSU.mjs";
41
54
  import {
42
55
  FARM_ISLAND_REPLAYABLE_SELECTOR,
43
56
  isFarmIslandStrategy
@@ -54,8 +67,9 @@ import {
54
67
  } from "./chunk-2ELDTQRN.mjs";
55
68
  import {
56
69
  generateFarmDocsAdapterClientRuntime,
57
- getFarmDocsAdapterConfigModule
58
- } from "./chunk-VVBO3QH7.mjs";
70
+ getFarmDocsAdapterConfigModule,
71
+ isSecretDocsConfigKey
72
+ } from "./chunk-ENLZ4R3Y.mjs";
59
73
  import {
60
74
  resolveFarmDocsFontAssets,
61
75
  toFarmDocsPublicFontAssets
@@ -109,7 +123,7 @@ import {
109
123
  resolveFarmLlmsTxtConfig,
110
124
  resolveFarmPerformanceConfig,
111
125
  resolveFarmSecurityConfig
112
- } from "./chunk-NGVORZVZ.mjs";
126
+ } from "./chunk-UJD4PHYB.mjs";
113
127
  import {
114
128
  getPublicFarmImageConfig,
115
129
  resolveFarmImageConfig
@@ -119,7 +133,7 @@ import {
119
133
  } from "./chunk-YHOCRI4H.mjs";
120
134
  import {
121
135
  resolveServerActionsConfig
122
- } from "./chunk-QCFFHV5H.mjs";
136
+ } from "./chunk-SMHH4VDG.mjs";
123
137
  import {
124
138
  createBundledEnv,
125
139
  getResolvedEnv
@@ -127,12 +141,12 @@ import {
127
141
  import {
128
142
  createFarmMarkdownRouteModuleFromFile,
129
143
  loadFarmMdxComponents
130
- } from "./chunk-3VSKDFAT.mjs";
144
+ } from "./chunk-YULD7ICZ.mjs";
131
145
  import {
132
146
  createFarmMarkdownSourceResponse,
133
147
  isFarmMarkdownPageFile,
134
148
  normalizeFarmMarkdownRoutePath
135
- } from "./chunk-AGC75XAE.mjs";
149
+ } from "./chunk-4JHOT46A.mjs";
136
150
  import {
137
151
  resolveFarmMdxComponentsModulePath,
138
152
  resolveMdxConfig
@@ -146,10 +160,10 @@ import {
146
160
  getFarmMarkdownMirrorPath,
147
161
  resolveMarkdownConfig,
148
162
  resolveMarkdownMirrorTarget
149
- } from "./chunk-ZUSJDQ2Q.mjs";
163
+ } from "./chunk-WWIKMBRN.mjs";
150
164
  import {
151
165
  resolveWorkflowsConfig
152
- } from "./chunk-3ATMYLLJ.mjs";
166
+ } from "./chunk-6WCPV6G2.mjs";
153
167
  import {
154
168
  initStorage
155
169
  } from "./chunk-UWPLULNK.mjs";
@@ -169,14 +183,14 @@ import {
169
183
  getRegisteredIntegrationAPIManifest,
170
184
  isFarmIntegrationProviderComponentReference,
171
185
  matchIntegrationRoute
172
- } from "./chunk-GNSDTTWZ.mjs";
186
+ } from "./chunk-HMIJDL7S.mjs";
173
187
  import {
174
188
  MiddlewareManager
175
- } from "./chunk-7Y6ZNFPX.mjs";
189
+ } from "./chunk-6TJOML4E.mjs";
176
190
  import {
177
191
  createRouteSlotContainerId,
178
192
  parseRouteSlotFile
179
- } from "./chunk-UBO4SGH4.mjs";
193
+ } from "./chunk-RHAZ22ZN.mjs";
180
194
  import {
181
195
  _clearCurrentMiddlewareContext,
182
196
  _clearCurrentMiddlewareData,
@@ -191,7 +205,7 @@ import {
191
205
  } from "./chunk-IOEH4VWN.mjs";
192
206
  import {
193
207
  APIRouteManager
194
- } from "./chunk-LMJ7VRHZ.mjs";
208
+ } from "./chunk-22LTEMGQ.mjs";
195
209
  import {
196
210
  findProgrammaticRouteFiles,
197
211
  loadProgrammaticRouteManifests
@@ -210,7 +224,10 @@ import {
210
224
  } from "./chunk-YOZYCI6Z.mjs";
211
225
  import {
212
226
  isFarmAPIPathname
213
- } from "./chunk-657WJNRY.mjs";
227
+ } from "./chunk-G5RT7EXW.mjs";
228
+ import {
229
+ registerFarmMCPServer
230
+ } from "./chunk-ZLAT2CWY.mjs";
214
231
  import {
215
232
  createProgrammaticRouteModuleId,
216
233
  getProgrammaticRouteSearchClientOptions,
@@ -235,6 +252,7 @@ import {
235
252
  clearRequestContext,
236
253
  copyRequestContext,
237
254
  createFarmNodeRequestAbortSignal,
255
+ createFarmNodeRequestBodyStream,
238
256
  createFarmRequestBodyErrorResponse,
239
257
  deleteRequestContext,
240
258
  getRequestContext,
@@ -244,7 +262,7 @@ import {
244
262
  readNodeRequestBody,
245
263
  resolveFarmServerConfig,
246
264
  setRequestContext
247
- } from "./chunk-XF7Q24PF.mjs";
265
+ } from "./chunk-Y7RKTKYI.mjs";
248
266
  import {
249
267
  createCliColors
250
268
  } from "./chunk-I2BHUNBU.mjs";
@@ -290,7 +308,7 @@ import {
290
308
  } from "./chunk-Z2RZJZIZ.mjs";
291
309
  import {
292
310
  FARM_VERSION
293
- } from "./chunk-X242HVD5.mjs";
311
+ } from "./chunk-3PXS2MHU.mjs";
294
312
  import {
295
313
  resolveFarmTrailingSlashRedirect,
296
314
  setFarmTrailingSlashPreference
@@ -307,9 +325,11 @@ import {
307
325
  addMetadataImageReference,
308
326
  addMetadataMarkdownAlternate,
309
327
  mergeMetadata,
328
+ mergeModuleViewport,
310
329
  renderMetadataHead,
330
+ renderViewportHead,
311
331
  resolveFarmNotFoundMetadata
312
- } from "./chunk-QZCT2CQ4.mjs";
332
+ } from "./chunk-CXEN47J3.mjs";
313
333
  import {
314
334
  FARM_DEPLOYMENT_ID_HEADER,
315
335
  createFarmDeploymentCookie,
@@ -752,6 +772,26 @@ function parseClientModuleMetadata(content, inspectIslandExport) {
752
772
  };
753
773
  }
754
774
  __name(parseClientModuleMetadata, "parseClientModuleMetadata");
775
+ var DEFAULT_REEXPORT = /export\s*\{\s*default(?:\s+as\s+default)?\s*\}\s*from\s*(["'])([^"']+)\1/;
776
+ function resolveDefaultReexport(ownerPath, content, root) {
777
+ const match = content ? DEFAULT_REEXPORT.exec(content) : null;
778
+ if (!match) return null;
779
+ const imported = resolveImportedModule(ownerPath, match[2], root);
780
+ return imported.local ? imported.path : null;
781
+ }
782
+ __name(resolveDefaultReexport, "resolveDefaultReexport");
783
+ function resolveOwnerSourcePath(resolvedPath, root) {
784
+ const seen = /* @__PURE__ */ new Set();
785
+ let current = resolvedPath;
786
+ while (current && !seen.has(current)) {
787
+ seen.add(current);
788
+ const target = resolveDefaultReexport(current, readIfExists(current), root);
789
+ if (!target) return current;
790
+ current = target;
791
+ }
792
+ return current;
793
+ }
794
+ __name(resolveOwnerSourcePath, "resolveOwnerSourcePath");
755
795
  function getClientModuleMetadata(modulePath, root) {
756
796
  const resolvedPath = resolveModuleSourcePath(modulePath, root);
757
797
  return inspectClientModuleMetadata(resolvedPath, root, /* @__PURE__ */ new Set(), true);
@@ -773,7 +813,7 @@ function getClientModuleHydrationPlan(modulePath, root, mode = "off", options =
773
813
  }), "emptyPlan");
774
814
  const asyncOwner = metadata.suppressedAsyncHydration === true && options.asyncOwnerIslands === true;
775
815
  if (mode === "off" && !asyncOwner) return emptyPlan();
776
- const resolvedPath = resolveModuleSourcePath(modulePath, root);
816
+ const resolvedPath = resolveOwnerSourcePath(resolveModuleSourcePath(modulePath, root), root);
777
817
  const content = readIfExists(resolvedPath ?? "");
778
818
  const parsed = parseClientModuleMetadata(content, true);
779
819
  if (!resolvedPath) return emptyPlan("the owner source could not be resolved");
@@ -827,6 +867,10 @@ function getClientModuleHydrationPlan(modulePath, root, mode = "off", options =
827
867
  return plan;
828
868
  }
829
869
  __name(getClientModuleHydrationPlan, "getClientModuleHydrationPlan");
870
+ function usesFarmServerTree(plan) {
871
+ return plan?.asyncOwnerIslands === true && plan.isolatedBoundaries.length > 0 && plan.isolatedBoundaries.every((boundary) => boundary.islandStrategy === "load");
872
+ }
873
+ __name(usesFarmServerTree, "usesFarmServerTree");
830
874
  function getMarkdownPageHydrationPlan(componentsModulePath, root, mode = "off", options = {}) {
831
875
  const plan = {
832
876
  isClientComponent: false,
@@ -1314,6 +1358,10 @@ function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandE
1314
1358
  }
1315
1359
  visited.add(resolvedPath);
1316
1360
  const content = readIfExists(resolvedPath);
1361
+ if (inspectIslandExport) {
1362
+ const target = resolveDefaultReexport(resolvedPath, content, root);
1363
+ if (target) return inspectClientModuleMetadata(target, root, visited, true);
1364
+ }
1317
1365
  const parsed = parseClientModuleMetadata(content, inspectIslandExport);
1318
1366
  if (parsed.isClientComponent) {
1319
1367
  return {
@@ -1895,6 +1943,10 @@ async function readAltText(filePath) {
1895
1943
  __name(readAltText, "readAltText");
1896
1944
 
1897
1945
  // src/routing/route-manager.ts
1946
+ function getRouteEntryDirectory(entry) {
1947
+ return entry.directory ?? entry.pattern;
1948
+ }
1949
+ __name(getRouteEntryDirectory, "getRouteEntryDirectory");
1898
1950
  function shouldSuggestStaticRenderingForI18n(i18n) {
1899
1951
  return !i18n || i18n.routing === "prefix-always" || i18n.routing === "prefix-except-default" && i18n.detection.every((signal) => signal === "url");
1900
1952
  }
@@ -1972,8 +2024,8 @@ var _RouteManager = class _RouteManager {
1972
2024
  )
1973
2025
  );
1974
2026
  this.orderedLayouts = Array.from(this.layouts.values()).sort(
1975
- (left, right) => left.route.segments.length - right.route.segments.length
1976
- );
2027
+ (left, right) => getRouteDirectoryDepth(left.pattern) - getRouteDirectoryDepth(right.pattern)
2028
+ ).map((entry) => ({ entry, groupScope: getRouteGroupScope(entry.pattern) }));
1977
2029
  for (const slot of this.routeSlots.values()) {
1978
2030
  if (!this.routeSlotOwnerSegments.has(slot.ownerPattern)) {
1979
2031
  this.routeSlotOwnerSegments.set(
@@ -2008,7 +2060,7 @@ var _RouteManager = class _RouteManager {
2008
2060
  break;
2009
2061
  }
2010
2062
  }
2011
- const layouts = this.findMatchingLayouts(normalizedPath, pathParts);
2063
+ const layouts = this.findMatchingLayouts(pathParts, matchedRoute);
2012
2064
  const slots = this.findMatchingRouteSlots(normalizedPath, pathParts, options.interceptFrom);
2013
2065
  return {
2014
2066
  route: matchedRoute,
@@ -2039,7 +2091,7 @@ var _RouteManager = class _RouteManager {
2039
2091
  throw new Error(`Cannot resolve runtime configuration for unknown route "${pattern}"`);
2040
2092
  }
2041
2093
  const inherited = resolveFarmRouteRuleRuntimeConfig(pattern, this.config.routeRules);
2042
- const layouts = this.findMatchingLayouts(pattern);
2094
+ const layouts = this.findMatchingLayouts(splitRoutePath(pattern), routeEntry);
2043
2095
  const layoutConfigs = [];
2044
2096
  for (const layout of layouts) {
2045
2097
  const layoutModule = await this.loadLayoutModule(layout.modulePath);
@@ -2106,16 +2158,19 @@ var _RouteManager = class _RouteManager {
2106
2158
  return null;
2107
2159
  }
2108
2160
  /**
2109
- * Return the nearest matching loading boundary for a pathname.
2161
+ * Return the nearest matching loading boundary for a pathname. Pass the page
2162
+ * `matchRoute` selected when it is known (`null` for none); otherwise the page is
2163
+ * matched only if a boundary inside a route group needs it.
2110
2164
  */
2111
- getMatchingLoading(pathname) {
2112
- return this.findNearestBoundary(this.toRoutePathname(pathname), this.loadings);
2165
+ getMatchingLoading(pathname, route) {
2166
+ return this.findNearestBoundary(this.toRoutePathname(pathname), this.loadings, route);
2113
2167
  }
2114
2168
  /**
2115
- * Return the nearest matching error boundary for a pathname.
2169
+ * Return the nearest matching error boundary for a pathname. `route` works as it
2170
+ * does for `getMatchingLoading`.
2116
2171
  */
2117
- getMatchingError(pathname) {
2118
- return this.findNearestBoundary(this.toRoutePathname(pathname), this.errors);
2172
+ getMatchingError(pathname, route) {
2173
+ return this.findNearestBoundary(this.toRoutePathname(pathname), this.errors, route);
2119
2174
  }
2120
2175
  matchMetadataImage(pathname) {
2121
2176
  const routePathname = this.toRoutePathname(pathname);
@@ -2283,15 +2338,15 @@ var _RouteManager = class _RouteManager {
2283
2338
  enforceFarmIsolatedHydrationRouteBudget(
2284
2339
  layoutEntries.map(({ entry, metadata }) => ({
2285
2340
  pattern: entry.pattern,
2286
- depth: entry.route.segments.length,
2341
+ depth: getRouteDirectoryDepth(entry.pattern),
2287
2342
  metadata
2288
2343
  })),
2289
2344
  routeEntries.map(({ entry, metadata }) => ({
2290
- pattern: entry.pattern,
2291
- depth: entry.route.segments.length,
2345
+ pattern: getRouteEntryDirectory(entry),
2346
+ depth: getRouteDirectoryDepth(getRouteEntryDirectory(entry)),
2292
2347
  metadata
2293
2348
  })),
2294
- (layoutPattern, routePattern) => layoutPattern === "/" || routePattern === layoutPattern || routePattern.startsWith(`${layoutPattern.replace(/\/$/, "")}/`)
2349
+ routeBoundaryCoversDirectory
2295
2350
  );
2296
2351
  for (const { entry, metadata } of [...layoutEntries, ...routeEntries]) {
2297
2352
  if (!metadata.costGuardExceeded) continue;
@@ -2310,10 +2365,11 @@ var _RouteManager = class _RouteManager {
2310
2365
  const routes = routeEntries.map(({ entry, metadata }) => {
2311
2366
  const programmaticPage = this.programmaticPages.get(entry.modulePath);
2312
2367
  const layoutShouldHydrate = layoutEntries.some(
2313
- ({ entry: layout, metadata: layoutMetadata }) => layoutMetadata.shouldHydrate && (layout.pattern === "/" || entry.pattern === layout.pattern || entry.pattern.startsWith(`${layout.pattern.replace(/\/$/, "")}/`))
2368
+ ({ entry: layout, metadata: layoutMetadata }) => layoutMetadata.shouldHydrate && routeBoundaryCoversDirectory(layout.pattern, getRouteEntryDirectory(entry))
2314
2369
  );
2315
2370
  return {
2316
2371
  pattern: entry.pattern,
2372
+ ...entry.directory ? { directory: entry.directory } : {},
2317
2373
  modulePath: toUrlPath(entry.modulePath),
2318
2374
  shouldHydrate: metadata.shouldHydrate,
2319
2375
  isClientComponent: metadata.isClientComponent,
@@ -2325,6 +2381,7 @@ var _RouteManager = class _RouteManager {
2325
2381
  modulePath: toUrlPath(boundary.modulePath)
2326
2382
  }))
2327
2383
  } : {},
2384
+ ...usesFarmServerTree(metadata) ? { serverTree: true } : {},
2328
2385
  renderPlan: createFarmRouteRenderPlan({
2329
2386
  pageShouldHydrate: metadata.shouldHydrate,
2330
2387
  layoutShouldHydrate,
@@ -2483,13 +2540,7 @@ var _RouteManager = class _RouteManager {
2483
2540
  */
2484
2541
  createRoutePattern(route) {
2485
2542
  if (route.segments.length === 0) return "/";
2486
- return "/" + route.segments.map((segment) => {
2487
- if (!segment.isDynamic) return segment.segment;
2488
- if (segment.isCatchAll) {
2489
- return segment.isOptional ? `[[...${segment.segment}]]` : `[...${segment.segment}]`;
2490
- }
2491
- return `[${segment.segment}]`;
2492
- }).join("/");
2543
+ return "/" + route.segments.map(formatRouteSegment).join("/");
2493
2544
  }
2494
2545
  registerPageRoute(entry) {
2495
2546
  assertUniqueRouteParameters(entry.pattern);
@@ -2570,6 +2621,7 @@ var _RouteManager = class _RouteManager {
2570
2621
  markdownSourcePath: path3.join(appDir, markdownFile)
2571
2622
  } : {},
2572
2623
  pattern,
2624
+ ...getPageDirectoryField(group.route, pattern),
2573
2625
  source: "file",
2574
2626
  sourceRoot: source.root
2575
2627
  });
@@ -2582,7 +2634,7 @@ var _RouteManager = class _RouteManager {
2582
2634
  for (const file of files) {
2583
2635
  const route = parseRoutePath(file);
2584
2636
  const modulePath = path3.join(appDir, file);
2585
- const pattern = this.createRoutePattern(route);
2637
+ const pattern = createRouteDirectoryPattern(route);
2586
2638
  const existing = target.get(pattern);
2587
2639
  if (existing?.sourceRoot === source.root) {
2588
2640
  throw new Error(
@@ -2604,6 +2656,7 @@ var _RouteManager = class _RouteManager {
2604
2656
  const modulePath = path3.join(appDir, file);
2605
2657
  const pattern = this.createRoutePattern(slot.route);
2606
2658
  const ownerPattern = this.createRoutePattern(slot.ownerRoute);
2659
+ const ownerDirectory = createRouteDirectoryPattern(slot.ownerRoute);
2607
2660
  const key = `${ownerPattern}:${slot.name}:${slot.interception ? "intercept" : "slot"}:${slot.fallback ? "default" : pattern}`;
2608
2661
  const existing = this.routeSlots.get(key);
2609
2662
  if (existing?.sourceRoot === source.root) {
@@ -2619,6 +2672,7 @@ var _RouteManager = class _RouteManager {
2619
2672
  sourceRoot: source.root,
2620
2673
  name: slot.name,
2621
2674
  ownerPattern,
2675
+ ...ownerDirectory === ownerPattern ? {} : { ownerDirectory },
2622
2676
  interception: slot.interception,
2623
2677
  fallback: slot.fallback,
2624
2678
  containerId: createRouteSlotContainerId(slot.name, ownerPattern)
@@ -2700,13 +2754,14 @@ var _RouteManager = class _RouteManager {
2700
2754
  route,
2701
2755
  modulePath,
2702
2756
  pattern,
2757
+ ...getPageDirectoryField(route, pattern),
2703
2758
  source: "programmatic",
2704
2759
  sourceRoot: source.root
2705
2760
  });
2706
2761
  }
2707
2762
  if (definition.kind === "layout") {
2708
2763
  const route = parseProgrammaticRoutePath(definition.path, "layout");
2709
- const pattern = this.createRoutePattern(route);
2764
+ const pattern = createRouteDirectoryPattern(route);
2710
2765
  const existing = this.layouts.get(pattern);
2711
2766
  if (existing?.sourceRoot === source.root) {
2712
2767
  throw new Error(
@@ -2746,17 +2801,26 @@ var _RouteManager = class _RouteManager {
2746
2801
  );
2747
2802
  }
2748
2803
  /**
2749
- * Find all layouts that should wrap a given path
2804
+ * Find all layouts that should wrap a given path. A layout inside a route group
2805
+ * wraps only the pages in that group, so it needs the selected page.
2750
2806
  */
2751
- findMatchingLayouts(pathname, pathnameParts = splitRoutePath(pathname)) {
2807
+ findMatchingLayouts(pathnameParts, route) {
2752
2808
  const matchingLayouts = [];
2753
- for (const layoutEntry of this.orderedLayouts) {
2754
- if (matchRoutePrefixParts(pathnameParts, layoutEntry.route.segments)) {
2755
- matchingLayouts.push(layoutEntry);
2809
+ for (const { entry, groupScope } of this.orderedLayouts) {
2810
+ if (!matchRoutePrefixParts(pathnameParts, entry.route.segments)) continue;
2811
+ if (groupScope !== null && !isInRouteGroupScope(route && getRouteEntryDirectory(route), groupScope)) {
2812
+ continue;
2756
2813
  }
2814
+ matchingLayouts.push(entry);
2757
2815
  }
2758
2816
  return matchingLayouts;
2759
2817
  }
2818
+ matchPageRoute(pathnameParts) {
2819
+ for (const routeEntry of this.routes.values()) {
2820
+ if (matchRouteParts(pathnameParts, routeEntry.route.segments).matches) return routeEntry;
2821
+ }
2822
+ return null;
2823
+ }
2760
2824
  findMatchingRouteSlots(pathname, pathnameParts, interceptFrom) {
2761
2825
  const groups = /* @__PURE__ */ new Map();
2762
2826
  for (const entry of this.routeSlots.values()) {
@@ -2786,6 +2850,7 @@ var _RouteManager = class _RouteManager {
2786
2850
  matches.push({
2787
2851
  name: selected.entry.name,
2788
2852
  ownerPattern: selected.entry.ownerPattern,
2853
+ ...selected.entry.ownerDirectory ? { ownerDirectory: selected.entry.ownerDirectory } : {},
2789
2854
  containerId: selected.entry.containerId,
2790
2855
  interception: selected.entry.interception,
2791
2856
  fallback: false,
@@ -2799,6 +2864,7 @@ var _RouteManager = class _RouteManager {
2799
2864
  matches.push({
2800
2865
  name: fallback.name,
2801
2866
  ownerPattern: fallback.ownerPattern,
2867
+ ...fallback.ownerDirectory ? { ownerDirectory: fallback.ownerDirectory } : {},
2802
2868
  containerId: fallback.containerId,
2803
2869
  interception: false,
2804
2870
  fallback: true,
@@ -2817,12 +2883,20 @@ var _RouteManager = class _RouteManager {
2817
2883
  const patternSegments = this.routeSlotOwnerSegments.get(pattern) ?? parseRoutePath(`${pattern}/page.tsx`).segments;
2818
2884
  return matchRoutePrefixParts(pathnameParts, patternSegments);
2819
2885
  }
2820
- findNearestBoundary(pathname, boundaries) {
2886
+ findNearestBoundary(pathname, boundaries, route) {
2821
2887
  const normalizedPath = pathname === "/" ? "/" : pathname.replace(/\/$/, "");
2822
2888
  let bestMatch = null;
2889
+ let page = route;
2823
2890
  for (const boundaryEntry of boundaries.values()) {
2824
2891
  if (!matchRoutePrefix(normalizedPath, boundaryEntry.route.segments)) continue;
2825
- if (!bestMatch || boundaryEntry.route.segments.length > bestMatch.route.segments.length) {
2892
+ const groupScope = getRouteGroupScope(boundaryEntry.pattern);
2893
+ if (groupScope !== null) {
2894
+ if (page === void 0) page = this.matchPageRoute(splitRoutePath(normalizedPath));
2895
+ if (!isInRouteGroupScope(page && getRouteEntryDirectory(page), groupScope)) continue;
2896
+ }
2897
+ const depth = boundaryEntry.route.segments.length;
2898
+ const bestDepth = bestMatch?.route.segments.length ?? -1;
2899
+ if (!bestMatch || depth > bestDepth || depth === bestDepth && getRouteDirectoryDepth(boundaryEntry.pattern) > getRouteDirectoryDepth(bestMatch.pattern)) {
2826
2900
  bestMatch = boundaryEntry;
2827
2901
  }
2828
2902
  }
@@ -2937,6 +3011,11 @@ var _RouteManager = class _RouteManager {
2937
3011
  };
2938
3012
  __name(_RouteManager, "RouteManager");
2939
3013
  var RouteManager = _RouteManager;
3014
+ function getPageDirectoryField(route, pattern) {
3015
+ const directory = createRouteDirectoryPattern(route);
3016
+ return directory === pattern ? {} : { directory };
3017
+ }
3018
+ __name(getPageDirectoryField, "getPageDirectoryField");
2940
3019
  function interpolateRedirectDestination(destination, params) {
2941
3020
  let result = destination;
2942
3021
  for (const [key, value] of Object.entries(params)) {
@@ -3054,112 +3133,6 @@ function collectDevStylesheetUrls(modules, alreadyLinked = ALREADY_LINKED) {
3054
3133
  }
3055
3134
  __name(collectDevStylesheetUrls, "collectDevStylesheetUrls");
3056
3135
 
3057
- // src/server/full-document.ts
3058
- var CONTENTS_WRAPPER = /^<div\b[^>]*style="display\s*:\s*contents"[^>]*>/i;
3059
- var HOISTED_HEAD_ELEMENT = /^(?:<(?:meta|link|base)\b[^>]*>|<title\b[^>]*>[\s\S]*?<\/title>|<script\b[^>]*\basync\b[^>]*><\/script>|<style\b[^>]*\bdata-precedence\b[^>]*>[\s\S]*?<\/style>)/i;
3060
- function peelDocumentPrefix(markup) {
3061
- let inner = markup.replace(/^\s+/, "");
3062
- let hoisted = "";
3063
- let match;
3064
- while (match = CONTENTS_WRAPPER.exec(inner) ?? HOISTED_HEAD_ELEMENT.exec(inner)) {
3065
- if (!/^<div/i.test(match[0])) hoisted += match[0];
3066
- inner = inner.slice(match[0].length).replace(/^\s+/, "");
3067
- }
3068
- return { inner, hoisted };
3069
- }
3070
- __name(peelDocumentPrefix, "peelDocumentPrefix");
3071
- function restoreHoistedHead(document, hoisted) {
3072
- if (!hoisted) return document;
3073
- if (/<head[\s>]/i.test(document)) {
3074
- return document.replace(/<head\b[^>]*>/i, (open) => open + hoisted);
3075
- }
3076
- return document.replace(/<html\b[^>]*>/i, (open) => `${open}<head>${hoisted}</head>`);
3077
- }
3078
- __name(restoreHoistedHead, "restoreHoistedHead");
3079
- function extractFarmFullDocument(markup) {
3080
- const { inner, hoisted } = peelDocumentPrefix(markup);
3081
- if (!/^<!doctype/i.test(inner) && !/^<html[\s>]/i.test(inner)) return null;
3082
- const start = markup.search(/<!doctype|<html[\s>]/i);
3083
- const lower = markup.toLowerCase();
3084
- let closeIndex = lower.lastIndexOf("</html>");
3085
- if (lower.length !== markup.length) {
3086
- closeIndex = -1;
3087
- const closing = /<\/html>/gi;
3088
- let match;
3089
- while (match = closing.exec(markup)) closeIndex = match.index;
3090
- }
3091
- if (start < 0 || closeIndex < 0) return null;
3092
- const closeEnd = closeIndex + "</html>".length;
3093
- let document = markup.slice(start, closeEnd);
3094
- const streamedTail = markup.slice(closeEnd).replace(/^(?:\s*<\/div>)+/i, "").trim();
3095
- if (streamedTail) {
3096
- document = document.replace(/<\/body>/i, () => `${streamedTail}</body>`);
3097
- }
3098
- return restoreHoistedHead(document, hoisted);
3099
- }
3100
- __name(extractFarmFullDocument, "extractFarmFullDocument");
3101
- function classifyFarmDocumentPrefix(markup) {
3102
- const { inner } = peelDocumentPrefix(markup);
3103
- if (/^<!doctype/i.test(inner) || /^<html[\s>]/i.test(inner)) return "document";
3104
- return inner === "" ? "pending" : "fragment";
3105
- }
3106
- __name(classifyFarmDocumentPrefix, "classifyFarmDocumentPrefix");
3107
- function ensureFarmDocumentHead(markup) {
3108
- if (/<head[\s>]/i.test(markup)) return markup;
3109
- return markup.replace(/<html([^>]*)>/i, (_match, attributes) => {
3110
- return `<html${attributes}><head></head>`;
3111
- });
3112
- }
3113
- __name(ensureFarmDocumentHead, "ensureFarmDocumentHead");
3114
- function ensureFarmDocumentRoot(markup) {
3115
- if (/\sid=["']root["']/i.test(markup)) return markup;
3116
- return markup.replace(
3117
- /<body\b([^>]*)>/i,
3118
- (_match, attributes) => `<body${attributes}><div id="root">`
3119
- ).replace(/<\/body>/i, () => "</div></body>");
3120
- }
3121
- __name(ensureFarmDocumentRoot, "ensureFarmDocumentRoot");
3122
- function hasFarmDocumentIcon(markup) {
3123
- return /<link\b[^>]*\brel=["']?(?:shortcut )?icon\b/i.test(markup);
3124
- }
3125
- __name(hasFarmDocumentIcon, "hasFarmDocumentIcon");
3126
- function removeFarmDocumentTitles(markup) {
3127
- return markup.replace(/<title\b[^>]*>[\s\S]*?<\/title>\s*/gi, "");
3128
- }
3129
- __name(removeFarmDocumentTitles, "removeFarmDocumentTitles");
3130
- function composeFarmFullDocument(documentHtml, assets) {
3131
- let html = ensureFarmDocumentHead(documentHtml);
3132
- if (assets.htmlAttributes) {
3133
- html = html.replace(/<html\b([^>]*)>/i, (_match, attrs) => {
3134
- let nextAttributes = attrs;
3135
- for (const name of assets.replaceHtmlAttributes ?? []) {
3136
- const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3137
- nextAttributes = nextAttributes.replace(
3138
- new RegExp("\\s+" + escapedName + `=(?:"[^"]*"|'[^']*'|[^\\s>]+)`, "gi"),
3139
- ""
3140
- );
3141
- }
3142
- return `<html${nextAttributes}${assets.htmlAttributes}>`;
3143
- });
3144
- }
3145
- html = ensureFarmDocumentRoot(html);
3146
- const headAssets = [
3147
- assets.fallbackIcon && !hasFarmDocumentIcon(html) ? '<link rel="icon" href="data:,">' : "",
3148
- assets.headAssets
3149
- ].filter(Boolean).join("\n ");
3150
- if (headAssets) {
3151
- html = html.replace(/<\/head>/i, () => ` ${headAssets}
3152
- </head>`);
3153
- }
3154
- if (assets.bodyFooter) {
3155
- html = html.replace(/<\/body>/i, () => ` ${assets.bodyFooter}
3156
- </body>`);
3157
- }
3158
- return /^\s*<!doctype/i.test(html) ? html : `<!DOCTYPE html>
3159
- ${html}`;
3160
- }
3161
- __name(composeFarmFullDocument, "composeFarmFullDocument");
3162
-
3163
3136
  // src/server/renderer.ts
3164
3137
  import { Readable, Writable } from "stream";
3165
3138
 
@@ -5028,7 +5001,7 @@ var _ServerRenderer = class _ServerRenderer {
5028
5001
  if (input.pageShouldHydrate && !input.layoutShouldHydrate) {
5029
5002
  element = this.wrapClientGraph(element);
5030
5003
  } else if (input.layoutShouldHydrate && !input.pageShouldHydrate && this.rendererRuntime.isolateServerPageGraph) {
5031
- element = this.rendererRuntime.isolateServerPageGraph(element);
5004
+ element = input.serverTree && this.rendererRuntime.renderServerTreePage ? await this.rendererRuntime.renderServerTreePage(element) : this.rendererRuntime.isolateServerPageGraph(element);
5032
5005
  }
5033
5006
  element = this.createPageBoundary(element, {
5034
5007
  pageShouldHydrate: input.pageShouldHydrate,
@@ -5045,7 +5018,9 @@ var _ServerRenderer = class _ServerRenderer {
5045
5018
  if (!LayoutComponent) continue;
5046
5019
  const slotProps = {};
5047
5020
  for (const slot of input.slots || []) {
5048
- if (slot.ownerPattern !== layout.pattern || !slot.module.default) continue;
5021
+ if ((slot.ownerDirectory ?? slot.ownerPattern) !== layout.pattern || !slot.module.default) {
5022
+ continue;
5023
+ }
5049
5024
  let slotElement = this.rendererRuntime.createElement(slot.module.default, slot.props);
5050
5025
  slotElement = this.wrapClientGraph(slotElement);
5051
5026
  slotProps[slot.name] = this.rendererRuntime.createElement(
@@ -5460,8 +5435,8 @@ var _ServerRenderer = class _ServerRenderer {
5460
5435
  route: route.pattern,
5461
5436
  params
5462
5437
  });
5463
- const loadingBoundaryEntry = this.routeManager.getMatchingLoading(pathname);
5464
- errorBoundaryEntry = this.routeManager.getMatchingError(pathname);
5438
+ const loadingBoundaryEntry = this.routeManager.getMatchingLoading(pathname, route);
5439
+ errorBoundaryEntry = this.routeManager.getMatchingError(pathname, route);
5465
5440
  middlewareMap = toMiddlewareMap(req.__FARM_MIDDLEWARE_DATA__);
5466
5441
  middlewareContext = toMiddlewareMap(req.__FARM_MIDDLEWARE_CONTEXT__);
5467
5442
  pluginExposedContext = getRequestContextSnapshot(req, {
@@ -5788,7 +5763,7 @@ var _ServerRenderer = class _ServerRenderer {
5788
5763
  if ((isClientComponent || shouldHydrate) && !shouldHydrateLayout) {
5789
5764
  pageElement = this.wrapClientGraph(pageElement);
5790
5765
  } else if (shouldHydrateLayout && !(isClientComponent || shouldHydrate) && this.rendererRuntime.isolateServerPageGraph) {
5791
- pageElement = this.rendererRuntime.isolateServerPageGraph(pageElement);
5766
+ pageElement = routeManifestEntry?.serverTree === true && this.rendererRuntime.renderServerTreePage ? await this.rendererRuntime.renderServerTreePage(pageElement) : this.rendererRuntime.isolateServerPageGraph(pageElement);
5792
5767
  }
5793
5768
  pageElement = this.createPageBoundary(pageElement, {
5794
5769
  pageShouldHydrate: isClientComponent || shouldHydrate,
@@ -5802,7 +5777,7 @@ var _ServerRenderer = class _ServerRenderer {
5802
5777
  const LayoutComponent = layoutModule.default;
5803
5778
  const slotProps = {};
5804
5779
  for (const slot of renderedRouteSlots) {
5805
- if (slot.ownerPattern !== layoutEntry.pattern) continue;
5780
+ if ((slot.ownerDirectory ?? slot.ownerPattern) !== layoutEntry.pattern) continue;
5806
5781
  let slotElement = this.rendererRuntime.createElement(
5807
5782
  slot.module.default,
5808
5783
  slot.props
@@ -6053,6 +6028,9 @@ var _ServerRenderer = class _ServerRenderer {
6053
6028
  })
6054
6029
  );
6055
6030
  }
6031
+ metadata = await mergeModuleViewport(metadata, layoutModule, {
6032
+ params: options.pageProps.params
6033
+ });
6056
6034
  }
6057
6035
  metadata = mergeMetadata(metadata, options.routeModule.metadata);
6058
6036
  if (!options.skipGeneratedRouteMetadata && typeof options.routeModule.generateMetadata === "function") {
@@ -6061,6 +6039,11 @@ var _ServerRenderer = class _ServerRenderer {
6061
6039
  await options.routeModule.generateMetadata(options.pageProps)
6062
6040
  );
6063
6041
  }
6042
+ metadata = await mergeModuleViewport(
6043
+ metadata,
6044
+ options.skipGeneratedRouteMetadata ? { viewport: options.routeModule.viewport } : options.routeModule,
6045
+ options.pageProps
6046
+ );
6064
6047
  if (!metadata.manifest) {
6065
6048
  const manifestMatch = this.routeManager.getMatchingMetadataRoute(
6066
6049
  options.pathname,
@@ -6278,7 +6261,20 @@ var _ServerRenderer = class _ServerRenderer {
6278
6261
  });
6279
6262
  return {
6280
6263
  pages,
6281
- defaults: createFarmDefaultLlmsTxt({ origin, pages, config, rootMetadata }),
6264
+ defaults: createFarmDefaultLlmsTxt({
6265
+ origin,
6266
+ pages,
6267
+ config,
6268
+ rootMetadata,
6269
+ mcp: this.config.agent?.aiCatalog === false ? [] : listFarmMCPLlmsTxtLinks(origin, {
6270
+ basePath: this.config.basePath,
6271
+ apiServerBasePath: resolveFarmAPIServerBasePath(
6272
+ normalizeFarmAPIConfig(
6273
+ this.config.api
6274
+ )
6275
+ )
6276
+ })
6277
+ }),
6282
6278
  ...options.full ? { markdown: this.createDevMarkdownReader(options.req) } : {}
6283
6279
  };
6284
6280
  }
@@ -6540,7 +6536,8 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
6540
6536
  title,
6541
6537
  tags: metaTags,
6542
6538
  hasFavicon,
6543
- hasExplicitTitle
6539
+ hasExplicitTitle,
6540
+ viewport: viewportTags
6544
6541
  } = renderMetadataHead(req.__FARM_METADATA__, {
6545
6542
  pathname: getFarmMetadataPathname(req),
6546
6543
  jsonLd: this.config.agent?.jsonLd
@@ -6566,6 +6563,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
6566
6563
  const effectiveRendererHead = hasExplicitTitle ? removeFarmDocumentTitles(rendererHead) : rendererHead;
6567
6564
  html = composeFarmFullDocument(documentHtml, {
6568
6565
  fallbackIcon: !hasFavicon,
6566
+ viewport: viewportTags,
6569
6567
  htmlAttributes: `${i18nSnapshot ? ` lang="${escapeHtmlAttribute2(i18nSnapshot.locale)}" dir="${escapeHtmlAttribute2(i18nSnapshot.direction)}"` : ""}${themeDocument.attributes}`,
6570
6568
  replaceHtmlAttributes: [
6571
6569
  ...i18nSnapshot ? ["lang", "dir"] : [],
@@ -6593,7 +6591,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
6593
6591
  <head>
6594
6592
  ${themeDocument.head}
6595
6593
  <meta charset="utf-8">
6596
- <meta name="viewport" content="width=device-width, initial-scale=1">
6594
+ ${viewportTags}
6597
6595
  <meta name="farm-deployment-id" content="${escapeHtmlAttribute2(deploymentId)}">
6598
6596
  ${hasFavicon ? "" : '<link rel="icon" href="data:,">'}
6599
6597
  ${documentTitleTag}${metaTags}${alternateTags}${rendererHead ? `
@@ -6778,7 +6776,8 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
6778
6776
  const {
6779
6777
  title,
6780
6778
  tags: metaTags,
6781
- hasFavicon
6779
+ hasFavicon,
6780
+ viewport: viewportTags
6782
6781
  } = renderMetadataHead(req.__FARM_METADATA__, {
6783
6782
  pathname: getFarmMetadataPathname(req),
6784
6783
  jsonLd: this.config.agent?.jsonLd
@@ -6827,7 +6826,7 @@ window.__FARM_I18N__ = ${getFarmI18nClientSnapshot() ? serializeInlineValue(getF
6827
6826
  <head>
6828
6827
  ${themeDocument.head}
6829
6828
  <meta charset="utf-8">
6830
- <meta name="viewport" content="width=device-width, initial-scale=1">
6829
+ ${viewportTags}
6831
6830
  <meta name="farm-deployment-id" content="${escapeHtmlAttribute2(deploymentId)}">
6832
6831
  ${hasFavicon ? "" : '<link rel="icon" href="data:,">'}
6833
6832
  <title>${title}</title>${metaTags}${i18nAlternateTags}
@@ -7202,12 +7201,14 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue(i18nSnapshot)};`
7202
7201
  getTheme()
7203
7202
  );
7204
7203
  const rendererHydrationScript = this.rendererRuntime.generateHydrationScript?.() || "";
7204
+ const viewportTags = renderViewportHead(alternates.metadata?.viewport);
7205
7205
  const fullDocument = extractFarmFullDocument(content);
7206
7206
  if (fullDocument) {
7207
7207
  return composeFarmFullDocument(
7208
7208
  metadataHead ? removeFarmDocumentTitles(fullDocument) : fullDocument,
7209
7209
  {
7210
7210
  fallbackIcon: !metadataHead,
7211
+ viewport: viewportTags,
7211
7212
  htmlAttributes: `${i18nSnapshot ? ` lang="${escapeHtmlAttribute2(i18nSnapshot.locale)}" dir="${escapeHtmlAttribute2(i18nSnapshot.direction)}"` : ""}${themeDocument.attributes}`,
7212
7213
  replaceHtmlAttributes: [
7213
7214
  ...i18nSnapshot ? ["lang", "dir"] : [],
@@ -7234,7 +7235,7 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue(i18nSnapshot)};`
7234
7235
  <head>
7235
7236
  ${themeDocument.head}
7236
7237
  <meta charset="utf-8">
7237
- <meta name="viewport" content="width=device-width, initial-scale=1">
7238
+ ${viewportTags}
7238
7239
  <meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">
7239
7240
  ${metadataHead ?? '<link rel="icon" href="data:,">\n <title>Farm.js App</title>'}${alternateLinks}
7240
7241
  ${fontHead}
@@ -7662,8 +7663,8 @@ __name(validateSchemaSteps, "validateSchemaSteps");
7662
7663
  var _FarmPluginOptionsError = class _FarmPluginOptionsError extends TypeError {
7663
7664
  constructor(issues) {
7664
7665
  const lines = issues.map((issue) => {
7665
- const path21 = formatIssuePath(issue.path);
7666
- return ` - ${path21 ? `${path21}: ` : ""}${issue.message}`;
7666
+ const path22 = formatIssuePath(issue.path);
7667
+ return ` - ${path22 ? `${path22}: ` : ""}${issue.message}`;
7667
7668
  });
7668
7669
  super(`Invalid plugin options:
7669
7670
  ${lines.join("\n")}`);
@@ -7673,9 +7674,9 @@ ${lines.join("\n")}`);
7673
7674
  };
7674
7675
  __name(_FarmPluginOptionsError, "FarmPluginOptionsError");
7675
7676
  var FarmPluginOptionsError = _FarmPluginOptionsError;
7676
- function formatIssuePath(path21) {
7677
- if (!path21?.length) return "";
7678
- return path21.map((segment) => {
7677
+ function formatIssuePath(path22) {
7678
+ if (!path22?.length) return "";
7679
+ return path22.map((segment) => {
7679
7680
  const key = typeof segment === "object" && segment !== null ? segment.key : segment;
7680
7681
  return typeof key === "symbol" ? key.toString() : String(key);
7681
7682
  }).join(".");
@@ -7911,23 +7912,23 @@ var _PluginManager = class _PluginManager {
7911
7912
  `Farm plugin "${plugin.name}" runtime.endpoints must contain endpoint objects`
7912
7913
  );
7913
7914
  }
7914
- const path21 = normalizeFarmPluginRuntimeEndpointPath(
7915
+ const path22 = normalizeFarmPluginRuntimeEndpointPath(
7915
7916
  endpoint.path,
7916
7917
  `Farm plugin "${plugin.name}" runtime endpoint`
7917
7918
  );
7918
7919
  if (typeof endpoint.handler !== "function") {
7919
7920
  throw new TypeError(
7920
- `Farm plugin "${plugin.name}" runtime endpoint ${path21} requires a handler`
7921
+ `Farm plugin "${plugin.name}" runtime endpoint ${path22} requires a handler`
7921
7922
  );
7922
7923
  }
7923
- const owner = owners.get(path21);
7924
+ const owner = owners.get(path22);
7924
7925
  if (owner) {
7925
7926
  throw new Error(
7926
- `Farm plugin runtime endpoint ${path21} from "${plugin.name}" conflicts with "${owner}"`
7927
+ `Farm plugin runtime endpoint ${path22} from "${plugin.name}" conflicts with "${owner}"`
7927
7928
  );
7928
7929
  }
7929
- owners.set(path21, plugin.name);
7930
- endpoints.push({ plugin, endpoint, path: path21 });
7930
+ owners.set(path22, plugin.name);
7931
+ endpoints.push({ plugin, endpoint, path: path22 });
7931
7932
  }
7932
7933
  }
7933
7934
  this.runtimeEndpoints = endpoints;
@@ -9360,7 +9361,7 @@ __name(isInside, "isInside");
9360
9361
 
9361
9362
  // src/vite.ts
9362
9363
  import * as fs11 from "fs";
9363
- import * as path20 from "path";
9364
+ import * as path21 from "path";
9364
9365
  import { pathToFileURL as pathToFileURL3 } from "url";
9365
9366
 
9366
9367
  // src/dev-static.ts
@@ -9810,6 +9811,87 @@ function mergeFarmProductionViteConfig(farmConfig, userConfig = {}) {
9810
9811
  }
9811
9812
  __name(mergeFarmProductionViteConfig, "mergeFarmProductionViteConfig");
9812
9813
 
9814
+ // src/docs/client-config.ts
9815
+ import { realpathSync } from "fs";
9816
+ import { createRequire as createRequire3 } from "module";
9817
+ import path20 from "path";
9818
+ var parseAst2;
9819
+ function propertyKeyName(property2) {
9820
+ if (property2.computed) return void 0;
9821
+ const key = property2.key;
9822
+ if (key.type === "Identifier") return key.name;
9823
+ if (key.type === "Literal" && typeof key.value === "string") return key.value;
9824
+ return void 0;
9825
+ }
9826
+ __name(propertyKeyName, "propertyKeyName");
9827
+ function redactFarmDocsClientConfig(code, filename) {
9828
+ parseAst2 ?? (parseAst2 = createRequire3(typeof __filename === "string" ? __filename : import.meta.url)(
9829
+ "rolldown/parseAst"
9830
+ ).parseAst);
9831
+ const extension = path20.extname(filename);
9832
+ const program = parseAst2(code, {
9833
+ lang: extension === ".tsx" || extension === ".jsx" ? "tsx" : "ts"
9834
+ });
9835
+ const edits = [];
9836
+ const visit = /* @__PURE__ */ __name((node) => {
9837
+ if (Array.isArray(node)) {
9838
+ for (const child of node) visit(child);
9839
+ return;
9840
+ }
9841
+ if (!node || typeof node !== "object") return;
9842
+ const current = node;
9843
+ if (current.type === "Property") {
9844
+ const name = propertyKeyName(current);
9845
+ const valueType = current.value?.type;
9846
+ const credential = name !== void 0 && (name.toLowerCase() === "headers" || isSecretDocsConfigKey(name) && valueType !== "ObjectExpression" && valueType !== "ArrayExpression");
9847
+ if (name && credential) {
9848
+ edits.push(
9849
+ current.shorthand || current.method || current.kind !== "init" ? { start: current.start, end: current.end, text: `${JSON.stringify(name)}: undefined` } : {
9850
+ start: current.value.start,
9851
+ end: current.value.end,
9852
+ text: "undefined"
9853
+ }
9854
+ );
9855
+ return;
9856
+ }
9857
+ }
9858
+ for (const [key, value] of Object.entries(current)) {
9859
+ if (key !== "start" && key !== "end" && value && typeof value === "object") visit(value);
9860
+ }
9861
+ }, "visit");
9862
+ visit(program);
9863
+ if (edits.length === 0) return null;
9864
+ let redacted = code;
9865
+ for (const edit of edits.sort((left, right) => right.start - left.start)) {
9866
+ redacted = redacted.slice(0, edit.start) + edit.text + redacted.slice(edit.end);
9867
+ }
9868
+ return redacted;
9869
+ }
9870
+ __name(redactFarmDocsClientConfig, "redactFarmDocsClientConfig");
9871
+ function isFarmDocsClientConfigModule(id, configModule) {
9872
+ if (!configModule) return false;
9873
+ const file = id.split("?")[0].replace(/\\/g, "/");
9874
+ if (file === configModule) return true;
9875
+ try {
9876
+ return file === realpathSync(configModule).replace(/\\/g, "/");
9877
+ } catch {
9878
+ return false;
9879
+ }
9880
+ }
9881
+ __name(isFarmDocsClientConfigModule, "isFarmDocsClientConfigModule");
9882
+ function farmDocsClientConfigPlugin(configModule) {
9883
+ return {
9884
+ name: "farm:docs-client-config",
9885
+ enforce: "pre",
9886
+ transform(code, id, options) {
9887
+ if (options?.ssr || !isFarmDocsClientConfigModule(id, configModule)) return null;
9888
+ const redacted = redactFarmDocsClientConfig(code, id.split("?")[0]);
9889
+ return redacted === null ? null : { code: redacted, map: null };
9890
+ }
9891
+ };
9892
+ }
9893
+ __name(farmDocsClientConfigPlugin, "farmDocsClientConfigPlugin");
9894
+
9813
9895
  // src/theme/vite.ts
9814
9896
  var FARM_DARK_VARIANT = '@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));';
9815
9897
  function createFarmThemeCssPlugin(input, basePath = "/") {
@@ -9929,7 +10011,7 @@ function loadFarmWorkflowsDevRuntime() {
9929
10011
  }
9930
10012
  __name(loadFarmWorkflowsDevRuntime, "loadFarmWorkflowsDevRuntime");
9931
10013
  function loadFarmDevtoolsSnapshotRuntime() {
9932
- return import("./devtools-RNXCTS4R.mjs");
10014
+ return import("./devtools-EE5RIBTH.mjs");
9933
10015
  }
9934
10016
  __name(loadFarmDevtoolsSnapshotRuntime, "loadFarmDevtoolsSnapshotRuntime");
9935
10017
  function loadFarmDevtoolsUIRuntime() {
@@ -10352,7 +10434,7 @@ function fileContainsProgrammaticPageRoute(file) {
10352
10434
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
10353
10435
  function rewriteEarlySsrRelativeImports(options) {
10354
10436
  const cleanId = options.id.split("?", 1)[0];
10355
- if (!path20.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
10437
+ if (!path21.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
10356
10438
  return null;
10357
10439
  }
10358
10440
  const replacements = [];
@@ -10372,7 +10454,7 @@ function rewriteEarlySsrRelativeImports(options) {
10372
10454
  const suffixIndex = source.value.search(/[?#]/);
10373
10455
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
10374
10456
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
10375
- const resolvedPath = path20.resolve(path20.dirname(cleanId), sourcePath);
10457
+ const resolvedPath = path21.resolve(path21.dirname(cleanId), sourcePath);
10376
10458
  replacements.push({
10377
10459
  start: source.start,
10378
10460
  end: source.end,
@@ -10540,6 +10622,11 @@ function farmPlugin(options = {}, initialPluginManager) {
10540
10622
  let refreshRouteDiscovery = null;
10541
10623
  let workflowHandler = null;
10542
10624
  let isBuild = false;
10625
+ const docsMCPServerDisposers = /* @__PURE__ */ new Set();
10626
+ const releaseDocsMCPServers = /* @__PURE__ */ __name(() => {
10627
+ for (const dispose of docsMCPServerDisposers) dispose();
10628
+ docsMCPServerDisposers.clear();
10629
+ }, "releaseDocsMCPServers");
10543
10630
  const logUpdate = /* @__PURE__ */ __name((tag, message) => {
10544
10631
  const pc = createCliColors();
10545
10632
  const log = [
@@ -10570,7 +10657,7 @@ function farmPlugin(options = {}, initialPluginManager) {
10570
10657
  },
10571
10658
  server: {
10572
10659
  fs: {
10573
- ...layerRoots.length ? { allow: [path20.resolve(options.root || process.cwd()), ...layerRoots] } : {},
10660
+ ...layerRoots.length ? { allow: [path21.resolve(options.root || process.cwd()), ...layerRoots] } : {},
10574
10661
  deny: getFarmDevFsDeny(userConfig.server?.fs?.deny, options)
10575
10662
  }
10576
10663
  }
@@ -10646,7 +10733,7 @@ function farmPlugin(options = {}, initialPluginManager) {
10646
10733
  });
10647
10734
  }
10648
10735
  const sourceRoots = getFarmSourceRoots(farmConfig);
10649
- server.watcher.add(sourceRoots.map((source) => path20.join(source.root, source.srcDir)));
10736
+ server.watcher.add(sourceRoots.map((source) => path21.join(source.root, source.srcDir)));
10650
10737
  if (farmConfig.i18n.enabled) {
10651
10738
  server.watcher.add(
10652
10739
  farmConfig.i18n.locales.map(
@@ -10661,7 +10748,7 @@ function farmPlugin(options = {}, initialPluginManager) {
10661
10748
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
10662
10749
  ], "getExtraRouteTypes");
10663
10750
  const appDirSlugs = sourceRoots.map(
10664
- (source) => path20.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
10751
+ (source) => path21.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
10665
10752
  );
10666
10753
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
10667
10754
  try {
@@ -10702,7 +10789,7 @@ function farmPlugin(options = {}, initialPluginManager) {
10702
10789
  }, "generateTypeArtifacts");
10703
10790
  await generateTypeArtifacts("startup");
10704
10791
  const srcDirSlugs = sourceRoots.map(
10705
- (source) => path20.join(source.root, source.srcDir).replace(/\\/g, "/")
10792
+ (source) => path21.join(source.root, source.srcDir).replace(/\\/g, "/")
10706
10793
  );
10707
10794
  const layerConfigFiles = new Set(
10708
10795
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -10841,7 +10928,7 @@ function farmPlugin(options = {}, initialPluginManager) {
10841
10928
  await apiRouteManager.discoverRoutes();
10842
10929
  let discoveredWorkflows = [];
10843
10930
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
10844
- (dir) => fs11.existsSync(path20.isAbsolute(dir) ? dir : path20.join(farmConfig.root, dir))
10931
+ (dir) => fs11.existsSync(path21.isAbsolute(dir) ? dir : path21.join(farmConfig.root, dir))
10845
10932
  );
10846
10933
  if (hasWorkflowDirectory) {
10847
10934
  const { createFarmWorkflowRequestHandler, discoverFarmWorkflows } = await loadFarmWorkflowsDevRuntime();
@@ -10919,6 +11006,7 @@ function farmPlugin(options = {}, initialPluginManager) {
10919
11006
  );
10920
11007
  return resolveFarmLayoutFonts(layoutModules);
10921
11008
  }, "resolveDocsLayoutFonts");
11009
+ releaseDocsMCPServers();
10922
11010
  const farmDocsHandler = farmDocsDevRuntime ? farmDocsDevRuntime.hasFarmDocsRuntimeAdapter(farmConfig.docs) ? await farmDocsDevRuntime.createFarmDocsAdapterHandler(farmConfig.docs, {
10923
11011
  root: farmConfig.root,
10924
11012
  srcDir: farmConfig.srcDir,
@@ -10938,7 +11026,15 @@ function farmPlugin(options = {}, initialPluginManager) {
10938
11026
  );
10939
11027
  }
10940
11028
  return loadFarmDevModule(server, resolved?.id ?? specifier);
10941
- }, "loadModule")
11029
+ }, "loadModule"),
11030
+ registerMCPServer: /* @__PURE__ */ __name((mcpServer) => {
11031
+ const dispose = registerFarmMCPServer(mcpServer);
11032
+ docsMCPServerDisposers.add(dispose);
11033
+ return () => {
11034
+ docsMCPServerDisposers.delete(dispose);
11035
+ dispose();
11036
+ };
11037
+ }, "registerMCPServer")
10942
11038
  }) : farmDocsDevRuntime.createFarmDocsHandler(farmConfig.docs, {
10943
11039
  root: farmConfig.root,
10944
11040
  srcDir: farmConfig.srcDir,
@@ -11263,6 +11359,23 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11263
11359
  );
11264
11360
  return;
11265
11361
  }
11362
+ if (options.agent?.aiCatalog !== false) {
11363
+ const aiCatalog = createFarmAiCatalogResponse(
11364
+ new Request(parsedRequestUrl, {
11365
+ method: requestMethod,
11366
+ headers: {
11367
+ "user-agent": String(req.headers["user-agent"] ?? ""),
11368
+ "if-none-match": String(req.headers["if-none-match"] ?? "")
11369
+ }
11370
+ }),
11371
+ { basePath: farmConfig.basePath, apiServerBasePath }
11372
+ );
11373
+ if (aiCatalog) {
11374
+ if (await runAppMiddlewareForContentRoute()) return;
11375
+ await sendWebResponse(res, aiCatalog);
11376
+ return;
11377
+ }
11378
+ }
11266
11379
  const docsHeaders = new Headers();
11267
11380
  for (const [key, value] of Object.entries(req.headers)) {
11268
11381
  if (value) {
@@ -11280,7 +11393,8 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11280
11393
  method: requestMethod,
11281
11394
  headers: docsHeaders
11282
11395
  });
11283
- const docsResponse = await farmDocsHandler(docsRequest.clone());
11396
+ const docsBodyInit = requestMethod === "GET" || requestMethod === "HEAD" ? {} : { body: createFarmNodeRequestBodyStream(req), duplex: "half" };
11397
+ const docsResponse = await farmDocsHandler(new Request(docsRequest, docsBodyInit));
11284
11398
  if (docsResponse) {
11285
11399
  if (await runAppMiddlewareForContentRoute()) return;
11286
11400
  await sendWebResponse(
@@ -11800,7 +11914,10 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11800
11914
  return;
11801
11915
  }
11802
11916
  const routeModule = await routeManager3.loadRouteModule(route.modulePath);
11803
- const loadingBoundary = routeManager3.getMatchingLoading(targetRequestUrl.pathname);
11917
+ const loadingBoundary = routeManager3.getMatchingLoading(
11918
+ targetRequestUrl.pathname,
11919
+ route
11920
+ );
11804
11921
  const loadingModule = loadingBoundary ? await routeManager3.loadRouteModule(loadingBoundary.modulePath) : null;
11805
11922
  const navigationManifest = routeManager3.generateClientManifest(server.config.root);
11806
11923
  const moduleMetadata = navigationManifest.routes.find((entry) => entry.pattern === route.pattern) ?? getClientModuleMetadata(route.modulePath, server.config.root);
@@ -11854,6 +11971,9 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11854
11971
  await layoutModule.generateMetadata({ params: routeProps.params })
11855
11972
  );
11856
11973
  }
11974
+ mergedMetadata = await mergeModuleViewport(mergedMetadata, layoutModule, {
11975
+ params: routeProps.params
11976
+ });
11857
11977
  }
11858
11978
  mergedMetadata = mergeMetadata(mergedMetadata, routeModule.metadata);
11859
11979
  if (typeof routeModule.generateMetadata === "function") {
@@ -11862,6 +11982,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11862
11982
  await routeModule.generateMetadata(routeProps)
11863
11983
  );
11864
11984
  }
11985
+ mergedMetadata = await mergeModuleViewport(mergedMetadata, routeModule, routeProps);
11865
11986
  mergedMetadata = addMetadataMarkdownAlternate(
11866
11987
  mergedMetadata,
11867
11988
  getFarmMarkdownAlternatePath(farmApp.getConfig().md, targetRequestUrl.pathname)
@@ -11893,6 +12014,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11893
12014
  return {
11894
12015
  name: slot.name,
11895
12016
  ownerPattern: slot.ownerPattern,
12017
+ ...slot.ownerDirectory ? { ownerDirectory: slot.ownerDirectory } : {},
11896
12018
  containerId: slot.containerId,
11897
12019
  interception: slot.interception,
11898
12020
  fallback: slot.fallback,
@@ -11945,13 +12067,15 @@ window.__FARM_MANIFEST__ = ${inlineValue({
11945
12067
  slots: routeSlots.map((slot) => ({
11946
12068
  name: slot.name,
11947
12069
  ownerPattern: slot.ownerPattern,
12070
+ ownerDirectory: slot.ownerDirectory,
11948
12071
  containerId: slot.containerId,
11949
12072
  module: slot.renderModule,
11950
12073
  props: slot.props
11951
12074
  })),
11952
12075
  pageShouldHydrate: shouldHydrate,
11953
12076
  layoutShouldHydrate: shouldHydrateLayout,
11954
- islandStrategy: hydrationIslandStrategy
12077
+ islandStrategy: hydrationIslandStrategy,
12078
+ serverTree: "serverTree" in moduleMetadata && moduleMetadata.serverTree === true
11955
12079
  })
11956
12080
  )
11957
12081
  );
@@ -12302,6 +12426,7 @@ export const getManifest = () => ({
12302
12426
  fullManifest.routes[route.pattern] = {
12303
12427
  modulePath: route.modulePath,
12304
12428
  pattern: route.pattern,
12429
+ ...route.directory ? { directory: route.directory } : {},
12305
12430
  segments: route.segments,
12306
12431
  search: route.search,
12307
12432
  isClientComponent: route.isClientComponent,
@@ -12314,9 +12439,11 @@ export const getManifest = () => ({
12314
12439
  };
12315
12440
  }
12316
12441
  for (const layout of manifest.layouts) {
12442
+ const groupScope = getRouteGroupScope(layout.pattern);
12317
12443
  fullManifest.layouts[layout.pattern] = {
12318
12444
  modulePath: layout.modulePath,
12319
12445
  pattern: layout.pattern,
12446
+ ...groupScope ? { urlPattern: stripRouteGroups(layout.pattern), groupScope } : {},
12320
12447
  shouldHydrate: layout.shouldHydrate,
12321
12448
  islandStrategy: layout.islandStrategy,
12322
12449
  preloads: [layout.modulePath],
@@ -12340,6 +12467,13 @@ export const manifest = getManifest();
12340
12467
  }
12341
12468
  },
12342
12469
  async transform(code, id, transformOptions) {
12470
+ if (!transformOptions?.ssr) {
12471
+ const docsConfigModule = getFarmDocsAdapterConfigModule(farmApp?.getConfig()?.docs);
12472
+ if (isFarmDocsClientConfigModule(id, docsConfigModule)) {
12473
+ const redacted = redactFarmDocsClientConfig(code, id.split("?")[0]);
12474
+ if (redacted !== null) return { code: redacted, map: null };
12475
+ }
12476
+ }
12343
12477
  if (!transformOptions?.ssr) {
12344
12478
  const currentConfig = farmApp?.getConfig() ?? options;
12345
12479
  if (currentConfig.experimental?.serverActions !== true || !serverFnTransformActive) {
@@ -12396,7 +12530,7 @@ export const manifest = getManifest();
12396
12530
  const root = currentConfig.root || server?.config.root || process.cwd();
12397
12531
  const cleanId = id.split("?", 1)[0];
12398
12532
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
12399
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path20.resolve(cleanId)) === true;
12533
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path21.resolve(cleanId)) === true;
12400
12534
  if (isReactRenderer(resolveFarmRenderer(currentConfig.renderer)) && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
12401
12535
  isolatedModuleReference = toViteModuleId(cleanId, root);
12402
12536
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -12476,6 +12610,7 @@ if (import.meta.hot) {
12476
12610
  });
12477
12611
  },
12478
12612
  async closeBundle() {
12613
+ if (!isBuild) releaseDocsMCPServers();
12479
12614
  if (!farmApp || !isBuild) return;
12480
12615
  try {
12481
12616
  const routeManager = farmApp.getRouteManager();
@@ -12487,8 +12622,8 @@ if (import.meta.hot) {
12487
12622
  }
12488
12623
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
12489
12624
  logger.info("Pre-rendering SSG pages...");
12490
- const outDir = path20.join(server?.config.root || process.cwd(), options.outDir || "dist");
12491
- const clientDir = path20.join(outDir, "client");
12625
+ const outDir = path21.join(server?.config.root || process.cwd(), options.outDir || "dist");
12626
+ const clientDir = path21.join(outDir, "client");
12492
12627
  for (const page of ssgPages) {
12493
12628
  try {
12494
12629
  const staticRequest = new Request(new URL(page.urlPath, "http://farm.static"));
@@ -12540,8 +12675,8 @@ if (import.meta.hot) {
12540
12675
  <script type="module" src="/assets/client.js"></script>
12541
12676
  </body>
12542
12677
  </html>`;
12543
- const outputPath = page.urlPath === "/" ? path20.join(clientDir, "index.html") : path20.join(clientDir, page.urlPath + ".html");
12544
- fs11.mkdirSync(path20.dirname(outputPath), { recursive: true });
12678
+ const outputPath = page.urlPath === "/" ? path21.join(clientDir, "index.html") : path21.join(clientDir, page.urlPath + ".html");
12679
+ fs11.mkdirSync(path21.dirname(outputPath), { recursive: true });
12545
12680
  fs11.writeFileSync(outputPath, fullHtml);
12546
12681
  const revalidateInfo = page.revalidate ? ` (revalidate: ${page.revalidate}s)` : "";
12547
12682
  logger.success(` \u2713 ${page.urlPath}${revalidateInfo}`);
@@ -12550,7 +12685,7 @@ if (import.meta.hot) {
12550
12685
  logger.error(` \u2717 ${page.urlPath}: ${error}`);
12551
12686
  }
12552
12687
  }
12553
- const manifestPath = path20.join(outDir, "__ssg_manifest.json");
12688
+ const manifestPath = path21.join(outDir, "__ssg_manifest.json");
12554
12689
  fs11.writeFileSync(
12555
12690
  manifestPath,
12556
12691
  JSON.stringify(
@@ -12594,9 +12729,9 @@ if (import.meta.hot) {
12594
12729
  server2.ws.send({ type: "full-reload", path: "*" });
12595
12730
  return [];
12596
12731
  }
12597
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path20.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
12732
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path21.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
12598
12733
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
12599
- logUpdate("PAGE", `updated ${path20.basename(file)}`);
12734
+ logUpdate("PAGE", `updated ${path21.basename(file)}`);
12600
12735
  for (const mod of modules) {
12601
12736
  server2.moduleGraph.invalidateModule(mod);
12602
12737
  }
@@ -12727,10 +12862,10 @@ function createPageDataMiddlewareRequest(req, target) {
12727
12862
  __name(createPageDataMiddlewareRequest, "createPageDataMiddlewareRequest");
12728
12863
  function resolveDevelopmentRoot(farmRoot, viteRoot) {
12729
12864
  if (!farmRoot) return viteRoot;
12730
- if (path20.resolve(farmRoot) === path20.resolve(viteRoot)) return farmRoot;
12865
+ if (path21.resolve(farmRoot) === path21.resolve(viteRoot)) return farmRoot;
12731
12866
  try {
12732
12867
  if (fs11.realpathSync(farmRoot) === fs11.realpathSync(viteRoot)) {
12733
- return path20.resolve(viteRoot);
12868
+ return path21.resolve(viteRoot);
12734
12869
  }
12735
12870
  } catch {
12736
12871
  }
@@ -13095,7 +13230,8 @@ function generateClientCode(integrationProviders = [], documentNavigationMatcher
13095
13230
  import { hydrateRoot, createRoot } from 'react-dom/client'` : appSetupPath ? `import React, { hydrateRoot, createRoot, configureApp as __farmConfigureApp } from ${JSON.stringify(renderer.client)}
13096
13231
  import __farmAppSetup from ${JSON.stringify(toViteModuleId(appSetupPath, root))}
13097
13232
  __farmConfigureApp(__farmAppSetup)` : `import React, { hydrateRoot, createRoot } from ${JSON.stringify(renderer.client)}`;
13098
- const isolatedHydrationImport = isolatedHydrationEnabled ? `import { createFarmIsolatedHydrationRuntime, createFarmServerPageBoundary, wrapFarmIsolatedClientGraph } from '@farm.js/core/internal/isolated-boundary'` : "";
13233
+ const isolatedHydrationImport = isolatedHydrationEnabled ? `import { createFarmIsolatedHydrationRuntime, createFarmServerPageBoundary, wrapFarmIsolatedClientGraph } from '@farm.js/core/internal/isolated-boundary'
13234
+ import { createFarmServerTreeElement } from '@farm.js/core/internal/server-tree'` : "";
13099
13235
  const docsAdapterImportBlock = generateFarmDocsAdapterClientRuntime(
13100
13236
  docsAdapterReact,
13101
13237
  docsConfigModule
@@ -13117,7 +13253,21 @@ function disposeFarmIsolatedClientBoundaries(scope) {
13117
13253
 
13118
13254
  async function hydrateFarmIsolatedClientBoundaries(scope = document, signal) {
13119
13255
  await farmIsolatedHydrationRuntime.hydrate(scope, signal);
13120
- }` : "";
13256
+ }
13257
+
13258
+ // A server-tree page (an async page below a hydrating layout) rebuilds in the layout's root.
13259
+ async function createFarmServerTreePageElement(source, pathname) {
13260
+ try {
13261
+ return await createFarmServerTreeElement(React, source, {
13262
+ load: (reference) => import(/* @vite-ignore */ reference),
13263
+ ServerHtml: FarmServerPage,
13264
+ key: pathname,
13265
+ });
13266
+ } catch (error) {
13267
+ console.warn('[Farm.js] Could not rebuild the server tree of ' + pathname + '; its server HTML was kept.', error);
13268
+ return null;
13269
+ }
13270
+ }` : `async function createFarmServerTreePageElement() { return null; }`;
13121
13271
  return `
13122
13272
  ${rendererClientImports}
13123
13273
  ${isolatedHydrationImport}
@@ -13258,14 +13408,29 @@ function findLayouts(pathname) {
13258
13408
  const manifest = getManifest();
13259
13409
  const layouts = Object.values(manifest.layouts);
13260
13410
  const matchingLayouts = [];
13411
+ let directory;
13261
13412
 
13262
13413
  for (const layout of layouts) {
13263
- if (layout.pattern === '/' || isFarmRouteActive(layout.pattern, pathname, { exact: false })) {
13264
- matchingLayouts.push(layout);
13414
+ // Route groups add no URL segment: match the layout's URL, then keep a
13415
+ // grouped layout to the pages inside its group directory.
13416
+ const urlPattern = layout.urlPattern || layout.pattern;
13417
+ if (urlPattern !== '/' && !isFarmRouteActive(urlPattern, pathname, { exact: false })) continue;
13418
+ if (layout.groupScope) {
13419
+ if (directory === undefined) {
13420
+ const route = findRoute(pathname)?.route;
13421
+ directory = route ? route.directory || route.pattern : null;
13422
+ }
13423
+ if (
13424
+ typeof directory !== 'string' ||
13425
+ (directory !== layout.groupScope && !directory.startsWith(layout.groupScope + '/'))
13426
+ ) continue;
13265
13427
  }
13428
+ matchingLayouts.push(layout);
13266
13429
  }
13267
13430
 
13268
- return matchingLayouts.sort((a, b) => a.pattern.length - b.pattern.length);
13431
+ return matchingLayouts.sort(
13432
+ (a, b) => a.pattern.split('/').filter(Boolean).length - b.pattern.split('/').filter(Boolean).length,
13433
+ );
13269
13434
  }
13270
13435
 
13271
13436
  // ====== SPA ROUTER ======
@@ -14047,14 +14212,23 @@ async function tryHydrateImportedPage(
14047
14212
  } else if (layoutShouldHydrate) {
14048
14213
  currentPageProps = existingProps || { params };
14049
14214
  const serverPage = document.getElementById('__farm_page__');
14050
- pageElement = createLayoutPageBoundary(
14051
- false,
14052
- islandStrategy,
14053
- null,
14054
- typeof hydrationOptions.serverHtml === 'string'
14055
- ? hydrationOptions.serverHtml
14056
- : serverPage ? serverPage.innerHTML : '',
14057
- );
14215
+ const pageSource = typeof hydrationOptions.serverHtml === 'string'
14216
+ ? hydrationOptions.serverHtml
14217
+ : serverPage;
14218
+ const serverTree = pageSource
14219
+ ? await createFarmServerTreePageElement(pageSource, window.location.pathname)
14220
+ : null;
14221
+ if (signal?.aborted || !container?.isConnected) return false;
14222
+ pageElement = serverTree
14223
+ ? createLayoutPageBoundary(false, islandStrategy, serverTree)
14224
+ : createLayoutPageBoundary(
14225
+ false,
14226
+ islandStrategy,
14227
+ null,
14228
+ typeof hydrationOptions.serverHtml === 'string'
14229
+ ? hydrationOptions.serverHtml
14230
+ : serverPage ? serverPage.innerHTML : '',
14231
+ );
14058
14232
  }
14059
14233
  if (signal?.aborted || !container?.isConnected || !pageElement) return false;
14060
14234
 
@@ -14240,6 +14414,8 @@ async function renderPage(pageData) {
14240
14414
  loadingModulePath: pageData.loadingModulePath,
14241
14415
  };
14242
14416
  const params = pageData.props?.params || {};
14417
+ // Page data carries middleware data as JSON, the way a full load embeds it.
14418
+ const pageProps = pageData.props ? normalizeServerProps(pageData.props) : pageData.props;
14243
14419
  const nextLayoutPatterns = Array.isArray(pageData.fragment?.layoutPatterns)
14244
14420
  ? pageData.fragment.layoutPatterns
14245
14421
  : [];
@@ -14256,6 +14432,20 @@ async function renderPage(pageData) {
14256
14432
  let fragmentHtml = pageData.fragment?.html;
14257
14433
  let layoutPatterns = nextLayoutPatterns;
14258
14434
 
14435
+ // The fragment leaves out the layouts both routes share. When React owns the
14436
+ // current layouts and will not keep rendering them, the swap below replaces the
14437
+ // whole container, so a fragment without its outer layouts would drop them.
14438
+ // Load the complete route for that swap instead.
14439
+ if (
14440
+ typeof fragmentHtml === 'string' &&
14441
+ activeLayoutShouldHydrate &&
14442
+ !(route.layoutShouldHydrate && (appRoot || reactRoot)) &&
14443
+ nextLayoutPatterns.length > 0 &&
14444
+ !findLayoutBoundary(parseNavigationFragment(fragmentHtml), nextLayoutPatterns[0])
14445
+ ) {
14446
+ fragmentHtml = undefined;
14447
+ }
14448
+
14259
14449
  if (typeof fragmentHtml !== 'string') {
14260
14450
  const deploymentId = window.__FARM_DEPLOYMENT_ID__;
14261
14451
  const response = await fetch(path, {
@@ -14296,7 +14486,7 @@ async function renderPage(pageData) {
14296
14486
  params,
14297
14487
  layouts,
14298
14488
  false,
14299
- pageData.props,
14489
+ pageProps,
14300
14490
  null,
14301
14491
  {
14302
14492
  pageShouldHydrate,
@@ -14342,7 +14532,7 @@ async function renderPage(pageData) {
14342
14532
  params,
14343
14533
  layouts,
14344
14534
  true,
14345
- pageData.props,
14535
+ pageProps,
14346
14536
  hydrationController.signal,
14347
14537
  {
14348
14538
  pageShouldHydrate,
@@ -14456,17 +14646,20 @@ async function hydrate() {
14456
14646
  return
14457
14647
  }
14458
14648
 
14459
- // Get props - either from server-injected props or by matching the current URL
14460
- if (!pageProps || !pageProps.params || Object.keys(pageProps.params).length === 0) {
14461
- // Extract params from URL using manifest route matching (fallback)
14649
+ // Use the server-injected props. A document that carries no params (a route
14650
+ // without any, or generated HTML) takes them from the current URL, keeping
14651
+ // what the server rendered with, such as middleware data.
14652
+ if (!pageProps.params || Object.keys(pageProps.params).length === 0) {
14462
14653
  const pathname = window.location.pathname;
14463
14654
  const foundRoute = findRoute(pathname);
14464
- pageProps = normalizeServerProps({
14465
- params: foundRoute?.params || {},
14466
- search: getCurrentSearchParams(),
14467
- searchParams: getCurrentSearchParams(),
14655
+ const search = getCurrentSearchParams();
14656
+ pageProps = {
14657
+ search,
14658
+ searchParams: search,
14468
14659
  path: pathname,
14469
- });
14660
+ ...pageProps,
14661
+ params: foundRoute?.params || {},
14662
+ };
14470
14663
  }
14471
14664
  currentPageProps = pageProps;
14472
14665
 
@@ -14659,7 +14852,7 @@ function generateClientManifest(bundle) {
14659
14852
  __name(generateClientManifest, "generateClientManifest");
14660
14853
  async function defineConfig(config = {}) {
14661
14854
  const tailwindVitePlugin = await loadTailwindVitePlugin();
14662
- const appRoot = path20.resolve(config.root || process.cwd());
14855
+ const appRoot = path21.resolve(config.root || process.cwd());
14663
14856
  if (config.extends?.length) {
14664
14857
  const { config: layeredConfig } = await import("./layers-BRQF5ETU.mjs").then(
14665
14858
  ({ resolveFarmLayers }) => resolveFarmLayers(config, {
@@ -14882,10 +15075,10 @@ export {
14882
15075
  resolveFarmIsolatedClientHydrationMode,
14883
15076
  getClientModuleMetadata,
14884
15077
  getClientModuleHydrationPlan,
15078
+ usesFarmServerTree,
14885
15079
  createMarkdownPageHydrationPlanner,
14886
15080
  enforceFarmIsolatedHydrationRouteBudget,
14887
15081
  RouteManager,
14888
- HOISTED_HEAD_ELEMENT,
14889
15082
  resolveFarmNotFoundComponentPath,
14890
15083
  farmFontImportsPlugin,
14891
15084
  mergeFarmFontCss,
@@ -14911,6 +15104,7 @@ export {
14911
15104
  createFarmSourceAlias,
14912
15105
  mergeFarmViteConfig,
14913
15106
  mergeFarmProductionViteConfig,
15107
+ farmDocsClientConfigPlugin,
14914
15108
  createFarmThemeCssPlugin,
14915
15109
  farmI18nClientBridgePlugin,
14916
15110
  farmServerOnlyEntriesPlugin,