@farm.js/core 0.1.0-beta.96 → 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 (311) 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 +6 -6
  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 +4 -4
  13. package/dist/api.cjs +239 -70
  14. package/dist/api.d.mts +7 -6
  15. package/dist/api.d.ts +7 -6
  16. package/dist/api.mjs +17 -11
  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-MM46HTX6.mjs → chunk-3TWQERDE.mjs} +4 -3
  31. package/dist/chunk-3TWQERDE.mjs.map +1 -0
  32. package/dist/{chunk-RWYRFCLG.mjs → chunk-4X57GXQA.mjs} +2 -2
  33. package/dist/{chunk-3I55IGXU.mjs → chunk-52BR7LTX.mjs} +14 -15
  34. package/dist/chunk-52BR7LTX.mjs.map +1 -0
  35. package/dist/{chunk-RAGSHKDC.mjs → chunk-6EJHNHH4.mjs} +38 -3
  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-54XSGLKT.mjs → chunk-D7F7YZ7L.mjs} +93 -67
  43. package/dist/chunk-D7F7YZ7L.mjs.map +1 -0
  44. package/dist/{chunk-SCFX4UTD.mjs → chunk-EHTUKVSW.mjs} +1 -1
  45. package/dist/chunk-EHTUKVSW.mjs.map +1 -0
  46. package/dist/{chunk-LZTGDH3H.mjs → chunk-EPDIF432.mjs} +424 -10
  47. package/dist/chunk-EPDIF432.mjs.map +1 -0
  48. package/dist/{chunk-GZHKWHCH.mjs → chunk-FP5Q67FO.mjs} +167 -96
  49. package/dist/chunk-FP5Q67FO.mjs.map +1 -0
  50. package/dist/{chunk-HHZAOTQD.mjs → chunk-GJ7W6LNK.mjs} +7 -6
  51. package/dist/chunk-GJ7W6LNK.mjs.map +1 -0
  52. package/dist/{chunk-RLGUZ3HS.mjs → chunk-I3OOUWO5.mjs} +3 -3
  53. package/dist/{chunk-LKKMI7JG.mjs → chunk-IZBX2TEU.mjs} +153 -68
  54. package/dist/chunk-IZBX2TEU.mjs.map +1 -0
  55. package/dist/{chunk-74QPONAN.mjs → chunk-J3MPQ4MQ.mjs} +2 -2
  56. package/dist/{chunk-74QPONAN.mjs.map → chunk-J3MPQ4MQ.mjs.map} +1 -1
  57. package/dist/{chunk-ODJGAWDH.mjs → chunk-JV7JUD7Q.mjs} +4 -4
  58. package/dist/{chunk-Q3OX763A.mjs → chunk-LXDASSTE.mjs} +2 -2
  59. package/dist/{chunk-ZRBCBOEX.mjs → chunk-N2FY2QZ7.mjs} +28 -3
  60. package/dist/chunk-N2FY2QZ7.mjs.map +1 -0
  61. package/dist/{chunk-MRVJCLYQ.mjs → chunk-PSQ7N4XP.mjs} +4 -2
  62. package/dist/chunk-PSQ7N4XP.mjs.map +1 -0
  63. package/dist/{chunk-HVG3HLQZ.mjs → chunk-Q7WGOOAI.mjs} +3 -3
  64. package/dist/{chunk-WTYAPO5I.mjs → chunk-RCNWMEBT.mjs} +3 -2
  65. package/dist/{chunk-WTYAPO5I.mjs.map → chunk-RCNWMEBT.mjs.map} +1 -1
  66. package/dist/{chunk-3INDBMUU.mjs → chunk-TGDIACZT.mjs} +2 -2
  67. package/dist/{chunk-WB75GIX2.mjs → chunk-TQTB33JS.mjs} +14 -3
  68. package/dist/chunk-TQTB33JS.mjs.map +1 -0
  69. package/dist/{chunk-WMAYETRD.mjs → chunk-TT3E2JOF.mjs} +3 -3
  70. package/dist/{chunk-FVAM43KI.mjs → chunk-UMUWR5XA.mjs} +2 -2
  71. package/dist/{chunk-VOUJW4FL.mjs → chunk-WD2EBM3I.mjs} +70 -15
  72. package/dist/chunk-WD2EBM3I.mjs.map +1 -0
  73. package/dist/{chunk-ZPG6SNHH.mjs → chunk-WMJGA32P.mjs} +47 -5
  74. package/dist/chunk-WMJGA32P.mjs.map +1 -0
  75. package/dist/{chunk-TKQCJMY7.mjs → chunk-X4SFHKFH.mjs} +7 -4
  76. package/dist/{chunk-TKQCJMY7.mjs.map → chunk-X4SFHKFH.mjs.map} +1 -1
  77. package/dist/{chunk-Q7GPJZCO.mjs → chunk-YIBV77KZ.mjs} +26 -7
  78. package/dist/chunk-YIBV77KZ.mjs.map +1 -0
  79. package/dist/client/lifecycle.mjs +2 -2
  80. package/dist/{client-mcMC334J.d.mts → client-DWoLZ3QU.d.mts} +52 -5
  81. package/dist/{client-d5ONQ-Pd.d.ts → client-DuQuQC1h.d.ts} +52 -5
  82. package/dist/client-cache-BMxuFqwH.d.ts +18 -0
  83. package/dist/client-cache-CCK-fCe0.d.mts +18 -0
  84. package/dist/{client-plugins-BvClItiL.d.mts → client-plugins-B6-07YmP.d.mts} +52 -99
  85. package/dist/{client-plugins-B9Sq-iMg.d.ts → client-plugins-By6MVUX-.d.ts} +52 -99
  86. package/dist/client-plugins.cjs +1 -1
  87. package/dist/client-plugins.d.mts +3 -2
  88. package/dist/client-plugins.d.ts +3 -2
  89. package/dist/client-plugins.mjs +2 -2
  90. package/dist/client.cjs +757 -104
  91. package/dist/client.d.mts +124 -16
  92. package/dist/client.d.ts +124 -16
  93. package/dist/client.mjs +28 -14
  94. package/dist/config.d.mts +3 -2
  95. package/dist/config.d.ts +3 -2
  96. package/dist/{devtools-S52RRRMN.mjs → devtools-XWZX6CCL.mjs} +5 -5
  97. package/dist/{devtools-client-EOVDBPOI.mjs → devtools-client-Z7QQA3Q2.mjs} +2 -2
  98. package/dist/{devtools-ui-NJKFORTG.mjs → devtools-ui-2HG5M4EL.mjs} +3 -1
  99. package/dist/devtools-ui-2HG5M4EL.mjs.map +1 -0
  100. package/dist/docs.cjs +24 -5
  101. package/dist/docs.mjs +5 -5
  102. package/dist/i18n/server.cjs +13 -2
  103. package/dist/i18n/server.d.mts +2 -2
  104. package/dist/i18n/server.d.ts +2 -2
  105. package/dist/i18n/server.mjs +1 -1
  106. package/dist/index.cjs +1578 -772
  107. package/dist/index.d.mts +28 -20
  108. package/dist/index.d.ts +28 -20
  109. package/dist/index.mjs +53 -33
  110. package/dist/index.mjs.map +1 -1
  111. package/dist/integration-api-BT024nuJ.d.mts +97 -0
  112. package/dist/integration-api-BT024nuJ.d.ts +97 -0
  113. package/dist/integrations.d.mts +3 -2
  114. package/dist/integrations.d.ts +3 -2
  115. package/dist/internal/build-runtime.cjs +710 -532
  116. package/dist/internal/build-runtime.d.mts +5 -4
  117. package/dist/internal/build-runtime.d.ts +5 -4
  118. package/dist/internal/build-runtime.mjs +15 -15
  119. package/dist/internal/client-runtime.cjs +1 -1
  120. package/dist/internal/client-runtime.mjs +2 -2
  121. package/dist/internal/config-runtime.cjs +4 -1
  122. package/dist/internal/config-runtime.d.mts +4 -3
  123. package/dist/internal/config-runtime.d.ts +4 -3
  124. package/dist/internal/config-runtime.mjs +4 -4
  125. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  126. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  127. package/dist/internal/production-runtime.cjs +29 -3
  128. package/dist/internal/production-runtime.d.mts +8 -7
  129. package/dist/internal/production-runtime.d.ts +8 -7
  130. package/dist/internal/production-runtime.mjs +5 -5
  131. package/dist/{metadata-route-yV4U6X8h.d.ts → metadata-route-8_V3UonT.d.ts} +1 -1
  132. package/dist/{metadata-route-p4K1l92V.d.mts → metadata-route-CWP_HjGU.d.mts} +1 -1
  133. package/dist/middleware.cjs +28 -2
  134. package/dist/middleware.d.mts +5 -4
  135. package/dist/middleware.d.ts +5 -4
  136. package/dist/middleware.mjs +4 -4
  137. package/dist/navigation.cjs +3 -1
  138. package/dist/navigation.mjs +3 -3
  139. package/dist/observability.cjs +27 -2
  140. package/dist/observability.mjs +1 -1
  141. package/dist/plugin.cjs +474 -334
  142. package/dist/plugin.d.mts +3 -2
  143. package/dist/plugin.d.ts +3 -2
  144. package/dist/plugin.mjs +12 -12
  145. package/dist/{production-runtime-IkB0Qj4i.d.mts → production-runtime-BGRH1dKG.d.mts} +1 -1
  146. package/dist/{production-runtime-0JTch4_d.d.ts → production-runtime-CdmzsDax.d.ts} +1 -1
  147. package/dist/query/client.cjs +11 -3
  148. package/dist/query/client.mjs +12 -4
  149. package/dist/query/client.mjs.map +1 -1
  150. package/dist/{render-plan-Dc8CjNI7.d.ts → render-plan-0GeHiGVZ.d.ts} +1 -1
  151. package/dist/{render-plan-CU31j-Jk.d.mts → render-plan-DLxJYAA5.d.mts} +1 -1
  152. package/dist/renderer-client.cjs +140 -26
  153. package/dist/renderer-client.d.mts +7 -6
  154. package/dist/renderer-client.d.ts +7 -6
  155. package/dist/renderer-client.mjs +16 -19
  156. package/dist/renderer-client.mjs.map +1 -1
  157. package/dist/{request-BXa1KY8i.d.mts → request-BCNXSXLh.d.mts} +1 -1
  158. package/dist/{request-CUUBujZt.d.ts → request-BstWbZ6O.d.ts} +1 -1
  159. package/dist/request.d.mts +4 -3
  160. package/dist/request.d.ts +4 -3
  161. package/dist/{route-Y8lfz1wF.d.ts → route-4pd-EVtw.d.ts} +45 -50
  162. package/dist/{route-Cq3aObmj.d.mts → route-CvEr4Uc9.d.mts} +45 -50
  163. package/dist/routes.cjs +27 -2
  164. package/dist/routes.d.mts +3 -2
  165. package/dist/routes.d.ts +3 -2
  166. package/dist/routes.mjs +4 -4
  167. package/dist/{runtime-j1S3sDTh.d.ts → runtime-BgDQzBiu.d.ts} +1 -0
  168. package/dist/{runtime-DDwvDtS4.d.mts → runtime-CV2UCV-5.d.mts} +1 -0
  169. package/dist/server-action-security.mjs +2 -2
  170. package/dist/server-fn-client.cjs +34 -2
  171. package/dist/server-fn-client.d.mts +6 -0
  172. package/dist/server-fn-client.d.ts +6 -0
  173. package/dist/server-fn-client.mjs +1 -1
  174. package/dist/server-fn.cjs +42 -4
  175. package/dist/server-fn.mjs +5 -5
  176. package/dist/server-plugins.d.mts +4 -3
  177. package/dist/server-plugins.d.ts +4 -3
  178. package/dist/server-query-client.cjs +146 -27
  179. package/dist/server-query-client.d.mts +3 -3
  180. package/dist/server-query-client.d.ts +3 -3
  181. package/dist/server-query-client.mjs +7 -7
  182. package/dist/{server-query-runtime-3zAj77yv.d.ts → server-query-runtime-DXRNhX_3.d.ts} +2 -0
  183. package/dist/{server-query-runtime-B50KAcj5.d.mts → server-query-runtime-aP52iuL5.d.mts} +2 -0
  184. package/dist/server-query.cjs +44 -5
  185. package/dist/server-query.d.mts +4 -0
  186. package/dist/server-query.d.ts +4 -0
  187. package/dist/server-query.mjs +7 -7
  188. package/dist/server.cjs +499 -355
  189. package/dist/server.d.mts +11 -10
  190. package/dist/server.d.ts +11 -10
  191. package/dist/server.mjs +16 -16
  192. package/dist/{spa-router-CyLkwst6.d.mts → spa-router-BeyAVSc6.d.mts} +1 -1
  193. package/dist/{spa-router-BkqGXaV_.d.ts → spa-router-COgu4txb.d.ts} +1 -1
  194. package/dist/testing.cjs +27 -2
  195. package/dist/testing.d.mts +3 -2
  196. package/dist/testing.d.ts +3 -2
  197. package/dist/testing.mjs +8 -8
  198. package/dist/{utils-NKR6SoNv.d.mts → utils-DL2VwDQl.d.mts} +1 -1
  199. package/dist/{utils-B2OHrb9F.d.ts → utils-DkU2c_1B.d.ts} +1 -1
  200. package/dist/version.cjs +1 -1
  201. package/dist/version.mjs +1 -1
  202. package/dist/vite.cjs +482 -338
  203. package/dist/vite.d.mts +3 -2
  204. package/dist/vite.d.ts +3 -2
  205. package/dist/vite.mjs +16 -12
  206. package/package.json +17 -17
  207. package/types/client.d.ts +87 -1
  208. package/dist/agent-runtime.cjs.map +0 -1
  209. package/dist/api/route-manager.cjs.map +0 -1
  210. package/dist/api/runtime.cjs.map +0 -1
  211. package/dist/api.cjs.map +0 -1
  212. package/dist/app-markdown.cjs.map +0 -1
  213. package/dist/cache.cjs.map +0 -1
  214. package/dist/chunk-3I55IGXU.mjs.map +0 -1
  215. package/dist/chunk-54XSGLKT.mjs.map +0 -1
  216. package/dist/chunk-7MABZJIM.mjs.map +0 -1
  217. package/dist/chunk-AXVJCMVF.mjs.map +0 -1
  218. package/dist/chunk-GZHKWHCH.mjs.map +0 -1
  219. package/dist/chunk-HHZAOTQD.mjs.map +0 -1
  220. package/dist/chunk-LKKMI7JG.mjs.map +0 -1
  221. package/dist/chunk-LZTGDH3H.mjs.map +0 -1
  222. package/dist/chunk-MM46HTX6.mjs.map +0 -1
  223. package/dist/chunk-MRVJCLYQ.mjs.map +0 -1
  224. package/dist/chunk-Q7GPJZCO.mjs.map +0 -1
  225. package/dist/chunk-RAGSHKDC.mjs.map +0 -1
  226. package/dist/chunk-RBRLLZL5.mjs.map +0 -1
  227. package/dist/chunk-SCFX4UTD.mjs.map +0 -1
  228. package/dist/chunk-VOUJW4FL.mjs.map +0 -1
  229. package/dist/chunk-WB75GIX2.mjs.map +0 -1
  230. package/dist/chunk-ZFNK77WN.mjs.map +0 -1
  231. package/dist/chunk-ZPG6SNHH.mjs.map +0 -1
  232. package/dist/chunk-ZRBCBOEX.mjs.map +0 -1
  233. package/dist/client/lifecycle.cjs.map +0 -1
  234. package/dist/client-cache-CopR_MaI.d.mts +0 -6
  235. package/dist/client-cache-Djy_TlE8.d.ts +0 -6
  236. package/dist/client-plugins.cjs.map +0 -1
  237. package/dist/client.cjs.map +0 -1
  238. package/dist/config.cjs.map +0 -1
  239. package/dist/cron.cjs.map +0 -1
  240. package/dist/deferred.cjs.map +0 -1
  241. package/dist/deployment.cjs.map +0 -1
  242. package/dist/devtools-ui-NJKFORTG.mjs.map +0 -1
  243. package/dist/docs.cjs.map +0 -1
  244. package/dist/env-types.cjs.map +0 -1
  245. package/dist/env.cjs.map +0 -1
  246. package/dist/environment/vite.cjs.map +0 -1
  247. package/dist/environment.cjs.map +0 -1
  248. package/dist/font.cjs.map +0 -1
  249. package/dist/headers.cjs.map +0 -1
  250. package/dist/i18n/client.cjs.map +0 -1
  251. package/dist/i18n/index.cjs.map +0 -1
  252. package/dist/i18n/server.cjs.map +0 -1
  253. package/dist/image/server.cjs.map +0 -1
  254. package/dist/image/sharp.cjs.map +0 -1
  255. package/dist/image.cjs.map +0 -1
  256. package/dist/index.cjs.map +0 -1
  257. package/dist/instrumentation.cjs.map +0 -1
  258. package/dist/integrations.cjs.map +0 -1
  259. package/dist/internal/build-runtime.cjs.map +0 -1
  260. package/dist/internal/client-runtime.cjs.map +0 -1
  261. package/dist/internal/config-runtime.cjs.map +0 -1
  262. package/dist/internal/isolated-boundary.cjs.map +0 -1
  263. package/dist/internal/metadata-image-runtime.cjs.map +0 -1
  264. package/dist/internal/product-telemetry-runtime.cjs.map +0 -1
  265. package/dist/internal/production-node-env.cjs.map +0 -1
  266. package/dist/internal/production-runtime.cjs.map +0 -1
  267. package/dist/markdown.cjs.map +0 -1
  268. package/dist/middleware.cjs.map +0 -1
  269. package/dist/navigation.cjs.map +0 -1
  270. package/dist/observability.cjs.map +0 -1
  271. package/dist/plugin.cjs.map +0 -1
  272. package/dist/query/client.cjs.map +0 -1
  273. package/dist/query/index.cjs.map +0 -1
  274. package/dist/query/parsers.cjs.map +0 -1
  275. package/dist/query/server.cjs.map +0 -1
  276. package/dist/renderer/react/client.cjs.map +0 -1
  277. package/dist/renderer/react/server.cjs.map +0 -1
  278. package/dist/renderer/react/vite.cjs.map +0 -1
  279. package/dist/renderer-client.cjs.map +0 -1
  280. package/dist/renderer.cjs.map +0 -1
  281. package/dist/request.cjs.map +0 -1
  282. package/dist/router.cjs.map +0 -1
  283. package/dist/routes.cjs.map +0 -1
  284. package/dist/server-action-security.cjs.map +0 -1
  285. package/dist/server-fn-client.cjs.map +0 -1
  286. package/dist/server-fn.cjs.map +0 -1
  287. package/dist/server-plugins.cjs.map +0 -1
  288. package/dist/server-query-client.cjs.map +0 -1
  289. package/dist/server-query.cjs.map +0 -1
  290. package/dist/server.cjs.map +0 -1
  291. package/dist/storage.cjs.map +0 -1
  292. package/dist/testing.cjs.map +0 -1
  293. package/dist/theme/client.cjs.map +0 -1
  294. package/dist/theme/index.cjs.map +0 -1
  295. package/dist/theme/runtime.cjs.map +0 -1
  296. package/dist/theme/server.cjs.map +0 -1
  297. package/dist/version.cjs.map +0 -1
  298. package/dist/vite.cjs.map +0 -1
  299. package/dist/workflows.cjs.map +0 -1
  300. /package/dist/{chunk-VV24CC42.mjs.map → chunk-35NPLKQJ.mjs.map} +0 -0
  301. /package/dist/{chunk-RWYRFCLG.mjs.map → chunk-4X57GXQA.mjs.map} +0 -0
  302. /package/dist/{chunk-MOW47IF5.mjs.map → chunk-6UYVU46O.mjs.map} +0 -0
  303. /package/dist/{chunk-RLGUZ3HS.mjs.map → chunk-I3OOUWO5.mjs.map} +0 -0
  304. /package/dist/{chunk-ODJGAWDH.mjs.map → chunk-JV7JUD7Q.mjs.map} +0 -0
  305. /package/dist/{chunk-Q3OX763A.mjs.map → chunk-LXDASSTE.mjs.map} +0 -0
  306. /package/dist/{chunk-HVG3HLQZ.mjs.map → chunk-Q7WGOOAI.mjs.map} +0 -0
  307. /package/dist/{chunk-3INDBMUU.mjs.map → chunk-TGDIACZT.mjs.map} +0 -0
  308. /package/dist/{chunk-WMAYETRD.mjs.map → chunk-TT3E2JOF.mjs.map} +0 -0
  309. /package/dist/{chunk-FVAM43KI.mjs.map → chunk-UMUWR5XA.mjs.map} +0 -0
  310. /package/dist/{devtools-S52RRRMN.mjs.map → devtools-XWZX6CCL.mjs.map} +0 -0
  311. /package/dist/{devtools-client-EOVDBPOI.mjs.map → devtools-client-Z7QQA3Q2.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.96";
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>
@@ -30822,6 +30959,8 @@ __export(vite_exports, {
30822
30959
  defineConfig: () => defineConfig2,
30823
30960
  farmI18nClientBridgePlugin: () => farmI18nClientBridgePlugin,
30824
30961
  farmPlugin: () => farmPlugin,
30962
+ generateClientCachePersistenceCode: () => generateClientCachePersistenceCode,
30963
+ resolveFarmClientCacheAdapterEntry: () => resolveFarmClientCacheAdapterEntry,
30825
30964
  rewriteEarlySsrRelativeImports: () => rewriteEarlySsrRelativeImports,
30826
30965
  transformIsolatedClientBoundaryModule: () => transformIsolatedClientBoundaryModule,
30827
30966
  withFarmRequestTracing: () => withFarmRequestTracing
@@ -31191,18 +31330,18 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
31191
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");
31192
31331
  }
31193
31332
  function fileContainsProgrammaticPageRoute(file) {
31194
- if (!fs13.existsSync(file)) {
31333
+ if (!fs14.existsSync(file)) {
31195
31334
  return false;
31196
31335
  }
31197
31336
  try {
31198
- return scanProgrammaticPagePaths(fs13.readFileSync(file, "utf8")).length > 0;
31337
+ return scanProgrammaticPagePaths(fs14.readFileSync(file, "utf8")).length > 0;
31199
31338
  } catch {
31200
31339
  return false;
31201
31340
  }
31202
31341
  }
31203
31342
  function rewriteEarlySsrRelativeImports(options) {
31204
31343
  const cleanId = options.id.split("?", 1)[0];
31205
- if (!path37.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31344
+ if (!path38.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31206
31345
  return null;
31207
31346
  }
31208
31347
  const replacements = [];
@@ -31222,7 +31361,7 @@ function rewriteEarlySsrRelativeImports(options) {
31222
31361
  const suffixIndex = source.value.search(/[?#]/);
31223
31362
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
31224
31363
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
31225
- const resolvedPath = path37.resolve(path37.dirname(cleanId), sourcePath);
31364
+ const resolvedPath = path38.resolve(path38.dirname(cleanId), sourcePath);
31226
31365
  replacements.push({
31227
31366
  start: source.start,
31228
31367
  end: source.end,
@@ -31379,7 +31518,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31379
31518
  ...layerRoots.length ? {
31380
31519
  server: {
31381
31520
  fs: {
31382
- allow: [path37.resolve(options.root || process.cwd()), ...layerRoots]
31521
+ allow: [path38.resolve(options.root || process.cwd()), ...layerRoots]
31383
31522
  }
31384
31523
  }
31385
31524
  } : {}
@@ -31410,13 +31549,13 @@ function farmPlugin(options = {}, initialPluginManager) {
31410
31549
  },
31411
31550
  server
31412
31551
  );
31413
- const globalsCSSPath = path37.join(server.config.root, "src/app/globals.css");
31414
- if (!fs13.existsSync(globalsCSSPath)) {
31415
- const appDir = path37.join(server.config.root, "src/app");
31416
- if (!fs13.existsSync(appDir)) {
31417
- 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 });
31418
31557
  }
31419
- fs13.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31558
+ fs14.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31420
31559
  }
31421
31560
  await farmApp.initialize();
31422
31561
  const farmConfig = farmApp.getConfig();
@@ -31437,10 +31576,10 @@ function farmPlugin(options = {}, initialPluginManager) {
31437
31576
  });
31438
31577
  }
31439
31578
  const sourceRoots = getFarmSourceRoots(farmConfig);
31440
- 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)));
31441
31580
  if (farmConfig.i18n.enabled) {
31442
31581
  server.watcher.add(
31443
- 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
31444
31583
  );
31445
31584
  }
31446
31585
  const workflowConfig = farmConfig.workflows;
@@ -31450,7 +31589,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31450
31589
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
31451
31590
  ], "getExtraRouteTypes");
