@farm.js/core 0.1.0-beta.95 → 0.1.0-beta.97

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 (317) hide show
  1. package/dist/after.cjs +1 -1
  2. package/dist/after.mjs +1 -1
  3. package/dist/agent-runtime.d.mts +3 -2
  4. package/dist/agent-runtime.d.ts +3 -2
  5. package/dist/api/route-manager.cjs +43 -4
  6. package/dist/api/route-manager.d.mts +4 -3
  7. package/dist/api/route-manager.d.ts +4 -3
  8. package/dist/api/route-manager.mjs +7 -7
  9. package/dist/api/runtime.cjs +43 -4
  10. package/dist/api/runtime.d.mts +1 -1
  11. package/dist/api/runtime.d.ts +1 -1
  12. package/dist/api/runtime.mjs +5 -5
  13. package/dist/api.cjs +352 -109
  14. package/dist/api.d.mts +7 -6
  15. package/dist/api.d.ts +7 -6
  16. package/dist/api.mjs +19 -12
  17. package/dist/{app-CIIEvA4r.d.ts → app-CIOx3LvY.d.ts} +4 -4
  18. package/dist/{app-O4AEC1OH.d.mts → app-DBd6437H.d.mts} +4 -4
  19. package/dist/app-markdown.d.mts +4 -3
  20. package/dist/app-markdown.d.ts +4 -3
  21. package/dist/cache.cjs +42 -4
  22. package/dist/cache.d.mts +68 -1
  23. package/dist/cache.d.ts +68 -1
  24. package/dist/cache.mjs +3 -3
  25. package/dist/{chunk-AXVJCMVF.mjs → chunk-2HDOV47R.mjs} +3 -3
  26. package/dist/chunk-2HDOV47R.mjs.map +1 -0
  27. package/dist/{chunk-RBRLLZL5.mjs → chunk-34IAPZBG.mjs} +16 -3
  28. package/dist/chunk-34IAPZBG.mjs.map +1 -0
  29. package/dist/{chunk-VV24CC42.mjs → chunk-35NPLKQJ.mjs} +2 -2
  30. package/dist/{chunk-D7QH7MDU.mjs → chunk-3TWQERDE.mjs} +5 -4
  31. package/dist/chunk-3TWQERDE.mjs.map +1 -0
  32. package/dist/{chunk-RWYRFCLG.mjs → chunk-4X57GXQA.mjs} +2 -2
  33. package/dist/{chunk-KOTSX5JH.mjs → chunk-52BR7LTX.mjs} +30 -21
  34. package/dist/chunk-52BR7LTX.mjs.map +1 -0
  35. package/dist/{chunk-SALMKQXH.mjs → chunk-6EJHNHH4.mjs} +80 -27
  36. package/dist/chunk-6EJHNHH4.mjs.map +1 -0
  37. package/dist/{chunk-ZFNK77WN.mjs → chunk-6JNGOC37.mjs} +2 -2
  38. package/dist/{after.cjs.map → chunk-6JNGOC37.mjs.map} +1 -1
  39. package/dist/{chunk-MOW47IF5.mjs → chunk-6UYVU46O.mjs} +2 -2
  40. package/dist/{chunk-7MABZJIM.mjs → chunk-7PYVLJ4J.mjs} +1 -1
  41. package/dist/chunk-7PYVLJ4J.mjs.map +1 -0
  42. package/dist/{chunk-FLHLPB57.mjs → chunk-D7F7YZ7L.mjs} +93 -67
  43. package/dist/chunk-D7F7YZ7L.mjs.map +1 -0
  44. package/dist/chunk-DU3PKDVQ.mjs +35 -0
  45. package/dist/chunk-DU3PKDVQ.mjs.map +1 -0
  46. package/dist/{chunk-SCFX4UTD.mjs → chunk-EHTUKVSW.mjs} +1 -1
  47. package/dist/chunk-EHTUKVSW.mjs.map +1 -0
  48. package/dist/{chunk-KWCNQUH5.mjs → chunk-EPDIF432.mjs} +526 -50
  49. package/dist/chunk-EPDIF432.mjs.map +1 -0
  50. package/dist/{chunk-A3636IHN.mjs → chunk-FP5Q67FO.mjs} +167 -96
  51. package/dist/chunk-FP5Q67FO.mjs.map +1 -0
  52. package/dist/{chunk-HHZAOTQD.mjs → chunk-GJ7W6LNK.mjs} +7 -6
  53. package/dist/chunk-GJ7W6LNK.mjs.map +1 -0
  54. package/dist/{chunk-RLGUZ3HS.mjs → chunk-I3OOUWO5.mjs} +3 -3
  55. package/dist/{chunk-75CGAL6E.mjs → chunk-IZBX2TEU.mjs} +217 -105
  56. package/dist/chunk-IZBX2TEU.mjs.map +1 -0
  57. package/dist/{chunk-22VG4DFJ.mjs → chunk-J3MPQ4MQ.mjs} +2 -2
  58. package/dist/{chunk-22VG4DFJ.mjs.map → chunk-J3MPQ4MQ.mjs.map} +1 -1
  59. package/dist/{chunk-2LS3KKE7.mjs → chunk-JV7JUD7Q.mjs} +4 -4
  60. package/dist/{chunk-Q3OX763A.mjs → chunk-LXDASSTE.mjs} +2 -2
  61. package/dist/{chunk-ZRBCBOEX.mjs → chunk-N2FY2QZ7.mjs} +28 -3
  62. package/dist/chunk-N2FY2QZ7.mjs.map +1 -0
  63. package/dist/{chunk-MRVJCLYQ.mjs → chunk-PSQ7N4XP.mjs} +4 -2
  64. package/dist/chunk-PSQ7N4XP.mjs.map +1 -0
  65. package/dist/{chunk-HVG3HLQZ.mjs → chunk-Q7WGOOAI.mjs} +3 -3
  66. package/dist/{chunk-WTYAPO5I.mjs → chunk-RCNWMEBT.mjs} +3 -2
  67. package/dist/{chunk-WTYAPO5I.mjs.map → chunk-RCNWMEBT.mjs.map} +1 -1
  68. package/dist/{chunk-3INDBMUU.mjs → chunk-TGDIACZT.mjs} +2 -2
  69. package/dist/{chunk-WB75GIX2.mjs → chunk-TQTB33JS.mjs} +14 -3
  70. package/dist/chunk-TQTB33JS.mjs.map +1 -0
  71. package/dist/{chunk-MH27UH72.mjs → chunk-TT3E2JOF.mjs} +3 -3
  72. package/dist/{chunk-UWRGX3J3.mjs → chunk-UMUWR5XA.mjs} +2 -2
  73. package/dist/{chunk-XTLLHCWU.mjs → chunk-V4VRLVLW.mjs} +52 -31
  74. package/dist/chunk-V4VRLVLW.mjs.map +1 -0
  75. package/dist/{chunk-EXCGBERG.mjs → chunk-WD2EBM3I.mjs} +79 -17
  76. package/dist/chunk-WD2EBM3I.mjs.map +1 -0
  77. package/dist/{chunk-DLBUAJTK.mjs → chunk-WMJGA32P.mjs} +74 -5
  78. package/dist/chunk-WMJGA32P.mjs.map +1 -0
  79. package/dist/{chunk-TKQCJMY7.mjs → chunk-X4SFHKFH.mjs} +7 -4
  80. package/dist/{chunk-TKQCJMY7.mjs.map → chunk-X4SFHKFH.mjs.map} +1 -1
  81. package/dist/{chunk-Q7GPJZCO.mjs → chunk-YIBV77KZ.mjs} +26 -7
  82. package/dist/chunk-YIBV77KZ.mjs.map +1 -0
  83. package/dist/client/lifecycle.mjs +2 -2
  84. package/dist/{client-mcMC334J.d.mts → client-DWoLZ3QU.d.mts} +52 -5
  85. package/dist/{client-d5ONQ-Pd.d.ts → client-DuQuQC1h.d.ts} +52 -5
  86. package/dist/client-cache-BMxuFqwH.d.ts +18 -0
  87. package/dist/client-cache-CCK-fCe0.d.mts +18 -0
  88. package/dist/{client-plugins-BvClItiL.d.mts → client-plugins-B6-07YmP.d.mts} +52 -99
  89. package/dist/{client-plugins-B9Sq-iMg.d.ts → client-plugins-By6MVUX-.d.ts} +52 -99
  90. package/dist/client-plugins.cjs +1 -1
  91. package/dist/client-plugins.d.mts +3 -2
  92. package/dist/client-plugins.d.ts +3 -2
  93. package/dist/client-plugins.mjs +2 -2
  94. package/dist/client.cjs +1046 -211
  95. package/dist/client.d.mts +136 -18
  96. package/dist/client.d.ts +136 -18
  97. package/dist/client.mjs +32 -15
  98. package/dist/config.d.mts +3 -2
  99. package/dist/config.d.ts +3 -2
  100. package/dist/{devtools-S52RRRMN.mjs → devtools-XWZX6CCL.mjs} +5 -5
  101. package/dist/{devtools-client-3XRTBND5.mjs → devtools-client-Z7QQA3Q2.mjs} +56 -17
  102. package/dist/devtools-client-Z7QQA3Q2.mjs.map +1 -0
  103. package/dist/{devtools-ui-NJKFORTG.mjs → devtools-ui-2HG5M4EL.mjs} +3 -1
  104. package/dist/devtools-ui-2HG5M4EL.mjs.map +1 -0
  105. package/dist/docs.cjs +24 -5
  106. package/dist/docs.mjs +5 -5
  107. package/dist/i18n/server.cjs +13 -2
  108. package/dist/i18n/server.d.mts +2 -2
  109. package/dist/i18n/server.d.ts +2 -2
  110. package/dist/i18n/server.mjs +1 -1
  111. package/dist/index.cjs +1928 -894
  112. package/dist/index.d.mts +139 -21
  113. package/dist/index.d.ts +139 -21
  114. package/dist/index.mjs +57 -34
  115. package/dist/index.mjs.map +1 -1
  116. package/dist/integration-api-BT024nuJ.d.mts +97 -0
  117. package/dist/integration-api-BT024nuJ.d.ts +97 -0
  118. package/dist/integrations.d.mts +3 -2
  119. package/dist/integrations.d.ts +3 -2
  120. package/dist/internal/build-runtime.cjs +764 -547
  121. package/dist/internal/build-runtime.d.mts +5 -4
  122. package/dist/internal/build-runtime.d.ts +5 -4
  123. package/dist/internal/build-runtime.mjs +16 -16
  124. package/dist/internal/client-runtime.cjs +1 -1
  125. package/dist/internal/client-runtime.mjs +2 -2
  126. package/dist/internal/config-runtime.cjs +4 -1
  127. package/dist/internal/config-runtime.d.mts +4 -3
  128. package/dist/internal/config-runtime.d.ts +4 -3
  129. package/dist/internal/config-runtime.mjs +4 -4
  130. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  131. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  132. package/dist/internal/production-runtime.cjs +29 -3
  133. package/dist/internal/production-runtime.d.mts +8 -7
  134. package/dist/internal/production-runtime.d.ts +8 -7
  135. package/dist/internal/production-runtime.mjs +5 -5
  136. package/dist/{metadata-route-yV4U6X8h.d.ts → metadata-route-8_V3UonT.d.ts} +1 -1
  137. package/dist/{metadata-route-p4K1l92V.d.mts → metadata-route-CWP_HjGU.d.mts} +1 -1
  138. package/dist/middleware.cjs +28 -2
  139. package/dist/middleware.d.mts +5 -4
  140. package/dist/middleware.d.ts +5 -4
  141. package/dist/middleware.mjs +4 -4
  142. package/dist/navigation.cjs +3 -1
  143. package/dist/navigation.mjs +3 -3
  144. package/dist/observability.cjs +27 -2
  145. package/dist/observability.mjs +1 -1
  146. package/dist/plugin.cjs +528 -349
  147. package/dist/plugin.d.mts +3 -2
  148. package/dist/plugin.d.ts +3 -2
  149. package/dist/plugin.mjs +13 -13
  150. package/dist/{production-runtime-IkB0Qj4i.d.mts → production-runtime-BGRH1dKG.d.mts} +1 -1
  151. package/dist/{production-runtime-0JTch4_d.d.ts → production-runtime-CdmzsDax.d.ts} +1 -1
  152. package/dist/query/client.cjs +68 -29
  153. package/dist/query/client.mjs +69 -30
  154. package/dist/query/client.mjs.map +1 -1
  155. package/dist/{render-plan-Dc8CjNI7.d.ts → render-plan-0GeHiGVZ.d.ts} +1 -1
  156. package/dist/{render-plan-CU31j-Jk.d.mts → render-plan-DLxJYAA5.d.mts} +1 -1
  157. package/dist/renderer-client.cjs +169 -26
  158. package/dist/renderer-client.d.mts +7 -6
  159. package/dist/renderer-client.d.ts +7 -6
  160. package/dist/renderer-client.mjs +16 -19
  161. package/dist/renderer-client.mjs.map +1 -1
  162. package/dist/{request-BXa1KY8i.d.mts → request-BCNXSXLh.d.mts} +1 -1
  163. package/dist/{request-CUUBujZt.d.ts → request-BstWbZ6O.d.ts} +1 -1
  164. package/dist/request.d.mts +4 -3
  165. package/dist/request.d.ts +4 -3
  166. package/dist/{route-Y8lfz1wF.d.ts → route-4pd-EVtw.d.ts} +45 -50
  167. package/dist/{route-Cq3aObmj.d.mts → route-CvEr4Uc9.d.mts} +45 -50
  168. package/dist/routes.cjs +27 -2
  169. package/dist/routes.d.mts +3 -2
  170. package/dist/routes.d.ts +3 -2
  171. package/dist/routes.mjs +4 -4
  172. package/dist/{runtime-j1S3sDTh.d.ts → runtime-BgDQzBiu.d.ts} +1 -0
  173. package/dist/{runtime-DDwvDtS4.d.mts → runtime-CV2UCV-5.d.mts} +1 -0
  174. package/dist/server-action-security.mjs +2 -2
  175. package/dist/server-fn-client.cjs +102 -26
  176. package/dist/server-fn-client.d.mts +6 -0
  177. package/dist/server-fn-client.d.ts +6 -0
  178. package/dist/server-fn-client.mjs +2 -1
  179. package/dist/server-fn.cjs +42 -4
  180. package/dist/server-fn.mjs +5 -5
  181. package/dist/server-plugins.d.mts +4 -3
  182. package/dist/server-plugins.d.ts +4 -3
  183. package/dist/server-query-client.cjs +195 -34
  184. package/dist/server-query-client.d.mts +3 -3
  185. package/dist/server-query-client.d.ts +3 -3
  186. package/dist/server-query-client.mjs +7 -7
  187. package/dist/{server-query-runtime-3zAj77yv.d.ts → server-query-runtime-DXRNhX_3.d.ts} +2 -0
  188. package/dist/{server-query-runtime-B50KAcj5.d.mts → server-query-runtime-aP52iuL5.d.mts} +2 -0
  189. package/dist/server-query.cjs +44 -5
  190. package/dist/server-query.d.mts +4 -0
  191. package/dist/server-query.d.ts +4 -0
  192. package/dist/server-query.mjs +7 -7
  193. package/dist/server.cjs +553 -370
  194. package/dist/server.d.mts +11 -10
  195. package/dist/server.d.ts +11 -10
  196. package/dist/server.mjs +17 -17
  197. package/dist/{spa-router-CyLkwst6.d.mts → spa-router-BeyAVSc6.d.mts} +1 -1
  198. package/dist/{spa-router-BkqGXaV_.d.ts → spa-router-COgu4txb.d.ts} +1 -1
  199. package/dist/testing.cjs +27 -2
  200. package/dist/testing.d.mts +3 -2
  201. package/dist/testing.d.ts +3 -2
  202. package/dist/testing.mjs +9 -9
  203. package/dist/{utils-NKR6SoNv.d.mts → utils-DL2VwDQl.d.mts} +1 -1
  204. package/dist/{utils-B2OHrb9F.d.ts → utils-DkU2c_1B.d.ts} +1 -1
  205. package/dist/version.cjs +1 -1
  206. package/dist/version.mjs +1 -1
  207. package/dist/vite.cjs +536 -353
  208. package/dist/vite.d.mts +3 -2
  209. package/dist/vite.d.ts +3 -2
  210. package/dist/vite.mjs +17 -13
  211. package/package.json +17 -17
  212. package/types/client.d.ts +115 -10
  213. package/dist/agent-runtime.cjs.map +0 -1
  214. package/dist/api/route-manager.cjs.map +0 -1
  215. package/dist/api/runtime.cjs.map +0 -1
  216. package/dist/api.cjs.map +0 -1
  217. package/dist/app-markdown.cjs.map +0 -1
  218. package/dist/cache.cjs.map +0 -1
  219. package/dist/chunk-75CGAL6E.mjs.map +0 -1
  220. package/dist/chunk-7MABZJIM.mjs.map +0 -1
  221. package/dist/chunk-A3636IHN.mjs.map +0 -1
  222. package/dist/chunk-AXVJCMVF.mjs.map +0 -1
  223. package/dist/chunk-D7QH7MDU.mjs.map +0 -1
  224. package/dist/chunk-DLBUAJTK.mjs.map +0 -1
  225. package/dist/chunk-EXCGBERG.mjs.map +0 -1
  226. package/dist/chunk-FLHLPB57.mjs.map +0 -1
  227. package/dist/chunk-HHZAOTQD.mjs.map +0 -1
  228. package/dist/chunk-KOTSX5JH.mjs.map +0 -1
  229. package/dist/chunk-KWCNQUH5.mjs.map +0 -1
  230. package/dist/chunk-MRVJCLYQ.mjs.map +0 -1
  231. package/dist/chunk-Q7GPJZCO.mjs.map +0 -1
  232. package/dist/chunk-RBRLLZL5.mjs.map +0 -1
  233. package/dist/chunk-SALMKQXH.mjs.map +0 -1
  234. package/dist/chunk-SCFX4UTD.mjs.map +0 -1
  235. package/dist/chunk-WB75GIX2.mjs.map +0 -1
  236. package/dist/chunk-XTLLHCWU.mjs.map +0 -1
  237. package/dist/chunk-ZFNK77WN.mjs.map +0 -1
  238. package/dist/chunk-ZRBCBOEX.mjs.map +0 -1
  239. package/dist/client/lifecycle.cjs.map +0 -1
  240. package/dist/client-cache-CopR_MaI.d.mts +0 -6
  241. package/dist/client-cache-Djy_TlE8.d.ts +0 -6
  242. package/dist/client-plugins.cjs.map +0 -1
  243. package/dist/client.cjs.map +0 -1
  244. package/dist/config.cjs.map +0 -1
  245. package/dist/cron.cjs.map +0 -1
  246. package/dist/deferred.cjs.map +0 -1
  247. package/dist/deployment.cjs.map +0 -1
  248. package/dist/devtools-client-3XRTBND5.mjs.map +0 -1
  249. package/dist/devtools-ui-NJKFORTG.mjs.map +0 -1
  250. package/dist/docs.cjs.map +0 -1
  251. package/dist/env-types.cjs.map +0 -1
  252. package/dist/env.cjs.map +0 -1
  253. package/dist/environment/vite.cjs.map +0 -1
  254. package/dist/environment.cjs.map +0 -1
  255. package/dist/font.cjs.map +0 -1
  256. package/dist/headers.cjs.map +0 -1
  257. package/dist/i18n/client.cjs.map +0 -1
  258. package/dist/i18n/index.cjs.map +0 -1
  259. package/dist/i18n/server.cjs.map +0 -1
  260. package/dist/image/server.cjs.map +0 -1
  261. package/dist/image/sharp.cjs.map +0 -1
  262. package/dist/image.cjs.map +0 -1
  263. package/dist/index.cjs.map +0 -1
  264. package/dist/instrumentation.cjs.map +0 -1
  265. package/dist/integrations.cjs.map +0 -1
  266. package/dist/internal/build-runtime.cjs.map +0 -1
  267. package/dist/internal/client-runtime.cjs.map +0 -1
  268. package/dist/internal/config-runtime.cjs.map +0 -1
  269. package/dist/internal/isolated-boundary.cjs.map +0 -1
  270. package/dist/internal/metadata-image-runtime.cjs.map +0 -1
  271. package/dist/internal/product-telemetry-runtime.cjs.map +0 -1
  272. package/dist/internal/production-node-env.cjs.map +0 -1
  273. package/dist/internal/production-runtime.cjs.map +0 -1
  274. package/dist/markdown.cjs.map +0 -1
  275. package/dist/middleware.cjs.map +0 -1
  276. package/dist/navigation.cjs.map +0 -1
  277. package/dist/observability.cjs.map +0 -1
  278. package/dist/plugin.cjs.map +0 -1
  279. package/dist/query/client.cjs.map +0 -1
  280. package/dist/query/index.cjs.map +0 -1
  281. package/dist/query/parsers.cjs.map +0 -1
  282. package/dist/query/server.cjs.map +0 -1
  283. package/dist/renderer/react/client.cjs.map +0 -1
  284. package/dist/renderer/react/server.cjs.map +0 -1
  285. package/dist/renderer/react/vite.cjs.map +0 -1
  286. package/dist/renderer-client.cjs.map +0 -1
  287. package/dist/renderer.cjs.map +0 -1
  288. package/dist/request.cjs.map +0 -1
  289. package/dist/router.cjs.map +0 -1
  290. package/dist/routes.cjs.map +0 -1
  291. package/dist/server-action-security.cjs.map +0 -1
  292. package/dist/server-fn-client.cjs.map +0 -1
  293. package/dist/server-fn.cjs.map +0 -1
  294. package/dist/server-plugins.cjs.map +0 -1
  295. package/dist/server-query-client.cjs.map +0 -1
  296. package/dist/server-query.cjs.map +0 -1
  297. package/dist/server.cjs.map +0 -1
  298. package/dist/storage.cjs.map +0 -1
  299. package/dist/testing.cjs.map +0 -1
  300. package/dist/theme/client.cjs.map +0 -1
  301. package/dist/theme/index.cjs.map +0 -1
  302. package/dist/theme/runtime.cjs.map +0 -1
  303. package/dist/theme/server.cjs.map +0 -1
  304. package/dist/version.cjs.map +0 -1
  305. package/dist/vite.cjs.map +0 -1
  306. package/dist/workflows.cjs.map +0 -1
  307. /package/dist/{chunk-VV24CC42.mjs.map → chunk-35NPLKQJ.mjs.map} +0 -0
  308. /package/dist/{chunk-RWYRFCLG.mjs.map → chunk-4X57GXQA.mjs.map} +0 -0
  309. /package/dist/{chunk-MOW47IF5.mjs.map → chunk-6UYVU46O.mjs.map} +0 -0
  310. /package/dist/{chunk-RLGUZ3HS.mjs.map → chunk-I3OOUWO5.mjs.map} +0 -0
  311. /package/dist/{chunk-2LS3KKE7.mjs.map → chunk-JV7JUD7Q.mjs.map} +0 -0
  312. /package/dist/{chunk-Q3OX763A.mjs.map → chunk-LXDASSTE.mjs.map} +0 -0
  313. /package/dist/{chunk-HVG3HLQZ.mjs.map → chunk-Q7WGOOAI.mjs.map} +0 -0
  314. /package/dist/{chunk-3INDBMUU.mjs.map → chunk-TGDIACZT.mjs.map} +0 -0
  315. /package/dist/{chunk-MH27UH72.mjs.map → chunk-TT3E2JOF.mjs.map} +0 -0
  316. /package/dist/{chunk-UWRGX3J3.mjs.map → chunk-UMUWR5XA.mjs.map} +0 -0
  317. /package/dist/{devtools-S52RRRMN.mjs.map → devtools-XWZX6CCL.mjs.map} +0 -0
@@ -856,11 +856,11 @@ function resolveFarmServerHealthConfig(config) {
856
856
  return Object.freeze({ enabled: true, livenessPath, readinessPath });
857
857
  }