31452
31591
  const appDirSlugs = sourceRoots.map(
31453
- (source) => path37.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31592
+ (source) => path38.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31454
31593
  );
31455
31594
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
31456
31595
  try {
@@ -31491,7 +31630,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31491
31630
  }, "generateTypeArtifacts");
31492
31631
  await generateTypeArtifacts("startup");
31493
31632
  const srcDirSlugs = sourceRoots.map(
31494
- (source) => path37.join(source.root, source.srcDir).replace(/\\/g, "/")
31633
+ (source) => path38.join(source.root, source.srcDir).replace(/\\/g, "/")
31495
31634
  );
31496
31635
  const layerConfigFiles = new Set(
31497
31636
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -31612,7 +31751,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31612
31751
  await apiRouteManager.discoverRoutes();
31613
31752
  let discoveredWorkflows = [];
31614
31753
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
31615
- (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))
31616
31755
  );
31617
31756
  if (hasWorkflowDirectory) {
31618
31757
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -31877,12 +32016,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31877
32016
  }
31878
32017
  }
31879
32018
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
31880
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs13.existsSync(farmDocsFontPath)) {
32019
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs14.existsSync(farmDocsFontPath)) {
31881
32020
  res.statusCode = 200;
31882
32021
  res.setHeader("Content-Type", "font/woff2");
31883
32022
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
31884
32023
  if (requestMethod === "HEAD") res.end();
31885
- else fs13.createReadStream(farmDocsFontPath).pipe(res);
32024
+ else fs14.createReadStream(farmDocsFontPath).pipe(res);
31886
32025
  return;
31887
32026
  }
31888
32027
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -31938,6 +32077,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31938
32077
  if (requestPathname.endsWith(".json")) {
31939
32078
  res.end(JSON.stringify(snapshot, null, 2));
31940
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
+ }
31941
32086
  const { renderFarmDevtoolsHtml: renderFarmDevtoolsHtml2 } = await loadFarmDevtoolsUIRuntime();
31942
32087
  res.end(renderFarmDevtoolsHtml2(snapshot));
31943
32088
  }
@@ -31980,7 +32125,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31980
32125
  return null;
31981
32126
  }
31982
32127
  return {
31983
- source: await fs13.promises.readFile(sourcePath, "utf8"),
32128
+ source: await fs14.promises.readFile(sourcePath, "utf8"),
31984
32129
  filePath: sourcePath
31985
32130
  };
31986
32131
  }, "resolveSource")
@@ -32864,7 +33009,10 @@ ${generatedDevIndicatorsClientRuntime}`,
32864
33009
  renderer,
32865
33010
  isolatedHydrationMode === "enabled",
32866
33011
  resolvedConfig?.trailingSlash ?? false,
32867
- resolvedConfig?.basePath ?? "/"
33012
+ resolvedConfig?.basePath ?? "/",
33013
+ generateClientCachePersistenceCode(
33014
+ resolveFarmClientCacheAdapterEntry(root, resolvedConfig?.cache)
33015
+ )
32868
33016
  );
32869
33017
  }
32870
33018
  if (id === "/@farm/server") {
@@ -33003,7 +33151,7 @@ export const manifest = getManifest();
33003
33151
  const root = currentConfig.root || server?.config.root || process.cwd();
33004
33152
  const cleanId = id.split("?", 1)[0];
33005
33153
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
33006
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path37.resolve(cleanId)) === true;
33154
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path38.resolve(cleanId)) === true;
33007
33155
  if (isolatedHydrationEnabled && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
33008
33156
  isolatedModuleReference = toViteModuleId(cleanId, root);
33009
33157
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -33094,8 +33242,8 @@ if (import.meta.hot) {
33094
33242
  }
33095
33243
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
33096
33244
  logger.info("Pre-rendering SSG pages...");
33097
- const outDir = path37.join(server?.config.root || process.cwd(), options.outDir || "dist");
33098
- 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");
33099
33247
  for (const page2 of ssgPages) {
33100
33248
  try {
33101
33249
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -33147,9 +33295,9 @@ if (import.meta.hot) {
33147
33295
  <script type="module" src="/assets/client.js"></script>
33148
33296
  </body>
33149
33297
  </html>`;
33150
- const outputPath = page2.urlPath === "/" ? path37.join(clientDir, "index.html") : path37.join(clientDir, page2.urlPath + ".html");
33151
- fs13.mkdirSync(path37.dirname(outputPath), { recursive: true });
33152
- 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);
33153
33301
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
33154
33302
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
33155
33303
  });
@@ -33157,8 +33305,8 @@ if (import.meta.hot) {
33157
33305
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
33158
33306
  }
33159
33307
  }