858
858
  function normalizeHealthPath(value, optionName) {
859
- const path41 = value.trim();
860
- if (!path41.startsWith("/") || path41.includes("?") || path41.includes("#") || path41.includes("*")) {
859
+ const path42 = value.trim();
860
+ if (!path42.startsWith("/") || path42.includes("?") || path42.includes("#") || path42.includes("*")) {
861
861
  throw new TypeError(`${optionName} must be an absolute pathname without a query or wildcard`);
862
862
  }
863
- const normalized = path41.length > 1 ? path41.replace(/\/+$/, "") || "/" : path41;
863
+ const normalized = path42.length > 1 ? path42.replace(/\/+$/, "") || "/" : path42;
864
864
  assertBrowserStableRoutePath(normalized);
865
865
  return normalized;
866
866
  }
@@ -1697,9 +1697,9 @@ function getFarmIntegrationPluginOwner(plugin) {
1697
1697
  const value = plugin[FARM_INTEGRATION_PLUGIN_OWNER];
1698
1698
  return value && typeof value === "object" ? value : void 0;
1699
1699
  }
1700
- function defineTypedIntegrationRoute(method, path41, input) {
1700
+ function defineTypedIntegrationRoute(method, path42, input) {
1701
1701
  return {
1702
- path: path41,
1702
+ path: path42,
1703
1703
  method,
1704
1704
  middleware: input.middleware,
1705
1705
  before: input.before,
@@ -1709,7 +1709,7 @@ function defineTypedIntegrationRoute(method, path41, input) {
1709
1709
  input: normalizeIntegrationRouteInputSchemas(input),
1710
1710
  handler: input.handler,
1711
1711
  __operation: defineIntegrationAPIOperation({
1712
- path: path41,
1712
+ path: path42,
1713
1713
  method,
1714
1714
  bodyFormat: input.bodyFormat,
1715
1715
  responseFormat: input.responseFormat,
@@ -1721,58 +1721,58 @@ function defineTypedIntegrationRoute(method, path41, input) {
1721
1721
  }
1722
1722
  function createIntegrationRouteFactory() {
1723
1723
  return {
1724
- get(path41, input) {
1724
+ get(path42, input) {
1725
1725
  return defineTypedIntegrationRoute(
1726
1726
  "GET",
1727
- path41,
1727
+ path42,
1728
1728
  input
1729
1729
  );
1730
1730
  },
1731
- post(path41, input) {
1731
+ post(path42, input) {
1732
1732
  return defineTypedIntegrationRoute(
1733
1733
  "POST",
1734
- path41,
1734
+ path42,
1735
1735
  {
1736
1736
  bodyFormat: "json",
1737
1737
  ...input
1738
1738
  }
1739
1739
  );
1740
1740
  },
1741
- query(path41, input) {
1742
- return defineTypedIntegrationRoute("QUERY", path41, {
1741
+ query(path42, input) {
1742
+ return defineTypedIntegrationRoute("QUERY", path42, {
1743
1743
  bodyFormat: "json",
1744
1744
  ...input
1745
1745
  });
1746
1746
  },
1747
- put(path41, input) {
1747
+ put(path42, input) {
1748
1748
  return defineTypedIntegrationRoute(
1749
1749
  "PUT",
1750
- path41,
1750
+ path42,
1751
1751
  {
1752
1752
  bodyFormat: "json",
1753
1753
  ...input
1754
1754
  }
1755
1755
  );
1756
1756
  },
1757
- patch(path41, input) {
1758
- return defineTypedIntegrationRoute("PATCH", path41, {
1757
+ patch(path42, input) {
1758
+ return defineTypedIntegrationRoute("PATCH", path42, {
1759
1759
  bodyFormat: "json",
1760
1760
  ...input
1761
1761
  });
1762
1762
  },
1763
- delete(path41, input) {
1764
- return defineTypedIntegrationRoute("DELETE", path41, {
1763
+ delete(path42, input) {
1764
+ return defineTypedIntegrationRoute("DELETE", path42, {
1765
1765
  bodyFormat: "json",
1766
1766
  ...input
1767
1767
  });
1768
1768
  },
1769
- options(path41, input) {
1770
- return defineTypedIntegrationRoute("OPTIONS", path41, input);
1769
+ options(path42, input) {
1770
+ return defineTypedIntegrationRoute("OPTIONS", path42, input);
1771
1771
  },
1772
- head(path41, input) {
1772
+ head(path42, input) {
1773
1773
  return defineTypedIntegrationRoute(
1774
1774
  "HEAD",
1775
- path41,
1775
+ path42,
1776
1776
  input
1777
1777
  );
1778
1778
  }
@@ -2053,8 +2053,8 @@ async function parseIntegrationConfigSchema(integration, schema, value) {
2053
2053
  function createIntegrationConfigValidationError(integration, error) {
2054
2054
  const issues = Array.isArray(error.issues) && error.issues.length > 0 ? error.issues.map((issue) => {
2055
2055
  const normalizedPath = normalizeIntegrationValidationPath(issue.path);
2056
- const path41 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
2057
- return `${path41}${issue.message || "Invalid config"}`;
2056
+ const path42 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
2057
+ return `${path42}${issue.message || "Invalid config"}`;
2058
2058
  }).join("; ") : error.message || "Invalid config";
2059
2059
  return new Error(`Integration "${integration.type}" config validation failed: ${issues}`);
2060
2060
  }
@@ -2778,8 +2778,8 @@ function normalizeIntegrationValidationIssues(source, error) {
2778
2778
  }
2779
2779
  ];
2780
2780
  }
2781
- function normalizeIntegrationValidationPath(path41) {
2782
- return (path41 || []).map((segment) => {
2781
+ function normalizeIntegrationValidationPath(path42) {
2782
+ return (path42 || []).map((segment) => {
2783
2783
  const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
2784
2784
  return typeof key === "symbol" ? key.description || key.toString() : key;
2785
2785
  });
@@ -4021,8 +4021,8 @@ function toViteModuleId(filePath, root) {
4021
4021
  }
4022
4022
  async function fileExists(filePath) {
4023
4023
  try {
4024
- const fs14 = await import("fs/promises");
4025
- await fs14.access(filePath);
4024
+ const fs15 = await import("fs/promises");
4025
+ await fs15.access(filePath);
4026
4026
  return true;
4027
4027
  } catch {
4028
4028
  return false;
@@ -4216,35 +4216,35 @@ async function prepareFarmWorkflowsForNitro(config) {
4216
4216
  const workflowConfig = isResolvedWorkflowConfig(config.workflows) ? config.workflows : resolveWorkflowsConfig(config.workflows);
4217
4217
  const root = config.root || process.cwd();
4218
4218
  const distDir = config.distDir || ".farm";
4219
- const fs14 = await import("fs/promises");
4220
- const path41 = await import("path");
4221
- const generatedDir = path41.join(root, distDir, ".nitro", "farm-workflows");
4219
+ const fs15 = await import("fs/promises");
4220
+ const path42 = await import("path");
4221
+ const generatedDir = path42.join(root, distDir, ".nitro", "farm-workflows");
4222
4222
  const workflows = await discoverFarmWorkflows({
4223
4223
  root,
4224
4224
  workflows: workflowConfig
4225
4225
  });
4226
4226
  if (workflows.length === 0) {
4227
- await fs14.rm(generatedDir, { recursive: true, force: true });
4227
+ await fs15.rm(generatedDir, { recursive: true, force: true });
4228
4228
  return {
4229
4229
  workflows,
4230
4230
  tasks: {},
4231
4231
  scheduledTasks: {}
4232
4232
  };
4233
4233
  }
4234
- await fs14.rm(generatedDir, { recursive: true, force: true });
4235
- await fs14.mkdir(generatedDir, { recursive: true });
4234
+ await fs15.rm(generatedDir, { recursive: true, force: true });
4235
+ await fs15.mkdir(generatedDir, { recursive: true });
4236
4236
  const tasks = {};
4237
4237
  const scheduledTasks = createScheduledTasks(workflows);
4238
4238
  for (const workflow of workflows) {
4239
- const wrapperPath = toPosixPath(path41.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
4240
- await fs14.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
4239
+ const wrapperPath = toPosixPath(path42.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
4240
+ await fs15.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
4241
4241
  tasks[workflow.id] = {
4242
4242
  handler: wrapperPath,
4243
4243
  description: workflow.description || `Farm workflow ${workflow.id}`
4244
4244
  };
4245
4245
  }
4246
- const handlerPath = toPosixPath(path41.join(generatedDir, "http-handler.mjs"));
4247
- await fs14.writeFile(
4246
+ const handlerPath = toPosixPath(path42.join(generatedDir, "http-handler.mjs"));
4247
+ await fs15.writeFile(
4248
4248
  handlerPath,
4249
4249
  createNitroWorkflowHTTPHandler(
4250
4250
  workflowConfig,
@@ -4253,8 +4253,8 @@ async function prepareFarmWorkflowsForNitro(config) {
4253
4253
  ),
4254
4254
  "utf8"
4255
4255
  );
4256
- const manifestPath = path41.join(generatedDir, "manifest.json");
4257
- await fs14.writeFile(
4256
+ const manifestPath = path42.join(generatedDir, "manifest.json");
4257
+ await fs15.writeFile(
4258
4258
  manifestPath,
4259
4259
  JSON.stringify(
4260
4260
  {
@@ -4342,21 +4342,21 @@ function resolveWorkflowDefinition(module2) {
4342
4342
  return null;
4343
4343
  }
4344
4344
  async function findWorkflowFiles(root, dirs) {
4345
- const path41 = await import("path");
4345
+ const path42 = await import("path");
4346
4346
  const files = [];
4347
4347
  for (const dir of dirs) {
4348
- const absoluteDir = path41.isAbsolute(dir) ? dir : path41.join(root, dir);
4348
+ const absoluteDir = path42.isAbsolute(dir) ? dir : path42.join(root, dir);
4349
4349
  if (!await pathExists(absoluteDir)) continue;
4350
4350
  await walkWorkflowDir(absoluteDir, files);
4351
4351
  }
4352
4352
  return files.sort();
4353
4353
  }
4354
4354
  async function walkWorkflowDir(dir, files) {
4355
- const fs14 = await import("fs/promises");
4356
- const path41 = await import("path");
4357
- const entries = await fs14.readdir(dir, { withFileTypes: true });
4355
+ const fs15 = await import("fs/promises");
4356
+ const path42 = await import("path");
4357
+ const entries = await fs15.readdir(dir, { withFileTypes: true });
4358
4358
  for (const entry of entries) {
4359
- const filePath = path41.join(dir, entry.name);
4359
+ const filePath = path42.join(dir, entry.name);
4360
4360
  if (entry.isDirectory()) {
4361
4361
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
4362
4362
  await walkWorkflowDir(filePath, files);
@@ -4368,20 +4368,20 @@ async function walkWorkflowDir(dir, files) {
4368
4368
  }
4369
4369
  }
4370
4370
  async function pathExists(filePath) {
4371
- const fs14 = await import("fs/promises");
4372
- return fs14.access(filePath).then(() => true).catch(() => false);
4371
+ const fs15 = await import("fs/promises");
4372
+ return fs15.access(filePath).then(() => true).catch(() => false);
4373
4373
  }
4374
4374
  function isWorkflowFile(fileName) {
4375
4375
  return /\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName);
4376
4376
  }
4377
4377
  async function loadWorkflowModule(filePath, root) {
4378
- const fs14 = await import("fs/promises");
4379
- const path41 = await import("path");
4378
+ const fs15 = await import("fs/promises");
4379
+ const path42 = await import("path");
4380
4380
  const { pathToFileURL: pathToFileURL10 } = await import("url");
4381
4381
  const { build: build3 } = await import("esbuild");
4382
- const outDir = path41.join(root, ".farm", ".workflow-loader");
4383
- await fs14.mkdir(outDir, { recursive: true });
4384
- const outfile = path41.join(
4382
+ const outDir = path42.join(root, ".farm", ".workflow-loader");
4383
+ await fs15.mkdir(outDir, { recursive: true });
4384
+ const outfile = path42.join(
4385
4385
  outDir,
4386
4386
  `workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
4387
4387
  );
@@ -4405,7 +4405,7 @@ async function loadWorkflowModule(filePath, root) {
4405
4405
  `${pathToFileURL10(outfile).href}?t=${Date.now()}`
4406
4406
  );
4407
4407
  } finally {
4408
- await fs14.unlink(outfile).catch(() => void 0);
4408
+ await fs15.unlink(outfile).catch(() => void 0);
4409
4409
  }
4410
4410
  }
4411
4411
  function workflowIdFromFile(root, dirs, filePath) {
@@ -4695,14 +4695,14 @@ async function prepareFarmCronForNitro(config) {
4695
4695
  const cron = isResolvedCronConfig(config.cron) ? config.cron : resolveCronConfig(config.cron);
4696
4696
  const root = config.root || process.cwd();
4697
4697
  const distDir = config.distDir || ".farm";
4698
- const fs14 = await import("fs/promises");
4699
- const path41 = await import("path");
4700
- const manifestPath = path41.join(root, distDir, FARM_CRON_MANIFEST);
4701
- const generatedDir = path41.join(root, distDir, ".nitro", "farm-cron");
4698
+ const fs15 = await import("fs/promises");
4699
+ const path42 = await import("path");
4700
+ const manifestPath = path42.join(root, distDir, FARM_CRON_MANIFEST);
4701
+ const generatedDir = path42.join(root, distDir, ".nitro", "farm-cron");
4702
4702
  if (!cron.enabled) {
4703
4703
  await Promise.all([
4704
- fs14.rm(manifestPath, { force: true }),
4705
- fs14.rm(generatedDir, { recursive: true, force: true })
4704
+ fs15.rm(manifestPath, { force: true }),
4705
+ fs15.rm(generatedDir, { recursive: true, force: true })
4706
4706
  ]);
4707
4707
  return {
4708
4708
  jobs: [],
@@ -4710,21 +4710,21 @@ async function prepareFarmCronForNitro(config) {
4710
4710
  scheduledTasks: {}
4711
4711
  };
4712
4712
  }
4713
- await fs14.rm(generatedDir, { recursive: true, force: true });
4714
- await fs14.mkdir(generatedDir, { recursive: true });
4713
+ await fs15.rm(generatedDir, { recursive: true, force: true });
4714
+ await fs15.mkdir(generatedDir, { recursive: true });
4715
4715
  const tasks = {};
4716
4716
  for (const job of cron.jobs) {
4717
4717
  const taskName = getFarmCronTaskName(job.name);
4718
- const wrapperPath = toPosixPath(path41.join(generatedDir, `${safeFileName2(job.name)}.mjs`));
4719
- await fs14.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), "utf8");
4718
+ const wrapperPath = toPosixPath(path42.join(generatedDir, `${safeFileName2(job.name)}.mjs`));
4719
+ await fs15.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), "utf8");
4720
4720
  tasks[taskName] = {
4721
4721
  handler: wrapperPath,
4722
4722
  description: job.description || `Farm cron ${job.name}`
4723
4723
  };
4724
4724
  }
4725
4725
  const manifest = createFarmCronManifest(cron);
4726
- await fs14.mkdir(path41.dirname(manifestPath), { recursive: true });
4727
- await fs14.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
4726
+ await fs15.mkdir(path42.dirname(manifestPath), { recursive: true });
4727
+ await fs15.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
4728
4728
  `, "utf8");
4729
4729
  return {
4730
4730
  jobs: cron.jobs,
@@ -4805,7 +4805,7 @@ function normalizeCronJob(name2, job) {
4805
4805
  if (!job || typeof job !== "object" || Array.isArray(job)) {
4806
4806
  throw new TypeError(`Farm cron ${JSON.stringify(name2)} must be a configuration object.`);
4807
4807
  }
4808
- const path41 = normalizeCronPath(name2, job.path);
4808
+ const path42 = normalizeCronPath(name2, job.path);
4809
4809
  const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
4810
4810
  const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name2, value)))];
4811
4811
  if (schedule.length === 0) {
@@ -4814,7 +4814,7 @@ function normalizeCronJob(name2, job) {
4814
4814
  return {
4815
4815
  name: name2,
4816
4816
  schedule,
4817
- path: path41,
4817
+ path: path42,
4818
4818
  description: job.description?.trim() || void 0
4819
4819
  };
4820
4820
  }
@@ -4831,13 +4831,13 @@ function normalizeCronPath(name2, value) {
4831
4831
  `Farm cron ${JSON.stringify(name2)} path cannot contain backslashes or control characters.`
4832
4832
  );
4833
4833
  }
4834
- const path41 = value.trim();
4835
- if (path41.startsWith("//") || path41.includes("?") || path41.includes("#")) {
4834
+ const path42 = value.trim();
4835
+ if (path42.startsWith("//") || path42.includes("?") || path42.includes("#")) {
4836
4836
  throw new TypeError(
4837
4837
  `Farm cron ${JSON.stringify(name2)} path must be an application pathname without a host, query, or hash.`
4838
4838
  );
4839
4839
  }
4840
- for (const segment of path41.split("/")) {
4840
+ for (const segment of path42.split("/")) {
4841
4841
  let decoded = segment;
4842
4842
  try {
4843
4843
  decoded = decodeURIComponent(segment);
@@ -4859,7 +4859,7 @@ function normalizeCronPath(name2, value) {
4859
4859
  );
4860
4860
  }
4861
4861
  }
4862
- return path41.length > 1 ? path41.replace(/\/+$/, "") : path41;
4862
+ return path42.length > 1 ? path42.replace(/\/+$/, "") : path42;
4863
4863
  }
4864
4864
  function normalizeCronExpression(name2, value) {
4865
4865
  if (typeof value !== "string") {
@@ -5526,15 +5526,27 @@ function getFarmCacheInvalidationState() {
5526
5526
  taskListeners: /* @__PURE__ */ new Set()
5527
5527
  });
5528
5528
  }
5529
+ function warnFarmCacheListenerError(scope, error) {
5530
+ const detail = error instanceof Error ? error.stack ?? error.message : String(error);
5531
+ console.warn(`[farm:cache] ${scope} listener failed: ${detail}`);
5532
+ }
5529
5533
  function notifyFarmCacheInvalidation(key) {
5530
5534
  if (typeof key !== "string" || key.length === 0) return;
5531
5535
  for (const listener of getFarmCacheInvalidationState().listeners) {
5532
- listener(key);
5536
+ try {
5537
+ listener(key);
5538
+ } catch (error) {
5539
+ warnFarmCacheListenerError("invalidation", error);
5540
+ }
5533
5541
  }
5534
5542
  }
5535
5543
  function notifyFarmCacheTask(task) {
5536
5544
  for (const listener of getFarmCacheInvalidationState().taskListeners) {
5537
- listener(task);
5545
+ try {
5546
+ listener(task);
5547
+ } catch (error) {
5548
+ warnFarmCacheListenerError("task", error);
5549
+ }
5538
5550
  }
5539
5551
  }
5540
5552
  function encodeFarmCacheInvalidations(keys) {
@@ -5573,6 +5585,7 @@ var init_cache_invalidation = __esm({
5573
5585
  FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationState");
5574
5586
  globalState = globalThis;
5575
5587
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
5588
+ __name(warnFarmCacheListenerError, "warnFarmCacheListenerError");
5576
5589
  __name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
5577
5590
  __name(notifyFarmCacheTask, "notifyFarmCacheTask");
5578
5591
  __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
@@ -6182,8 +6195,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
6182
6195
  }
6183
6196
  );
6184
6197
  }
6185
- function createFarmDeploymentCookie(deploymentId, path41 = "/", secure = false) {
6186
- const normalizedPath = path41.startsWith("/") ? path41 : `/${path41}`;
6198
+ function createFarmDeploymentCookie(deploymentId, path42 = "/", secure = false) {
6199
+ const normalizedPath = path42.startsWith("/") ? path42 : `/${path42}`;
6187
6200
  return [
6188
6201
  `${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
6189
6202
  `Path=${normalizedPath}`,
@@ -6412,7 +6425,7 @@ var init_dev_indicators = __esm({
6412
6425
 
6413
6426
  // src/image-config.ts
6414
6427
  function resolveFarmImageConfig(config) {
6415
- const path41 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
6428
+ const path42 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
6416
6429
  const deviceSizes = normalizeIntegerList(
6417
6430
  config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
6418
6431
  "images.deviceSizes"
@@ -6440,7 +6453,7 @@ function resolveFarmImageConfig(config) {
6440
6453
  );
6441
6454
  return Object.freeze({
6442
6455
  provider: config?.provider ?? "auto",
6443
- path: path41,
6456
+ path: path42,
6444
6457
  domains: Object.freeze([
6445
6458
  ...new Set(
6446
6459
  (config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
@@ -6486,11 +6499,11 @@ function normalizeImagePath(value) {
6486
6499
  if (hasUnstableCharacters(value)) {
6487
6500
  throw new TypeError("images.path cannot contain backslashes or control characters");
6488
6501
  }
6489
- const path41 = value.trim().replace(/\/+$/, "") || "/";
6490
- if (!path41.startsWith("/") || path41.startsWith("//") || path41.includes("?") || path41.includes("#")) {
6502
+ const path42 = value.trim().replace(/\/+$/, "") || "/";
6503
+ if (!path42.startsWith("/") || path42.startsWith("//") || path42.includes("?") || path42.includes("#")) {
6491
6504
  throw new TypeError("images.path must be an absolute pathname without a query or hash");
6492
6505
  }
6493
- for (const segment of path41.split("/")) {
6506
+ for (const segment of path42.split("/")) {
6494
6507
  let decoded = segment;
6495
6508
  try {
6496
6509
  decoded = decodeURIComponent(segment);
@@ -6506,7 +6519,7 @@ function normalizeImagePath(value) {
6506
6519
  throw new TypeError('images.path cannot contain "." or ".." path segments');
6507
6520
  }
6508
6521
  }
6509
- return path41;
6522
+ return path42;
6510
6523
  }
6511
6524
  function normalizeIntegerList(values, name2, max) {
6512
6525
  if (values.length === 0) {
@@ -7399,17 +7412,17 @@ function normalizeFarmAPIBasePath(value) {
7399
7412
  if (hasUnstableCharacters(value)) {
7400
7413
  throw new Error("Farm api.basePath cannot contain backslashes or control characters.");
7401
7414
  }
7402
- const path41 = value.trim();
7403
- if (!path41) {
7415
+ const path42 = value.trim();
7416
+ if (!path42) {
7404
7417
  throw new Error("Farm api.basePath cannot be empty.");
7405
7418
  }
7406
- if (path41.includes("?") || path41.includes("#")) {
7419
+ if (path42.includes("?") || path42.includes("#")) {
7407
7420
  throw new Error("Farm api.basePath cannot contain a query string or hash.");
7408
7421
  }
7409
- if (path41.startsWith("//")) {
7422
+ if (path42.startsWith("//")) {
7410
7423
  throw new Error('Farm api.basePath must be a pathname such as "/api", not a URL.');
7411
7424
  }
7412
- for (const segment of path41.split("/")) {
7425
+ for (const segment of path42.split("/")) {
7413
7426
  let decoded = segment;
7414
7427
  try {
7415
7428
  decoded = decodeURIComponent(segment);
@@ -7425,7 +7438,7 @@ function normalizeFarmAPIBasePath(value) {
7425
7438
  throw new Error('Farm api.basePath cannot contain "." or ".." path segments.');
7426
7439
  }
7427
7440
  }
7428
- const normalized = `/${path41.replace(/^\/+|\/+$/g, "")}`;
7441
+ const normalized = `/${path42.replace(/^\/+|\/+$/g, "")}`;
7429
7442
  return normalized === "/" ? "/" : normalized;
7430
7443
  }
7431
7444
  function getFarmAPIBaseURL() {
@@ -7574,7 +7587,9 @@ function resolveDeployConfig(config, overrides = {}) {
7574
7587
  }
7575
7588
  }
7576
7589
  }
7577
- const preset = overrides.preset || deploy.preset || config.preset || getPresetForDeployTarget(target) || "node-server";
7590
+ const configuredPreset = deploy.preset || config.preset;
7591
+ const overrideTargetPreset = overrideTarget && getDeployTargetForPreset(configuredPreset) !== overrideTarget ? getPresetForDeployTarget(overrideTarget) : void 0;
7592
+ const preset = overrides.preset || overrideTargetPreset || configuredPreset || getPresetForDeployTarget(target) || "node-server";
7578
7593
  const resolvedTarget = target || getDeployTargetForPreset(preset);
7579
7594
  if (detectedTarget && resolvedTarget !== detectedTarget) {
7580
7595
  const mismatchKey = `mismatch:${resolvedTarget}:${detectedTarget}`;
@@ -7676,19 +7691,19 @@ async function findDocsConfigPath(rootDir, configPath) {
7676
7691
  return void 0;
7677
7692
  }
7678
7693
  async function loadDocsConfig(rootDir, configPath) {
7679
- const fs14 = await import("fs/promises");
7694
+ const fs15 = await import("fs/promises");
7680
7695
  const { pathToFileURL: pathToFileURL10 } = await import("url");
7681
7696
  const root = import_path2.default.resolve(rootDir || process.cwd());
7682
7697
  const resolvedPath = await findDocsConfigPath(root, configPath);
7683
7698
  if (!resolvedPath) return void 0;
7684
7699
  try {
7685
7700
  if (resolvedPath.endsWith(".json")) {
7686
- const content = await fs14.readFile(resolvedPath, "utf8");
7701
+ const content = await fs15.readFile(resolvedPath, "utf8");
7687
7702
  return { config: JSON.parse(content), configPath: resolvedPath };
7688
7703
  }
7689
7704
  const { build: build3 } = await import("esbuild");
7690
7705
  const configCacheDir = import_path2.default.join(root, ".farm", ".config-loader");
7691
- await fs14.mkdir(configCacheDir, { recursive: true });
7706
+ await fs15.mkdir(configCacheDir, { recursive: true });
7692
7707
  const modulePath = import_path2.default.join(
7693
7708
  configCacheDir,
7694
7709
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -7714,7 +7729,7 @@ async function loadDocsConfig(rootDir, configPath) {
7714
7729
  moduleUrl
7715
7730
  );
7716
7731
  } finally {
7717
- await fs14.unlink(modulePath).catch(() => void 0);
7732
+ await fs15.unlink(modulePath).catch(() => void 0);
7718
7733
  }
7719
7734
  return {
7720
7735
  config: importedConfig.default || importedConfig,
@@ -7907,6 +7922,7 @@ async function resolveConfig(userConfig, mode) {
7907
7922
  serverComponents: false,
7908
7923
  serverActions: false,
7909
7924
  isolatedClientHydration: "off",
7925
+ ppr: false,
7910
7926
  ...userConfig.experimental
7911
7927
  },
7912
7928
  plugins: [...resolveIntegrationPlugins(integrations), ...userConfig.plugins || []],
@@ -8180,7 +8196,13 @@ function recordFarmEventTrace(event) {
8180
8196
  activeSpan.addEvent(event.type, toEventAttributes(event), event.timestamp);
8181
8197
  }
8182
8198
  const error = event.type === "request.error" ? void 0 : getEventError(event);
8183
- if (error !== void 0) recordSpanError(activeSpan, error);
8199
+ if (error !== void 0) {
8200
+ if (event.type === "render.error") {
8201
+ recordSpanException(activeSpan, error);
8202
+ } else {
8203
+ recordSpanError(activeSpan, error);
8204
+ }
8205
+ }
8184
8206
  }
8185
8207
  const completedTraceContext = recordCompletedEventSpan(event, activeContext);
8186
8208
  return traceContext ?? completedTraceContext;
@@ -8274,12 +8296,25 @@ function getCompletedSpanDescriptor(event) {
8274
8296
  return void 0;
8275
8297
  }
8276
8298
  }
8299
+ function hashFarmCacheKey(value) {
8300
+ let hash = 2166136261;
8301
+ for (let index = 0; index < value.length; index++) {
8302
+ hash ^= value.charCodeAt(index);
8303
+ hash = Math.imul(hash, 16777619);
8304
+ }
8305
+ return (hash >>> 0).toString(16).padStart(8, "0");
8306
+ }
8277
8307
  function toEventAttributes(event) {
8278
8308
  const attributes = {};
8309
+ const redactKey = typeof event.type === "string" && event.type.startsWith("cache.");
8279
8310
  for (const [key, value] of Object.entries(event)) {
8280
8311
  if (key === "timestamp" || key === "level" || key === "error" || key === "traceId" || key === "spanId" || key === "traceSampled" || value === void 0) {
8281
8312
  continue;
8282
8313
  }
8314
+ if (redactKey && key === "key" && typeof value === "string") {
8315
+ attributes["farm.key_hash"] = hashFarmCacheKey(value);
8316
+ continue;
8317
+ }
8283
8318
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
8284
8319
  attributes[`farm.${key}`] = value;
8285
8320
  } else if (Array.isArray(value)) {
@@ -8297,9 +8332,13 @@ function toEventAttributes(event) {
8297
8332
  function getEventError(event) {
8298
8333
  return "error" in event ? event.error : void 0;
8299
8334
  }
8300
- function recordSpanError(span, error) {
8335
+ function recordSpanException(span, error) {
8301
8336
  const normalized = error instanceof Error ? error : new Error(String(error));
8302
8337
  span.recordException(normalized);
8338
+ return normalized;
8339
+ }
8340
+ function recordSpanError(span, error) {
8341
+ const normalized = recordSpanException(span, error);
8303
8342
  span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: normalized.message });
8304
8343
  }
8305
8344
  function setResponseStatus(span, status) {
@@ -8357,8 +8396,10 @@ var init_tracing = __esm({
8357
8396
  __name(recordFarmEventTrace, "recordFarmEventTrace");
8358
8397
  __name(recordCompletedEventSpan, "recordCompletedEventSpan");
8359
8398
  __name(getCompletedSpanDescriptor, "getCompletedSpanDescriptor");
8399
+ __name(hashFarmCacheKey, "hashFarmCacheKey");
8360
8400
  __name(toEventAttributes, "toEventAttributes");
8361
8401
  __name(getEventError, "getEventError");
8402
+ __name(recordSpanException, "recordSpanException");
8362
8403
  __name(recordSpanError, "recordSpanError");
8363
8404
  __name(setResponseStatus, "setResponseStatus");
8364
8405
  __name(resolveResultStatus, "resolveResultStatus");
@@ -8553,10 +8594,11 @@ var init_observability = __esm({
8553
8594
  });
8554
8595
 
8555
8596
  // src/ssg.ts
8556
- function resolveConfiguredRouteRenderingConfig(mod, source) {
8597
+ function resolveConfiguredRouteRenderingConfig(mod, source, options) {
8598
+ const pprEnabled = options?.experimentalPPR === true;
8557
8599
  const directiveConfig = parseRouteRenderingDirective(source);
8558
8600
  let ssg = directiveConfig?.ssg ?? false;
8559
- let ppr = directiveConfig?.ppr ?? false;
8601
+ let requestedPPR = directiveConfig?.ppr ?? false;
8560
8602
  let revalidate = directiveConfig?.revalidate;
8561
8603
  const moduleDynamic = normalizeDynamicMode(mod?.dynamic);
8562
8604
  const dynamic = moduleDynamic ?? directiveConfig?.dynamic;
@@ -8566,12 +8608,12 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
8566
8608
  ssg = mod.ssg === true;
8567
8609
  }
8568
8610
  if (hasExplicitPPR) {
8569
- ppr = mod?.ppr === true || mod?.experimental_ppr === true;
8611
+ requestedPPR = mod?.ppr === true || mod?.experimental_ppr === true;
8570
8612
  }
8571
8613
  if (typeof mod?.revalidate === "number") {
8572
8614
  if (mod.revalidate > 0) {
8573
8615
  revalidate = mod.revalidate;
8574
- if (!hasExplicitSsg && !ppr) {
8616
+ if (!hasExplicitSsg && !requestedPPR) {
8575
8617
  ssg = true;
8576
8618
  }
8577
8619
  } else {
@@ -8585,22 +8627,23 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
8585
8627
  }
8586
8628
  if (moduleDynamic === "force-static" || moduleDynamic === "error") {
8587
8629
  ssg = true;
8588
- ppr = false;
8630
+ requestedPPR = false;
8589
8631
  } else if (moduleDynamic === "force-dynamic") {
8590
8632
  ssg = false;
8591
- ppr = false;
8633
+ requestedPPR = false;
8592
8634
  revalidate = void 0;
8593
8635
  }
8636
+ const ppr = pprEnabled && !ssg && requestedPPR;
8594
8637
  return {
8595
8638
  ssg,
8596
- ppr: ssg ? false : ppr,
8639
+ ppr,
8597
8640
  revalidate: ssg || ppr ? revalidate : void 0,
8598
8641
  dynamic,
8599
8642
  directive: directiveConfig?.directive
8600
8643
  };
8601
8644
  }
8602
- function resolveRouteRenderingConfig(mod, source) {
8603
- const rendering = resolveConfiguredRouteRenderingConfig(mod, source);
8645
+ function resolveRouteRenderingConfig(mod, source, options) {
8646
+ const rendering = resolveConfiguredRouteRenderingConfig(mod, source, options);
8604
8647
  if (!rendering.ssg || !source) {
8605
8648
  return rendering;
8606
8649
  }
@@ -8614,9 +8657,9 @@ function resolveRouteRenderingConfig(mod, source) {
8614
8657
  revalidate: void 0
8615
8658
  };
8616
8659
  }
8617
- async function resolveRouteRenderingConfigFromFile(mod, filePath) {
8660
+ async function resolveRouteRenderingConfigFromFile(mod, filePath, options) {
8618
8661
  const source = await (0, import_promises3.readFile)(filePath, "utf8").catch(() => void 0);
8619
- return resolveRouteRenderingConfig(mod, source);
8662
+ return resolveRouteRenderingConfig(mod, source, options);
8620
8663
  }
8621
8664
  function analyzeStaticRouteCandidate(mod, source, options = {}) {
8622
8665
  const blockers = [];
@@ -10115,7 +10158,7 @@ function getProgrammaticRouteSearchClientOptions2(search) {
10115
10158
  if (search.temporary?.length) options.temporary = [...search.temporary];
10116
10159
  return Object.keys(options).length > 0 ? options : void 0;
10117
10160
  }
10118
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path41, routePath) {
10161
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path42, routePath) {
10119
10162
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
10120
10163
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
10121
10164
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -10124,7 +10167,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path41, routePa
10124
10167
  schema,
10125
10168
  rawSearch,
10126
10169
  parsedSearch: search,
10127
- path: path41
10170
+ path: path42
10128
10171
  });
10129
10172
  return { search, canonicalPath };
10130
10173
  }
@@ -10203,8 +10246,8 @@ function normalizeComparableValue(value) {
10203
10246
  }
10204
10247
  return value;
10205
10248
  }
10206
- function createRoute(path41, options) {
10207
- return routesBuilder.page(path41, options);
10249
+ function createRoute(path42, options) {
10250
+ return routesBuilder.page(path42, options);
10208
10251
  }
10209
10252
  function isProgrammaticRoutesFileName2(fileName) {
10210
10253
  const normalized = fileName.replace(/\\/g, "/");
@@ -10287,7 +10330,7 @@ function createRouteModuleFromProgrammaticPage(route, rendererRuntime) {
10287
10330
  mod.__farmRouteData = route.data;
10288
10331
  mod.__farmRouteParsesProps = true;
10289
10332
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
10290
- mod.__farmResolveRouteCanonicalPath = (rawSearch, path41) => resolveProgrammaticRouteSearch(route.search, rawSearch, path41, route.path).canonicalPath;
10333
+ mod.__farmResolveRouteCanonicalPath = (rawSearch, path42) => resolveProgrammaticRouteSearch(route.search, rawSearch, path42, route.path).canonicalPath;
10291
10334
  }
10292
10335
  if (route.pending || route.error || route.notFound) {
10293
10336
  mod.__farmRouteComponents = {
@@ -10697,25 +10740,25 @@ var init_routes = __esm({
10697
10740
  ];
10698
10741
  __name(defineRoutes, "defineRoutes");
10699
10742
  routesBuilder = {
10700
- page(path41, options) {
10743
+ page(path42, options) {
10701
10744
  return normalizeProgrammaticRoute({
10702
10745
  kind: "page",
10703
- path: path41,
10746
+ path: path42,
10704
10747
  ...options
10705
10748
  });
10706
10749
  },
10707
- layout(path41, options) {
10750
+ layout(path42, options) {
10708
10751
  return normalizeProgrammaticRoute({
10709
10752
  kind: "layout",
10710
- path: path41,
10753
+ path: path42,
10711
10754
  ...options
10712
10755
  });
10713
10756
  },
10714
- api(path41, options) {
10757
+ api(path42, options) {
10715
10758
  const { render, runtime, regions, maxDuration, ...methods } = options;
10716
10759
  return normalizeProgrammaticRoute({
10717
10760
  kind: "api",
10718
- path: path41,
10761
+ path: path42,
10719
10762
  render,
10720
10763
  runtime,
10721
10764
  regions,
@@ -11300,7 +11343,7 @@ function getIslandStrategyExport(content) {
11300
11343
  }
11301
11344
  function stripUseClientDirective(content) {
11302
11345
  return content.replace(
11303
- /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*)(["'])use client\2\s*;?\s*/,
11346
+ /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/|(?:"[^"\n]*"|'[^'\n]*')\s*;?)*)(["'])use client\2\s*;?\s*/,
11304
11347
  "$1"
11305
11348
  );
11306
11349
  }
@@ -14588,7 +14631,7 @@ var init_runtime = __esm({
14588
14631
  return this.resolveMessage(locale, key);
14589
14632
  }
14590
14633
  hasMessage(locale, key) {
14591
- return (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !== void 0;
14634
+ return this.readOwnMessage(locale, key) !== void 0;
14592
14635
  }
14593
14636
  getClientSnapshot(resolution) {
14594
14637
  return {
@@ -14616,8 +14659,19 @@ var init_runtime = __esm({
14616
14659
  }
14617
14660
  return formatter.format(values);
14618
14661
  }
14662
+ // Look up a message by own-property only. A key named after an
14663
+ // Object.prototype member (toString, valueOf, constructor, ...) must resolve
14664
+ // to a real catalog entry or undefined, never the inherited prototype value
14665
+ // (mirrors the own-property handling added to catalog.ts in #454).
14666
+ readOwnMessage(locale, key) {
14667
+ const direct = this.catalogs[locale];
14668
+ if (direct && Object.prototype.hasOwnProperty.call(direct, key)) return direct[key];
14669
+ const fallback = this.catalogs[this.config.fallbackLocale];
14670
+ if (fallback && Object.prototype.hasOwnProperty.call(fallback, key)) return fallback[key];
14671
+ return void 0;
14672
+ }
14619
14673
  resolveMessage(locale, key) {
14620
- const message = this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];
14674
+ const message = this.readOwnMessage(locale, key);
14621
14675
  if (message !== void 0) return message;
14622
14676
  if (this.config.strict) {
14623
14677
  throw new Error(`Missing Farm i18n message "${key}" for locale "${locale}".`);
@@ -17043,7 +17097,7 @@ var init_server3 = __esm({
17043
17097
  var version;
17044
17098
  var init_package = __esm({
17045
17099
  "package.json"() {
17046
- version = "0.1.0-beta.95";
17100
+ version = "0.1.0-beta.97";
17047
17101
  }
17048
17102
  });
17049
17103
 
@@ -18111,7 +18165,8 @@ var init_renderer2 = __esm({
18111
18165
  }
18112
18166
  const renderingConfig = await resolveRouteRenderingConfigFromFile(
18113
18167
  routeModule,
18114
- route.modulePath
18168
+ route.modulePath,
18169
+ { experimentalPPR: this.config.experimental?.ppr === true }
18115
18170
  );
18116
18171
  const pprBypassReason = renderingConfig.ppr ? this.getPPRShellBypassReason(req, middlewareMap, middlewareContext, pluginExposedContext) : void 0;
18117
18172
  const canCachePPRShell = renderingConfig.ppr && !pprBypassReason;
@@ -18816,6 +18871,11 @@ var init_renderer2 = __esm({
18816
18871
  );
18817
18872
  res.statusCode = options.statusCode;
18818
18873
  res.setHeader("Content-Type", "text/html; charset=utf-8");
18874
+ res.setHeader("Cache-Control", "private, no-store");
18875
+ res.setHeader("X-Content-Type-Options", "nosniff");
18876
+ if (typeof res.removeHeader === "function") {
18877
+ res.removeHeader("X-Farm-PPR");
18878
+ }
18819
18879
  res.write(this.createFullHTML(html, false, options.pathname));
18820
18880
  res.end();
18821
18881
  return true;
@@ -19595,6 +19655,7 @@ var init_app = __esm({
19595
19655
  serverComponents: config.experimental?.serverComponents ?? false,
19596
19656
  serverActions: config.experimental?.serverActions ?? false,
19597
19657
  isolatedClientHydration: config.experimental?.isolatedClientHydration ?? "off",
19658
+ ppr: config.experimental?.ppr ?? false,
19598
19659
  ...config.experimental
19599
19660
  },
19600
19661
  vite: config.vite || {}
@@ -19656,15 +19717,15 @@ function isEndpointFailure(value) {
19656
19717
  return value instanceof EndpointFailure;
19657
19718
  }
19658
19719
  function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
19659
- let path41;
19720
+ let path42;
19660
19721
  let options;
19661
19722
  let handler;
19662
19723
  if (typeof pathOrOptions === "string") {
19663
- path41 = pathOrOptions;
19724
+ path42 = pathOrOptions;
19664
19725
  options = optionsOrHandler;
19665
19726
  handler = maybeHandler;
19666
19727
  } else {
19667
- path41 = "";
19728
+ path42 = "";
19668
19729
  options = pathOrOptions;
19669
19730
  handler = optionsOrHandler;
19670
19731
  }
@@ -19691,13 +19752,13 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
19691
19752
  ...betterCallOptions
19692
19753
  } = options;
19693
19754
  const endpoint = (0, import_better_call.createEndpoint)(
19694
- path41 || "/__farm_auto_path__",
19755
+ path42 || "/__farm_auto_path__",
19695
19756
  betterCallOptions,
19696
19757
  wrappedHandler
19697
19758
  );
19698
- endpoint.__path = path41 || void 0;
19759
+ endpoint.__path = path42 || void 0;
19699
19760
  endpoint.__method = options.method || "GET";
19700
- endpoint.__autoPath = !path41;
19761
+ endpoint.__autoPath = !path42;
19701
19762
  endpoint.__handler = wrappedHandler;
19702
19763
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
19703
19764
  endpoint.__middleware = middleware;
@@ -19708,6 +19769,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
19708
19769
  body: options.body,
19709
19770
  inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
19710
19771
  query: options.query,
19772
+ inputQuery: options.query,
19711
19773
  headers: options.headers,
19712
19774
  response: null,
19713
19775
  errors
@@ -19923,10 +19985,10 @@ function createRouteFactoryAt(prefix) {
19923
19985
  "OPTIONS"
19924
19986
  ]) {
19925
19987
  factory[method.toLowerCase()] = (child, options) => {
19926
- const path41 = joinRoutePath(prefix, child);
19988
+ const path42 = joinRoutePath(prefix, child);
19927
19989
  const input = options.input ?? {};
19928
19990
  const endpoint = createEndpoint(
19929
- path41,
19991
+ path42,
19930
19992
  {
19931
19993
  method,
19932
19994
  body: input.body,
@@ -19942,28 +20004,28 @@ function createRouteFactoryAt(prefix) {
19942
20004
  );
19943
20005
  endpoint.__types.params = input.params;
19944
20006
  endpoint.__output = options.output;
19945
- return Object.freeze({ path: path41, method, endpoint });
20007
+ return Object.freeze({ path: path42, method, endpoint });
19946
20008
  };
19947
20009
  }
19948
20010
  return Object.freeze(factory);
19949
20011
  }
19950
20012
  function joinRoutePath(prefix, child) {
19951
20013
  if (typeof child !== "string") throw new TypeError("Route paths must be strings.");
19952
- const path41 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
19953
- if (!(path41 === "/api" || path41.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path41)) {
20014
+ const path42 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
20015
+ if (!(path42 === "/api" || path42.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path42)) {
19954
20016
  throw new TypeError(
19955
- `Plugin route "${path41}" must be a canonical /api path without a query, hash, or empty segment.`
20017
+ `Plugin route "${path42}" must be a canonical /api path without a query, hash, or empty segment.`
19956
20018
  );
19957
20019
  }
19958
- assertBrowserStableRoutePath(path41);
19959
- assertUniqueRouteParameters(path41, "api");
19960
- getRoutePatternShape(path41, "api");
19961
- for (const segment of path41.split("/")) {
20020
+ assertBrowserStableRoutePath(path42);
20021
+ assertUniqueRouteParameters(path42, "api");
20022
+ getRoutePatternShape(path42, "api");
20023
+ for (const segment of path42.split("/")) {
19962
20024
  if (["__proto__", "constructor", "prototype", "$params"].includes(segment)) {
19963
20025
  throw new TypeError(`Route segment "${segment}" is reserved.`);
19964
20026
  }
19965
20027
  }
19966
- return path41;
20028
+ return path42;
19967
20029
  }
19968
20030
  function resolvePluginRoutes(plugins = []) {
19969
20031
  return plugins.flatMap((plugin) => {
@@ -20046,7 +20108,7 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
20046
20108
  }
20047
20109
  const result = [...routes.values()];
20048
20110
  if (expected) {
20049
- const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path41, methods }) => `${path41}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
20111
+ const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path42, methods }) => `${path42}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
20050
20112
  if (signature(result) !== signature(expected)) {
20051
20113
  throw new Error(
20052
20114
  "Plugin API routes changed between build and runtime. Route paths and methods must be stable across environments; rebuild the app."
@@ -21150,6 +21212,59 @@ var init_client_plugin_build = __esm({
21150
21212
  }
21151
21213
  });
21152
21214
 
21215
+ // src/client-cache-persistence-build.ts
21216
+ function resolveFarmClientCacheAdapterEntry(root, cache) {
21217
+ const client = cache?.client;
21218
+ const adapter = client?.adapter;
21219
+ if (adapter === void 0) return void 0;
21220
+ if (typeof adapter !== "string" || adapter.trim().length === 0) {
21221
+ throw new Error(
21222
+ 'cache.client.adapter must be a module path string, for example "./src/cache-adapter".'
21223
+ );
21224
+ }
21225
+ const resolved = import_node_path11.default.resolve(root, adapter);
21226
+ const found = resolveAdapterFile(resolved);
21227
+ if (!found) {
21228
+ throw new Error(
21229
+ `cache.client.adapter was not found: ${adapter} (resolved to ${resolved}). Point it at a client module whose default export is created with defineClientCacheAdapter().`
21230
+ );
21231
+ }
21232
+ const options = {};
21233
+ if (client?.version !== void 0) options.version = client.version;
21234
+ if (client?.flushDelayMs !== void 0) options.flushDelayMs = client.flushDelayMs;
21235
+ return { importPath: found.replace(/\\/g, "/"), options };
21236
+ }
21237
+ function resolveAdapterFile(resolved) {
21238
+ if (import_node_fs5.default.existsSync(resolved) && import_node_fs5.default.statSync(resolved).isFile()) return resolved;
21239
+ for (const extension of ADAPTER_EXTENSIONS) {
21240
+ const candidate = `${resolved}.${extension}`;
21241
+ if (import_node_fs5.default.existsSync(candidate) && import_node_fs5.default.statSync(candidate).isFile()) return candidate;
21242
+ }
21243
+ return void 0;
21244
+ }
21245
+ function generateClientCachePersistenceCode(entry) {
21246
+ if (!entry) return { imports: "", init: "" };
21247
+ return {
21248
+ imports: [
21249
+ `import * as __farmClientCacheAdapterModule from ${JSON.stringify(entry.importPath)};`,
21250
+ `import { initConfiguredClientCachePersistence as __farmInitClientCachePersistence } from "@farm.js/core/client";`
21251
+ ].join("\n"),
21252
+ init: `__farmInitClientCachePersistence(__farmClientCacheAdapterModule, ${JSON.stringify(entry.options)});`
21253
+ };
21254
+ }
21255
+ var import_node_fs5, import_node_path11, ADAPTER_EXTENSIONS;
21256
+ var init_client_cache_persistence_build = __esm({
21257
+ "src/client-cache-persistence-build.ts"() {
21258
+ "use strict";
21259
+ import_node_fs5 = __toESM(require("fs"));
21260
+ import_node_path11 = __toESM(require("path"));
21261
+ ADAPTER_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
21262
+ __name(resolveFarmClientCacheAdapterEntry, "resolveFarmClientCacheAdapterEntry");
21263
+ __name(resolveAdapterFile, "resolveAdapterFile");
21264
+ __name(generateClientCachePersistenceCode, "generateClientCachePersistenceCode");
21265
+ }
21266
+ });
21267
+
21153
21268
  // src/environment-vite.ts
21154
21269
  function transformEnvironmentFunctions(options) {
21155
21270
  if (!isTransformableModule(options.id) || !containsEnvironmentFunction(options.code)) {
@@ -21505,22 +21620,22 @@ function normalizeRelativePath(value) {
21505
21620
  }
21506
21621
  function resolveExistingPath(filePath) {
21507
21622
  try {
21508
- return (0, import_node_fs5.realpathSync)(filePath);
21623
+ return (0, import_node_fs6.realpathSync)(filePath);
21509
21624
  } catch {
21510
- return import_node_path11.default.resolve(filePath);
21625
+ return import_node_path12.default.resolve(filePath);
21511
21626
  }
21512
21627
  }
21513
21628
  function isDocsSourceFile(filePath) {
21514
- return DOCS_FILE_EXTENSIONS.has(import_node_path11.default.extname(filePath).toLowerCase());
21629
+ return DOCS_FILE_EXTENSIONS.has(import_node_path12.default.extname(filePath).toLowerCase());
21515
21630
  }
21516
21631
  function discoverDocsSourceFiles(contentDir) {
21517
21632
  const files = [];
21518
21633
  const visit = /* @__PURE__ */ __name((dir) => {
21519
- for (const entry of (0, import_node_fs5.readdirSync)(dir, { withFileTypes: true }).sort(
21634
+ for (const entry of (0, import_node_fs6.readdirSync)(dir, { withFileTypes: true }).sort(
21520
21635
  (a, b) => a.name.localeCompare(b.name)
21521
21636
  )) {
21522
21637
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
21523
- const absolutePath = import_node_path11.default.join(dir, entry.name);
21638
+ const absolutePath = import_node_path12.default.join(dir, entry.name);
21524
21639
  if (entry.isDirectory()) {
21525
21640
  visit(absolutePath);
21526
21641
  } else if (entry.isFile() && isDocsSourceFile(absolutePath)) {
@@ -21528,7 +21643,7 @@ function discoverDocsSourceFiles(contentDir) {
21528
21643
  }
21529
21644
  }
21530
21645
  }, "visit");
21531
- if ((0, import_node_fs5.existsSync)(contentDir)) visit(contentDir);
21646
+ if ((0, import_node_fs6.existsSync)(contentDir)) visit(contentDir);
21532
21647
  return files;
21533
21648
  }
21534
21649
  function getGitLastModifiedDates(contentDir) {
@@ -21538,7 +21653,7 @@ function getGitLastModifiedDates(contentDir) {
21538
21653
  stdio: ["ignore", "pipe", "ignore"]
21539
21654
  }).trim();
21540
21655
  if (!gitRoot) return {};
21541
- const contentPathspec = normalizeRelativePath(import_node_path11.default.relative(gitRoot, contentDir)) || ".";
21656
+ const contentPathspec = normalizeRelativePath(import_node_path12.default.relative(gitRoot, contentDir)) || ".";
21542
21657
  const contentPrefix = contentPathspec === "." ? "" : `${contentPathspec}/`;
21543
21658
  const history = (0, import_node_child_process.execFileSync)(
21544
21659
  "git",
@@ -21580,11 +21695,11 @@ function getGitLastModifiedDates(contentDir) {
21580
21695
  }
21581
21696
  }
21582
21697
  function readManifest(contentDir) {
21583
- const manifestPath = import_node_path11.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
21584
- if (!(0, import_node_fs5.existsSync)(manifestPath)) return null;
21698
+ const manifestPath = import_node_path12.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
21699
+ if (!(0, import_node_fs6.existsSync)(manifestPath)) return null;
21585
21700
  try {
21586
21701
  const parsed = JSON.parse(
21587
- (0, import_node_fs5.readFileSync)(manifestPath, "utf8")
21702
+ (0, import_node_fs6.readFileSync)(manifestPath, "utf8")
21588
21703
  );
21589
21704
  if (parsed.version !== 1 || !parsed.pages || typeof parsed.pages !== "object") return null;
21590
21705
  const pages = Object.fromEntries(
@@ -21603,15 +21718,15 @@ function createFarmDocsLastModifiedManifest(contentDir, options = {}) {
21603
21718
  const fallbackDate = (options.now ?? /* @__PURE__ */ new Date()).toISOString();
21604
21719
  const pages = {};
21605
21720
  for (const sourcePath of discoverDocsSourceFiles(resolvedContentDir)) {
21606
- const relativePath2 = normalizeRelativePath(import_node_path11.default.relative(resolvedContentDir, sourcePath));
21607
- pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs5.statSync)(sourcePath).mtime.toISOString());
21721
+ const relativePath2 = normalizeRelativePath(import_node_path12.default.relative(resolvedContentDir, sourcePath));
21722
+ pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs6.statSync)(sourcePath).mtime.toISOString());
21608
21723
  }
21609
21724
  return { version: 1, pages };
21610
21725
  }
21611
21726
  function getLastModifiedManifest(contentDir) {
21612
21727
  const resolvedContentDir = resolveExistingPath(contentDir);
21613
- const manifestPath = import_node_path11.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
21614
- const manifestStat = (0, import_node_fs5.existsSync)(manifestPath) ? (0, import_node_fs5.statSync)(manifestPath) : null;
21728
+ const manifestPath = import_node_path12.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
21729
+ const manifestStat = (0, import_node_fs6.existsSync)(manifestPath) ? (0, import_node_fs6.statSync)(manifestPath) : null;
21615
21730
  const signature = manifestStat ? `file:${manifestStat.mtimeMs}:${manifestStat.size}` : "generated";
21616
21731
  const cached = manifestCache.get(resolvedContentDir);
21617
21732
  if (cached?.signature === signature) return cached.manifest;
@@ -21624,21 +21739,21 @@ function resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter) {
21624
21739
  if (configured) return configured;
21625
21740
  const resolvedContentDir = resolveExistingPath(contentDir);
21626
21741
  const resolvedSourcePath = resolveExistingPath(sourcePath);
21627
- const relativePath2 = normalizeRelativePath(import_node_path11.default.relative(resolvedContentDir, resolvedSourcePath));
21628
- const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path11.default.isAbsolute(relativePath2);
21742
+ const relativePath2 = normalizeRelativePath(import_node_path12.default.relative(resolvedContentDir, resolvedSourcePath));
21743
+ const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path12.default.isAbsolute(relativePath2);
21629
21744
  if (isInsideContentDir) {
21630
21745
  const generated = getLastModifiedManifest(resolvedContentDir).pages[relativePath2];
21631
21746
  if (generated) return generated;
21632
21747
  }
21633
- return (0, import_node_fs5.statSync)(resolvedSourcePath).mtime.toISOString();
21748
+ return (0, import_node_fs6.statSync)(resolvedSourcePath).mtime.toISOString();
21634
21749
  }
21635
- var import_node_child_process, import_node_fs5, import_node_path11, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
21750
+ var import_node_child_process, import_node_fs6, import_node_path12, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
21636
21751
  var init_last_modified = __esm({
21637
21752
  "src/docs/last-modified.ts"() {
21638
21753
  "use strict";
21639
21754
  import_node_child_process = require("child_process");
21640
- import_node_fs5 = require("fs");
21641
- import_node_path11 = __toESM(require("path"));
21755
+ import_node_fs6 = require("fs");
21756
+ import_node_path12 = __toESM(require("path"));
21642
21757
  FARM_DOCS_LAST_MODIFIED_MANIFEST = ".farm-docs-last-modified.json";
21643
21758
  COMMIT_MARKER = "__FARM_DOCS_COMMIT__";
21644
21759
  DOCS_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx"]);
@@ -21671,10 +21786,10 @@ function isFarmDocsSearchEnabled(docs) {
21671
21786
  }
21672
21787
  function resolveFarmDocsSearchClientModule(root) {
21673
21788
  try {
21674
- const requireFromApp = (0, import_node_module6.createRequire)(import_node_path12.default.join(import_node_path12.default.resolve(root), "package.json"));
21789
+ const requireFromApp = (0, import_node_module6.createRequire)(import_node_path13.default.join(import_node_path13.default.resolve(root), "package.json"));
21675
21790
  const themeEntry = requireFromApp.resolve("@farming-labs/theme");
21676
- const commandSearchModule = import_node_path12.default.join(import_node_path12.default.dirname(themeEntry), "docs-command-search.mjs");
21677
- if ((0, import_node_fs6.existsSync)(commandSearchModule)) return commandSearchModule;
21791
+ const commandSearchModule = import_node_path13.default.join(import_node_path13.default.dirname(themeEntry), "docs-command-search.mjs");
21792
+ if ((0, import_node_fs7.existsSync)(commandSearchModule)) return commandSearchModule;
21678
21793
  } catch {
21679
21794
  }
21680
21795
  return void 0;
@@ -21813,13 +21928,13 @@ async function mountFarmDocsSearch() {
21813
21928
  window.__FARM_MOUNT_DOCS_SEARCH__ = mountFarmDocsSearch;
21814
21929
  `;
21815
21930
  }
21816
- var import_node_fs6, import_node_module6, import_node_path12;
21931
+ var import_node_fs7, import_node_module6, import_node_path13;
21817
21932
  var init_search_client = __esm({
21818
21933
  "src/docs/search-client.ts"() {
21819
21934
  "use strict";
21820
- import_node_fs6 = require("fs");
21935
+ import_node_fs7 = require("fs");
21821
21936
  import_node_module6 = require("module");
21822
- import_node_path12 = __toESM(require("path"));
21937
+ import_node_path13 = __toESM(require("path"));
21823
21938
  __name(isFarmDocsSearchEnabled, "isFarmDocsSearchEnabled");
21824
21939
  __name(resolveFarmDocsSearchClientModule, "resolveFarmDocsSearchClientModule");
21825
21940
  __name(generateFarmDocsSearchBootstrapRuntime, "generateFarmDocsSearchBootstrapRuntime");
@@ -21830,12 +21945,12 @@ var init_search_client = __esm({
21830
21945
  // src/docs/fonts.ts
21831
21946
  function resolveFarmDocsFontAssets(root) {
21832
21947
  return FARM_DOCS_FONT_SOURCES.flatMap(({ family, packagePath }) => {
21833
- const sourcePath = import_node_path13.default.join(root, "node_modules", packagePath);
21834
- if (!(0, import_node_fs7.existsSync)(sourcePath)) return [];
21835
- const source = (0, import_node_fs7.readFileSync)(sourcePath);
21948
+ const sourcePath = import_node_path14.default.join(root, "node_modules", packagePath);
21949
+ if (!(0, import_node_fs8.existsSync)(sourcePath)) return [];
21950
+ const source = (0, import_node_fs8.readFileSync)(sourcePath);
21836
21951
  const fingerprint = (0, import_node_crypto3.createHash)("sha256").update(source).digest("hex").slice(0, 12);
21837
- const extension = import_node_path13.default.extname(packagePath);
21838
- const baseName = import_node_path13.default.basename(packagePath, extension);
21952
+ const extension = import_node_path14.default.extname(packagePath);
21953
+ const baseName = import_node_path14.default.basename(packagePath, extension);
21839
21954
  return [
21840
21955
  {
21841
21956
  family,
@@ -21848,13 +21963,13 @@ function resolveFarmDocsFontAssets(root) {
21848
21963
  function toFarmDocsPublicFontAssets(assets) {
21849
21964
  return assets.map(({ family, url }) => ({ family, url }));
21850
21965
  }
21851
- var import_node_crypto3, import_node_fs7, import_node_path13, FARM_DOCS_FONT_SOURCES;
21966
+ var import_node_crypto3, import_node_fs8, import_node_path14, FARM_DOCS_FONT_SOURCES;
21852
21967
  var init_fonts = __esm({
21853
21968
  "src/docs/fonts.ts"() {
21854
21969
  "use strict";
21855
21970
  import_node_crypto3 = require("crypto");
21856
- import_node_fs7 = require("fs");
21857
- import_node_path13 = __toESM(require("path"));
21971
+ import_node_fs8 = require("fs");
21972
+ import_node_path14 = __toESM(require("path"));
21858
21973
  FARM_DOCS_FONT_SOURCES = [
21859
21974
  {
21860
21975
  family: "Geist Sans",
@@ -21948,13 +22063,13 @@ function generateFarmIntegrationProviderServerModules(providers, root) {
21948
22063
  }
21949
22064
  function resolveProviderModule(moduleId, root) {
21950
22065
  if (!moduleId.startsWith(".")) return moduleId;
21951
- return toViteModuleId(import_node_path14.default.resolve(root, moduleId), root);
22066
+ return toViteModuleId(import_node_path15.default.resolve(root, moduleId), root);
21952
22067
  }
21953
- var import_node_path14;
22068
+ var import_node_path15;
21954
22069
  var init_integration_provider_build = __esm({
21955
22070
  "src/integration-provider-build.ts"() {
21956
22071
  "use strict";
21957
- import_node_path14 = __toESM(require("path"));
22072
+ import_node_path15 = __toESM(require("path"));
21958
22073
  init_integrations();
21959
22074
  init_utils();
21960
22075
  __name(generateFarmIntegrationProviderClientCode, "generateFarmIntegrationProviderClientCode");
@@ -21971,9 +22086,9 @@ function getFarmClientOptimizeDepsInclude(renderer) {
21971
22086
  );
21972
22087
  }
21973
22088
  function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
21974
- const resolvedProjectRoot = import_node_path15.default.resolve(projectRoot);
22089
+ const resolvedProjectRoot = import_node_path16.default.resolve(projectRoot);
21975
22090
  return appDirectories.map((appDirectory) => {
21976
- const relativeAppDirectory = import_node_path15.default.relative(resolvedProjectRoot, import_node_path15.default.resolve(appDirectory)).replace(/\\/g, "/");
22091
+ const relativeAppDirectory = import_node_path16.default.relative(resolvedProjectRoot, import_node_path16.default.resolve(appDirectory)).replace(/\\/g, "/");
21977
22092
  const prefix = relativeAppDirectory || ".";
21978
22093
  return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
21979
22094
  });
@@ -21995,7 +22110,7 @@ function createFarmClientOptimizeDepsConfig(entries, renderer) {
21995
22110
  }
21996
22111
  function createFarmSourceAlias(projectRoot, srcDir = "src") {
21997
22112
  return {
21998
- "@": import_node_path15.default.resolve(projectRoot, srcDir)
22113
+ "@": import_node_path16.default.resolve(projectRoot, srcDir)
21999
22114
  };
22000
22115
  }
22001
22116
  function mergeNoExternal(farmValue, userValue) {
@@ -22059,11 +22174,11 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
22059
22174
  }
22060
22175
  };
22061
22176
  }
22062
- var import_node_path15, FARM_CLIENT_ENTRY_PATTERN, FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE;
22177
+ var import_node_path16, FARM_CLIENT_ENTRY_PATTERN, FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE;
22063
22178
  var init_vite_config = __esm({
22064
22179
  "src/server/vite-config.ts"() {
22065
22180
  "use strict";
22066
- import_node_path15 = __toESM(require("path"));
22181
+ import_node_path16 = __toESM(require("path"));
22067
22182
  FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
22068
22183
  FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
22069
22184
  "react",
@@ -23161,12 +23276,12 @@ var init_cli_colors = __esm({
23161
23276
  function isMiddlewareResponse(value) {
23162
23277
  return value instanceof Response;
23163
23278
  }
23164
- var fs8, path28, _MiddlewareManager, MiddlewareManager;
23279
+ var fs9, path29, _MiddlewareManager, MiddlewareManager;
23165
23280
  var init_manager = __esm({
23166
23281
  "src/middleware/manager.ts"() {
23167
23282
  "use strict";
23168
- fs8 = __toESM(require("fs"));
23169
- path28 = __toESM(require("path"));
23283
+ fs9 = __toESM(require("fs"));
23284
+ path29 = __toESM(require("path"));
23170
23285
  init_decode();
23171
23286
  init_context();
23172
23287
  init_module();
@@ -23238,7 +23353,7 @@ var init_manager = __esm({
23238
23353
  * Recursively discover middleware files
23239
23354
  */
23240
23355
  async discoverInDirectory(dir, routePath, discovered) {
23241
- if (!fs8.existsSync(dir)) {
23356
+ if (!fs9.existsSync(dir)) {
23242
23357
  return;
23243
23358
  }
23244
23359
  const middlewareFile = this.findMiddlewareFile(dir);
@@ -23248,10 +23363,10 @@ var init_manager = __esm({
23248
23363
  discovered.push(middleware);
23249
23364
  }
23250
23365
  }
23251
- const entries = fs8.readdirSync(dir, { withFileTypes: true });
23366
+ const entries = fs9.readdirSync(dir, { withFileTypes: true });
23252
23367
  for (const entry of entries) {
23253
23368
  if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
23254
- const subPath = path28.join(dir, entry.name);
23369
+ const subPath = path29.join(dir, entry.name);
23255
23370
  const subRoutePath = appendMiddlewareRoutePath(routePath, entry.name);
23256
23371
  await this.discoverInDirectory(subPath, subRoutePath, discovered);
23257
23372
  }
@@ -23263,8 +23378,8 @@ var init_manager = __esm({
23263
23378
  findMiddlewareFile(dir) {
23264
23379
  const extensions = [".ts", ".tsx", ".js", ".jsx"];
23265
23380
  for (const ext of extensions) {
23266
- const filePath = path28.join(dir, `middleware${ext}`);
23267
- if (fs8.existsSync(filePath)) {
23381
+ const filePath = path29.join(dir, `middleware${ext}`);
23382
+ if (fs9.existsSync(filePath)) {
23268
23383
  return filePath;
23269
23384
  }
23270
23385
  }
@@ -23603,7 +23718,7 @@ var init_manager = __esm({
23603
23718
  // src/write-file-if-changed.ts
23604
23719
  function writeFileIfChanged(filePath, content) {
23605
23720
  try {
23606
- if ((0, import_node_fs9.readFileSync)(filePath, "utf8") === content) {
23721
+ if ((0, import_node_fs10.readFileSync)(filePath, "utf8") === content) {
23607
23722
  return false;
23608
23723
  }
23609
23724
  } catch (error) {
@@ -23611,14 +23726,14 @@ function writeFileIfChanged(filePath, content) {
23611
23726
  throw error;
23612
23727
  }
23613
23728
  }
23614
- (0, import_node_fs9.writeFileSync)(filePath, content, "utf8");
23729
+ (0, import_node_fs10.writeFileSync)(filePath, content, "utf8");
23615
23730
  return true;
23616
23731
  }
23617
- var import_node_fs9;
23732
+ var import_node_fs10;
23618
23733
  var init_write_file_if_changed = __esm({
23619
23734
  "src/write-file-if-changed.ts"() {
23620
23735
  "use strict";
23621
- import_node_fs9 = require("fs");
23736
+ import_node_fs10 = require("fs");
23622
23737
  __name(writeFileIfChanged, "writeFileIfChanged");
23623
23738
  }
23624
23739
  });
@@ -23796,9 +23911,9 @@ var init_type_generator = __esm({
23796
23911
  }
23797
23912
  const nestedStructure = {};
23798
23913
  const usedRouteNames = /* @__PURE__ */ new Map();
23799
- for (const [path41, routeList] of routeGroups) {
23800
- const routeName = this.uniqueRouteName(path41, usedRouteNames);
23801
- const cleanPath = path41 === "/api" ? "" : path41.replace(/^\/api\//, "");
23914
+ for (const [path42, routeList] of routeGroups) {
23915
+ const routeName = this.uniqueRouteName(path42, usedRouteNames);
23916
+ const cleanPath = path42 === "/api" ? "" : path42.replace(/^\/api\//, "");
23802
23917
  const parts = cleanPath ? cleanPath.split("/") : [];
23803
23918
  const methodSources = /* @__PURE__ */ new Map();
23804
23919
  for (const route of routeList) {
@@ -23862,11 +23977,11 @@ var init_type_generator = __esm({
23862
23977
  methods.add(route.method);
23863
23978
  manifest.set(route.path, methods);
23864
23979
  }
23865
- const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path41, methods]) => ({ path: path41, methods: [...methods].sort() }));
23980
+ const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path42, methods]) => ({ path: path42, methods: [...methods].sort() }));
23866
23981
  const manifestSource = routeManifest.length ? `[
23867
23982
  ${routeManifest.map(
23868
- ({ path: path41, methods }) => ` {
23869
- path: ${JSON.stringify(path41)},
23983
+ ({ path: path42, methods }) => ` {
23984
+ path: ${JSON.stringify(path42)},
23870
23985
  methods: [${methods.map((method) => JSON.stringify(method)).join(", ")}],
23871
23986
  },`
23872
23987
  ).join("\n")}
@@ -23896,11 +24011,11 @@ export const apiRoutes = ${manifestSource} as const;
23896
24011
  const relativeImport = (0, import_path12.relative)((0, import_path12.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
23897
24012
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
23898
24013
  }
23899
- pathToRouteName(path41) {
23900
- return (path41 === "/api" ? "root" : path41.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
24014
+ pathToRouteName(path42) {
24015
+ return (path42 === "/api" ? "root" : path42.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
23901
24016
  }
23902
- uniqueRouteName(path41, usedNames) {
23903
- const base = this.pathToRouteName(path41);
24017
+ uniqueRouteName(path42, usedNames) {
24018
+ const base = this.pathToRouteName(path42);
23904
24019
  const seen = usedNames.get(base);
23905
24020
  usedNames.set(base, (seen ?? 0) + 1);
23906
24021
  return seen ? `${base}_${seen + 1}` : base;
@@ -23923,15 +24038,15 @@ export const apiRoutes = ${manifestSource} as const;
23923
24038
  toTypePropertyKey(key) {
23924
24039
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
23925
24040
  }
23926
- getBaseExportName(path41) {
23927
- const cleanPath = path41.replace(/^\/api\//, "");
24041
+ getBaseExportName(path42) {
24042
+ const cleanPath = path42.replace(/^\/api\//, "");
23928
24043
  if (cleanPath === "") {
23929
24044
  return "api";
23930
24045
  }
23931
24046
  return cleanPath;
23932
24047
  }
23933
- getExportName(path41, method) {
23934
- const cleanPath = path41.replace(/^\/api\//, "");
24048
+ getExportName(path42, method) {
24049
+ const cleanPath = path42.replace(/^\/api\//, "");
23935
24050
  if (cleanPath === "") {
23936
24051
  return method.toLowerCase();
23937
24052
  }
@@ -24000,12 +24115,12 @@ function createRoutePattern(route) {
24000
24115
  }).join("/");
24001
24116
  }
24002
24117
  async function generateRouteTypes(options) {
24003
- const root = path29.resolve(options.root);
24118
+ const root = path30.resolve(options.root);
24004
24119
  const srcDir = options.srcDir || "src";
24005
24120
  const outFile = options.outFile || DEFAULT_OUT_FILE;
24006
- const outPath = path29.isAbsolute(outFile) ? outFile : path29.join(root, srcDir, outFile);
24121
+ const outPath = path30.isAbsolute(outFile) ? outFile : path30.join(root, srcDir, outFile);
24007
24122
  const content = await createRouteTypeDeclarations(options, outPath);
24008
- fs9.mkdirSync(path29.dirname(outPath), { recursive: true });
24123
+ fs10.mkdirSync(path30.dirname(outPath), { recursive: true });
24009
24124
  writeFileIfChanged(outPath, content);
24010
24125
  return outPath;
24011
24126
  }
@@ -24019,8 +24134,8 @@ async function createRouteTypeDeclarations(options, outPath) {
24019
24134
  const routeModulePatterns = /* @__PURE__ */ new Set();
24020
24135
  const glob = await import("fast-glob");
24021
24136
  for (const source of sourceRoots) {
24022
- const appDir = path29.join(source.root, source.srcDir, "app");
24023
- if (fs9.existsSync(appDir)) {
24137
+ const appDir = path30.join(source.root, source.srcDir, "app");
24138
+ if (fs10.existsSync(appDir)) {
24024
24139
  const routeModuleFiles = await glob.default(
24025
24140
  `**/{page,layout,loading,error}.{${componentExtensions.join(",")},md,mdx}`,
24026
24141
  {
@@ -24056,7 +24171,7 @@ async function createRouteTypeDeclarations(options, outPath) {
24056
24171
  const routePathType = suppressLintOnLink ? "string" : renderTypeUnion(typeLiterals);
24057
24172
  const routePatternType = suppressLintOnLink ? "string" : renderTypeUnion(patternLiterals);
24058
24173
  const routeModulePatternType = renderTypeUnion(routeModulePatternLiterals);
24059
- const routeTypesImportPath = `./${path29.basename(outPath).replace(/\.d\.ts$/, "")}`;
24174
+ const routeTypesImportPath = `./${path30.basename(outPath).replace(/\.d\.ts$/, "")}`;
24060
24175
  const linkAugmentationBlock = suppressLintOnLink ? "" : `
24061
24176
  declare module "@farm.js/core/client" {
24062
24177
  interface LinkDefaultRoute {
@@ -24103,12 +24218,12 @@ ${renderTypeAlias("RouteModulePattern", routeModulePatternType)}${linkAugmentati
24103
24218
  `;
24104
24219
  return content;
24105
24220
  }
24106
- var path29, fs9, DEFAULT_OUT_FILE;
24221
+ var path30, fs10, DEFAULT_OUT_FILE;
24107
24222
  var init_generate_route_types = __esm({
24108
24223
  "src/routing/generate-route-types.ts"() {
24109
24224
  "use strict";
24110
- path29 = __toESM(require("path"));
24111
- fs9 = __toESM(require("fs"));
24225
+ path30 = __toESM(require("path"));
24226
+ fs10 = __toESM(require("fs"));
24112
24227
  init_utils();
24113
24228
  init_route_slots();
24114
24229
  init_routes_server();
@@ -24128,20 +24243,20 @@ var init_generate_route_types = __esm({
24128
24243
 
24129
24244
  // src/env-types.ts
24130
24245
  async function generateEnvTypes(options) {
24131
- const root = path30.resolve(options.root);
24246
+ const root = path31.resolve(options.root);
24132
24247
  const srcDir = options.srcDir || "src";
24133
24248
  const outFile = options.outFile || DEFAULT_OUT_FILE2;
24134
- const outPath = path30.isAbsolute(outFile) ? outFile : path30.join(root, srcDir, outFile);
24249
+ const outPath = path31.isAbsolute(outFile) ? outFile : path31.join(root, srcDir, outFile);
24135
24250
  const content = createEnvTypeDeclarations(options, outPath);
24136
- fs10.mkdirSync(path30.dirname(outPath), { recursive: true });
24251
+ fs11.mkdirSync(path31.dirname(outPath), { recursive: true });
24137
24252
  writeFileIfChanged(outPath, content);
24138
24253
  return outPath;
24139
24254
  }
24140
24255
  function createEnvTypeDeclarations(options, outPath) {
24141
- const root = path30.resolve(options.root);
24256
+ const root = path31.resolve(options.root);
24142
24257
  const configPath = findConfigPath(root, options.configPath);
24143
24258
  const configPaths = [
24144
- ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
24259
+ ...(options.layerConfigPaths ?? []).filter((value) => fs11.existsSync(value)),
24145
24260
  ...configPath ? [configPath] : []
24146
24261
  ];
24147
24262
  const content = configPaths.length > 1 ? createLayeredConfigBackedEnvTypes(outPath, configPaths) : configPaths.length === 1 ? createConfigBackedEnvTypes(outPath, configPaths[0]) : createEmptyEnvTypes();
@@ -24201,12 +24316,12 @@ export {};
24201
24316
  }
24202
24317
  function findConfigPath(root, configPath) {
24203
24318
  if (configPath) {
24204
- const resolvedPath = path30.isAbsolute(configPath) ? configPath : path30.join(root, configPath);
24205
- return fs10.existsSync(resolvedPath) ? resolvedPath : null;
24319
+ const resolvedPath = path31.isAbsolute(configPath) ? configPath : path31.join(root, configPath);
24320
+ return fs11.existsSync(resolvedPath) ? resolvedPath : null;
24206
24321
  }
24207
24322
  for (const filename of CONFIG_FILENAMES2) {
24208
- const resolvedPath = path30.join(root, filename);
24209
- if (fs10.existsSync(resolvedPath)) {
24323
+ const resolvedPath = path31.join(root, filename);
24324
+ if (fs11.existsSync(resolvedPath)) {
24210
24325
  return resolvedPath;
24211
24326
  }
24212
24327
  }
@@ -24266,15 +24381,15 @@ export {};
24266
24381
  `;
24267
24382
  }
24268
24383
  function toTypeImportPath(outPath, targetPath) {
24269
- const relativePath2 = path30.relative(path30.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
24384
+ const relativePath2 = path31.relative(path31.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
24270
24385
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
24271
24386
  }
24272
- var fs10, path30, DEFAULT_OUT_FILE2, CONFIG_FILENAMES2;
24387
+ var fs11, path31, DEFAULT_OUT_FILE2, CONFIG_FILENAMES2;
24273
24388
  var init_env_types = __esm({
24274
24389
  "src/env-types.ts"() {
24275
24390
  "use strict";
24276
- fs10 = __toESM(require("fs"));
24277
- path30 = __toESM(require("path"));
24391
+ fs11 = __toESM(require("fs"));
24392
+ path31 = __toESM(require("path"));
24278
24393
  init_write_file_if_changed();
24279
24394
  DEFAULT_OUT_FILE2 = "farm-env.d.ts";
24280
24395
  CONFIG_FILENAMES2 = [
@@ -24307,8 +24422,8 @@ var init_env_types = __esm({
24307
24422
 
24308
24423
  // src/image-types.ts
24309
24424
  function generateFarmImageTypes(options) {
24310
- const outputPath = options.outFile ? import_node_path17.default.resolve(options.root, options.outFile) : import_node_path17.default.join(options.root, options.srcDir || "src", "farm-images.d.ts");
24311
- (0, import_node_fs10.mkdirSync)(import_node_path17.default.dirname(outputPath), { recursive: true });
24425
+ const outputPath = options.outFile ? import_node_path18.default.resolve(options.root, options.outFile) : import_node_path18.default.join(options.root, options.srcDir || "src", "farm-images.d.ts");
24426
+ (0, import_node_fs11.mkdirSync)(import_node_path18.default.dirname(outputPath), { recursive: true });
24312
24427
  writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
24313
24428
  return outputPath;
24314
24429
  }
@@ -24332,12 +24447,12 @@ declare module "*?url" {
24332
24447
  }
24333
24448
  `;
24334
24449
  }
24335
- var import_node_fs10, import_node_path17, FARM_STATIC_IMAGE_EXTENSIONS;
24450
+ var import_node_fs11, import_node_path18, FARM_STATIC_IMAGE_EXTENSIONS;
24336
24451
  var init_image_types = __esm({
24337
24452
  "src/image-types.ts"() {
24338
24453
  "use strict";
24339
- import_node_fs10 = require("fs");
24340
- import_node_path17 = __toESM(require("path"));
24454
+ import_node_fs11 = require("fs");
24455
+ import_node_path18 = __toESM(require("path"));
24341
24456
  init_write_file_if_changed();
24342
24457
  FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
24343
24458
  __name(generateFarmImageTypes, "generateFarmImageTypes");
@@ -24347,10 +24462,10 @@ var init_image_types = __esm({
24347
24462
 
24348
24463
  // src/content-types.ts
24349
24464
  function createContentTypeDeclarations(options, outPath) {
24350
- const root = path32.resolve(options.root);
24465
+ const root = path33.resolve(options.root);
24351
24466
  const projectConfig = findConfigPath2(root, options.configPath);
24352
24467
  const configPaths = [
24353
- ...(options.layerConfigPaths ?? []).filter((value) => fs11.existsSync(value)),
24468
+ ...(options.layerConfigPaths ?? []).filter((value) => fs12.existsSync(value)),
24354
24469
  ...projectConfig ? [projectConfig] : []
24355
24470
  ];
24356
24471
  if (configPaths.length === 0) return createEmptyContentTypes();
@@ -24418,25 +24533,25 @@ export {};
24418
24533
  }
24419
24534
  function findConfigPath2(root, configPath) {
24420
24535
  if (configPath) {
24421
- const resolvedPath = path32.isAbsolute(configPath) ? configPath : path32.join(root, configPath);
24422
- return fs11.existsSync(resolvedPath) ? resolvedPath : null;
24536
+ const resolvedPath = path33.isAbsolute(configPath) ? configPath : path33.join(root, configPath);
24537
+ return fs12.existsSync(resolvedPath) ? resolvedPath : null;
24423
24538
  }
24424
24539
  for (const filename of CONFIG_FILENAMES3) {
24425
- const resolvedPath = path32.join(root, filename);
24426
- if (fs11.existsSync(resolvedPath)) return resolvedPath;
24540
+ const resolvedPath = path33.join(root, filename);
24541
+ if (fs12.existsSync(resolvedPath)) return resolvedPath;
24427
24542
  }
24428
24543
  return null;
24429
24544
  }
24430
24545
  function toTypeImportPath2(outPath, targetPath) {
24431
- const relativePath2 = path32.relative(path32.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
24546
+ const relativePath2 = path33.relative(path33.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
24432
24547
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
24433
24548
  }
24434
- var fs11, path32, CONFIG_FILENAMES3;
24549
+ var fs12, path33, CONFIG_FILENAMES3;
24435
24550
  var init_content_types = __esm({
24436
24551
  "src/content-types.ts"() {
24437
24552
  "use strict";
24438
- fs11 = __toESM(require("fs"));
24439
- path32 = __toESM(require("path"));
24553
+ fs12 = __toESM(require("fs"));
24554
+ path33 = __toESM(require("path"));
24440
24555
  CONFIG_FILENAMES3 = [
24441
24556
  "farm.config.ts",
24442
24557
  "farm.config.tsx",
@@ -24466,9 +24581,9 @@ var init_content_types = __esm({
24466
24581
  async function generateFarmI18nTypes(options) {
24467
24582
  if (!options.config.enabled) return void 0;
24468
24583
  const { signatures } = await readFarmI18nCatalogs(options.config);
24469
- const outFile = options.outFile ? (0, import_node_path18.resolve)(options.root, options.outFile) : (0, import_node_path18.join)((0, import_node_path18.resolve)(options.root), options.srcDir || "src", "farm-i18n.d.ts");
24584
+ const outFile = options.outFile ? (0, import_node_path19.resolve)(options.root, options.outFile) : (0, import_node_path19.join)((0, import_node_path19.resolve)(options.root), options.srcDir || "src", "farm-i18n.d.ts");
24470
24585
  const content = renderFarmI18nTypes(options.config.locales, signatures);
24471
- (0, import_node_fs11.mkdirSync)((0, import_node_path18.dirname)(outFile), { recursive: true });
24586
+ (0, import_node_fs12.mkdirSync)((0, import_node_path19.dirname)(outFile), { recursive: true });
24472
24587
  writeFileIfChanged(outFile, content);
24473
24588
  return outFile;
24474
24589
  }
@@ -24509,12 +24624,12 @@ function argumentType(kind) {
24509
24624
  return "string";
24510
24625
  }
24511
24626
  }
24512
- var import_node_fs11, import_node_path18;
24627
+ var import_node_fs12, import_node_path19;
24513
24628
  var init_type_generator2 = __esm({
24514
24629
  "src/i18n/type-generator.ts"() {
24515
24630
  "use strict";
24516
- import_node_fs11 = require("fs");
24517
- import_node_path18 = require("path");
24631
+ import_node_fs12 = require("fs");
24632
+ import_node_path19 = require("path");
24518
24633
  init_catalog();
24519
24634
  init_write_file_if_changed();
24520
24635
  __name(generateFarmI18nTypes, "generateFarmI18nTypes");
@@ -24936,11 +25051,11 @@ function devServableFileExists(pathname, baseDirs) {
24936
25051
  if (!relativePathname) return false;
24937
25052
  for (const baseDir of baseDirs) {
24938
25053
  if (typeof baseDir !== "string" || baseDir.length === 0) continue;
24939
- const resolvedBase = path33.resolve(baseDir);
24940
- const candidate = path33.resolve(resolvedBase, relativePathname);
24941
- if (!candidate.startsWith(resolvedBase + path33.sep)) continue;
25054
+ const resolvedBase = path34.resolve(baseDir);
25055
+ const candidate = path34.resolve(resolvedBase, relativePathname);
25056
+ if (!candidate.startsWith(resolvedBase + path34.sep)) continue;
24942
25057
  try {
24943
- if (fs12.existsSync(candidate) && fs12.statSync(candidate).isFile()) {
25058
+ if (fs13.existsSync(candidate) && fs13.statSync(candidate).isFile()) {
24944
25059
  return true;
24945
25060
  }
24946
25061
  } catch {
@@ -24948,12 +25063,12 @@ function devServableFileExists(pathname, baseDirs) {
24948
25063
  }
24949
25064
  return false;
24950
25065
  }
24951
- var fs12, path33;
25066
+ var fs13, path34;
24952
25067
  var init_dev_static = __esm({
24953
25068
  "src/dev-static.ts"() {
24954
25069
  "use strict";
24955
- fs12 = __toESM(require("fs"));
24956
- path33 = __toESM(require("path"));
25070
+ fs13 = __toESM(require("fs"));
25071
+ path34 = __toESM(require("path"));
24957
25072
  __name(shouldBypassFarmRouterForDottedPath, "shouldBypassFarmRouterForDottedPath");
24958
25073
  __name(devServableFileExists, "devServableFileExists");
24959
25074
  }
@@ -24962,6 +25077,7 @@ var init_dev_static = __esm({
24962
25077
  // src/server-query-boundary.ts
24963
25078
  function findClientServerFnViolation(code, id) {
24964
25079
  if (id.startsWith("\0") || id.startsWith("virtual:") || id.includes("node_modules")) return null;
25080
+ if (/\.(md|mdx)(\?|$)/.test(id)) return null;
24965
25081
  if (!code.includes("@farm.js/core")) return null;
24966
25082
  for (const match of code.matchAll(FARM_CORE_IMPORT_RE)) {
24967
25083
  const specifiers = match[1];
@@ -25052,12 +25168,12 @@ async function createBlurDataURL(bytes) {
25052
25168
  return void 0;
25053
25169
  }
25054
25170
  }
25055
- var import_promises8, import_node_path19, import_image_size2, FARM_IMAGE_ID_PREFIX, STATIC_IMAGE_RE, SCRIPT_IMPORTER_RE;
25171
+ var import_promises8, import_node_path20, import_image_size2, FARM_IMAGE_ID_PREFIX, STATIC_IMAGE_RE, SCRIPT_IMPORTER_RE;
25056
25172
  var init_image_vite = __esm({
25057
25173
  "src/image-vite.ts"() {
25058
25174
  "use strict";
25059
25175
  import_promises8 = require("fs/promises");
25060
- import_node_path19 = __toESM(require("path"));
25176
+ import_node_path20 = __toESM(require("path"));
25061
25177
  import_image_size2 = require("image-size");
25062
25178
  FARM_IMAGE_ID_PREFIX = "\0farm:image:";
25063
25179
  STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
@@ -26072,10 +26188,10 @@ function resolveFarmDocsFavicon(docs, options) {
26072
26188
  if (typeof configuredFavicon === "string" && configuredFavicon.trim()) {
26073
26189
  return configuredFavicon.trim();
26074
26190
  }
26075
- const publicDir = import_node_path20.default.join(import_node_path20.default.resolve(options.root), "public");
26191
+ const publicDir = import_node_path21.default.join(import_node_path21.default.resolve(options.root), "public");
26076
26192
  for (const fileName of FARM_DOCS_FAVICON_FILES) {
26077
- const faviconPath = import_node_path20.default.join(publicDir, fileName);
26078
- if ((0, import_node_fs12.existsSync)(faviconPath) && (0, import_node_fs12.statSync)(faviconPath).isFile()) {
26193
+ const faviconPath = import_node_path21.default.join(publicDir, fileName);
26194
+ if ((0, import_node_fs13.existsSync)(faviconPath) && (0, import_node_fs13.statSync)(faviconPath).isFile()) {
26079
26195
  return `/${fileName}`;
26080
26196
  }
26081
26197
  }
@@ -26109,10 +26225,10 @@ function isSafeSegment(segment) {
26109
26225
  return segment !== ".." && !segment.includes("/") && !segment.includes("\\");
26110
26226
  }
26111
26227
  function resolveInside(root, target) {
26112
- const resolvedRoot = import_node_path20.default.resolve(root);
26113
- const resolvedTarget = import_node_path20.default.resolve(target);
26114
- const relative6 = import_node_path20.default.relative(resolvedRoot, resolvedTarget);
26115
- if (relative6 === "" || !relative6.startsWith("..") && !import_node_path20.default.isAbsolute(relative6)) {
26228
+ const resolvedRoot = import_node_path21.default.resolve(root);
26229
+ const resolvedTarget = import_node_path21.default.resolve(target);
26230
+ const relative6 = import_node_path21.default.relative(resolvedRoot, resolvedTarget);
26231
+ if (relative6 === "" || !relative6.startsWith("..") && !import_node_path21.default.isAbsolute(relative6)) {
26116
26232
  return resolvedTarget;
26117
26233
  }
26118
26234
  return null;
@@ -26121,10 +26237,10 @@ function resolveExistingFileInside(root, target) {
26121
26237
  const safePath = resolveInside(root, target);
26122
26238
  if (!safePath) return null;
26123
26239
  try {
26124
- const realRoot = (0, import_node_fs12.realpathSync)(root);
26125
- const realTarget = (0, import_node_fs12.realpathSync)(safePath);
26240
+ const realRoot = (0, import_node_fs13.realpathSync)(root);
26241
+ const realTarget = (0, import_node_fs13.realpathSync)(safePath);
26126
26242
  const containedTarget = resolveInside(realRoot, realTarget);
26127
- return containedTarget && (0, import_node_fs12.statSync)(containedTarget).isFile() ? containedTarget : null;
26243
+ return containedTarget && (0, import_node_fs13.statSync)(containedTarget).isFile() ? containedTarget : null;
26128
26244
  } catch {
26129
26245
  return null;
26130
26246
  }
@@ -26138,16 +26254,16 @@ function isFarmDocsRequest(docs, request) {
26138
26254
  return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
26139
26255
  }
26140
26256
  function resolveFarmDocsContentDir(docs, options) {
26141
- const root = import_node_path20.default.resolve(options.root);
26257
+ const root = import_node_path21.default.resolve(options.root);
26142
26258
  const srcDir = options.srcDir || "src";
26143
26259
  const configuredContentDir = docs.contentDir || docs.config.contentDir;
26144
26260
  if (configuredContentDir) {
26145
- return import_node_path20.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path20.default.join(root, configuredContentDir);
26261
+ return import_node_path21.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path21.default.join(root, configuredContentDir);
26146
26262
  }
26147
26263
  const entryDir = docs.config.entry || trimSlashes2(docs.entry) || "docs";
26148
- const appDocsDir = import_node_path20.default.join(root, srcDir, "app", entryDir);
26149
- if ((0, import_node_fs12.existsSync)(appDocsDir)) return appDocsDir;
26150
- return import_node_path20.default.join(root, entryDir);
26264
+ const appDocsDir = import_node_path21.default.join(root, srcDir, "app", entryDir);
26265
+ if ((0, import_node_fs13.existsSync)(appDocsDir)) return appDocsDir;
26266
+ return import_node_path21.default.join(root, entryDir);
26151
26267
  }
26152
26268
  function getFarmDocsRouteTypeEntries(docs) {
26153
26269
  if (!docs?.enabled) return [];
@@ -26170,10 +26286,10 @@ function getRequestSlug(docs, request) {
26170
26286
  function findDocsPageFile(contentDir, slug) {
26171
26287
  const segments = slug ? slug.split("/").filter(Boolean) : [];
26172
26288
  if (!segments.every(isSafeSegment)) return null;
26173
- const slugDir = import_node_path20.default.join(contentDir, ...segments);
26174
- const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path20.default.join(contentDir, filename)) : [
26175
- ...DOCS_FILE_NAMES.map((filename) => import_node_path20.default.join(slugDir, filename)),
26176
- ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path20.default.join(contentDir, `${slug}${extension}`))
26289
+ const slugDir = import_node_path21.default.join(contentDir, ...segments);
26290
+ const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path21.default.join(contentDir, filename)) : [
26291
+ ...DOCS_FILE_NAMES.map((filename) => import_node_path21.default.join(slugDir, filename)),
26292
+ ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path21.default.join(contentDir, `${slug}${extension}`))
26177
26293
  ];
26178
26294
  for (const candidate of candidates) {
26179
26295
  const safePath = resolveExistingFileInside(contentDir, candidate);
@@ -26212,7 +26328,7 @@ function titleFromMarkdown2(body, fallback) {
26212
26328
  function loadFarmDocsPage(contentDir, docs, slug) {
26213
26329
  const sourcePath = findDocsPageFile(contentDir, slug);
26214
26330
  if (!sourcePath) return null;
26215
- const source = (0, import_node_fs12.readFileSync)(sourcePath, "utf8");
26331
+ const source = (0, import_node_fs13.readFileSync)(sourcePath, "utf8");
26216
26332
  const { frontmatter, body } = parseFrontmatter(source);
26217
26333
  const title = frontmatter.title || titleFromMarkdown2(body, titleFromSlug(slug));
26218
26334
  const href = createDocsHref(docs.entry, slug);
@@ -26235,9 +26351,9 @@ function createDocsHref(entry, slug) {
26235
26351
  return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
26236
26352
  }
26237
26353
  function pathToSlug(contentDir, filePath) {
26238
- const relative6 = import_node_path20.default.relative(contentDir, filePath).replace(/\\/g, "/");
26354
+ const relative6 = import_node_path21.default.relative(contentDir, filePath).replace(/\\/g, "/");
26239
26355
  if (relative6.startsWith("..")) return null;
26240
- const extension = import_node_path20.default.extname(relative6);
26356
+ const extension = import_node_path21.default.extname(relative6);
26241
26357
  if (!DOCS_FILE_EXTENSIONS2.includes(extension)) return null;
26242
26358
  const withoutExtension = relative6.slice(0, -extension.length);
26243
26359
  if (withoutExtension === "page" || withoutExtension === "index") return "";
@@ -26250,12 +26366,12 @@ function loadPage(contentDir, docs, request) {
26250
26366
  return loadFarmDocsPage(contentDir, docs, getRequestSlug(docs, request));
26251
26367
  }
26252
26368
  function discoverFarmDocsPages(contentDir, docs) {
26253
- if (!(0, import_node_fs12.existsSync)(contentDir)) return [];
26369
+ if (!(0, import_node_fs13.existsSync)(contentDir)) return [];
26254
26370
  const pages = [];
26255
26371
  const visit = /* @__PURE__ */ __name((dir) => {
26256
- for (const entry of (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true })) {
26372
+ for (const entry of (0, import_node_fs13.readdirSync)(dir, { withFileTypes: true })) {
26257
26373
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
26258
- const absolutePath = import_node_path20.default.join(dir, entry.name);
26374
+ const absolutePath = import_node_path21.default.join(dir, entry.name);
26259
26375
  if (entry.isDirectory()) {
26260
26376
  visit(absolutePath);
26261
26377
  continue;
@@ -26263,7 +26379,7 @@ function discoverFarmDocsPages(contentDir, docs) {
26263
26379
  if (!entry.isFile()) continue;
26264
26380
  const slug = pathToSlug(contentDir, absolutePath);
26265
26381
  if (slug === null) continue;
26266
- const source = (0, import_node_fs12.readFileSync)(absolutePath, "utf8");
26382
+ const source = (0, import_node_fs13.readFileSync)(absolutePath, "utf8");
26267
26383
  const { frontmatter, body } = parseFrontmatter(source);
26268
26384
  pages.push({
26269
26385
  slug,
@@ -26782,11 +26898,30 @@ function renderMarkdownHtml(body) {
26782
26898
  function extractTocItems(body, depth) {
26783
26899
  const slug = createSlugger();
26784
26900
  const maxLevel = Math.max(2, Math.min(depth, 6));
26785
- return body.split(/\r?\n/).map((line) => line.match(/^(#{2,6})\s+(.+)$/)).filter((match) => Boolean(match)).map((match) => ({
26786
- id: slug(match[2].trim()),
26787
- title: match[2].trim(),
26788
- level: match[1].length
26789
- })).filter((item) => item.level <= maxLevel);
26901
+ const items = [];
26902
+ let fence = null;
26903
+ for (const line of body.split(/\r?\n/)) {
26904
+ const nextFence = getCodeFence(line);
26905
+ if (fence) {
26906
+ if (nextFence && nextFence.marker === fence.marker && isClosingCodeFence(line, fence)) {
26907
+ fence = null;
26908
+ }
26909
+ continue;
26910
+ }
26911
+ if (nextFence) {
26912
+ fence = nextFence;
26913
+ continue;
26914
+ }
26915
+ const match = line.match(/^(#{2,6})\s+(.+)$/);
26916
+ if (!match) continue;
26917
+ const title = match[2].trim();
26918
+ const id = slug(title);
26919
+ const level = match[1].length;
26920
+ if (level <= maxLevel) {
26921
+ items.push({ id, title, level });
26922
+ }
26923
+ }
26924
+ return items;
26790
26925
  }
26791
26926
  function getThemeUI(docs) {
26792
26927
  const theme = docs.config.theme;
@@ -27275,12 +27410,12 @@ function createFarmDocsHandler(docs, options) {
27275
27410
  );
27276
27411
  }, "handleFarmDocsRequest");
27277
27412
  }
27278
- var import_node_fs12, import_node_path20, import_docs, import_marked, import_sugar_high, DOCS_FILE_NAMES, DOCS_FILE_EXTENSIONS2, FARM_DOCS_FALLBACK_FAVICON, FARM_DOCS_FAVICON_FILES, CODE_LANGUAGE_LABELS, EXTENSIONLESS_CODE_FILENAMES, SIDEBAR_SECTION_ORDER, SIDEBAR_PAGE_ORDER;
27413
+ var import_node_fs13, import_node_path21, import_docs, import_marked, import_sugar_high, DOCS_FILE_NAMES, DOCS_FILE_EXTENSIONS2, FARM_DOCS_FALLBACK_FAVICON, FARM_DOCS_FAVICON_FILES, CODE_LANGUAGE_LABELS, EXTENSIONLESS_CODE_FILENAMES, SIDEBAR_SECTION_ORDER, SIDEBAR_PAGE_ORDER;
27279
27414
  var init_handler = __esm({
27280
27415
  "src/docs/handler.ts"() {
27281
27416
  "use strict";
27282
- import_node_fs12 = require("fs");
27283
- import_node_path20 = __toESM(require("path"));
27417
+ import_node_fs13 = require("fs");
27418
+ import_node_path21 = __toESM(require("path"));
27284
27419
  import_docs = require("@farming-labs/docs");
27285
27420
  import_marked = require("marked");
27286
27421
  import_sugar_high = require("sugar-high");
@@ -28313,8 +28448,8 @@ var init_generator = __esm({
28313
28448
  }
28314
28449
  routeGroups.get(key).push(route);
28315
28450
  }
28316
- for (const [path41, routeList] of routeGroups) {
28317
- const openAPIPath = this.convertToOpenAPIPath(path41);
28451
+ for (const [path42, routeList] of routeGroups) {
28452
+ const openAPIPath = this.convertToOpenAPIPath(path42);
28318
28453
  spec.paths[openAPIPath] = {};
28319
28454
  for (const route of routeList) {
28320
28455
  for (const method of route.methods) {
@@ -28334,8 +28469,8 @@ var init_generator = __esm({
28334
28469
  /**
28335
28470
  * Convert Farm.js API path to OpenAPI path format
28336
28471
  */
28337
- convertToOpenAPIPath(path41) {
28338
- return path41.replace(/^\/api/, "");
28472
+ convertToOpenAPIPath(path42) {
28473
+ return path42.replace(/^\/api/, "");
28339
28474
  }
28340
28475
  /**
28341
28476
  * Extract request body schema from endpoint
@@ -28497,8 +28632,8 @@ var init_generator = __esm({
28497
28632
  /**
28498
28633
  * Generate operation summary
28499
28634
  */
28500
- generateSummary(path41, method) {
28501
- const cleanPath = path41.replace(/^\/api\//, "");
28635
+ generateSummary(path42, method) {
28636
+ const cleanPath = path42.replace(/^\/api\//, "");
28502
28637
  const pathParts = cleanPath.split("/");
28503
28638
  const lastPart = pathParts[pathParts.length - 1];
28504
28639
  const action = method === "GET" ? "Get" : method === "QUERY" ? "Query" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -28507,22 +28642,22 @@ var init_generator = __esm({
28507
28642
  /**
28508
28643
  * Generate operation description
28509
28644
  */
28510
- generateDescription(path41, method) {
28511
- const cleanPath = path41.replace(/^\/api\//, "");
28645
+ generateDescription(path42, method) {
28646
+ const cleanPath = path42.replace(/^\/api\//, "");
28512
28647
  return `${method} ${cleanPath} endpoint`;
28513
28648
  }
28514
28649
  /**
28515
28650
  * Generate operation ID
28516
28651
  */
28517
- generateOperationId(path41, method) {
28518
- const cleanPath = path41.replace(/^\/api\//, "").replace(/\//g, "_");
28652
+ generateOperationId(path42, method) {
28653
+ const cleanPath = path42.replace(/^\/api\//, "").replace(/\//g, "_");
28519
28654
  return `${method.toLowerCase()}_${cleanPath}`;
28520
28655
  }
28521
28656
  /**
28522
28657
  * Generate tags for grouping operations
28523
28658
  */
28524
- generateTags(path41) {
28525
- const cleanPath = path41.replace(/^\/api\//, "");
28659
+ generateTags(path42) {
28660
+ const cleanPath = path42.replace(/^\/api\//, "");
28526
28661
  const pathParts = cleanPath.split("/");
28527
28662
  if (pathParts.length > 1) {
28528
28663
  return [pathParts[0]];
@@ -28534,13 +28669,13 @@ var init_generator = __esm({
28534
28669
  */
28535
28670
  async generateSpecFile(routes, outputPath) {
28536
28671
  const spec = await this.generateSpec(routes);
28537
- const fs14 = require("fs");
28538
- const path41 = require("path");
28539
- const dir = path41.dirname(outputPath);
28540
- if (!fs14.existsSync(dir)) {
28541
- fs14.mkdirSync(dir, { recursive: true });
28672
+ const fs15 = require("fs");
28673
+ const path42 = require("path");
28674
+ const dir = path42.dirname(outputPath);
28675
+ if (!fs15.existsSync(dir)) {
28676
+ fs15.mkdirSync(dir, { recursive: true });
28542
28677
  }
28543
- fs14.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
28678
+ fs15.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
28544
28679
  }
28545
28680
  };
28546
28681
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -28968,7 +29103,7 @@ async function createFarmDevtoolsSnapshot(input) {
28968
29103
  generatedAt: (input.now?.() || /* @__PURE__ */ new Date()).toISOString(),
28969
29104
  health: resolveHealth(diagnostics),
28970
29105
  project: {
28971
- name: import_node_path21.default.basename(import_node_path21.default.resolve(input.root)),
29106
+ name: import_node_path22.default.basename(import_node_path22.default.resolve(input.root)),
28972
29107
  root: input.root,
28973
29108
  srcDir: input.srcDir,
28974
29109
  basePath: config.basePath || "/",
@@ -29017,11 +29152,11 @@ async function createFarmDevtoolsSnapshot(input) {
29017
29152
  diagnostics
29018
29153
  };
29019
29154
  }
29020
- var import_node_path21;
29155
+ var import_node_path22;
29021
29156
  var init_devtools = __esm({
29022
29157
  "src/devtools.ts"() {
29023
29158
  "use strict";
29024
- import_node_path21 = __toESM(require("path"));
29159
+ import_node_path22 = __toESM(require("path"));
29025
29160
  init_config4();
29026
29161
  init_cron();
29027
29162
  init_route_runtime();
@@ -29662,6 +29797,7 @@ function renderFarmDevtoolsHtml(snapshot) {
29662
29797
  .nav-item .icon { width: 13px; height: 13px; }
29663
29798
  .nav-item small { color: #666; font-size: 9px; font-weight: 400; }
29664
29799
  .topbar-meta { display: flex; flex: 0 0 auto; margin-left: auto; border-left: 1px solid var(--line); }
29800
+ .deprecation-tag { display: inline-flex; align-items: center; padding: 0 10px; border-right: 1px solid var(--line); color: #d9a626; font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; white-space: nowrap; }
29665
29801
  .topbar-status { display: flex; min-width: max-content; align-items: center; gap: 7px; padding: 0 11px; color: var(--muted-strong); font-family: var(--font-mono); font-size: 9px; text-transform: uppercase; }
29666
29802
  .status-dot { width: 5px; height: 5px; background: #fff; box-shadow: 0 0 0 3px rgb(255 255 255 / 0.06); }
29667
29803
  .status-dot-attention { background: #909090; animation: status-pulse 1.8s ease-in-out infinite; }
@@ -30171,6 +30307,7 @@ function renderFarmDevtoolsHtml(snapshot) {
30171
30307
  ${renderNavigationItem("raw", "Raw")}
30172
30308
  </nav>
30173
30309
  <div class="topbar-meta">
30310
+ <span class="deprecation-tag" title="The built-in dashboard is deprecated. Install @farm.js/devtools for the maintained workspace.">Deprecated &middot; use @farm.js/devtools</span>
30174
30311
  <span class="project-select">${escapeHtml3(snapshot.project.name)} ${icon(
30175
30312
  "chevron"
30176
30313
  )}</span>
@@ -30426,23 +30563,26 @@ function generateFarmDevtoolsClientRuntime(config) {
30426
30563
  z-index: 2147483646;
30427
30564
  display: grid;
30428
30565
  place-items: center;
30566
+ box-sizing: border-box;
30429
30567
  padding: 20px;
30430
30568
  background: rgb(0 0 0 / 0);
30431
- backdrop-filter: blur(0);
30569
+ backdrop-filter: blur(6px);
30570
+ -webkit-backdrop-filter: blur(6px);
30571
+ overscroll-behavior: none;
30572
+ isolation: isolate;
30432
30573
  opacity: 0;
30433
30574
  pointer-events: none;
30434
- transition: background-color 150ms ease-out, backdrop-filter 150ms ease-out, opacity 150ms ease-out;
30575
+ transition: opacity 150ms ease-out;
30435
30576
  }
30436
30577
  #__farm_devtools_overlay__[data-open="true"] {
30437
- background: rgb(0 0 0 / 0.12);
30438
- backdrop-filter: blur(1px);
30578
+ background: rgb(0 0 0 / 0.32);
30439
30579
  opacity: 1;
30440
30580
  pointer-events: auto;
30441
30581
  }
30442
30582
  #__farm_devtools_overlay__ > iframe {
30443
30583
  display: block;
30444
- width: min(960px, calc(100vw - 40px));
30445
- height: min(560px, calc(100dvh - 40px));
30584
+ width: min(1100px, calc(100vw - 48px));
30585
+ height: min(720px, calc(100dvh - 48px));
30446
30586
  border: 0;
30447
30587
  border-radius: 12px;
30448
30588
  background: transparent;
@@ -30458,7 +30598,7 @@ function generateFarmDevtoolsClientRuntime(config) {
30458
30598
  #__farm_devtools_overlay__ > iframe {
30459
30599
  width: calc(100vw - 16px);
30460
30600
  height: calc(100dvh - 16px);
30461
- border-radius: 10px;
30601
+ border-radius: 12px;
30462
30602
  }
30463
30603
  }
30464
30604
  @media (prefers-reduced-motion: reduce) {
@@ -30472,10 +30612,32 @@ function generateFarmDevtoolsClientRuntime(config) {
30472
30612
  const runtimeKey = "__FARM_DEVTOOLS_RUNTIME__";
30473
30613
  const launchParam = ${JSON.stringify(FARM_DEVTOOLS_LAUNCH_PARAM)};
30474
30614
  const devtoolsPath = ${JSON.stringify(FARM_DEVTOOLS_PATH)};
30475
- const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw"]);
30615
+ const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw", "inspect", "diagnostics"]);
30476
30616
  const shortcut = ${JSON.stringify(shortcut)};
30477
30617
  const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform);
30478
30618
  let returnFocus = null;
30619
+ let restorePage = null;
30620
+ let closeTimer = null;
30621
+
30622
+ const lockPage = () => {
30623
+ const styles = [];
30624
+ for (const element of [document.documentElement, document.body]) {
30625
+ for (const [property, value] of [["overflow-x", "hidden"], ["overflow-y", "hidden"], ["overscroll-behavior", "none"]]) {
30626
+ const previous = element.style.getPropertyValue(property);
30627
+ const priority = element.style.getPropertyPriority(property);
30628
+ element.style.setProperty(property, value, "important");
30629
+ styles.push({ element, property, value, previous, priority });
30630
+ }
30631
+ }
30632
+ return () => {
30633
+ for (const { element, property, value, previous, priority } of styles) {
30634
+ // Do not overwrite a newer style set by the application while the panel was open.
30635
+ if (element.style.getPropertyValue(property) !== value || element.style.getPropertyPriority(property) !== "important") continue;
30636
+ if (previous) element.style.setProperty(property, previous, priority);
30637
+ else element.style.removeProperty(property);
30638
+ }
30639
+ };
30640
+ };
30479
30641
 
30480
30642
  const matchesShortcut = (event) => {
30481
30643
  if (!shortcut || event.repeat) return false;
@@ -30502,24 +30664,35 @@ function generateFarmDevtoolsClientRuntime(config) {
30502
30664
  document.head.appendChild(style);
30503
30665
  };
30504
30666
 
30505
- const close = () => {
30667
+ const finishClose = () => {
30668
+ if (closeTimer !== null) window.clearTimeout(closeTimer);
30669
+ closeTimer = null;
30506
30670
  const overlay = document.getElementById(overlayId);
30507
- if (!overlay) return;
30671
+ overlay?.remove();
30672
+ restorePage?.();
30673
+ restorePage = null;
30508
30674
  const focusTarget = returnFocus;
30509
30675
  returnFocus = null;
30676
+ focusTarget?.focus?.({ preventScroll: true });
30677
+ };
30678
+
30679
+ const close = () => {
30680
+ const overlay = document.getElementById(overlayId);
30681
+ if (!overlay || closeTimer !== null) return;
30510
30682
  overlay.dataset.open = "false";
30511
- window.setTimeout(() => {
30512
- overlay.remove();
30513
- focusTarget?.focus?.();
30514
- }, 160);
30683
+ closeTimer = window.setTimeout(finishClose, 160);
30515
30684
  };
30516
30685
 
30517
30686
  const open = (view = "overview") => {
30687
+ if (closeTimer !== null) finishClose();
30518
30688
  if (document.getElementById(overlayId)) return;
30519
30689
  ensureStyles();
30520
30690
  returnFocus = document.activeElement;
30691
+ restorePage = lockPage();
30521
30692
  const overlay = document.createElement("div");
30522
30693
  overlay.id = overlayId;
30694
+ overlay.setAttribute("role", "dialog");
30695
+ overlay.setAttribute("aria-modal", "true");
30523
30696
  overlay.setAttribute("aria-label", "Farm.js DevTools overlay");
30524
30697
  const frame = document.createElement("iframe");
30525
30698
  const resolvedView = validViews.has(view) ? view : "overview";
@@ -30530,9 +30703,11 @@ function generateFarmDevtoolsClientRuntime(config) {
30530
30703
  overlay.addEventListener("pointerdown", (event) => {
30531
30704
  if (event.target === overlay) close();
30532
30705
  });
30706
+ overlay.addEventListener("wheel", (event) => event.preventDefault(), { passive: false });
30707
+ overlay.addEventListener("touchmove", (event) => event.preventDefault(), { passive: false });
30533
30708
  document.body.appendChild(overlay);
30534
30709
  requestAnimationFrame(() => {
30535
- overlay.dataset.open = "true";
30710
+ if (overlay.isConnected && closeTimer === null) overlay.dataset.open = "true";
30536
30711
  });
30537
30712
  };
30538
30713
 
@@ -30566,6 +30741,7 @@ function generateFarmDevtoolsClientRuntime(config) {
30566
30741
  window.addEventListener("message", onMessage);
30567
30742
  window[runtimeKey] = {
30568
30743
  dispose() {
30744
+ finishClose();
30569
30745
  window.removeEventListener("keydown", onKeydown, true);
30570
30746
  window.removeEventListener("message", onMessage);
30571
30747
  },
@@ -30783,6 +30959,8 @@ __export(vite_exports, {
30783
30959
  defineConfig: () => defineConfig2,
30784
30960
  farmI18nClientBridgePlugin: () => farmI18nClientBridgePlugin,
30785
30961
  farmPlugin: () => farmPlugin,
30962
+ generateClientCachePersistenceCode: () => generateClientCachePersistenceCode,
30963
+ resolveFarmClientCacheAdapterEntry: () => resolveFarmClientCacheAdapterEntry,
30786
30964
  rewriteEarlySsrRelativeImports: () => rewriteEarlySsrRelativeImports,
30787
30965
  transformIsolatedClientBoundaryModule: () => transformIsolatedClientBoundaryModule,
30788
30966
  withFarmRequestTracing: () => withFarmRequestTracing
@@ -31152,18 +31330,18 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
31152
31330
  return normalizedFile.startsWith(`${srcDirSlug}/`) && /\.(ts|tsx|js|jsx)$/.test(normalizedFile) && !normalizedFile.endsWith(".d.ts") && !normalizedFile.endsWith("/farm-routes.d.ts") && !normalizedFile.endsWith("/farm-env.d.ts") && !normalizedFile.endsWith("/lib/api.generated.ts");
31153
31331
  }
31154
31332
  function fileContainsProgrammaticPageRoute(file) {
31155
- if (!fs13.existsSync(file)) {
31333
+ if (!fs14.existsSync(file)) {
31156
31334
  return false;
31157
31335
  }
31158
31336
  try {
31159
- return scanProgrammaticPagePaths(fs13.readFileSync(file, "utf8")).length > 0;
31337
+ return scanProgrammaticPagePaths(fs14.readFileSync(file, "utf8")).length > 0;
31160
31338
  } catch {
31161
31339
  return false;
31162
31340
  }
31163
31341
  }
31164
31342
  function rewriteEarlySsrRelativeImports(options) {
31165
31343
  const cleanId = options.id.split("?", 1)[0];
31166
- if (!path37.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31344
+ if (!path38.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31167
31345
  return null;
31168
31346
  }
31169
31347
  const replacements = [];
@@ -31183,7 +31361,7 @@ function rewriteEarlySsrRelativeImports(options) {
31183
31361
  const suffixIndex = source.value.search(/[?#]/);
31184
31362
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
31185
31363
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
31186
- const resolvedPath = path37.resolve(path37.dirname(cleanId), sourcePath);
31364
+ const resolvedPath = path38.resolve(path38.dirname(cleanId), sourcePath);
31187
31365
  replacements.push({
31188
31366
  start: source.start,
31189
31367
  end: source.end,
@@ -31340,7 +31518,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31340
31518
  ...layerRoots.length ? {
31341
31519
  server: {
31342
31520
  fs: {
31343
- allow: [path37.resolve(options.root || process.cwd()), ...layerRoots]
31521
+ allow: [path38.resolve(options.root || process.cwd()), ...layerRoots]
31344
31522
  }
31345
31523
  }
31346
31524
  } : {}
@@ -31371,13 +31549,13 @@ function farmPlugin(options = {}, initialPluginManager) {
31371
31549
  },
31372
31550
  server
31373
31551
  );
31374
- const globalsCSSPath = path37.join(server.config.root, "src/app/globals.css");
31375
- if (!fs13.existsSync(globalsCSSPath)) {
31376
- const appDir = path37.join(server.config.root, "src/app");
31377
- if (!fs13.existsSync(appDir)) {
31378
- fs13.mkdirSync(appDir, { recursive: true });
31552
+ const globalsCSSPath = path38.join(server.config.root, "src/app/globals.css");
31553
+ if (!fs14.existsSync(globalsCSSPath)) {
31554
+ const appDir = path38.join(server.config.root, "src/app");
31555
+ if (!fs14.existsSync(appDir)) {
31556
+ fs14.mkdirSync(appDir, { recursive: true });
31379
31557
  }
31380
- fs13.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31558
+ fs14.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31381
31559
  }
31382
31560
  await farmApp.initialize();
31383
31561
  const farmConfig = farmApp.getConfig();
@@ -31398,10 +31576,10 @@ function farmPlugin(options = {}, initialPluginManager) {
31398
31576
  });
31399
31577
  }
31400
31578
  const sourceRoots = getFarmSourceRoots(farmConfig);
31401
- server.watcher.add(sourceRoots.map((source) => path37.join(source.root, source.srcDir)));
31579
+ server.watcher.add(sourceRoots.map((source) => path38.join(source.root, source.srcDir)));
31402
31580
  if (farmConfig.i18n.enabled) {
31403
31581
  server.watcher.add(
31404
- farmConfig.i18n.messages.includes("{locale}") ? path37.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
31582
+ farmConfig.i18n.messages.includes("{locale}") ? path38.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
31405
31583
  );
31406
31584
  }
31407
31585
  const workflowConfig = farmConfig.workflows;
@@ -31411,7 +31589,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31411
31589
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
31412
31590
  ], "getExtraRouteTypes");
31413
31591
  const appDirSlugs = sourceRoots.map(
31414
- (source) => path37.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31592
+ (source) => path38.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31415
31593
  );
31416
31594
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
31417
31595
  try {
@@ -31452,7 +31630,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31452
31630
  }, "generateTypeArtifacts");
31453
31631
  await generateTypeArtifacts("startup");
31454
31632
  const srcDirSlugs = sourceRoots.map(
31455
- (source) => path37.join(source.root, source.srcDir).replace(/\\/g, "/")
31633
+ (source) => path38.join(source.root, source.srcDir).replace(/\\/g, "/")
31456
31634
  );
31457
31635
  const layerConfigFiles = new Set(
31458
31636
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -31573,7 +31751,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31573
31751
  await apiRouteManager.discoverRoutes();
31574
31752
  let discoveredWorkflows = [];
31575
31753
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
31576
- (dir) => fs13.existsSync(path37.isAbsolute(dir) ? dir : path37.join(farmConfig.root, dir))
31754
+ (dir) => fs14.existsSync(path38.isAbsolute(dir) ? dir : path38.join(farmConfig.root, dir))
31577
31755
  );
31578
31756
  if (hasWorkflowDirectory) {
31579
31757
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -31838,12 +32016,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31838
32016
  }
31839
32017
  }
31840
32018
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
31841
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs13.existsSync(farmDocsFontPath)) {
32019
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs14.existsSync(farmDocsFontPath)) {
31842
32020
  res.statusCode = 200;
31843
32021
  res.setHeader("Content-Type", "font/woff2");
31844
32022
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
31845
32023
  if (requestMethod === "HEAD") res.end();
31846
- else fs13.createReadStream(farmDocsFontPath).pipe(res);
32024
+ else fs14.createReadStream(farmDocsFontPath).pipe(res);
31847
32025
  return;
31848
32026
  }
31849
32027
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -31899,6 +32077,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31899
32077
  if (requestPathname.endsWith(".json")) {
31900
32078
  res.end(JSON.stringify(snapshot, null, 2));
31901
32079
  } else {
32080
+ if (!warnedDeprecatedDevtoolsDashboard) {
32081
+ warnedDeprecatedDevtoolsDashboard = true;
32082
+ logger.warn(
32083
+ "The built-in DevTools dashboard is deprecated. Install @farm.js/devtools and add devtools() to plugins in farm.config.ts."
32084
+ );
32085
+ }
31902
32086
  const { renderFarmDevtoolsHtml: renderFarmDevtoolsHtml2 } = await loadFarmDevtoolsUIRuntime();
31903
32087
  res.end(renderFarmDevtoolsHtml2(snapshot));
31904
32088
  }
@@ -31941,7 +32125,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31941
32125
  return null;
31942
32126
  }
31943
32127
  return {
31944
- source: await fs13.promises.readFile(sourcePath, "utf8"),
32128
+ source: await fs14.promises.readFile(sourcePath, "utf8"),
31945
32129
  filePath: sourcePath
31946
32130
  };
31947
32131
  }, "resolveSource")
@@ -32825,7 +33009,10 @@ ${generatedDevIndicatorsClientRuntime}`,
32825
33009
  renderer,
32826
33010
  isolatedHydrationMode === "enabled",
32827
33011
  resolvedConfig?.trailingSlash ?? false,
32828
- resolvedConfig?.basePath ?? "/"
33012
+ resolvedConfig?.basePath ?? "/",
33013
+ generateClientCachePersistenceCode(
33014
+ resolveFarmClientCacheAdapterEntry(root, resolvedConfig?.cache)
33015
+ )
32829
33016
  );
32830
33017
  }
32831
33018
  if (id === "/@farm/server") {
@@ -32964,7 +33151,7 @@ export const manifest = getManifest();
32964
33151
  const root = currentConfig.root || server?.config.root || process.cwd();
32965
33152
  const cleanId = id.split("?", 1)[0];
32966
33153
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
32967
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path37.resolve(cleanId)) === true;
33154
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path38.resolve(cleanId)) === true;
32968
33155
  if (isolatedHydrationEnabled && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
32969
33156
  isolatedModuleReference = toViteModuleId(cleanId, root);
32970
33157
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -33055,8 +33242,8 @@ if (import.meta.hot) {
33055
33242
  }
33056
33243
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
33057
33244
  logger.info("Pre-rendering SSG pages...");
33058
- const outDir = path37.join(server?.config.root || process.cwd(), options.outDir || "dist");
33059
- const clientDir = path37.join(outDir, "client");
33245
+ const outDir = path38.join(server?.config.root || process.cwd(), options.outDir || "dist");
33246
+ const clientDir = path38.join(outDir, "client");
33060
33247
  for (const page2 of ssgPages) {
33061
33248
  try {
33062
33249
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -33108,9 +33295,9 @@ if (import.meta.hot) {
33108
33295
  <script type="module" src="/assets/client.js"></script>
33109
33296
  </body>
33110
33297
  </html>`;
33111
- const outputPath = page2.urlPath === "/" ? path37.join(clientDir, "index.html") : path37.join(clientDir, page2.urlPath + ".html");
33112
- fs13.mkdirSync(path37.dirname(outputPath), { recursive: true });
33113
- fs13.writeFileSync(outputPath, fullHtml);
33298
+ const outputPath = page2.urlPath === "/" ? path38.join(clientDir, "index.html") : path38.join(clientDir, page2.urlPath + ".html");
33299
+ fs14.mkdirSync(path38.dirname(outputPath), { recursive: true });
33300
+ fs14.writeFileSync(outputPath, fullHtml);
33114
33301
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
33115
33302
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
33116
33303
  });
@@ -33118,8 +33305,8 @@ if (import.meta.hot) {
33118
33305
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
33119
33306
  }
33120
33307
  }
33121
- const manifestPath = path37.join(outDir, "__ssg_manifest.json");
33122
- fs13.writeFileSync(
33308
+ const manifestPath = path38.join(outDir, "__ssg_manifest.json");
33309
+ fs14.writeFileSync(
33123
33310
  manifestPath,
33124
33311
  JSON.stringify(
33125
33312
  ssgPages.map((p) => ({
@@ -33162,9 +33349,9 @@ if (import.meta.hot) {
33162
33349
  server2.ws.send({ type: "full-reload", path: "*" });
33163
33350
  return [];
33164
33351
  }
33165
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path37.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
33352
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path38.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
33166
33353
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
33167
- logUpdate("PAGE", `updated ${path37.basename(file)}`);
33354
+ logUpdate("PAGE", `updated ${path38.basename(file)}`);
33168
33355
  for (const mod of modules) {
33169
33356
  server2.moduleGraph.invalidateModule(mod);
33170
33357
  }
@@ -33580,7 +33767,7 @@ function parseRouteModuleSchema2(schema, value, label, routePath) {
33580
33767
  throw new Error(`Invalid ${label} for route "${routePath}": ${message}`);
33581
33768
  }
33582
33769
  }
33583
- function generateClientCode(integrationProviders = [], documentNavigationMatchers = [], docsSearchClientRuntime = EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, devtoolsClientRuntime = "", plugins = [], root = process.cwd(), srcDir = "src", publicRuntimeConfig = void 0, docsAdapterReact, renderer = REACT_RENDERER, isolatedHydrationEnabled = false, trailingSlash = false, basePath = "/") {
33770
+ function generateClientCode(integrationProviders = [], documentNavigationMatchers = [], docsSearchClientRuntime = EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, devtoolsClientRuntime = "", plugins = [], root = process.cwd(), srcDir = "src", publicRuntimeConfig = void 0, docsAdapterReact, renderer = REACT_RENDERER, isolatedHydrationEnabled = false, trailingSlash = false, basePath = "/", clientCachePersistence = { imports: "", init: "" }) {
33584
33771
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
33585
33772
  const clientPluginEntry = generateFarmClientPluginEntryCode(
33586
33773
  plugins,
@@ -33636,6 +33823,7 @@ import {
33636
33823
  } from '@farm.js/core/deployment'
33637
33824
  ${providerClientCode.imports}
33638
33825
  ${clientPluginEntry.imports}
33826
+ ${clientCachePersistence.imports}
33639
33827
  ${docsSearchClientRuntime}
33640
33828
  ${devtoolsClientRuntime}
33641
33829
  ${docsAdapterImportBlock}
@@ -33651,6 +33839,7 @@ const integrationDocumentNavigationMatchers = ${JSON.stringify(documentNavigatio
33651
33839
  setFarmBasePath(${JSON.stringify(basePath)});
33652
33840
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
33653
33841
  installChunkErrorRecovery();
33842
+ ${clientCachePersistence.init}
33654
33843
 
33655
33844
  let reactRoot = null;
33656
33845
  ${isolatedHydrationRuntime}
@@ -35031,7 +35220,7 @@ function generateClientManifest(bundle) {
35031
35220
  }
35032
35221
  async function defineConfig2(config = {}) {
35033
35222
  const tailwindcss = (await import("@tailwindcss/vite")).default;
35034
- const appRoot = path37.resolve(config.root || process.cwd());
35223
+ const appRoot = path38.resolve(config.root || process.cwd());
35035
35224
  if (config.extends?.length) {
35036
35225
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
35037
35226
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
@@ -35245,7 +35434,7 @@ async function defineConfig2(config = {}) {
35245
35434
  }
35246
35435
  };
35247
35436
  }
35248
- var fs13, path37, import_node_url9, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifactSelection, FARM_I18N_CLIENT_BRIDGE_ID, EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, FARM_CONFIG_FILENAMES;
35437
+ var fs14, path38, import_node_url9, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifactSelection, FARM_I18N_CLIENT_BRIDGE_ID, warnedDeprecatedDevtoolsDashboard, EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, FARM_CONFIG_FILENAMES;
35249
35438
  var init_vite2 = __esm({
35250
35439
  "src/vite.ts"() {
35251
35440
  "use strict";
@@ -35254,6 +35443,8 @@ var init_vite2 = __esm({
35254
35443
  init_default_styles();
35255
35444
  init_plugin();
35256
35445
  init_client_plugin_build();
35446
+ init_client_cache_persistence_build();
35447
+ init_client_cache_persistence_build();
35257
35448
  init_route_manager2();
35258
35449
  init_config3();
35259
35450
  init_server_path();
@@ -35269,8 +35460,8 @@ var init_vite2 = __esm({
35269
35460
  init_route_context();
35270
35461
  init_devtools_config();
35271
35462
  init_dev_indicators();
35272
- fs13 = __toESM(require("fs"));
35273
- path37 = __toESM(require("path"));
35463
+ fs14 = __toESM(require("fs"));
35464
+ path38 = __toESM(require("path"));
35274
35465
  import_node_url9 = require("url");
35275
35466
  init_layers();
35276
35467
  init_environment_vite();
@@ -35319,6 +35510,7 @@ var init_vite2 = __esm({
35319
35510
  i18n: false
35320
35511
  }), "createEmptyTypeArtifactSelection");
35321
35512
  FARM_I18N_CLIENT_BRIDGE_ID = "\0farm-i18n-client-bridge";
35513
+ warnedDeprecatedDevtoolsDashboard = false;
35322
35514
  EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME = `
35323
35515
  function isFarmDocsSearchPage() {
35324
35516
  return false;
@@ -36055,7 +36247,7 @@ module.exports = __toCommonJS(build_runtime_exports);
36055
36247
  // src/build/index.ts
36056
36248
  init_config4();
36057
36249
  var import_path17 = __toESM(require("path"));
36058
- var import_node_fs13 = require("fs");
36250
+ var import_node_fs14 = require("fs");
36059
36251
  init_utils();
36060
36252
  init_app();
36061
36253
  init_route_manager2();
@@ -36070,15 +36262,15 @@ var import_path8 = __toESM(require("path"));
36070
36262
  var FARM_CLIENT_CSS_HREF_PLACEHOLDER = "/__farm_client_css_href__";
36071
36263
  var FARM_CLIENT_JS_SRC_PLACEHOLDER = "/__farm_client_js_src__";
36072
36264
  async function hashAndCopy(sourcePath, destinationDir, hashedName) {
36073
- const fs14 = await import("fs/promises");
36265
+ const fs15 = await import("fs/promises");
36074
36266
  try {
36075
- const bytes = await fs14.readFile(sourcePath);
36267
+ const bytes = await fs15.readFile(sourcePath);
36076
36268
  if (bytes.length === 0) return null;
36077
36269
  const { createHash: createHash5 } = await import("crypto");
36078
36270
  const hash = createHash5("sha256").update(bytes).digest("hex").slice(0, 8);
36079
36271
  const name2 = hashedName(hash);
36080
- await fs14.mkdir(destinationDir, { recursive: true });
36081
- await fs14.writeFile(import_path8.default.join(destinationDir, name2), bytes);
36272
+ await fs15.mkdir(destinationDir, { recursive: true });
36273
+ await fs15.writeFile(import_path8.default.join(destinationDir, name2), bytes);
36082
36274
  return name2;
36083
36275
  } catch {
36084
36276
  return null;
@@ -36095,9 +36287,9 @@ async function resolveHashedClientCssHref(clientOutputDir) {
36095
36287
  }
36096
36288
  __name(resolveHashedClientCssHref, "resolveHashedClientCssHref");
36097
36289
  async function findFingerprintedClientEntry(clientOutputDir) {
36098
- const fs14 = await import("fs/promises");
36290
+ const fs15 = await import("fs/promises");
36099
36291
  try {
36100
- const entries = await fs14.readdir(clientOutputDir);
36292
+ const entries = await fs15.readdir(clientOutputDir);
36101
36293
  return entries.find((name2) => /^farm-client-h[0-9a-f]+\.js$/.test(name2)) ?? null;
36102
36294
  } catch {
36103
36295
  return null;
@@ -36107,10 +36299,10 @@ __name(findFingerprintedClientEntry, "findFingerprintedClientEntry");
36107
36299
  async function resolveHashedClientJsSrc(clientOutputDir) {
36108
36300
  const entryName = await findFingerprintedClientEntry(clientOutputDir);
36109
36301
  if (!entryName) return "/farm-client.js";
36110
- const fs14 = await import("fs/promises");
36302
+ const fs15 = await import("fs/promises");
36111
36303
  const shim = `export * from "./${entryName}";
36112
36304
  `;
36113
- await fs14.writeFile(import_path8.default.join(clientOutputDir, "farm-client.js"), shim);
36305
+ await fs15.writeFile(import_path8.default.join(clientOutputDir, "farm-client.js"), shim);
36114
36306
  return `/${entryName}`;
36115
36307
  }
36116
36308
  __name(resolveHashedClientJsSrc, "resolveHashedClientJsSrc");
@@ -36118,6 +36310,7 @@ __name(resolveHashedClientJsSrc, "resolveHashedClientJsSrc");
36118
36310
  // src/nitro/universal-build.ts
36119
36311
  init_server_path();
36120
36312
  init_client_plugin_build();
36313
+ init_client_cache_persistence_build();
36121
36314
  var import_os = __toESM(require("os"));
36122
36315
  var import_path14 = __toESM(require("path"));
36123
36316
  var import_fs5 = require("fs");
@@ -36214,10 +36407,10 @@ async function createFarmRouteRuntimeManifest(options) {
36214
36407
  }
36215
36408
  __name(createFarmRouteRuntimeManifest, "createFarmRouteRuntimeManifest");
36216
36409
  async function writeFarmRouteRuntimeManifest(directory, manifest) {
36217
- const fs14 = await import("fs/promises");
36410
+ const fs15 = await import("fs/promises");
36218
36411
  const manifestPath = import_path9.default.join(directory, FARM_ROUTE_RUNTIME_MANIFEST);
36219
- await fs14.mkdir(directory, { recursive: true });
36220
- await fs14.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
36412
+ await fs15.mkdir(directory, { recursive: true });
36413
+ await fs15.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
36221
36414
  `);
36222
36415
  return manifestPath;
36223
36416
  }
@@ -36263,7 +36456,7 @@ __name(normalizeManifestSource, "normalizeManifestSource");
36263
36456
  // src/nitro/vercel-route-runtime.ts
36264
36457
  var import_path10 = __toESM(require("path"));
36265
36458
  init_route_runtime();
36266
- async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs14) {
36459
+ async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs15) {
36267
36460
  const dynamicRoutes = manifest.routes.filter(
36268
36461
  (route) => route.rendering === "dynamic" && route.runtime !== "edge"
36269
36462
  );
@@ -36294,8 +36487,8 @@ async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs14)
36294
36487
  groupIndex += 1;
36295
36488
  const functionName = `__farm_runtime_${groupIndex}`;
36296
36489
  const functionDir = import_path10.default.join(functionsDir, `${functionName}.func`);
36297
- await fs14.cp(baseFunctionDir, functionDir, { recursive: true, force: true });
36298
- await configureVercelFunction(functionDir, group.config, fs14);
36490
+ await fs15.cp(baseFunctionDir, functionDir, { recursive: true, force: true });
36491
+ await configureVercelFunction(functionDir, group.config, fs15);
36299
36492
  destinations.set(key, `/${functionName}`);
36300
36493
  }
36301
36494
  const routes = [];
@@ -36342,15 +36535,15 @@ function farmRoutePatternToVercelSource(pattern) {
36342
36535
  return source || "/";
36343
36536
  }
36344
36537
  __name(farmRoutePatternToVercelSource, "farmRoutePatternToVercelSource");
36345
- async function configureVercelFunction(functionDir, config, fs14) {
36538
+ async function configureVercelFunction(functionDir, config, fs15) {
36346
36539
  const configPath = import_path10.default.join(functionDir, ".vc-config.json");
36347
- const current = JSON.parse(await fs14.readFile(configPath, "utf8"));
36540
+ const current = JSON.parse(await fs15.readFile(configPath, "utf8"));
36348
36541
  const next = {
36349
36542
  ...current,
36350
36543
  ...config.regions?.length ? { regions: config.regions } : {},
36351
36544
  ...config.maxDuration ? { maxDuration: config.maxDuration } : {}
36352
36545
  };
36353
- await fs14.writeFile(configPath, `${JSON.stringify(next, null, 2)}
36546
+ await fs15.writeFile(configPath, `${JSON.stringify(next, null, 2)}
36354
36547
  `);
36355
36548
  }
36356
36549
  __name(configureVercelFunction, "configureVercelFunction");
@@ -36400,6 +36593,34 @@ function createFarmVercelImmutableAssetRoute() {
36400
36593
  };
36401
36594
  }
36402
36595
  __name(createFarmVercelImmutableAssetRoute, "createFarmVercelImmutableAssetRoute");
36596
+ function buildFarmVercelRoutes(options) {
36597
+ const { presetRoutes, runtimeRoutes, apiBasePath } = options;
36598
+ const filesystemIndex = presetRoutes.findIndex((route) => route.handle === "filesystem");
36599
+ const sourceRoutes = filesystemIndex >= 0 ? presetRoutes.slice(0, filesystemIndex) : [];
36600
+ const preservedSourceRoutes = sourceRoutes.filter((route) => route.continue !== true);
36601
+ return [
36602
+ ...preservedSourceRoutes,
36603
+ createFarmVercelImmutableAssetRoute(),
36604
+ { handle: "filesystem" },
36605
+ ...runtimeRoutes,
36606
+ ...apiBasePath === "/" ? [] : [
36607
+ {
36608
+ src: `${apiBasePath}/(.*)`,
36609
+ dest: "/__nitro",
36610
+ headers: {
36611
+ "Access-Control-Allow-Origin": "*",
36612
+ "Access-Control-Allow-Methods": "*",
36613
+ "Access-Control-Allow-Headers": "*"
36614
+ }
36615
+ }
36616
+ ],
36617
+ {
36618
+ src: "/(.*)",
36619
+ dest: "/__nitro"
36620
+ }
36621
+ ];
36622
+ }
36623
+ __name(buildFarmVercelRoutes, "buildFarmVercelRoutes");
36403
36624
 
36404
36625
  // src/nitro/node-server-entry.ts
36405
36626
  function createFarmNodeServerEntry(options) {
@@ -36693,23 +36914,23 @@ init_vite();
36693
36914
 
36694
36915
  // src/instrumentation.ts
36695
36916
  var import_esbuild = require("esbuild");
36696
- var import_node_fs8 = __toESM(require("fs"));
36697
- var import_node_path16 = __toESM(require("path"));
36917
+ var import_node_fs9 = __toESM(require("fs"));
36918
+ var import_node_path17 = __toESM(require("path"));
36698
36919
  var import_node_url8 = require("url");
36699
36920
  var INSTRUMENTATION_EXTENSIONS = ["ts", "mts", "js", "mjs"];
36700
36921
  function resolveFarmInstrumentationFile(root, srcDir = "src") {
36701
36922
  const candidates = [
36702
36923
  ...INSTRUMENTATION_EXTENSIONS.map(
36703
- (extension) => import_node_path16.default.join(root, srcDir, `instrumentation.${extension}`)
36924
+ (extension) => import_node_path17.default.join(root, srcDir, `instrumentation.${extension}`)
36704
36925
  ),
36705
36926
  ...INSTRUMENTATION_EXTENSIONS.map(
36706
- (extension) => import_node_path16.default.join(root, `instrumentation.${extension}`)
36927
+ (extension) => import_node_path17.default.join(root, `instrumentation.${extension}`)
36707
36928
  )
36708
- ].filter((candidate) => import_node_fs8.default.existsSync(candidate));
36929
+ ].filter((candidate) => import_node_fs9.default.existsSync(candidate));
36709
36930
  if (candidates.length > 1) {
36710
36931
  throw new Error(
36711
36932
  `Farm.js found multiple instrumentation files:
36712
- ${candidates.map((candidate) => `- ${import_node_path16.default.relative(root, candidate)}`).join("\n")}
36933
+ ${candidates.map((candidate) => `- ${import_node_path17.default.relative(root, candidate)}`).join("\n")}
36713
36934
  Keep only one instrumentation file in the project root or ${srcDir}/.`
36714
36935
  );
36715
36936
  }
@@ -37064,7 +37285,7 @@ function hasProjectPostcssConfig(root) {
37064
37285
  }
37065
37286
  __name(hasProjectPostcssConfig, "hasProjectPostcssConfig");
37066
37287
  async function findFarmConfigPath(root) {
37067
- const fs14 = await import("fs/promises");
37288
+ const fs15 = await import("fs/promises");
37068
37289
  const candidates = [
37069
37290
  "farm.config.ts",
37070
37291
  "farm.config.mts",
@@ -37078,7 +37299,7 @@ async function findFarmConfigPath(root) {
37078
37299
  for (const candidate of candidates) {
37079
37300
  const resolvedPath = import_path14.default.join(root, candidate);
37080
37301
  try {
37081
- await fs14.access(resolvedPath);
37302
+ await fs15.access(resolvedPath);
37082
37303
  return resolvedPath;
37083
37304
  } catch {
37084
37305
  }
@@ -37105,13 +37326,13 @@ function hasFarmServerRuntimePlugins(config) {
37105
37326
  }
37106
37327
  __name(hasFarmServerRuntimePlugins, "hasFarmServerRuntimePlugins");
37107
37328
  async function discoverMiddlewareRoutes(appDir) {
37108
- const fs14 = await import("fs/promises");
37329
+ const fs15 = await import("fs/promises");
37109
37330
  const appDirs = Array.isArray(appDir) ? [...appDir] : [appDir];
37110
37331
  const routes = /* @__PURE__ */ new Map();
37111
37332
  async function walk(dir, routePath, discovered) {
37112
37333
  let entries;
37113
37334
  try {
37114
- entries = await fs14.readdir(dir, { withFileTypes: true });
37335
+ entries = await fs15.readdir(dir, { withFileTypes: true });
37115
37336
  } catch {
37116
37337
  return;
37117
37338
  }
@@ -37192,12 +37413,12 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
37192
37413
  })
37193
37414
  );
37194
37415
  logger.info(`\u{1F4CB} Found ${pageRoutes.length} page routes`);
37195
- const fs14 = await import("fs/promises");
37416
+ const fs15 = await import("fs/promises");
37196
37417
  const layoutRoutes = [];
37197
37418
  const appDir = import_path14.default.join(root, srcDir, "app");
37198
37419
  async function findLayoutsForClient(dir, routePrefix = "/") {
37199
37420
  try {
37200
- const entries = await fs14.readdir(dir, { withFileTypes: true });
37421
+ const entries = await fs15.readdir(dir, { withFileTypes: true });
37201
37422
  for (const entry of entries) {
37202
37423
  if (entry.isFile() && entry.name.match(/^layout\.(tsx?|jsx?|vue|svelte)$/)) {
37203
37424
  layoutRoutes.push({
@@ -37345,7 +37566,7 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
37345
37566
  }
37346
37567
  __name(buildUniversal, "buildUniversal");
37347
37568
  async function writeSSRAssetsToClient(bundle, outputDir) {
37348
- const fs14 = await import("fs/promises");
37569
+ const fs15 = await import("fs/promises");
37349
37570
  for (const [fileName, output] of Object.entries(bundle)) {
37350
37571
  if (output.type !== "asset") continue;
37351
37572
  if (fileName === "farm-fonts.css") {
@@ -37353,29 +37574,29 @@ async function writeSSRAssetsToClient(bundle, outputDir) {
37353
37574
  continue;
37354
37575
  }
37355
37576
  const filePath = import_path14.default.join(outputDir, fileName);
37356
- await fs14.mkdir(import_path14.default.dirname(filePath), { recursive: true });
37357
- await fs14.writeFile(filePath, output.source);
37577
+ await fs15.mkdir(import_path14.default.dirname(filePath), { recursive: true });
37578
+ await fs15.writeFile(filePath, output.source);
37358
37579
  }
37359
37580
  }
37360
37581
  __name(writeSSRAssetsToClient, "writeSSRAssetsToClient");
37361
37582
  async function copyFarmDocsFontAssetsToClient(root, outputDir) {
37362
- const fs14 = await import("fs/promises");
37583
+ const fs15 = await import("fs/promises");
37363
37584
  await Promise.all(
37364
37585
  resolveFarmDocsFontAssets(root).map(async ({ sourcePath, url }) => {
37365
37586
  const targetPath = import_path14.default.join(outputDir, url.replace(/^\/+/, ""));
37366
- await fs14.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
37367
- await fs14.copyFile(sourcePath, targetPath);
37587
+ await fs15.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
37588
+ await fs15.copyFile(sourcePath, targetPath);
37368
37589
  })
37369
37590
  );
37370
37591
  }
37371
37592
  __name(copyFarmDocsFontAssetsToClient, "copyFarmDocsFontAssetsToClient");
37372
37593
  async function mergeBuiltFontCss(outputDir, fontCssSource) {
37373
- const fs14 = await import("fs/promises");
37594
+ const fs15 = await import("fs/promises");
37374
37595
  const fontCssPath = import_path14.default.join(outputDir, "farm-fonts.css");
37375
37596
  let fontCss = fontCssSource;
37376
37597
  if (fontCss === void 0) {
37377
37598
  try {
37378
- fontCss = await fs14.readFile(fontCssPath);
37599
+ fontCss = await fs15.readFile(fontCssPath);
37379
37600
  } catch {
37380
37601
  return;
37381
37602
  }
@@ -37383,12 +37604,12 @@ async function mergeBuiltFontCss(outputDir, fontCssSource) {
37383
37604
  const clientCssPath = import_path14.default.join(outputDir, "farm-client.css");
37384
37605
  let clientCss = "";
37385
37606
  try {
37386
- clientCss = await fs14.readFile(clientCssPath, "utf8");
37607
+ clientCss = await fs15.readFile(clientCssPath, "utf8");
37387
37608
  } catch {
37388
37609
  }
37389
37610
  const normalizedFontCss = typeof fontCss === "string" ? fontCss : Buffer.from(fontCss).toString("utf8");
37390
- await fs14.writeFile(fontCssPath, normalizedFontCss);
37391
- await fs14.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
37611
+ await fs15.writeFile(fontCssPath, normalizedFontCss);
37612
+ await fs15.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
37392
37613
  }
37393
37614
  __name(mergeBuiltFontCss, "mergeBuiltFontCss");
37394
37615
  var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError extends Error {
@@ -37400,12 +37621,12 @@ var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError
37400
37621
  __name(_IncompleteClientBuildOutputError, "IncompleteClientBuildOutputError");
37401
37622
  var IncompleteClientBuildOutputError = _IncompleteClientBuildOutputError;
37402
37623
  async function validateClientBuildOutput(root, srcDir, outputDir) {
37403
- const fs14 = await import("fs/promises");
37624
+ const fs15 = await import("fs/promises");
37404
37625
  const fingerprinted = await findFingerprintedClientEntry(outputDir);
37405
37626
  const clientEntryPath = import_path14.default.join(outputDir, fingerprinted ?? "farm-client.js");
37406
37627
  let clientEntrySize = 0;
37407
37628
  try {
37408
- const clientEntry = await fs14.stat(clientEntryPath);
37629
+ const clientEntry = await fs15.stat(clientEntryPath);
37409
37630
  if (clientEntry.isFile()) clientEntrySize = clientEntry.size;
37410
37631
  } catch {
37411
37632
  }
@@ -37416,12 +37637,12 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
37416
37637
  const globalsCssPath = import_path14.default.join(root, srcDir, "app", "globals.css");
37417
37638
  let expectsCss = false;
37418
37639
  try {
37419
- const globalsCss = await fs14.readFile(globalsCssPath, "utf8");
37640
+ const globalsCss = await fs15.readFile(globalsCssPath, "utf8");
37420
37641
  expectsCss = globalsCss.replace(/\/\*[\s\S]*?\*\//g, "").trim().length > 0;
37421
37642
  } catch {
37422
37643
  }
37423
37644
  try {
37424
- const clientCss = await fs14.stat(clientCssPath);
37645
+ const clientCss = await fs15.stat(clientCssPath);
37425
37646
  if (expectsCss && (!clientCss.isFile() || clientCss.size === 0)) {
37426
37647
  throw new IncompleteClientBuildOutputError("farm-client.css is empty");
37427
37648
  }
@@ -37430,7 +37651,7 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
37430
37651
  if (expectsCss) {
37431
37652
  throw new IncompleteClientBuildOutputError("farm-client.css is missing");
37432
37653
  }
37433
- await fs14.writeFile(clientCssPath, "");
37654
+ await fs15.writeFile(clientCssPath, "");
37434
37655
  }
37435
37656
  }
37436
37657
  __name(validateClientBuildOutput, "validateClientBuildOutput");
@@ -37448,7 +37669,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37448
37669
  const viteBuild = productionVite.build;
37449
37670
  const { farmPlugin: farmPlugin2 } = await Promise.resolve().then(() => (init_vite2(), vite_exports));
37450
37671
  const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_plugin(), plugin_exports));
37451
- const fs14 = await import("fs/promises");
37672
+ const fs15 = await import("fs/promises");
37452
37673
  const pluginManager = new PluginManager2({
37453
37674
  config,
37454
37675
  isDev: false,
@@ -37640,8 +37861,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37640
37861
  `\u{1F4F1} Total hydratable routes detected: ${clientPages.length} pages, ${clientLayouts.filter((layout2) => layout2.shouldHydrate).length} layouts, and ${clientRouteSlots.length} slots`
37641
37862
  );
37642
37863
  const clientEntryRoot = import_path14.default.join(root, ".farm", "tmp");
37643
- await fs14.mkdir(clientEntryRoot, { recursive: true });
37644
- const clientEntryDir = await fs14.mkdtemp(import_path14.default.join(clientEntryRoot, "client-entry-"));
37864
+ await fs15.mkdir(clientEntryRoot, { recursive: true });
37865
+ const clientEntryDir = await fs15.mkdtemp(import_path14.default.join(clientEntryRoot, "client-entry-"));
37645
37866
  const clientEntryPath = import_path14.default.join(clientEntryDir, "farm-client-entry.tsx");
37646
37867
  const clientHydrationCode = generateClientHydrationEntry(
37647
37868
  clientPages,
@@ -37659,9 +37880,10 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37659
37880
  config.publicRuntimeConfig,
37660
37881
  config.trailingSlash,
37661
37882
  getIntegrationProviders(config.integrations),
37662
- config.basePath
37883
+ config.basePath,
37884
+ generateClientCachePersistenceCode(resolveFarmClientCacheAdapterEntry(root, config.cache))
37663
37885
  );
37664
- await fs14.writeFile(clientEntryPath, clientHydrationCode);
37886
+ await fs15.writeFile(clientEntryPath, clientHydrationCode);
37665
37887
  const hasScopedPostcssConfig = hasProjectPostcssConfig(root);
37666
37888
  let postcssSearchPath;
37667
37889
  let tailwindVitePlugin = void 0;
@@ -37672,7 +37894,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37672
37894
  logger.info("\u{1F4E6} Using project PostCSS/Tailwind configuration");
37673
37895
  } else {
37674
37896
  const postcssConfigPath = import_path14.default.join(clientEntryDir, "postcss.config.cjs");
37675
- await fs14.writeFile(postcssConfigPath, "module.exports = { plugins: [] };\n");
37897
+ await fs15.writeFile(postcssConfigPath, "module.exports = { plugins: [] };\n");
37676
37898
  postcssSearchPath = clientEntryDir;
37677
37899
  try {
37678
37900
  const tailwindVite = (await import("@tailwindcss/vite")).default;
@@ -37823,7 +38045,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37823
38045
  await validateClientBuildOutput(root, srcDir, outputDir);
37824
38046
  } finally {
37825
38047
  try {
37826
- await fs14.rm(clientEntryDir, { recursive: true, force: true });
38048
+ await fs15.rm(clientEntryDir, { recursive: true, force: true });
37827
38049
  } catch {
37828
38050
  }
37829
38051
  }
@@ -37970,6 +38192,46 @@ function matchRuntimePathPattern(pattern, pathname) {
37970
38192
  `.trim();
37971
38193
  }
37972
38194
  __name(generateRuntimePathMatcherSource, "generateRuntimePathMatcherSource");
38195
+ function generateRedirectInterpolationSource() {
38196
+ return `
38197
+ function encodeRuntimePathSegment(value) {
38198
+ return encodeURIComponent(String(value)).replace(
38199
+ /[!'()*]/g,
38200
+ function(character) {
38201
+ return "%" + character.charCodeAt(0).toString(16).toUpperCase();
38202
+ },
38203
+ );
38204
+ }
38205
+
38206
+ function interpolateRedirectDestination(destination, params) {
38207
+ let result = destination;
38208
+ const catchAllParamSegments = params[farmCatchAllParamSegments] || {};
38209
+ const orderedCaptures = [];
38210
+ for (const [key, value] of Object.entries(params)) {
38211
+ const segments = catchAllParamSegments[key];
38212
+ const encodedValue = Array.isArray(segments)
38213
+ ? segments.map(encodeRuntimePathSegment).join("/")
38214
+ : encodeRuntimePathSegment(value);
38215
+ orderedCaptures.push(encodedValue);
38216
+ result = result.split("[[..." + key + "]]").join(encodedValue);
38217
+ result = result.split("[..." + key + "]").join(encodedValue);
38218
+ result = result.split("[" + key + "]").join(encodedValue);
38219
+ result = result.split(":" + key + "*").join(encodedValue);
38220
+ result = result.split(":" + key).join(encodedValue);
38221
+ if (key === "wildcard") result = result.split("*").join(encodedValue);
38222
+ }
38223
+ // Numbered captures resolve after the named substitutions. Encoded values
38224
+ // never contain "$", so this cannot rewrite an already-injected value. An
38225
+ // out-of-range index resolves to "", matching the development path.
38226
+ result = result.replace(/\\$(\\d+)/g, function(_whole, group) {
38227
+ const captured = orderedCaptures[Number(group) - 1];
38228
+ return captured === undefined ? "" : captured;
38229
+ });
38230
+ return result;
38231
+ }
38232
+ `.trim();
38233
+ }
38234
+ __name(generateRedirectInterpolationSource, "generateRedirectInterpolationSource");
37973
38235
  function generateUniversalRouterStateProperties() {
37974
38236
  return `
37975
38237
  blockers: new Set(),
@@ -38261,7 +38523,7 @@ function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlot
38261
38523
  secure: false
38262
38524
  },
38263
38525
  direction: {}
38264
- }, plugins = [], renderer = REACT_RENDERER, publicRuntimeConfig = void 0, trailingSlash = false, integrationProviders = [], basePath = "/") {
38526
+ }, plugins = [], renderer = REACT_RENDERER, publicRuntimeConfig = void 0, trailingSlash = false, integrationProviders = [], basePath = "/", clientCachePersistence = { imports: "", init: "" }) {
38265
38527
  const toImportPath = /* @__PURE__ */ __name((targetPath) => targetPath.replace(/\\/g, "/"), "toImportPath");
38266
38528
  const clientPluginEntry = generateFarmClientPluginEntryCode(
38267
38529
  plugins,
@@ -38273,8 +38535,7 @@ function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlot
38273
38535
  import { createRoot, hydrateRoot } from "react-dom/client";` : `import React, { createRoot, hydrateRoot } from ${JSON.stringify(renderer.client)};`;
38274
38536
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
38275
38537
  const globalsCssPath = import_path14.default.join(root, srcDir, "app", "globals.css");
38276
- const cssImportPath = toImportPath(globalsCssPath);
38277
- const cssImport = `import ${JSON.stringify(cssImportPath)};`;
38538
+ const cssImport = (0, import_fs5.existsSync)(globalsCssPath) ? `import ${JSON.stringify(toImportPath(globalsCssPath))};` : "";
38278
38539
  const layoutImportStatements = [];
38279
38540
  const layoutRegistrations = [];
38280
38541
  layoutRoutes.forEach((layout2, index) => {
@@ -38359,6 +38620,7 @@ ${layoutImports}
38359
38620
  import { createClientPluginManager, getHashTargetElement, installChunkErrorRecovery, isFarmExternalNavigationURL, reconcileFarmDocumentHead, setFarmBasePath, setFarmTrailingSlashPreference, stripFarmBasePath } from "@farm.js/core/internal/client-runtime";
38360
38621
  import { createFarmDeploymentMismatchError, createFarmDeploymentRequestHeaders, isFarmDeploymentMismatchResponse } from "@farm.js/core/deployment";
38361
38622
  ${clientPluginEntry.imports}
38623
+ ${clientCachePersistence.imports}
38362
38624
  ${i18nClientRuntime}
38363
38625
  ${docsNavigationRuntime}
38364
38626
  ${docsAdapterRuntime}
@@ -38367,6 +38629,7 @@ ${generateFarmDocsSearchClientRuntime(docsSearchEnabled, docsSearchModuleId)}
38367
38629
  setFarmBasePath(${JSON.stringify(basePath)});
38368
38630
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
38369
38631
  installChunkErrorRecovery();
38632
+ ${clientCachePersistence.init}
38370
38633
  mountFarmDocsSearch();
38371
38634
 
38372
38635
  ${generateUniversalRouterStateRuntime()}
@@ -38721,6 +38984,7 @@ import { createClientPluginManager, getHashTargetElement, installChunkErrorRecov
38721
38984
  import { createFarmDeploymentMismatchError, createFarmDeploymentRequestHeaders, isFarmDeploymentMismatchResponse } from "@farm.js/core/deployment";
38722
38985
  import { isFarmRouteActive, matchFarmRoute } from "@farm.js/core/router";
38723
38986
  ${clientPluginEntry.imports}
38987
+ ${clientCachePersistence.imports}
38724
38988
  ${i18nClientRuntime}
38725
38989
  ${docsNavigationRuntime}
38726
38990
  ${docsAdapterRuntime}
@@ -38733,6 +38997,7 @@ ${providerClientCode.runtime}
38733
38997
  setFarmBasePath(${JSON.stringify(basePath)});
38734
38998
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
38735
38999
  installChunkErrorRecovery();
39000
+ ${clientCachePersistence.init}
38736
39001
 
38737
39002
  // Client component routes
38738
39003
  const clientRoutes = [
@@ -39675,7 +39940,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39675
39940
  const viteBuild = productionVite.build;
39676
39941
  const { farmPlugin: farmPlugin2 } = await Promise.resolve().then(() => (init_vite2(), vite_exports));
39677
39942
  const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_plugin(), plugin_exports));
39678
- const fs14 = await import("fs/promises");
39943
+ const fs15 = await import("fs/promises");
39679
39944
  const pluginManager = new PluginManager2({
39680
39945
  config,
39681
39946
  isDev: false,
@@ -39689,8 +39954,8 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39689
39954
  ssr: true
39690
39955
  });
39691
39956
  if (!hasScopedPostcssConfig) {
39692
- postcssConfigDir = await fs14.mkdtemp(import_path14.default.join(import_os.default.tmpdir(), "farm-postcss-"));
39693
- await fs14.writeFile(
39957
+ postcssConfigDir = await fs15.mkdtemp(import_path14.default.join(import_os.default.tmpdir(), "farm-postcss-"));
39958
+ await fs15.writeFile(
39694
39959
  import_path14.default.join(postcssConfigDir, "postcss.config.cjs"),
39695
39960
  "module.exports = { plugins: [] };\n"
39696
39961
  );
@@ -39720,7 +39985,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39720
39985
  fileName: entry.fileName,
39721
39986
  sourceType: "static",
39722
39987
  staticInfo: entry.staticInfo,
39723
- data: (await fs14.readFile(entry.modulePath)).toString("base64")
39988
+ data: (await fs15.readFile(entry.modulePath)).toString("base64")
39724
39989
  });
39725
39990
  continue;
39726
39991
  }
@@ -40016,7 +40281,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
40016
40281
  } finally {
40017
40282
  if (postcssConfigDir) {
40018
40283
  try {
40019
- await fs14.rm(postcssConfigDir, { recursive: true, force: true });
40284
+ await fs15.rm(postcssConfigDir, { recursive: true, force: true });
40020
40285
  } catch {
40021
40286
  }
40022
40287
  }
@@ -40748,7 +41013,7 @@ const farmDocsAPIHandler = ${config.docs?.enabled ? adapterOwnsDocsRuntime ? "nu
40748
41013
 
40749
41014
  // API routes bundled at build time
40750
41015
  const apiRoutes = ${apiRoutes.length > 0 ? "mergePluginAPIRoutes(" : ""}[${apiRegistrations.join(",")}
40751
- ]${apiRoutes.length > 0 ? `, configuredPlugins, ${JSON.stringify(apiRoutes.map(({ path: path41, methods }) => ({ path: path41, methods })))})` : ""};
41016
+ ]${apiRoutes.length > 0 ? `, configuredPlugins, ${JSON.stringify(apiRoutes.map(({ path: path42, methods }) => ({ path: path42, methods })))})` : ""};
40752
41017
  const farmLocalAPIBasePath = ${JSON.stringify(resolveFarmAPIServerBasePath(config.api))};
40753
41018
  const farmOpenAPIReference = ${JSON.stringify(openAPIReference)};
40754
41019
 
@@ -41477,32 +41742,7 @@ async function handleApplicationMetadataRouteRequest(request, routePathname) {
41477
41742
  }
41478
41743
  }
41479
41744
 
41480
- function encodeRuntimePathSegment(value) {
41481
- return encodeURIComponent(String(value)).replace(
41482
- /[!'()*]/g,
41483
- function(character) {
41484
- return "%" + character.charCodeAt(0).toString(16).toUpperCase();
41485
- },
41486
- );
41487
- }
41488
-
41489
- function interpolateRedirectDestination(destination, params) {
41490
- let result = destination;
41491
- const catchAllParamSegments = params[farmCatchAllParamSegments] || {};
41492
- for (const [key, value] of Object.entries(params)) {
41493
- const segments = catchAllParamSegments[key];
41494
- const encodedValue = Array.isArray(segments)
41495
- ? segments.map(encodeRuntimePathSegment).join("/")
41496
- : encodeRuntimePathSegment(value);
41497
- result = result.split("[[..." + key + "]]").join(encodedValue);
41498
- result = result.split("[..." + key + "]").join(encodedValue);
41499
- result = result.split("[" + key + "]").join(encodedValue);
41500
- result = result.split(":" + key + "*").join(encodedValue);
41501
- result = result.split(":" + key).join(encodedValue);
41502
- if (key === "wildcard") result = result.split("*").join(encodedValue);
41503
- }
41504
- return result;
41505
- }
41745
+ ${generateRedirectInterpolationSource()}
41506
41746
 
41507
41747
  function matchRedirectRoute(pathname, locale, search) {
41508
41748
  for (const redirect of redirectRoutes) {
@@ -41925,9 +42165,10 @@ ${config.docs?.enabled ? `async function wrapFarmDocsResponseWithLayouts(request
41925
42165
  }` : ""}
41926
42166
 
41927
42167
  const pprShellCache = getFarmDataCache();
42168
+ const experimentalPPREnabled = ${JSON.stringify(config.experimental?.ppr === true)};
41928
42169
 
41929
42170
  function resolvePPRConfig(routeModule) {
41930
- if (!routeModule || routeModule.dynamic === "force-dynamic") {
42171
+ if (!experimentalPPREnabled || !routeModule || routeModule.dynamic === "force-dynamic") {
41931
42172
  return { enabled: false };
41932
42173
  }
41933
42174
 
@@ -43465,7 +43706,7 @@ function getPhysicalPrerenderBypassReason(options) {
43465
43706
  }
43466
43707
  __name(getPhysicalPrerenderBypassReason, "getPhysicalPrerenderBypassReason");
43467
43708
  async function buildNitroUniversal(config, routeManager, apiRouteManager, serverRenderer, preset, root, distDir, ssrBundle, ssrEntryFile, clientOutputDir, routeRuntimeManifest, configuredHeaderRoutes, nitroRuntimeResultPromise, pluginManager) {
43468
- const [fs14, nitroRuntimeResult] = await Promise.all([
43709
+ const [fs15, nitroRuntimeResult] = await Promise.all([
43469
43710
  import("fs/promises"),
43470
43711
  nitroRuntimeResultPromise
43471
43712
  ]);
@@ -43556,11 +43797,11 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
43556
43797
  output.code = output.code.split(FARM_CLIENT_JS_SRC_PLACEHOLDER).join(clientJsSrc);
43557
43798
  }
43558
43799
  }
43559
- await fs14.mkdir(ssrOutputDir, { recursive: true });
43800
+ await fs15.mkdir(ssrOutputDir, { recursive: true });
43560
43801
  for (const [fileName, output] of Object.entries(ssrBundle)) {
43561
43802
  const filePath = import_path14.default.join(ssrOutputDir, fileName);
43562
- await fs14.mkdir(import_path14.default.dirname(filePath), { recursive: true });
43563
- await fs14.writeFile(filePath, output.type === "chunk" ? output.code : output.source);
43803
+ await fs15.mkdir(import_path14.default.dirname(filePath), { recursive: true });
43804
+ await fs15.writeFile(filePath, output.type === "chunk" ? output.code : output.source);
43564
43805
  }
43565
43806
  const nitroEntryPath = import_path14.default.join(ssrOutputDir, "nitro-entry.mjs");
43566
43807
  const nitroEntryCode = `
@@ -43632,10 +43873,10 @@ export default async function farmNitroEventHandler(event) {
43632
43873
  return response
43633
43874
  }
43634
43875
  `.trim();
43635
- await fs14.writeFile(nitroEntryPath, nitroEntryCode);
43876
+ await fs15.writeFile(nitroEntryPath, nitroEntryCode);
43636
43877
  const farmNodeServerEntryPath = preset === "node-server" ? import_path14.default.join(ssrOutputDir, "farm-node-server-entry.mjs") : null;
43637
43878
  if (farmNodeServerEntryPath) {
43638
- await fs14.writeFile(
43879
+ await fs15.writeFile(
43639
43880
  farmNodeServerEntryPath,
43640
43881
  createFarmNodeServerEntry({
43641
43882
  nitroEntryFile: import_path14.default.basename(nitroEntryPath),
@@ -43853,9 +44094,9 @@ export default async function farmNitroEventHandler(event) {
43853
44094
  import_path14.default.join(prerenderServerDir, FARM_SSR_OUTPUT_DIR),
43854
44095
  {},
43855
44096
  false,
43856
- fs14
44097
+ fs15
43857
44098
  );
43858
- await registerPrebuiltSSRPackageImport(prerenderServerDir, ssrEntryFile, fs14);
44099
+ await registerPrebuiltSSRPackageImport(prerenderServerDir, ssrEntryFile, fs15);
43859
44100
  });
43860
44101
  });
43861
44102
  }
@@ -43887,17 +44128,17 @@ export default async function farmNitroEventHandler(event) {
43887
44128
  import_path14.default.join(outputDir, "server", FARM_SSR_OUTPUT_DIR),
43888
44129
  prebuiltSSREsbuildOptions,
43889
44130
  effectiveMinify,
43890
- fs14
44131
+ fs15
43891
44132
  ) : Promise.resolve(),
43892
- imageRuntime === "node" ? copySharpRuntime(config, root, import_path14.default.join(outputDir, "server"), fs14) : Promise.resolve(),
43893
- useExternalMetadataImageRuntime ? copyMetadataImageRuntime(root, import_path14.default.join(outputDir, "server"), fs14) : Promise.resolve()
44133
+ imageRuntime === "node" ? copySharpRuntime(config, root, import_path14.default.join(outputDir, "server"), fs15) : Promise.resolve(),
44134
+ useExternalMetadataImageRuntime ? copyMetadataImageRuntime(root, import_path14.default.join(outputDir, "server"), fs15) : Promise.resolve()
43894
44135
  ]);
43895
44136
  const failedCopy = copyResults.find(
43896
44137
  (result) => result.status === "rejected"
43897
44138
  );
43898
44139
  if (failedCopy) throw failedCopy.reason;
43899
44140
  if (canReusePrebuiltSSR) {
43900
- await registerPrebuiltSSRPackageImport(import_path14.default.join(outputDir, "server"), ssrEntryFile, fs14);
44141
+ await registerPrebuiltSSRPackageImport(import_path14.default.join(outputDir, "server"), ssrEntryFile, fs15);
43901
44142
  logger.info("\u26A1 Reused Farm's prebuilt SSR bundle for the Node output");
43902
44143
  }
43903
44144
  if (useRolldownBuilder) {
@@ -43912,12 +44153,12 @@ export default async function farmNitroEventHandler(event) {
43912
44153
  });
43913
44154
  }
43914
44155
  if (isVercel) {
43915
- await postProcessVercelOutput(root, outputDir, fs14, config, farmWorkflows, routeRuntimeManifest);
44156
+ await postProcessVercelOutput(root, outputDir, fs15, config, farmWorkflows, routeRuntimeManifest);
43916
44157
  }
43917
44158
  logger.success(`\u2705 Nitro build completed with preset: ${preset}`);
43918
44159
  }
43919
44160
  __name(buildNitroUniversal, "buildNitroUniversal");
43920
- async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOptions, minify, fs14) {
44161
+ async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOptions, minify, fs15) {
43921
44162
  const {
43922
44163
  include: _include,
43923
44164
  exclude: _exclude,
@@ -43934,13 +44175,13 @@ async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOpti
43934
44175
  "node18"
43935
44176
  );
43936
44177
  const transform = minify || hasConfiguredTransforms ? (await import("esbuild")).transform : null;
43937
- await fs14.rm(targetDir, { recursive: true, force: true });
44178
+ await fs15.rm(targetDir, { recursive: true, force: true });
43938
44179
  await Promise.all(
43939
44180
  Object.entries(ssrBundle).map(async ([fileName, output]) => {
43940
44181
  const targetPath = import_path14.default.join(targetDir, fileName);
43941
- await fs14.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
44182
+ await fs15.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
43942
44183
  if (output.type === "asset") {
43943
- await fs14.writeFile(targetPath, output.source);
44184
+ await fs15.writeFile(targetPath, output.source);
43944
44185
  return;
43945
44186
  }
43946
44187
  let code = output.code;
@@ -43951,14 +44192,14 @@ async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOpti
43951
44192
  });
43952
44193
  code = result.code;
43953
44194
  }
43954
- await fs14.writeFile(targetPath, code);
44195
+ await fs15.writeFile(targetPath, code);
43955
44196
  })
43956
44197
  );
43957
44198
  }
43958
44199
  __name(copyPrebuiltSSRBundle, "copyPrebuiltSSRBundle");
43959
- async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs14) {
44200
+ async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs15) {
43960
44201
  const packagePath = import_path14.default.join(serverDir, "package.json");
43961
- const packageJSON = await fs14.readFile(packagePath, "utf8").then((contents) => JSON.parse(contents)).catch((error) => {
44202
+ const packageJSON = await fs15.readFile(packagePath, "utf8").then((contents) => JSON.parse(contents)).catch((error) => {
43962
44203
  if (error.code === "ENOENT") return { type: "module" };
43963
44204
  throw error;
43964
44205
  });
@@ -43968,14 +44209,14 @@ async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs14) {
43968
44209
  ...existingImports,
43969
44210
  [FARM_SSR_PACKAGE_IMPORT]: `./${outputEntry}`
43970
44211
  };
43971
- await fs14.mkdir(serverDir, { recursive: true });
43972
- await fs14.writeFile(packagePath, `${JSON.stringify(packageJSON, null, 2)}
44212
+ await fs15.mkdir(serverDir, { recursive: true });
44213
+ await fs15.writeFile(packagePath, `${JSON.stringify(packageJSON, null, 2)}
43973
44214
  `);
43974
44215
  }
43975
44216
  __name(registerPrebuiltSSRPackageImport, "registerPrebuiltSSRPackageImport");
43976
- async function moveVercelOutputPath(src, dest, fs14) {
44217
+ async function moveVercelOutputPath(src, dest, fs15) {
43977
44218
  try {
43978
- await fs14.rename(src, dest);
44219
+ await fs15.rename(src, dest);
43979
44220
  return;
43980
44221
  } catch (error) {
43981
44222
  const code = error?.code;
@@ -43983,68 +44224,44 @@ async function moveVercelOutputPath(src, dest, fs14) {
43983
44224
  throw error;
43984
44225
  }
43985
44226
  }
43986
- await fs14.cp(src, dest, { recursive: true, force: true });
43987
- await fs14.rm(src, { recursive: true, force: true });
44227
+ await fs15.cp(src, dest, { recursive: true, force: true });
44228
+ await fs15.rm(src, { recursive: true, force: true });
43988
44229
  }
43989
44230
  __name(moveVercelOutputPath, "moveVercelOutputPath");
43990
- async function postProcessVercelOutput(root, outputDir, fs14, config, farmWorkflows, routeRuntimeManifest) {
44231
+ async function postProcessVercelOutput(root, outputDir, fs15, config, farmWorkflows, routeRuntimeManifest) {
43991
44232
  const serverDir = import_path14.default.join(outputDir, "server");
43992
44233
  const functionsDir = import_path14.default.join(outputDir, "functions");
43993
44234
  const nitroFuncDir = import_path14.default.join(functionsDir, "__nitro.func");
43994
44235
  const staticDir = import_path14.default.join(outputDir, "static");
43995
44236
  const publicDir = import_path14.default.join(outputDir, "public");
43996
- await fs14.mkdir(nitroFuncDir, { recursive: true });
43997
- const serverContents = await fs14.readdir(serverDir);
44237
+ await fs15.mkdir(nitroFuncDir, { recursive: true });
44238
+ const serverContents = await fs15.readdir(serverDir);
43998
44239
  for (const file of serverContents) {
43999
44240
  const src = import_path14.default.join(serverDir, file);
44000
44241
  const dest = import_path14.default.join(nitroFuncDir, file);
44001
- await moveVercelOutputPath(src, dest, fs14);
44242
+ await moveVercelOutputPath(src, dest, fs15);
44002
44243
  }
44003
- await fs14.rm(serverDir, { recursive: true, force: true });
44244
+ await fs15.rm(serverDir, { recursive: true, force: true });
44004
44245
  try {
44005
- await moveVercelOutputPath(publicDir, staticDir, fs14);
44246
+ await moveVercelOutputPath(publicDir, staticDir, fs15);
44006
44247
  } catch (error) {
44007
44248
  if (error?.code !== "ENOENT") throw error;
44008
44249
  }
44009
- await copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs14);
44010
- await copyPrismaClientForVercel(root, nitroFuncDir, fs14);
44250
+ await copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs15);
44251
+ await copyPrismaClientForVercel(root, nitroFuncDir, fs15);
44011
44252
  const configPath = import_path14.default.join(outputDir, "config.json");
44012
- const configContent = await fs14.readFile(configPath, "utf-8");
44253
+ const configContent = await fs15.readFile(configPath, "utf-8");
44013
44254
  const vercelConfig = JSON.parse(configContent);
44014
44255
  const runtimeRoutes = await createFarmVercelRouteRuntimeFunctions(
44015
44256
  outputDir,
44016
44257
  routeRuntimeManifest,
44017
- fs14
44258
+ fs15
44018
44259
  );
44019
- vercelConfig.routes = [
44020
- // Apply the header before the filesystem handler. `continue` lets Vercel
44021
- // serve the matching file while preserving the immutable cache policy.
44022
- // Hashed client assets ship at the root regardless of basePath, so the
44023
- // route is deliberately not basePath-scoped.
44024
- createFarmVercelImmutableAssetRoute(),
44025
- // Serve static files first
44026
- {
44027
- handle: "filesystem"
44028
- },
44029
- ...runtimeRoutes,
44030
- // API routes
44031
- ...resolveFarmAPIServerBasePath(config.api) === "/" ? [] : [
44032
- {
44033
- src: `${resolveFarmAPIServerBasePath(config.api)}/(.*)`,
44034
- dest: "/__nitro",
44035
- headers: {
44036
- "Access-Control-Allow-Origin": "*",
44037
- "Access-Control-Allow-Methods": "*",
44038
- "Access-Control-Allow-Headers": "*"
44039
- }
44040
- }
44041
- ],
44042
- // All other routes go to the serverless function
44043
- {
44044
- src: "/(.*)",
44045
- dest: "/__nitro"
44046
- }
44047
- ];
44260
+ vercelConfig.routes = buildFarmVercelRoutes({
44261
+ presetRoutes: Array.isArray(vercelConfig.routes) ? vercelConfig.routes : [],
44262
+ runtimeRoutes,
44263
+ apiBasePath: resolveFarmAPIServerBasePath(config.api)
44264
+ });
44048
44265
  const vercelConfigWithWorkflowCrons = applyFarmWorkflowVercelCrons(
44049
44266
  vercelConfig,
44050
44267
  farmWorkflows.workflows
@@ -44053,24 +44270,24 @@ async function postProcessVercelOutput(root, outputDir, fs14, config, farmWorkfl
44053
44270
  vercelConfigWithWorkflowCrons,
44054
44271
  config.cron.jobs
44055
44272
  );
44056
- await fs14.writeFile(configPath, JSON.stringify(vercelConfigWithCrons, null, 2));
44273
+ await fs15.writeFile(configPath, JSON.stringify(vercelConfigWithCrons, null, 2));
44057
44274
  logger.info("\u2705 Post-processed Vercel output for Build Output API v3");
44058
44275
  }
44059
44276
  __name(postProcessVercelOutput, "postProcessVercelOutput");
44060
- async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs14) {
44277
+ async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs15) {
44061
44278
  const docsContentDir = resolveBuildDocsContentDir(config, root);
44062
44279
  if (!docsContentDir) return;
44063
44280
  const bundledContentDir = import_path14.default.join(nitroFuncDir, "chunks", "nitro", "farm-docs-content");
44064
44281
  const lastModifiedManifest = createFarmDocsLastModifiedManifest(docsContentDir, {
44065
44282
  fallback: "now"
44066
44283
  });
44067
- await fs14.rm(bundledContentDir, { recursive: true, force: true });
44068
- await fs14.mkdir(import_path14.default.dirname(bundledContentDir), { recursive: true });
44069
- await fs14.cp(docsContentDir, bundledContentDir, {
44284
+ await fs15.rm(bundledContentDir, { recursive: true, force: true });
44285
+ await fs15.mkdir(import_path14.default.dirname(bundledContentDir), { recursive: true });
44286
+ await fs15.cp(docsContentDir, bundledContentDir, {
44070
44287
  recursive: true,
44071
44288
  force: true
44072
44289
  });
44073
- await fs14.writeFile(
44290
+ await fs15.writeFile(
44074
44291
  import_path14.default.join(bundledContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST),
44075
44292
  `${JSON.stringify(lastModifiedManifest, null, 2)}
44076
44293
  `
@@ -44078,7 +44295,7 @@ async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs14) {
44078
44295
  logger.info(`\u{1F4DA} Bundled docs content for Vercel: ${import_path14.default.relative(root, docsContentDir)}`);
44079
44296
  }
44080
44297
  __name(copyFarmDocsContentForVercel, "copyFarmDocsContentForVercel");
44081
- async function copySharpRuntime(config, root, nitroFuncDir, fs14) {
44298
+ async function copySharpRuntime(config, root, nitroFuncDir, fs15) {
44082
44299
  if (config.images.provider === "none") return;
44083
44300
  const projectRequire = (0, import_module2.createRequire)(import_path14.default.join(root, "package.json"));
44084
44301
  let sharpRequire = projectRequire;
@@ -44102,18 +44319,18 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs14) {
44102
44319
  async function copyPackageOnce(packageName, parentRequire) {
44103
44320
  const packageJsonPath = resolvePackageJson(parentRequire, packageName);
44104
44321
  if (!packageJsonPath) return;
44105
- const packageJson = JSON.parse(await fs14.readFile(packageJsonPath, "utf8"));
44322
+ const packageJson = JSON.parse(await fs15.readFile(packageJsonPath, "utf8"));
44106
44323
  const packageDir = import_path14.default.dirname(packageJsonPath);
44107
44324
  const targetDir = import_path14.default.join(targetNodeModules, ...packageName.split("/"));
44108
44325
  copiedPackages.set(packageName, String(packageJson.version || "*"));
44109
- await fs14.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44326
+ await fs15.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44110
44327
  const packageRequire = (0, import_module2.createRequire)(packageJsonPath);
44111
44328
  const dependencies = {
44112
44329
  ...packageJson.dependencies,
44113
44330
  ...packageJson.optionalDependencies
44114
44331
  };
44115
44332
  await Promise.all([
44116
- fs14.cp(packageDir, targetDir, {
44333
+ fs15.cp(packageDir, targetDir, {
44117
44334
  recursive: true,
44118
44335
  force: true,
44119
44336
  dereference: true,
@@ -44132,16 +44349,16 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs14) {
44132
44349
  );
44133
44350
  }
44134
44351
  const functionPackagePath = import_path14.default.join(nitroFuncDir, "package.json");
44135
- const functionPackage = JSON.parse(await fs14.readFile(functionPackagePath, "utf8"));
44352
+ const functionPackage = JSON.parse(await fs15.readFile(functionPackagePath, "utf8"));
44136
44353
  functionPackage.dependencies = {
44137
44354
  ...functionPackage.dependencies,
44138
44355
  ...Object.fromEntries([...copiedPackages].sort(([left], [right]) => left.localeCompare(right)))
44139
44356
  };
44140
- await fs14.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44357
+ await fs15.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44141
44358
  logger.info(`\u{1F5BC}\uFE0F Bundled Sharp image runtime (${copiedPackages.size} packages)`);
44142
44359
  }
44143
44360
  __name(copySharpRuntime, "copySharpRuntime");
44144
- async function copyMetadataImageRuntime(root, nitroFuncDir, fs14) {
44361
+ async function copyMetadataImageRuntime(root, nitroFuncDir, fs15) {
44145
44362
  const projectRequire = (0, import_module2.createRequire)(import_path14.default.join(root, "package.json"));
44146
44363
  let runtimeRequire = projectRequire;
44147
44364
  let packageJsonPath = resolvePackageJson(runtimeRequire, "@vercel/og");
@@ -44157,23 +44374,23 @@ async function copyMetadataImageRuntime(root, nitroFuncDir, fs14) {
44157
44374
  "Generated metadata images require @vercel/og. Reinstall @farm.js/core with production dependencies."
44158
44375
  );
44159
44376
  }
44160
- const packageJson = JSON.parse(await fs14.readFile(packageJsonPath, "utf8"));
44377
+ const packageJson = JSON.parse(await fs15.readFile(packageJsonPath, "utf8"));
44161
44378
  const packageDir = import_path14.default.dirname(packageJsonPath);
44162
44379
  const targetDir = import_path14.default.join(nitroFuncDir, "node_modules", "@vercel", "og");
44163
- await fs14.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44164
- await fs14.cp(packageDir, targetDir, {
44380
+ await fs15.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44381
+ await fs15.cp(packageDir, targetDir, {
44165
44382
  recursive: true,
44166
44383
  force: true,
44167
44384
  dereference: true,
44168
44385
  mode: import_fs5.constants.COPYFILE_FICLONE
44169
44386
  });
44170
44387
  const functionPackagePath = import_path14.default.join(nitroFuncDir, "package.json");
44171
- const functionPackage = JSON.parse(await fs14.readFile(functionPackagePath, "utf8"));
44388
+ const functionPackage = JSON.parse(await fs15.readFile(functionPackagePath, "utf8"));
44172
44389
  functionPackage.dependencies = {
44173
44390
  ...functionPackage.dependencies,
44174
44391
  "@vercel/og": String(packageJson.version || "0.11.1")
44175
44392
  };
44176
- await fs14.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44393
+ await fs15.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44177
44394
  logger.info("\u{1F5BC}\uFE0F Bundled generated metadata image runtime");
44178
44395
  }
44179
44396
  __name(copyMetadataImageRuntime, "copyMetadataImageRuntime");
@@ -44187,7 +44404,7 @@ function resolvePackageJson(parentRequire, packageName) {
44187
44404
  return null;
44188
44405
  }
44189
44406
  __name(resolvePackageJson, "resolvePackageJson");
44190
- async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44407
+ async function copyPrismaClientForVercel(root, nitroFuncDir, fs15) {
44191
44408
  const projectRequire = (0, import_module2.createRequire)(import_path14.default.join(root, "package.json"));
44192
44409
  let prismaClientDir;
44193
44410
  try {
@@ -44197,7 +44414,7 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44197
44414
  }
44198
44415
  const generatedClientDir = import_path14.default.join(prismaClientDir, "..", "..", ".prisma", "client");
44199
44416
  try {
44200
- await fs14.access(generatedClientDir);
44417
+ await fs15.access(generatedClientDir);
44201
44418
  } catch {
44202
44419
  return;
44203
44420
  }
@@ -44205,20 +44422,20 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44205
44422
  const targetPrismaScopeDir = import_path14.default.join(targetNodeModules, "@prisma");
44206
44423
  const targetGeneratedDir = import_path14.default.join(targetNodeModules, ".prisma", "client");
44207
44424
  const targetClientDir = import_path14.default.join(targetPrismaScopeDir, "client");
44208
- await fs14.mkdir(targetPrismaScopeDir, { recursive: true });
44209
- await fs14.cp(prismaClientDir, targetClientDir, {
44425
+ await fs15.mkdir(targetPrismaScopeDir, { recursive: true });
44426
+ await fs15.cp(prismaClientDir, targetClientDir, {
44210
44427
  recursive: true,
44211
44428
  force: true
44212
44429
  });
44213
- await fs14.cp(generatedClientDir, targetGeneratedDir, {
44430
+ await fs15.cp(generatedClientDir, targetGeneratedDir, {
44214
44431
  recursive: true,
44215
44432
  force: true
44216
44433
  });
44217
44434
  const functionPackagePath = import_path14.default.join(nitroFuncDir, "package.json");
44218
44435
  const clientPackagePath = import_path14.default.join(prismaClientDir, "package.json");
44219
44436
  const [functionPackageContent, clientPackageContent] = await Promise.all([
44220
- fs14.readFile(functionPackagePath, "utf-8"),
44221
- fs14.readFile(clientPackagePath, "utf-8")
44437
+ fs15.readFile(functionPackagePath, "utf-8"),
44438
+ fs15.readFile(clientPackagePath, "utf-8")
44222
44439
  ]);
44223
44440
  const functionPackage = JSON.parse(functionPackageContent);
44224
44441
  const clientPackage = JSON.parse(clientPackageContent);
@@ -44226,7 +44443,7 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44226
44443
  ...functionPackage.dependencies,
44227
44444
  "@prisma/client": clientPackage.version
44228
44445
  };
44229
- await fs14.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44446
+ await fs15.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44230
44447
  }
44231
44448
  __name(copyPrismaClientForVercel, "copyPrismaClientForVercel");
44232
44449
 
@@ -44588,7 +44805,7 @@ function resolveLegacyPageEntry(config, root, srcDir) {
44588
44805
  const appDir = import_path17.default.join(root, srcDir, "app");
44589
44806
  for (const extension of getFarmRendererComponentExtensions(config.renderer)) {
44590
44807
  const candidate = import_path17.default.join(appDir, `page${extension}`);
44591
- if ((0, import_node_fs13.existsSync)(candidate)) return candidate;
44808
+ if ((0, import_node_fs14.existsSync)(candidate)) return candidate;
44592
44809
  }
44593
44810
  return import_path17.default.join(appDir, "page.tsx");
44594
44811
  }
@@ -44622,10 +44839,10 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
44622
44839
  const manifestPath = import_path17.default.join(publicOutputDir, "farm-client-manifest.json");
44623
44840
  const assetsDir = import_path17.default.join(publicOutputDir, "assets");
44624
44841
  const manifestExists = await import("fs/promises").then(
44625
- (fs14) => fs14.access(manifestPath).then(() => true).catch(() => false)
44842
+ (fs15) => fs15.access(manifestPath).then(() => true).catch(() => false)
44626
44843
  );
44627
44844
  const assetsExist = await import("fs/promises").then(
44628
- (fs14) => fs14.access(assetsDir).then(() => true).catch(() => false)
44845
+ (fs15) => fs15.access(assetsDir).then(() => true).catch(() => false)
44629
44846
  );
44630
44847
  if (manifestExists && assetsExist) {
44631
44848
  logger.info("\u2705 Verified client assets are present");