33160
- const manifestPath = path37.join(outDir, "__ssg_manifest.json");
33161
- fs13.writeFileSync(
33308
+ const manifestPath = path38.join(outDir, "__ssg_manifest.json");
33309
+ fs14.writeFileSync(
33162
33310
  manifestPath,
33163
33311
  JSON.stringify(
33164
33312
  ssgPages.map((p) => ({
@@ -33201,9 +33349,9 @@ if (import.meta.hot) {
33201
33349
  server2.ws.send({ type: "full-reload", path: "*" });
33202
33350
  return [];
33203
33351
  }
33204
- 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;
33205
33353
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
33206
- logUpdate("PAGE", `updated ${path37.basename(file)}`);
33354
+ logUpdate("PAGE", `updated ${path38.basename(file)}`);
33207
33355
  for (const mod of modules) {
33208
33356
  server2.moduleGraph.invalidateModule(mod);
33209
33357
  }
@@ -33619,7 +33767,7 @@ function parseRouteModuleSchema2(schema, value, label, routePath) {
33619
33767
  throw new Error(`Invalid ${label} for route "${routePath}": ${message}`);
33620
33768
  }
33621
33769
  }
33622
- 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: "" }) {
33623
33771
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
33624
33772
  const clientPluginEntry = generateFarmClientPluginEntryCode(
33625
33773
  plugins,
@@ -33675,6 +33823,7 @@ import {
33675
33823
  } from '@farm.js/core/deployment'
33676
33824
  ${providerClientCode.imports}
33677
33825
  ${clientPluginEntry.imports}
33826
+ ${clientCachePersistence.imports}
33678
33827
  ${docsSearchClientRuntime}
33679
33828
  ${devtoolsClientRuntime}
33680
33829
  ${docsAdapterImportBlock}
@@ -33690,6 +33839,7 @@ const integrationDocumentNavigationMatchers = ${JSON.stringify(documentNavigatio
33690
33839
  setFarmBasePath(${JSON.stringify(basePath)});
33691
33840
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
33692
33841
  installChunkErrorRecovery();
33842
+ ${clientCachePersistence.init}
33693
33843
 
33694
33844
  let reactRoot = null;
33695
33845
  ${isolatedHydrationRuntime}
@@ -35070,7 +35220,7 @@ function generateClientManifest(bundle) {
35070
35220
  }
35071
35221
  async function defineConfig2(config = {}) {
35072
35222
  const tailwindcss = (await import("@tailwindcss/vite")).default;
35073
- const appRoot = path37.resolve(config.root || process.cwd());
35223
+ const appRoot = path38.resolve(config.root || process.cwd());
35074
35224
  if (config.extends?.length) {
35075
35225
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
35076
35226
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
@@ -35284,7 +35434,7 @@ async function defineConfig2(config = {}) {
35284
35434
  }
35285
35435
  };
35286
35436
  }
35287
- 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;
35288
35438
  var init_vite2 = __esm({
35289
35439
  "src/vite.ts"() {
35290
35440
  "use strict";
@@ -35293,6 +35443,8 @@ var init_vite2 = __esm({
35293
35443
  init_default_styles();
35294
35444
  init_plugin();
35295
35445
  init_client_plugin_build();
35446
+ init_client_cache_persistence_build();
35447
+ init_client_cache_persistence_build();
35296
35448
  init_route_manager2();
35297
35449
  init_config3();
35298
35450
  init_server_path();
@@ -35308,8 +35460,8 @@ var init_vite2 = __esm({
35308
35460
  init_route_context();
35309
35461
  init_devtools_config();
35310
35462
  init_dev_indicators();
35311
- fs13 = __toESM(require("fs"));
35312
- path37 = __toESM(require("path"));
35463
+ fs14 = __toESM(require("fs"));
35464
+ path38 = __toESM(require("path"));
35313
35465
  import_node_url9 = require("url");
35314
35466
  init_layers();
35315
35467
  init_environment_vite();
@@ -35358,6 +35510,7 @@ var init_vite2 = __esm({
35358
35510
  i18n: false
35359
35511
  }), "createEmptyTypeArtifactSelection");
35360
35512
  FARM_I18N_CLIENT_BRIDGE_ID = "\0farm-i18n-client-bridge";
35513
+ warnedDeprecatedDevtoolsDashboard = false;
35361
35514
  EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME = `
35362
35515
  function isFarmDocsSearchPage() {
35363
35516
  return false;
@@ -36094,7 +36247,7 @@ module.exports = __toCommonJS(build_runtime_exports);
36094
36247
  // src/build/index.ts
36095
36248
  init_config4();
36096
36249
  var import_path17 = __toESM(require("path"));
36097
- var import_node_fs13 = require("fs");
36250
+ var import_node_fs14 = require("fs");
36098
36251
  init_utils();
36099
36252
  init_app();
36100
36253
  init_route_manager2();
@@ -36109,15 +36262,15 @@ var import_path8 = __toESM(require("path"));
36109
36262
  var FARM_CLIENT_CSS_HREF_PLACEHOLDER = "/__farm_client_css_href__";
36110
36263
  var FARM_CLIENT_JS_SRC_PLACEHOLDER = "/__farm_client_js_src__";
36111
36264
  async function hashAndCopy(sourcePath, destinationDir, hashedName) {
36112
- const fs14 = await import("fs/promises");
36265
+ const fs15 = await import("fs/promises");
36113
36266
  try {
36114
- const bytes = await fs14.readFile(sourcePath);
36267
+ const bytes = await fs15.readFile(sourcePath);
36115
36268
  if (bytes.length === 0) return null;
36116
36269
  const { createHash: createHash5 } = await import("crypto");
36117
36270
  const hash = createHash5("sha256").update(bytes).digest("hex").slice(0, 8);
36118
36271
  const name2 = hashedName(hash);
36119
- await fs14.mkdir(destinationDir, { recursive: true });
36120
- 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);
36121
36274
  return name2;
36122
36275
  } catch {
36123
36276
  return null;
@@ -36134,9 +36287,9 @@ async function resolveHashedClientCssHref(clientOutputDir) {
36134
36287
  }
36135
36288
  __name(resolveHashedClientCssHref, "resolveHashedClientCssHref");
36136
36289
  async function findFingerprintedClientEntry(clientOutputDir) {
36137
- const fs14 = await import("fs/promises");
36290
+ const fs15 = await import("fs/promises");
36138
36291
  try {
36139
- const entries = await fs14.readdir(clientOutputDir);
36292
+ const entries = await fs15.readdir(clientOutputDir);
36140
36293
  return entries.find((name2) => /^farm-client-h[0-9a-f]+\.js$/.test(name2)) ?? null;
36141
36294
  } catch {
36142
36295
  return null;
@@ -36146,10 +36299,10 @@ __name(findFingerprintedClientEntry, "findFingerprintedClientEntry");
36146
36299
  async function resolveHashedClientJsSrc(clientOutputDir) {
36147
36300
  const entryName = await findFingerprintedClientEntry(clientOutputDir);
36148
36301
  if (!entryName) return "/farm-client.js";
36149
- const fs14 = await import("fs/promises");
36302
+ const fs15 = await import("fs/promises");
36150
36303
  const shim = `export * from "./${entryName}";
36151
36304
  `;
36152
- 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);
36153
36306
  return `/${entryName}`;
36154
36307
  }
36155
36308
  __name(resolveHashedClientJsSrc, "resolveHashedClientJsSrc");
@@ -36157,6 +36310,7 @@ __name(resolveHashedClientJsSrc, "resolveHashedClientJsSrc");
36157
36310
  // src/nitro/universal-build.ts
36158
36311
  init_server_path();
36159
36312
  init_client_plugin_build();
36313
+ init_client_cache_persistence_build();
36160
36314
  var import_os = __toESM(require("os"));
36161
36315
  var import_path14 = __toESM(require("path"));
36162
36316
  var import_fs5 = require("fs");
@@ -36253,10 +36407,10 @@ async function createFarmRouteRuntimeManifest(options) {
36253
36407
  }
36254
36408
  __name(createFarmRouteRuntimeManifest, "createFarmRouteRuntimeManifest");
36255
36409
  async function writeFarmRouteRuntimeManifest(directory, manifest) {
36256
- const fs14 = await import("fs/promises");
36410
+ const fs15 = await import("fs/promises");
36257
36411
  const manifestPath = import_path9.default.join(directory, FARM_ROUTE_RUNTIME_MANIFEST);
36258
- await fs14.mkdir(directory, { recursive: true });
36259
- 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)}
36260
36414
  `);
36261
36415
  return manifestPath;
36262
36416
  }
@@ -36302,7 +36456,7 @@ __name(normalizeManifestSource, "normalizeManifestSource");
36302
36456
  // src/nitro/vercel-route-runtime.ts
36303
36457
  var import_path10 = __toESM(require("path"));
36304
36458
  init_route_runtime();
36305
- async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs14) {
36459
+ async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs15) {
36306
36460
  const dynamicRoutes = manifest.routes.filter(
36307
36461
  (route) => route.rendering === "dynamic" && route.runtime !== "edge"
36308
36462
  );
@@ -36333,8 +36487,8 @@ async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs14)
36333
36487
  groupIndex += 1;
36334
36488
  const functionName = `__farm_runtime_${groupIndex}`;
36335
36489
  const functionDir = import_path10.default.join(functionsDir, `${functionName}.func`);
36336
- await fs14.cp(baseFunctionDir, functionDir, { recursive: true, force: true });
36337
- await configureVercelFunction(functionDir, group.config, fs14);
36490
+ await fs15.cp(baseFunctionDir, functionDir, { recursive: true, force: true });
36491
+ await configureVercelFunction(functionDir, group.config, fs15);
36338
36492
  destinations.set(key, `/${functionName}`);
36339
36493
  }
36340
36494
  const routes = [];
@@ -36381,15 +36535,15 @@ function farmRoutePatternToVercelSource(pattern) {
36381
36535
  return source || "/";
36382
36536
  }
36383
36537
  __name(farmRoutePatternToVercelSource, "farmRoutePatternToVercelSource");
36384
- async function configureVercelFunction(functionDir, config, fs14) {
36538
+ async function configureVercelFunction(functionDir, config, fs15) {
36385
36539
  const configPath = import_path10.default.join(functionDir, ".vc-config.json");
36386
- const current = JSON.parse(await fs14.readFile(configPath, "utf8"));
36540
+ const current = JSON.parse(await fs15.readFile(configPath, "utf8"));
36387
36541
  const next = {
36388
36542
  ...current,
36389
36543
  ...config.regions?.length ? { regions: config.regions } : {},
36390
36544
  ...config.maxDuration ? { maxDuration: config.maxDuration } : {}
36391
36545
  };
36392
- await fs14.writeFile(configPath, `${JSON.stringify(next, null, 2)}
36546
+ await fs15.writeFile(configPath, `${JSON.stringify(next, null, 2)}
36393
36547
  `);
36394
36548
  }
36395
36549
  __name(configureVercelFunction, "configureVercelFunction");
@@ -36439,6 +36593,34 @@ function createFarmVercelImmutableAssetRoute() {
36439
36593
  };
36440
36594
  }
36441
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");
36442
36624
 
36443
36625
  // src/nitro/node-server-entry.ts
36444
36626
  function createFarmNodeServerEntry(options) {
@@ -36732,23 +36914,23 @@ init_vite();
36732
36914
 
36733
36915
  // src/instrumentation.ts
36734
36916
  var import_esbuild = require("esbuild");
36735
- var import_node_fs8 = __toESM(require("fs"));
36736
- var import_node_path16 = __toESM(require("path"));
36917
+ var import_node_fs9 = __toESM(require("fs"));
36918
+ var import_node_path17 = __toESM(require("path"));
36737
36919
  var import_node_url8 = require("url");
36738
36920
  var INSTRUMENTATION_EXTENSIONS = ["ts", "mts", "js", "mjs"];
36739
36921
  function resolveFarmInstrumentationFile(root, srcDir = "src") {
36740
36922
  const candidates = [
36741
36923
  ...INSTRUMENTATION_EXTENSIONS.map(
36742
- (extension) => import_node_path16.default.join(root, srcDir, `instrumentation.${extension}`)
36924
+ (extension) => import_node_path17.default.join(root, srcDir, `instrumentation.${extension}`)
36743
36925
  ),
36744
36926
  ...INSTRUMENTATION_EXTENSIONS.map(
36745
- (extension) => import_node_path16.default.join(root, `instrumentation.${extension}`)
36927
+ (extension) => import_node_path17.default.join(root, `instrumentation.${extension}`)
36746
36928
  )
36747
- ].filter((candidate) => import_node_fs8.default.existsSync(candidate));
36929
+ ].filter((candidate) => import_node_fs9.default.existsSync(candidate));
36748
36930
  if (candidates.length > 1) {
36749
36931
  throw new Error(
36750
36932
  `Farm.js found multiple instrumentation files:
36751
- ${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")}
36752
36934
  Keep only one instrumentation file in the project root or ${srcDir}/.`
36753
36935
  );
36754
36936
  }
@@ -37103,7 +37285,7 @@ function hasProjectPostcssConfig(root) {
37103
37285
  }
37104
37286
  __name(hasProjectPostcssConfig, "hasProjectPostcssConfig");
37105
37287
  async function findFarmConfigPath(root) {
37106
- const fs14 = await import("fs/promises");
37288
+ const fs15 = await import("fs/promises");
37107
37289
  const candidates = [
37108
37290
  "farm.config.ts",
37109
37291
  "farm.config.mts",
@@ -37117,7 +37299,7 @@ async function findFarmConfigPath(root) {
37117
37299
  for (const candidate of candidates) {
37118
37300
  const resolvedPath = import_path14.default.join(root, candidate);
37119
37301
  try {
37120
- await fs14.access(resolvedPath);
37302
+ await fs15.access(resolvedPath);
37121
37303
  return resolvedPath;
37122
37304
  } catch {
37123
37305
  }
@@ -37144,13 +37326,13 @@ function hasFarmServerRuntimePlugins(config) {
37144
37326
  }
37145
37327
  __name(hasFarmServerRuntimePlugins, "hasFarmServerRuntimePlugins");
37146
37328
  async function discoverMiddlewareRoutes(appDir) {
37147
- const fs14 = await import("fs/promises");
37329
+ const fs15 = await import("fs/promises");
37148
37330
  const appDirs = Array.isArray(appDir) ? [...appDir] : [appDir];
37149
37331
  const routes = /* @__PURE__ */ new Map();
37150
37332
  async function walk(dir, routePath, discovered) {
37151
37333
  let entries;
37152
37334
  try {
37153
- entries = await fs14.readdir(dir, { withFileTypes: true });
37335
+ entries = await fs15.readdir(dir, { withFileTypes: true });
37154
37336
  } catch {
37155
37337
  return;
37156
37338
  }
@@ -37231,12 +37413,12 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
37231
37413
  })
37232
37414
  );
37233
37415
  logger.info(`\u{1F4CB} Found ${pageRoutes.length} page routes`);
37234
- const fs14 = await import("fs/promises");
37416
+ const fs15 = await import("fs/promises");
37235
37417
  const layoutRoutes = [];
37236
37418
  const appDir = import_path14.default.join(root, srcDir, "app");
37237
37419
  async function findLayoutsForClient(dir, routePrefix = "/") {
37238
37420
  try {
37239
- const entries = await fs14.readdir(dir, { withFileTypes: true });
37421
+ const entries = await fs15.readdir(dir, { withFileTypes: true });
37240
37422
  for (const entry of entries) {
37241
37423
  if (entry.isFile() && entry.name.match(/^layout\.(tsx?|jsx?|vue|svelte)$/)) {
37242
37424
  layoutRoutes.push({
@@ -37384,7 +37566,7 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
37384
37566
  }
37385
37567
  __name(buildUniversal, "buildUniversal");
37386
37568
  async function writeSSRAssetsToClient(bundle, outputDir) {
37387
- const fs14 = await import("fs/promises");
37569
+ const fs15 = await import("fs/promises");
37388
37570
  for (const [fileName, output] of Object.entries(bundle)) {
37389
37571
  if (output.type !== "asset") continue;
37390
37572
  if (fileName === "farm-fonts.css") {
@@ -37392,29 +37574,29 @@ async function writeSSRAssetsToClient(bundle, outputDir) {
37392
37574
  continue;
37393
37575
  }
37394
37576
  const filePath = import_path14.default.join(outputDir, fileName);
37395
- await fs14.mkdir(import_path14.default.dirname(filePath), { recursive: true });
37396
- await fs14.writeFile(filePath, output.source);
37577
+ await fs15.mkdir(import_path14.default.dirname(filePath), { recursive: true });
37578
+ await fs15.writeFile(filePath, output.source);
37397
37579
  }
37398
37580
  }
37399
37581
  __name(writeSSRAssetsToClient, "writeSSRAssetsToClient");
37400
37582
  async function copyFarmDocsFontAssetsToClient(root, outputDir) {
37401
- const fs14 = await import("fs/promises");
37583
+ const fs15 = await import("fs/promises");
37402
37584
  await Promise.all(
37403
37585
  resolveFarmDocsFontAssets(root).map(async ({ sourcePath, url }) => {
37404
37586
  const targetPath = import_path14.default.join(outputDir, url.replace(/^\/+/, ""));
37405
- await fs14.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
37406
- await fs14.copyFile(sourcePath, targetPath);
37587
+ await fs15.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
37588
+ await fs15.copyFile(sourcePath, targetPath);
37407
37589
  })
37408
37590
  );
37409
37591
  }
37410
37592
  __name(copyFarmDocsFontAssetsToClient, "copyFarmDocsFontAssetsToClient");
37411
37593
  async function mergeBuiltFontCss(outputDir, fontCssSource) {
37412
- const fs14 = await import("fs/promises");
37594
+ const fs15 = await import("fs/promises");
37413
37595
  const fontCssPath = import_path14.default.join(outputDir, "farm-fonts.css");
37414
37596
  let fontCss = fontCssSource;
37415
37597
  if (fontCss === void 0) {
37416
37598
  try {
37417
- fontCss = await fs14.readFile(fontCssPath);
37599
+ fontCss = await fs15.readFile(fontCssPath);
37418
37600
  } catch {
37419
37601
  return;
37420
37602
  }
@@ -37422,12 +37604,12 @@ async function mergeBuiltFontCss(outputDir, fontCssSource) {
37422
37604
  const clientCssPath = import_path14.default.join(outputDir, "farm-client.css");
37423
37605
  let clientCss = "";
37424
37606
  try {
37425
- clientCss = await fs14.readFile(clientCssPath, "utf8");
37607
+ clientCss = await fs15.readFile(clientCssPath, "utf8");
37426
37608
  } catch {
37427
37609
  }
37428
37610
  const normalizedFontCss = typeof fontCss === "string" ? fontCss : Buffer.from(fontCss).toString("utf8");
37429
- await fs14.writeFile(fontCssPath, normalizedFontCss);
37430
- await fs14.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
37611
+ await fs15.writeFile(fontCssPath, normalizedFontCss);
37612
+ await fs15.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
37431
37613
  }
37432
37614
  __name(mergeBuiltFontCss, "mergeBuiltFontCss");
37433
37615
  var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError extends Error {
@@ -37439,12 +37621,12 @@ var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError
37439
37621
  __name(_IncompleteClientBuildOutputError, "IncompleteClientBuildOutputError");
37440
37622
  var IncompleteClientBuildOutputError = _IncompleteClientBuildOutputError;
37441
37623
  async function validateClientBuildOutput(root, srcDir, outputDir) {
37442
- const fs14 = await import("fs/promises");
37624
+ const fs15 = await import("fs/promises");
37443
37625
  const fingerprinted = await findFingerprintedClientEntry(outputDir);
37444
37626
  const clientEntryPath = import_path14.default.join(outputDir, fingerprinted ?? "farm-client.js");
37445
37627
  let clientEntrySize = 0;
37446
37628
  try {
37447
- const clientEntry = await fs14.stat(clientEntryPath);
37629
+ const clientEntry = await fs15.stat(clientEntryPath);
37448
37630
  if (clientEntry.isFile()) clientEntrySize = clientEntry.size;
37449
37631
  } catch {
37450
37632
  }
@@ -37455,12 +37637,12 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
37455
37637
  const globalsCssPath = import_path14.default.join(root, srcDir, "app", "globals.css");
37456
37638
  let expectsCss = false;
37457
37639
  try {
37458
- const globalsCss = await fs14.readFile(globalsCssPath, "utf8");
37640
+ const globalsCss = await fs15.readFile(globalsCssPath, "utf8");
37459
37641
  expectsCss = globalsCss.replace(/\/\*[\s\S]*?\*\//g, "").trim().length > 0;
37460
37642
  } catch {
37461
37643
  }
37462
37644
  try {
37463
- const clientCss = await fs14.stat(clientCssPath);
37645
+ const clientCss = await fs15.stat(clientCssPath);
37464
37646
  if (expectsCss && (!clientCss.isFile() || clientCss.size === 0)) {
37465
37647
  throw new IncompleteClientBuildOutputError("farm-client.css is empty");
37466
37648
  }
@@ -37469,7 +37651,7 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
37469
37651
  if (expectsCss) {
37470
37652
  throw new IncompleteClientBuildOutputError("farm-client.css is missing");
37471
37653
  }
37472
- await fs14.writeFile(clientCssPath, "");
37654
+ await fs15.writeFile(clientCssPath, "");
37473
37655
  }
37474
37656
  }
37475
37657
  __name(validateClientBuildOutput, "validateClientBuildOutput");
@@ -37487,7 +37669,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37487
37669
  const viteBuild = productionVite.build;
37488
37670
  const { farmPlugin: farmPlugin2 } = await Promise.resolve().then(() => (init_vite2(), vite_exports));
37489
37671
  const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_plugin(), plugin_exports));
37490
- const fs14 = await import("fs/promises");
37672
+ const fs15 = await import("fs/promises");
37491
37673
  const pluginManager = new PluginManager2({
37492
37674
  config,
37493
37675
  isDev: false,
@@ -37679,8 +37861,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37679
37861
  `\u{1F4F1} Total hydratable routes detected: ${clientPages.length} pages, ${clientLayouts.filter((layout2) => layout2.shouldHydrate).length} layouts, and ${clientRouteSlots.length} slots`
37680
37862
  );
37681
37863
  const clientEntryRoot = import_path14.default.join(root, ".farm", "tmp");
37682
- await fs14.mkdir(clientEntryRoot, { recursive: true });
37683
- 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-"));
37684
37866
  const clientEntryPath = import_path14.default.join(clientEntryDir, "farm-client-entry.tsx");
37685
37867
  const clientHydrationCode = generateClientHydrationEntry(
37686
37868
  clientPages,
@@ -37698,9 +37880,10 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37698
37880
  config.publicRuntimeConfig,
37699
37881
  config.trailingSlash,
37700
37882
  getIntegrationProviders(config.integrations),
37701
- config.basePath
37883
+ config.basePath,
37884
+ generateClientCachePersistenceCode(resolveFarmClientCacheAdapterEntry(root, config.cache))
37702
37885
  );
37703
- await fs14.writeFile(clientEntryPath, clientHydrationCode);
37886
+ await fs15.writeFile(clientEntryPath, clientHydrationCode);
37704
37887
  const hasScopedPostcssConfig = hasProjectPostcssConfig(root);
37705
37888
  let postcssSearchPath;
37706
37889
  let tailwindVitePlugin = void 0;
@@ -37711,7 +37894,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37711
37894
  logger.info("\u{1F4E6} Using project PostCSS/Tailwind configuration");
37712
37895
  } else {
37713
37896
  const postcssConfigPath = import_path14.default.join(clientEntryDir, "postcss.config.cjs");
37714
- await fs14.writeFile(postcssConfigPath, "module.exports = { plugins: [] };\n");
37897
+ await fs15.writeFile(postcssConfigPath, "module.exports = { plugins: [] };\n");
37715
37898
  postcssSearchPath = clientEntryDir;
37716
37899
  try {
37717
37900
  const tailwindVite = (await import("@tailwindcss/vite")).default;
@@ -37862,7 +38045,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
37862
38045
  await validateClientBuildOutput(root, srcDir, outputDir);
37863
38046
  } finally {
37864
38047
  try {
37865
- await fs14.rm(clientEntryDir, { recursive: true, force: true });
38048
+ await fs15.rm(clientEntryDir, { recursive: true, force: true });
37866
38049
  } catch {
37867
38050
  }
37868
38051
  }
@@ -38009,6 +38192,46 @@ function matchRuntimePathPattern(pattern, pathname) {
38009
38192
  `.trim();
38010
38193
  }
38011
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");
38012
38235
  function generateUniversalRouterStateProperties() {
38013
38236
  return `
38014
38237
  blockers: new Set(),
@@ -38300,7 +38523,7 @@ function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlot
38300
38523
  secure: false
38301
38524
  },
38302
38525
  direction: {}
38303
- }, 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: "" }) {
38304
38527
  const toImportPath = /* @__PURE__ */ __name((targetPath) => targetPath.replace(/\\/g, "/"), "toImportPath");
38305
38528
  const clientPluginEntry = generateFarmClientPluginEntryCode(
38306
38529
  plugins,
@@ -38312,8 +38535,7 @@ function generateClientHydrationEntry(clientPages, layoutRoutes, clientRouteSlot
38312
38535
  import { createRoot, hydrateRoot } from "react-dom/client";` : `import React, { createRoot, hydrateRoot } from ${JSON.stringify(renderer.client)};`;
38313
38536
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
38314
38537
  const globalsCssPath = import_path14.default.join(root, srcDir, "app", "globals.css");
38315
- const cssImportPath = toImportPath(globalsCssPath);
38316
- const cssImport = `import ${JSON.stringify(cssImportPath)};`;
38538
+ const cssImport = (0, import_fs5.existsSync)(globalsCssPath) ? `import ${JSON.stringify(toImportPath(globalsCssPath))};` : "";
38317
38539
  const layoutImportStatements = [];
38318
38540
  const layoutRegistrations = [];
38319
38541
  layoutRoutes.forEach((layout2, index) => {
@@ -38398,6 +38620,7 @@ ${layoutImports}
38398
38620
  import { createClientPluginManager, getHashTargetElement, installChunkErrorRecovery, isFarmExternalNavigationURL, reconcileFarmDocumentHead, setFarmBasePath, setFarmTrailingSlashPreference, stripFarmBasePath } from "@farm.js/core/internal/client-runtime";
38399
38621
  import { createFarmDeploymentMismatchError, createFarmDeploymentRequestHeaders, isFarmDeploymentMismatchResponse } from "@farm.js/core/deployment";
38400
38622
  ${clientPluginEntry.imports}
38623
+ ${clientCachePersistence.imports}
38401
38624
  ${i18nClientRuntime}
38402
38625
  ${docsNavigationRuntime}
38403
38626
  ${docsAdapterRuntime}
@@ -38406,6 +38629,7 @@ ${generateFarmDocsSearchClientRuntime(docsSearchEnabled, docsSearchModuleId)}
38406
38629
  setFarmBasePath(${JSON.stringify(basePath)});
38407
38630
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
38408
38631
  installChunkErrorRecovery();
38632
+ ${clientCachePersistence.init}
38409
38633
  mountFarmDocsSearch();
38410
38634
 
38411
38635
  ${generateUniversalRouterStateRuntime()}
@@ -38760,6 +38984,7 @@ import { createClientPluginManager, getHashTargetElement, installChunkErrorRecov
38760
38984
  import { createFarmDeploymentMismatchError, createFarmDeploymentRequestHeaders, isFarmDeploymentMismatchResponse } from "@farm.js/core/deployment";
38761
38985
  import { isFarmRouteActive, matchFarmRoute } from "@farm.js/core/router";
38762
38986
  ${clientPluginEntry.imports}
38987
+ ${clientCachePersistence.imports}
38763
38988
  ${i18nClientRuntime}
38764
38989
  ${docsNavigationRuntime}
38765
38990
  ${docsAdapterRuntime}
@@ -38772,6 +38997,7 @@ ${providerClientCode.runtime}
38772
38997
  setFarmBasePath(${JSON.stringify(basePath)});
38773
38998
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
38774
38999
  installChunkErrorRecovery();
39000
+ ${clientCachePersistence.init}
38775
39001
 
38776
39002
  // Client component routes
38777
39003
  const clientRoutes = [
@@ -39714,7 +39940,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39714
39940
  const viteBuild = productionVite.build;
39715
39941
  const { farmPlugin: farmPlugin2 } = await Promise.resolve().then(() => (init_vite2(), vite_exports));
39716
39942
  const { PluginManager: PluginManager2 } = await Promise.resolve().then(() => (init_plugin(), plugin_exports));
39717
- const fs14 = await import("fs/promises");
39943
+ const fs15 = await import("fs/promises");
39718
39944
  const pluginManager = new PluginManager2({
39719
39945
  config,
39720
39946
  isDev: false,
@@ -39728,8 +39954,8 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39728
39954
  ssr: true
39729
39955
  });
39730
39956
  if (!hasScopedPostcssConfig) {
39731
- postcssConfigDir = await fs14.mkdtemp(import_path14.default.join(import_os.default.tmpdir(), "farm-postcss-"));
39732
- await fs14.writeFile(
39957
+ postcssConfigDir = await fs15.mkdtemp(import_path14.default.join(import_os.default.tmpdir(), "farm-postcss-"));
39958
+ await fs15.writeFile(
39733
39959
  import_path14.default.join(postcssConfigDir, "postcss.config.cjs"),
39734
39960
  "module.exports = { plugins: [] };\n"
39735
39961
  );
@@ -39759,7 +39985,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39759
39985
  fileName: entry.fileName,
39760
39986
  sourceType: "static",
39761
39987
  staticInfo: entry.staticInfo,
39762
- data: (await fs14.readFile(entry.modulePath)).toString("base64")
39988
+ data: (await fs15.readFile(entry.modulePath)).toString("base64")
39763
39989
  });
39764
39990
  continue;
39765
39991
  }
@@ -40055,7 +40281,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
40055
40281
  } finally {
40056
40282
  if (postcssConfigDir) {
40057
40283
  try {
40058
- await fs14.rm(postcssConfigDir, { recursive: true, force: true });
40284
+ await fs15.rm(postcssConfigDir, { recursive: true, force: true });
40059
40285
  } catch {
40060
40286
  }
40061
40287
  }
@@ -40787,7 +41013,7 @@ const farmDocsAPIHandler = ${config.docs?.enabled ? adapterOwnsDocsRuntime ? "nu
40787
41013
 
40788
41014
  // API routes bundled at build time
40789
41015
  const apiRoutes = ${apiRoutes.length > 0 ? "mergePluginAPIRoutes(" : ""}[${apiRegistrations.join(",")}
40790
- ]${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 })))})` : ""};
40791
41017
  const farmLocalAPIBasePath = ${JSON.stringify(resolveFarmAPIServerBasePath(config.api))};
40792
41018
  const farmOpenAPIReference = ${JSON.stringify(openAPIReference)};
40793
41019
 
@@ -41516,32 +41742,7 @@ async function handleApplicationMetadataRouteRequest(request, routePathname) {
41516
41742
  }
41517
41743
  }
41518
41744
 
41519
- function encodeRuntimePathSegment(value) {
41520
- return encodeURIComponent(String(value)).replace(
41521
- /[!'()*]/g,
41522
- function(character) {
41523
- return "%" + character.charCodeAt(0).toString(16).toUpperCase();
41524
- },
41525
- );
41526
- }
41527
-
41528
- function interpolateRedirectDestination(destination, params) {
41529
- let result = destination;
41530
- const catchAllParamSegments = params[farmCatchAllParamSegments] || {};
41531
- for (const [key, value] of Object.entries(params)) {
41532
- const segments = catchAllParamSegments[key];
41533
- const encodedValue = Array.isArray(segments)
41534
- ? segments.map(encodeRuntimePathSegment).join("/")
41535
- : encodeRuntimePathSegment(value);
41536
- result = result.split("[[..." + key + "]]").join(encodedValue);
41537
- result = result.split("[..." + key + "]").join(encodedValue);
41538
- result = result.split("[" + key + "]").join(encodedValue);
41539
- result = result.split(":" + key + "*").join(encodedValue);
41540
- result = result.split(":" + key).join(encodedValue);
41541
- if (key === "wildcard") result = result.split("*").join(encodedValue);
41542
- }
41543
- return result;
41544
- }
41745
+ ${generateRedirectInterpolationSource()}
41545
41746
 
41546
41747
  function matchRedirectRoute(pathname, locale, search) {
41547
41748
  for (const redirect of redirectRoutes) {
@@ -41964,9 +42165,10 @@ ${config.docs?.enabled ? `async function wrapFarmDocsResponseWithLayouts(request
41964
42165
  }` : ""}
41965
42166
 
41966
42167
  const pprShellCache = getFarmDataCache();
42168
+ const experimentalPPREnabled = ${JSON.stringify(config.experimental?.ppr === true)};
41967
42169
 
41968
42170
  function resolvePPRConfig(routeModule) {
41969
- if (!routeModule || routeModule.dynamic === "force-dynamic") {
42171
+ if (!experimentalPPREnabled || !routeModule || routeModule.dynamic === "force-dynamic") {
41970
42172
  return { enabled: false };
41971
42173
  }
41972
42174
 
@@ -43504,7 +43706,7 @@ function getPhysicalPrerenderBypassReason(options) {
43504
43706
  }
43505
43707
  __name(getPhysicalPrerenderBypassReason, "getPhysicalPrerenderBypassReason");
43506
43708
  async function buildNitroUniversal(config, routeManager, apiRouteManager, serverRenderer, preset, root, distDir, ssrBundle, ssrEntryFile, clientOutputDir, routeRuntimeManifest, configuredHeaderRoutes, nitroRuntimeResultPromise, pluginManager) {
43507
- const [fs14, nitroRuntimeResult] = await Promise.all([
43709
+ const [fs15, nitroRuntimeResult] = await Promise.all([
43508
43710
  import("fs/promises"),
43509
43711
  nitroRuntimeResultPromise
43510
43712
  ]);
@@ -43595,11 +43797,11 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
43595
43797
  output.code = output.code.split(FARM_CLIENT_JS_SRC_PLACEHOLDER).join(clientJsSrc);
43596
43798
  }
43597
43799
  }
43598
- await fs14.mkdir(ssrOutputDir, { recursive: true });
43800
+ await fs15.mkdir(ssrOutputDir, { recursive: true });
43599
43801
  for (const [fileName, output] of Object.entries(ssrBundle)) {
43600
43802
  const filePath = import_path14.default.join(ssrOutputDir, fileName);
43601
- await fs14.mkdir(import_path14.default.dirname(filePath), { recursive: true });
43602
- 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);
43603
43805
  }
43604
43806
  const nitroEntryPath = import_path14.default.join(ssrOutputDir, "nitro-entry.mjs");
43605
43807
  const nitroEntryCode = `
@@ -43671,10 +43873,10 @@ export default async function farmNitroEventHandler(event) {
43671
43873
  return response
43672
43874
  }
43673
43875
  `.trim();
43674
- await fs14.writeFile(nitroEntryPath, nitroEntryCode);
43876
+ await fs15.writeFile(nitroEntryPath, nitroEntryCode);
43675
43877
  const farmNodeServerEntryPath = preset === "node-server" ? import_path14.default.join(ssrOutputDir, "farm-node-server-entry.mjs") : null;
43676
43878
  if (farmNodeServerEntryPath) {
43677
- await fs14.writeFile(
43879
+ await fs15.writeFile(
43678
43880
  farmNodeServerEntryPath,
43679
43881
  createFarmNodeServerEntry({
43680
43882
  nitroEntryFile: import_path14.default.basename(nitroEntryPath),
@@ -43892,9 +44094,9 @@ export default async function farmNitroEventHandler(event) {
43892
44094
  import_path14.default.join(prerenderServerDir, FARM_SSR_OUTPUT_DIR),
43893
44095
  {},
43894
44096
  false,
43895
- fs14
44097
+ fs15
43896
44098
  );
43897
- await registerPrebuiltSSRPackageImport(prerenderServerDir, ssrEntryFile, fs14);
44099
+ await registerPrebuiltSSRPackageImport(prerenderServerDir, ssrEntryFile, fs15);
43898
44100
  });
43899
44101
  });
43900
44102
  }
@@ -43926,17 +44128,17 @@ export default async function farmNitroEventHandler(event) {
43926
44128
  import_path14.default.join(outputDir, "server", FARM_SSR_OUTPUT_DIR),
43927
44129
  prebuiltSSREsbuildOptions,
43928
44130
  effectiveMinify,
43929
- fs14
44131
+ fs15
43930
44132
  ) : Promise.resolve(),
43931
- imageRuntime === "node" ? copySharpRuntime(config, root, import_path14.default.join(outputDir, "server"), fs14) : Promise.resolve(),
43932
- 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()
43933
44135
  ]);
43934
44136
  const failedCopy = copyResults.find(
43935
44137
  (result) => result.status === "rejected"
43936
44138
  );
43937
44139
  if (failedCopy) throw failedCopy.reason;
43938
44140
  if (canReusePrebuiltSSR) {
43939
- await registerPrebuiltSSRPackageImport(import_path14.default.join(outputDir, "server"), ssrEntryFile, fs14);
44141
+ await registerPrebuiltSSRPackageImport(import_path14.default.join(outputDir, "server"), ssrEntryFile, fs15);
43940
44142
  logger.info("\u26A1 Reused Farm's prebuilt SSR bundle for the Node output");
43941
44143
  }
43942
44144
  if (useRolldownBuilder) {
@@ -43951,12 +44153,12 @@ export default async function farmNitroEventHandler(event) {
43951
44153
  });
43952
44154
  }
43953
44155
  if (isVercel) {
43954
- await postProcessVercelOutput(root, outputDir, fs14, config, farmWorkflows, routeRuntimeManifest);
44156
+ await postProcessVercelOutput(root, outputDir, fs15, config, farmWorkflows, routeRuntimeManifest);
43955
44157
  }
43956
44158
  logger.success(`\u2705 Nitro build completed with preset: ${preset}`);
43957
44159
  }
43958
44160
  __name(buildNitroUniversal, "buildNitroUniversal");
43959
- async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOptions, minify, fs14) {
44161
+ async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOptions, minify, fs15) {
43960
44162
  const {
43961
44163
  include: _include,
43962
44164
  exclude: _exclude,
@@ -43973,13 +44175,13 @@ async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOpti
43973
44175
  "node18"
43974
44176
  );
43975
44177
  const transform = minify || hasConfiguredTransforms ? (await import("esbuild")).transform : null;
43976
- await fs14.rm(targetDir, { recursive: true, force: true });
44178
+ await fs15.rm(targetDir, { recursive: true, force: true });
43977
44179
  await Promise.all(
43978
44180
  Object.entries(ssrBundle).map(async ([fileName, output]) => {
43979
44181
  const targetPath = import_path14.default.join(targetDir, fileName);
43980
- await fs14.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
44182
+ await fs15.mkdir(import_path14.default.dirname(targetPath), { recursive: true });
43981
44183
  if (output.type === "asset") {
43982
- await fs14.writeFile(targetPath, output.source);
44184
+ await fs15.writeFile(targetPath, output.source);
43983
44185
  return;
43984
44186
  }
43985
44187
  let code = output.code;
@@ -43990,14 +44192,14 @@ async function copyPrebuiltSSRBundle(ssrBundle, targetDir, configuredEsbuildOpti
43990
44192
  });
43991
44193
  code = result.code;
43992
44194
  }
43993
- await fs14.writeFile(targetPath, code);
44195
+ await fs15.writeFile(targetPath, code);
43994
44196
  })
43995
44197
  );
43996
44198
  }
43997
44199
  __name(copyPrebuiltSSRBundle, "copyPrebuiltSSRBundle");
43998
- async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs14) {
44200
+ async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs15) {
43999
44201
  const packagePath = import_path14.default.join(serverDir, "package.json");
44000
- 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) => {
44001
44203
  if (error.code === "ENOENT") return { type: "module" };
44002
44204
  throw error;
44003
44205
  });
@@ -44007,14 +44209,14 @@ async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs14) {
44007
44209
  ...existingImports,
44008
44210
  [FARM_SSR_PACKAGE_IMPORT]: `./${outputEntry}`
44009
44211
  };
44010
- await fs14.mkdir(serverDir, { recursive: true });
44011
- 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)}
44012
44214
  `);
44013
44215
  }
44014
44216
  __name(registerPrebuiltSSRPackageImport, "registerPrebuiltSSRPackageImport");
44015
- async function moveVercelOutputPath(src, dest, fs14) {
44217
+ async function moveVercelOutputPath(src, dest, fs15) {
44016
44218
  try {
44017
- await fs14.rename(src, dest);
44219
+ await fs15.rename(src, dest);
44018
44220
  return;
44019
44221
  } catch (error) {
44020
44222
  const code = error?.code;
@@ -44022,68 +44224,44 @@ async function moveVercelOutputPath(src, dest, fs14) {
44022
44224
  throw error;
44023
44225
  }
44024
44226
  }
44025
- await fs14.cp(src, dest, { recursive: true, force: true });
44026
- 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 });
44027
44229
  }
44028
44230
  __name(moveVercelOutputPath, "moveVercelOutputPath");
44029
- async function postProcessVercelOutput(root, outputDir, fs14, config, farmWorkflows, routeRuntimeManifest) {
44231
+ async function postProcessVercelOutput(root, outputDir, fs15, config, farmWorkflows, routeRuntimeManifest) {
44030
44232
  const serverDir = import_path14.default.join(outputDir, "server");
44031
44233
  const functionsDir = import_path14.default.join(outputDir, "functions");
44032
44234
  const nitroFuncDir = import_path14.default.join(functionsDir, "__nitro.func");
44033
44235
  const staticDir = import_path14.default.join(outputDir, "static");
44034
44236
  const publicDir = import_path14.default.join(outputDir, "public");
44035
- await fs14.mkdir(nitroFuncDir, { recursive: true });
44036
- const serverContents = await fs14.readdir(serverDir);
44237
+ await fs15.mkdir(nitroFuncDir, { recursive: true });
44238
+ const serverContents = await fs15.readdir(serverDir);
44037
44239
  for (const file of serverContents) {
44038
44240
  const src = import_path14.default.join(serverDir, file);
44039
44241
  const dest = import_path14.default.join(nitroFuncDir, file);
44040
- await moveVercelOutputPath(src, dest, fs14);
44242
+ await moveVercelOutputPath(src, dest, fs15);
44041
44243
  }
44042
- await fs14.rm(serverDir, { recursive: true, force: true });
44244
+ await fs15.rm(serverDir, { recursive: true, force: true });
44043
44245
  try {
44044
- await moveVercelOutputPath(publicDir, staticDir, fs14);
44246
+ await moveVercelOutputPath(publicDir, staticDir, fs15);
44045
44247
  } catch (error) {
44046
44248
  if (error?.code !== "ENOENT") throw error;
44047
44249
  }
44048
- await copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs14);
44049
- await copyPrismaClientForVercel(root, nitroFuncDir, fs14);
44250
+ await copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs15);
44251
+ await copyPrismaClientForVercel(root, nitroFuncDir, fs15);
44050
44252
  const configPath = import_path14.default.join(outputDir, "config.json");
44051
- const configContent = await fs14.readFile(configPath, "utf-8");
44253
+ const configContent = await fs15.readFile(configPath, "utf-8");
44052
44254
  const vercelConfig = JSON.parse(configContent);
44053
44255
  const runtimeRoutes = await createFarmVercelRouteRuntimeFunctions(
44054
44256
  outputDir,
44055
44257
  routeRuntimeManifest,
44056
- fs14
44258
+ fs15
44057
44259
  );
44058
- vercelConfig.routes = [
44059
- // Apply the header before the filesystem handler. `continue` lets Vercel
44060
- // serve the matching file while preserving the immutable cache policy.
44061
- // Hashed client assets ship at the root regardless of basePath, so the
44062
- // route is deliberately not basePath-scoped.
44063
- createFarmVercelImmutableAssetRoute(),
44064
- // Serve static files first
44065
- {
44066
- handle: "filesystem"
44067
- },
44068
- ...runtimeRoutes,
44069
- // API routes
44070
- ...resolveFarmAPIServerBasePath(config.api) === "/" ? [] : [
44071
- {
44072
- src: `${resolveFarmAPIServerBasePath(config.api)}/(.*)`,
44073
- dest: "/__nitro",
44074
- headers: {
44075
- "Access-Control-Allow-Origin": "*",
44076
- "Access-Control-Allow-Methods": "*",
44077
- "Access-Control-Allow-Headers": "*"
44078
- }
44079
- }
44080
- ],
44081
- // All other routes go to the serverless function
44082
- {
44083
- src: "/(.*)",
44084
- dest: "/__nitro"
44085
- }
44086
- ];
44260
+ vercelConfig.routes = buildFarmVercelRoutes({
44261
+ presetRoutes: Array.isArray(vercelConfig.routes) ? vercelConfig.routes : [],
44262
+ runtimeRoutes,
44263
+ apiBasePath: resolveFarmAPIServerBasePath(config.api)
44264
+ });
44087
44265
  const vercelConfigWithWorkflowCrons = applyFarmWorkflowVercelCrons(
44088
44266
  vercelConfig,
44089
44267
  farmWorkflows.workflows
@@ -44092,24 +44270,24 @@ async function postProcessVercelOutput(root, outputDir, fs14, config, farmWorkfl
44092
44270
  vercelConfigWithWorkflowCrons,
44093
44271
  config.cron.jobs
44094
44272
  );
44095
- await fs14.writeFile(configPath, JSON.stringify(vercelConfigWithCrons, null, 2));
44273
+ await fs15.writeFile(configPath, JSON.stringify(vercelConfigWithCrons, null, 2));
44096
44274
  logger.info("\u2705 Post-processed Vercel output for Build Output API v3");
44097
44275
  }
44098
44276
  __name(postProcessVercelOutput, "postProcessVercelOutput");
44099
- async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs14) {
44277
+ async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs15) {
44100
44278
  const docsContentDir = resolveBuildDocsContentDir(config, root);
44101
44279
  if (!docsContentDir) return;
44102
44280
  const bundledContentDir = import_path14.default.join(nitroFuncDir, "chunks", "nitro", "farm-docs-content");
44103
44281
  const lastModifiedManifest = createFarmDocsLastModifiedManifest(docsContentDir, {
44104
44282
  fallback: "now"
44105
44283
  });
44106
- await fs14.rm(bundledContentDir, { recursive: true, force: true });
44107
- await fs14.mkdir(import_path14.default.dirname(bundledContentDir), { recursive: true });
44108
- 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, {
44109
44287
  recursive: true,
44110
44288
  force: true
44111
44289
  });
44112
- await fs14.writeFile(
44290
+ await fs15.writeFile(
44113
44291
  import_path14.default.join(bundledContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST),
44114
44292
  `${JSON.stringify(lastModifiedManifest, null, 2)}
44115
44293
  `
@@ -44117,7 +44295,7 @@ async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs14) {
44117
44295
  logger.info(`\u{1F4DA} Bundled docs content for Vercel: ${import_path14.default.relative(root, docsContentDir)}`);
44118
44296
  }
44119
44297
  __name(copyFarmDocsContentForVercel, "copyFarmDocsContentForVercel");
44120
- async function copySharpRuntime(config, root, nitroFuncDir, fs14) {
44298
+ async function copySharpRuntime(config, root, nitroFuncDir, fs15) {
44121
44299
  if (config.images.provider === "none") return;
44122
44300
  const projectRequire = (0, import_module2.createRequire)(import_path14.default.join(root, "package.json"));
44123
44301
  let sharpRequire = projectRequire;
@@ -44141,18 +44319,18 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs14) {
44141
44319
  async function copyPackageOnce(packageName, parentRequire) {
44142
44320
  const packageJsonPath = resolvePackageJson(parentRequire, packageName);
44143
44321
  if (!packageJsonPath) return;
44144
- const packageJson = JSON.parse(await fs14.readFile(packageJsonPath, "utf8"));
44322
+ const packageJson = JSON.parse(await fs15.readFile(packageJsonPath, "utf8"));
44145
44323
  const packageDir = import_path14.default.dirname(packageJsonPath);
44146
44324
  const targetDir = import_path14.default.join(targetNodeModules, ...packageName.split("/"));
44147
44325
  copiedPackages.set(packageName, String(packageJson.version || "*"));
44148
- await fs14.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44326
+ await fs15.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44149
44327
  const packageRequire = (0, import_module2.createRequire)(packageJsonPath);
44150
44328
  const dependencies = {
44151
44329
  ...packageJson.dependencies,
44152
44330
  ...packageJson.optionalDependencies
44153
44331
  };
44154
44332
  await Promise.all([
44155
- fs14.cp(packageDir, targetDir, {
44333
+ fs15.cp(packageDir, targetDir, {
44156
44334
  recursive: true,
44157
44335
  force: true,
44158
44336
  dereference: true,
@@ -44171,16 +44349,16 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs14) {
44171
44349
  );
44172
44350
  }
44173
44351
  const functionPackagePath = import_path14.default.join(nitroFuncDir, "package.json");
44174
- const functionPackage = JSON.parse(await fs14.readFile(functionPackagePath, "utf8"));
44352
+ const functionPackage = JSON.parse(await fs15.readFile(functionPackagePath, "utf8"));
44175
44353
  functionPackage.dependencies = {
44176
44354
  ...functionPackage.dependencies,
44177
44355
  ...Object.fromEntries([...copiedPackages].sort(([left], [right]) => left.localeCompare(right)))
44178
44356
  };
44179
- await fs14.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44357
+ await fs15.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44180
44358
  logger.info(`\u{1F5BC}\uFE0F Bundled Sharp image runtime (${copiedPackages.size} packages)`);
44181
44359
  }
44182
44360
  __name(copySharpRuntime, "copySharpRuntime");
44183
- async function copyMetadataImageRuntime(root, nitroFuncDir, fs14) {
44361
+ async function copyMetadataImageRuntime(root, nitroFuncDir, fs15) {
44184
44362
  const projectRequire = (0, import_module2.createRequire)(import_path14.default.join(root, "package.json"));
44185
44363
  let runtimeRequire = projectRequire;
44186
44364
  let packageJsonPath = resolvePackageJson(runtimeRequire, "@vercel/og");
@@ -44196,23 +44374,23 @@ async function copyMetadataImageRuntime(root, nitroFuncDir, fs14) {
44196
44374
  "Generated metadata images require @vercel/og. Reinstall @farm.js/core with production dependencies."
44197
44375
  );
44198
44376
  }
44199
- const packageJson = JSON.parse(await fs14.readFile(packageJsonPath, "utf8"));
44377
+ const packageJson = JSON.parse(await fs15.readFile(packageJsonPath, "utf8"));
44200
44378
  const packageDir = import_path14.default.dirname(packageJsonPath);
44201
44379
  const targetDir = import_path14.default.join(nitroFuncDir, "node_modules", "@vercel", "og");
44202
- await fs14.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44203
- await fs14.cp(packageDir, targetDir, {
44380
+ await fs15.mkdir(import_path14.default.dirname(targetDir), { recursive: true });
44381
+ await fs15.cp(packageDir, targetDir, {
44204
44382
  recursive: true,
44205
44383
  force: true,
44206
44384
  dereference: true,
44207
44385
  mode: import_fs5.constants.COPYFILE_FICLONE
44208
44386
  });
44209
44387
  const functionPackagePath = import_path14.default.join(nitroFuncDir, "package.json");
44210
- const functionPackage = JSON.parse(await fs14.readFile(functionPackagePath, "utf8"));
44388
+ const functionPackage = JSON.parse(await fs15.readFile(functionPackagePath, "utf8"));
44211
44389
  functionPackage.dependencies = {
44212
44390
  ...functionPackage.dependencies,
44213
44391
  "@vercel/og": String(packageJson.version || "0.11.1")
44214
44392
  };
44215
- await fs14.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44393
+ await fs15.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44216
44394
  logger.info("\u{1F5BC}\uFE0F Bundled generated metadata image runtime");
44217
44395
  }
44218
44396
  __name(copyMetadataImageRuntime, "copyMetadataImageRuntime");
@@ -44226,7 +44404,7 @@ function resolvePackageJson(parentRequire, packageName) {
44226
44404
  return null;
44227
44405
  }
44228
44406
  __name(resolvePackageJson, "resolvePackageJson");
44229
- async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44407
+ async function copyPrismaClientForVercel(root, nitroFuncDir, fs15) {
44230
44408
  const projectRequire = (0, import_module2.createRequire)(import_path14.default.join(root, "package.json"));
44231
44409
  let prismaClientDir;
44232
44410
  try {
@@ -44236,7 +44414,7 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44236
44414
  }
44237
44415
  const generatedClientDir = import_path14.default.join(prismaClientDir, "..", "..", ".prisma", "client");
44238
44416
  try {
44239
- await fs14.access(generatedClientDir);
44417
+ await fs15.access(generatedClientDir);
44240
44418
  } catch {
44241
44419
  return;
44242
44420
  }
@@ -44244,20 +44422,20 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44244
44422
  const targetPrismaScopeDir = import_path14.default.join(targetNodeModules, "@prisma");
44245
44423
  const targetGeneratedDir = import_path14.default.join(targetNodeModules, ".prisma", "client");
44246
44424
  const targetClientDir = import_path14.default.join(targetPrismaScopeDir, "client");
44247
- await fs14.mkdir(targetPrismaScopeDir, { recursive: true });
44248
- await fs14.cp(prismaClientDir, targetClientDir, {
44425
+ await fs15.mkdir(targetPrismaScopeDir, { recursive: true });
44426
+ await fs15.cp(prismaClientDir, targetClientDir, {
44249
44427
  recursive: true,
44250
44428
  force: true
44251
44429
  });
44252
- await fs14.cp(generatedClientDir, targetGeneratedDir, {
44430
+ await fs15.cp(generatedClientDir, targetGeneratedDir, {
44253
44431
  recursive: true,
44254
44432
  force: true
44255
44433
  });
44256
44434
  const functionPackagePath = import_path14.default.join(nitroFuncDir, "package.json");
44257
44435
  const clientPackagePath = import_path14.default.join(prismaClientDir, "package.json");
44258
44436
  const [functionPackageContent, clientPackageContent] = await Promise.all([
44259
- fs14.readFile(functionPackagePath, "utf-8"),
44260
- fs14.readFile(clientPackagePath, "utf-8")
44437
+ fs15.readFile(functionPackagePath, "utf-8"),
44438
+ fs15.readFile(clientPackagePath, "utf-8")
44261
44439
  ]);
44262
44440
  const functionPackage = JSON.parse(functionPackageContent);
44263
44441
  const clientPackage = JSON.parse(clientPackageContent);
@@ -44265,7 +44443,7 @@ async function copyPrismaClientForVercel(root, nitroFuncDir, fs14) {
44265
44443
  ...functionPackage.dependencies,
44266
44444
  "@prisma/client": clientPackage.version
44267
44445
  };
44268
- await fs14.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44446
+ await fs15.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
44269
44447
  }
44270
44448
  __name(copyPrismaClientForVercel, "copyPrismaClientForVercel");
44271
44449
 
@@ -44627,7 +44805,7 @@ function resolveLegacyPageEntry(config, root, srcDir) {
44627
44805
  const appDir = import_path17.default.join(root, srcDir, "app");
44628
44806
  for (const extension of getFarmRendererComponentExtensions(config.renderer)) {
44629
44807
  const candidate = import_path17.default.join(appDir, `page${extension}`);
44630
- if ((0, import_node_fs13.existsSync)(candidate)) return candidate;
44808
+ if ((0, import_node_fs14.existsSync)(candidate)) return candidate;
44631
44809
  }
44632
44810
  return import_path17.default.join(appDir, "page.tsx");
44633
44811
  }
@@ -44661,10 +44839,10 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
44661
44839
  const manifestPath = import_path17.default.join(publicOutputDir, "farm-client-manifest.json");
44662
44840
  const assetsDir = import_path17.default.join(publicOutputDir, "assets");
44663
44841
  const manifestExists = await import("fs/promises").then(
44664
- (fs14) => fs14.access(manifestPath).then(() => true).catch(() => false)
44842
+ (fs15) => fs15.access(manifestPath).then(() => true).catch(() => false)
44665
44843
  );
44666
44844
  const assetsExist = await import("fs/promises").then(
44667
- (fs14) => fs14.access(assetsDir).then(() => true).catch(() => false)
44845
+ (fs15) => fs15.access(assetsDir).then(() => true).catch(() => false)
44668
44846
  );
44669
44847
  if (manifestExists && assetsExist) {
44670
44848
  logger.info("\u2705 Verified client assets are present");