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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/dist/after.cjs +1 -1
  2. package/dist/after.mjs +1 -1
  3. package/dist/agent-runtime.d.mts +3 -2
  4. package/dist/agent-runtime.d.ts +3 -2
  5. package/dist/api/route-manager.cjs +43 -4
  6. package/dist/api/route-manager.d.mts +4 -3
  7. package/dist/api/route-manager.d.ts +4 -3
  8. package/dist/api/route-manager.mjs +7 -7
  9. package/dist/api/runtime.cjs +43 -4
  10. package/dist/api/runtime.d.mts +1 -1
  11. package/dist/api/runtime.d.ts +1 -1
  12. package/dist/api/runtime.mjs +5 -5
  13. package/dist/api.cjs +352 -109
  14. package/dist/api.d.mts +7 -6
  15. package/dist/api.d.ts +7 -6
  16. package/dist/api.mjs +19 -12
  17. package/dist/{app-CIIEvA4r.d.ts → app-CIOx3LvY.d.ts} +4 -4
  18. package/dist/{app-O4AEC1OH.d.mts → app-DBd6437H.d.mts} +4 -4
  19. package/dist/app-markdown.d.mts +4 -3
  20. package/dist/app-markdown.d.ts +4 -3
  21. package/dist/cache.cjs +42 -4
  22. package/dist/cache.d.mts +68 -1
  23. package/dist/cache.d.ts +68 -1
  24. package/dist/cache.mjs +3 -3
  25. package/dist/{chunk-AXVJCMVF.mjs → chunk-2HDOV47R.mjs} +3 -3
  26. package/dist/chunk-2HDOV47R.mjs.map +1 -0
  27. package/dist/{chunk-RBRLLZL5.mjs → chunk-34IAPZBG.mjs} +16 -3
  28. package/dist/chunk-34IAPZBG.mjs.map +1 -0
  29. package/dist/{chunk-VV24CC42.mjs → chunk-35NPLKQJ.mjs} +2 -2
  30. package/dist/{chunk-D7QH7MDU.mjs → chunk-3TWQERDE.mjs} +5 -4
  31. package/dist/chunk-3TWQERDE.mjs.map +1 -0
  32. package/dist/{chunk-RWYRFCLG.mjs → chunk-4X57GXQA.mjs} +2 -2
  33. package/dist/{chunk-KOTSX5JH.mjs → chunk-52BR7LTX.mjs} +30 -21
  34. package/dist/chunk-52BR7LTX.mjs.map +1 -0
  35. package/dist/{chunk-SALMKQXH.mjs → chunk-6EJHNHH4.mjs} +80 -27
  36. package/dist/chunk-6EJHNHH4.mjs.map +1 -0
  37. package/dist/{chunk-ZFNK77WN.mjs → chunk-6JNGOC37.mjs} +2 -2
  38. package/dist/{after.cjs.map → chunk-6JNGOC37.mjs.map} +1 -1
  39. package/dist/{chunk-MOW47IF5.mjs → chunk-6UYVU46O.mjs} +2 -2
  40. package/dist/{chunk-7MABZJIM.mjs → chunk-7PYVLJ4J.mjs} +1 -1
  41. package/dist/chunk-7PYVLJ4J.mjs.map +1 -0
  42. package/dist/{chunk-FLHLPB57.mjs → chunk-D7F7YZ7L.mjs} +93 -67
  43. package/dist/chunk-D7F7YZ7L.mjs.map +1 -0
  44. package/dist/chunk-DU3PKDVQ.mjs +35 -0
  45. package/dist/chunk-DU3PKDVQ.mjs.map +1 -0
  46. package/dist/{chunk-SCFX4UTD.mjs → chunk-EHTUKVSW.mjs} +1 -1
  47. package/dist/chunk-EHTUKVSW.mjs.map +1 -0
  48. package/dist/{chunk-KWCNQUH5.mjs → chunk-EPDIF432.mjs} +526 -50
  49. package/dist/chunk-EPDIF432.mjs.map +1 -0
  50. package/dist/{chunk-A3636IHN.mjs → chunk-FP5Q67FO.mjs} +167 -96
  51. package/dist/chunk-FP5Q67FO.mjs.map +1 -0
  52. package/dist/{chunk-HHZAOTQD.mjs → chunk-GJ7W6LNK.mjs} +7 -6
  53. package/dist/chunk-GJ7W6LNK.mjs.map +1 -0
  54. package/dist/{chunk-RLGUZ3HS.mjs → chunk-I3OOUWO5.mjs} +3 -3
  55. package/dist/{chunk-75CGAL6E.mjs → chunk-IZBX2TEU.mjs} +217 -105
  56. package/dist/chunk-IZBX2TEU.mjs.map +1 -0
  57. package/dist/{chunk-22VG4DFJ.mjs → chunk-J3MPQ4MQ.mjs} +2 -2
  58. package/dist/{chunk-22VG4DFJ.mjs.map → chunk-J3MPQ4MQ.mjs.map} +1 -1
  59. package/dist/{chunk-2LS3KKE7.mjs → chunk-JV7JUD7Q.mjs} +4 -4
  60. package/dist/{chunk-Q3OX763A.mjs → chunk-LXDASSTE.mjs} +2 -2
  61. package/dist/{chunk-ZRBCBOEX.mjs → chunk-N2FY2QZ7.mjs} +28 -3
  62. package/dist/chunk-N2FY2QZ7.mjs.map +1 -0
  63. package/dist/{chunk-MRVJCLYQ.mjs → chunk-PSQ7N4XP.mjs} +4 -2
  64. package/dist/chunk-PSQ7N4XP.mjs.map +1 -0
  65. package/dist/{chunk-HVG3HLQZ.mjs → chunk-Q7WGOOAI.mjs} +3 -3
  66. package/dist/{chunk-WTYAPO5I.mjs → chunk-RCNWMEBT.mjs} +3 -2
  67. package/dist/{chunk-WTYAPO5I.mjs.map → chunk-RCNWMEBT.mjs.map} +1 -1
  68. package/dist/{chunk-3INDBMUU.mjs → chunk-TGDIACZT.mjs} +2 -2
  69. package/dist/{chunk-WB75GIX2.mjs → chunk-TQTB33JS.mjs} +14 -3
  70. package/dist/chunk-TQTB33JS.mjs.map +1 -0
  71. package/dist/{chunk-MH27UH72.mjs → chunk-TT3E2JOF.mjs} +3 -3
  72. package/dist/{chunk-UWRGX3J3.mjs → chunk-UMUWR5XA.mjs} +2 -2
  73. package/dist/{chunk-XTLLHCWU.mjs → chunk-V4VRLVLW.mjs} +52 -31
  74. package/dist/chunk-V4VRLVLW.mjs.map +1 -0
  75. package/dist/{chunk-EXCGBERG.mjs → chunk-WD2EBM3I.mjs} +79 -17
  76. package/dist/chunk-WD2EBM3I.mjs.map +1 -0
  77. package/dist/{chunk-DLBUAJTK.mjs → chunk-WMJGA32P.mjs} +74 -5
  78. package/dist/chunk-WMJGA32P.mjs.map +1 -0
  79. package/dist/{chunk-TKQCJMY7.mjs → chunk-X4SFHKFH.mjs} +7 -4
  80. package/dist/{chunk-TKQCJMY7.mjs.map → chunk-X4SFHKFH.mjs.map} +1 -1
  81. package/dist/{chunk-Q7GPJZCO.mjs → chunk-YIBV77KZ.mjs} +26 -7
  82. package/dist/chunk-YIBV77KZ.mjs.map +1 -0
  83. package/dist/client/lifecycle.mjs +2 -2
  84. package/dist/{client-mcMC334J.d.mts → client-DWoLZ3QU.d.mts} +52 -5
  85. package/dist/{client-d5ONQ-Pd.d.ts → client-DuQuQC1h.d.ts} +52 -5
  86. package/dist/client-cache-BMxuFqwH.d.ts +18 -0
  87. package/dist/client-cache-CCK-fCe0.d.mts +18 -0
  88. package/dist/{client-plugins-BvClItiL.d.mts → client-plugins-B6-07YmP.d.mts} +52 -99
  89. package/dist/{client-plugins-B9Sq-iMg.d.ts → client-plugins-By6MVUX-.d.ts} +52 -99
  90. package/dist/client-plugins.cjs +1 -1
  91. package/dist/client-plugins.d.mts +3 -2
  92. package/dist/client-plugins.d.ts +3 -2
  93. package/dist/client-plugins.mjs +2 -2
  94. package/dist/client.cjs +1046 -211
  95. package/dist/client.d.mts +136 -18
  96. package/dist/client.d.ts +136 -18
  97. package/dist/client.mjs +32 -15
  98. package/dist/config.d.mts +3 -2
  99. package/dist/config.d.ts +3 -2
  100. package/dist/{devtools-S52RRRMN.mjs → devtools-XWZX6CCL.mjs} +5 -5
  101. package/dist/{devtools-client-3XRTBND5.mjs → devtools-client-Z7QQA3Q2.mjs} +56 -17
  102. package/dist/devtools-client-Z7QQA3Q2.mjs.map +1 -0
  103. package/dist/{devtools-ui-NJKFORTG.mjs → devtools-ui-2HG5M4EL.mjs} +3 -1
  104. package/dist/devtools-ui-2HG5M4EL.mjs.map +1 -0
  105. package/dist/docs.cjs +24 -5
  106. package/dist/docs.mjs +5 -5
  107. package/dist/i18n/server.cjs +13 -2
  108. package/dist/i18n/server.d.mts +2 -2
  109. package/dist/i18n/server.d.ts +2 -2
  110. package/dist/i18n/server.mjs +1 -1
  111. package/dist/index.cjs +1928 -894
  112. package/dist/index.d.mts +139 -21
  113. package/dist/index.d.ts +139 -21
  114. package/dist/index.mjs +57 -34
  115. package/dist/index.mjs.map +1 -1
  116. package/dist/integration-api-BT024nuJ.d.mts +97 -0
  117. package/dist/integration-api-BT024nuJ.d.ts +97 -0
  118. package/dist/integrations.d.mts +3 -2
  119. package/dist/integrations.d.ts +3 -2
  120. package/dist/internal/build-runtime.cjs +764 -547
  121. package/dist/internal/build-runtime.d.mts +5 -4
  122. package/dist/internal/build-runtime.d.ts +5 -4
  123. package/dist/internal/build-runtime.mjs +16 -16
  124. package/dist/internal/client-runtime.cjs +1 -1
  125. package/dist/internal/client-runtime.mjs +2 -2
  126. package/dist/internal/config-runtime.cjs +4 -1
  127. package/dist/internal/config-runtime.d.mts +4 -3
  128. package/dist/internal/config-runtime.d.ts +4 -3
  129. package/dist/internal/config-runtime.mjs +4 -4
  130. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  131. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  132. package/dist/internal/production-runtime.cjs +29 -3
  133. package/dist/internal/production-runtime.d.mts +8 -7
  134. package/dist/internal/production-runtime.d.ts +8 -7
  135. package/dist/internal/production-runtime.mjs +5 -5
  136. package/dist/{metadata-route-yV4U6X8h.d.ts → metadata-route-8_V3UonT.d.ts} +1 -1
  137. package/dist/{metadata-route-p4K1l92V.d.mts → metadata-route-CWP_HjGU.d.mts} +1 -1
  138. package/dist/middleware.cjs +28 -2
  139. package/dist/middleware.d.mts +5 -4
  140. package/dist/middleware.d.ts +5 -4
  141. package/dist/middleware.mjs +4 -4
  142. package/dist/navigation.cjs +3 -1
  143. package/dist/navigation.mjs +3 -3
  144. package/dist/observability.cjs +27 -2
  145. package/dist/observability.mjs +1 -1
  146. package/dist/plugin.cjs +528 -349
  147. package/dist/plugin.d.mts +3 -2
  148. package/dist/plugin.d.ts +3 -2
  149. package/dist/plugin.mjs +13 -13
  150. package/dist/{production-runtime-IkB0Qj4i.d.mts → production-runtime-BGRH1dKG.d.mts} +1 -1
  151. package/dist/{production-runtime-0JTch4_d.d.ts → production-runtime-CdmzsDax.d.ts} +1 -1
  152. package/dist/query/client.cjs +68 -29
  153. package/dist/query/client.mjs +69 -30
  154. package/dist/query/client.mjs.map +1 -1
  155. package/dist/{render-plan-Dc8CjNI7.d.ts → render-plan-0GeHiGVZ.d.ts} +1 -1
  156. package/dist/{render-plan-CU31j-Jk.d.mts → render-plan-DLxJYAA5.d.mts} +1 -1
  157. package/dist/renderer-client.cjs +169 -26
  158. package/dist/renderer-client.d.mts +7 -6
  159. package/dist/renderer-client.d.ts +7 -6
  160. package/dist/renderer-client.mjs +16 -19
  161. package/dist/renderer-client.mjs.map +1 -1
  162. package/dist/{request-BXa1KY8i.d.mts → request-BCNXSXLh.d.mts} +1 -1
  163. package/dist/{request-CUUBujZt.d.ts → request-BstWbZ6O.d.ts} +1 -1
  164. package/dist/request.d.mts +4 -3
  165. package/dist/request.d.ts +4 -3
  166. package/dist/{route-Y8lfz1wF.d.ts → route-4pd-EVtw.d.ts} +45 -50
  167. package/dist/{route-Cq3aObmj.d.mts → route-CvEr4Uc9.d.mts} +45 -50
  168. package/dist/routes.cjs +27 -2
  169. package/dist/routes.d.mts +3 -2
  170. package/dist/routes.d.ts +3 -2
  171. package/dist/routes.mjs +4 -4
  172. package/dist/{runtime-j1S3sDTh.d.ts → runtime-BgDQzBiu.d.ts} +1 -0
  173. package/dist/{runtime-DDwvDtS4.d.mts → runtime-CV2UCV-5.d.mts} +1 -0
  174. package/dist/server-action-security.mjs +2 -2
  175. package/dist/server-fn-client.cjs +102 -26
  176. package/dist/server-fn-client.d.mts +6 -0
  177. package/dist/server-fn-client.d.ts +6 -0
  178. package/dist/server-fn-client.mjs +2 -1
  179. package/dist/server-fn.cjs +42 -4
  180. package/dist/server-fn.mjs +5 -5
  181. package/dist/server-plugins.d.mts +4 -3
  182. package/dist/server-plugins.d.ts +4 -3
  183. package/dist/server-query-client.cjs +195 -34
  184. package/dist/server-query-client.d.mts +3 -3
  185. package/dist/server-query-client.d.ts +3 -3
  186. package/dist/server-query-client.mjs +7 -7
  187. package/dist/{server-query-runtime-3zAj77yv.d.ts → server-query-runtime-DXRNhX_3.d.ts} +2 -0
  188. package/dist/{server-query-runtime-B50KAcj5.d.mts → server-query-runtime-aP52iuL5.d.mts} +2 -0
  189. package/dist/server-query.cjs +44 -5
  190. package/dist/server-query.d.mts +4 -0
  191. package/dist/server-query.d.ts +4 -0
  192. package/dist/server-query.mjs +7 -7
  193. package/dist/server.cjs +553 -370
  194. package/dist/server.d.mts +11 -10
  195. package/dist/server.d.ts +11 -10
  196. package/dist/server.mjs +17 -17
  197. package/dist/{spa-router-CyLkwst6.d.mts → spa-router-BeyAVSc6.d.mts} +1 -1
  198. package/dist/{spa-router-BkqGXaV_.d.ts → spa-router-COgu4txb.d.ts} +1 -1
  199. package/dist/testing.cjs +27 -2
  200. package/dist/testing.d.mts +3 -2
  201. package/dist/testing.d.ts +3 -2
  202. package/dist/testing.mjs +9 -9
  203. package/dist/{utils-NKR6SoNv.d.mts → utils-DL2VwDQl.d.mts} +1 -1
  204. package/dist/{utils-B2OHrb9F.d.ts → utils-DkU2c_1B.d.ts} +1 -1
  205. package/dist/version.cjs +1 -1
  206. package/dist/version.mjs +1 -1
  207. package/dist/vite.cjs +536 -353
  208. package/dist/vite.d.mts +3 -2
  209. package/dist/vite.d.ts +3 -2
  210. package/dist/vite.mjs +17 -13
  211. package/package.json +17 -17
  212. package/types/client.d.ts +115 -10
  213. package/dist/agent-runtime.cjs.map +0 -1
  214. package/dist/api/route-manager.cjs.map +0 -1
  215. package/dist/api/runtime.cjs.map +0 -1
  216. package/dist/api.cjs.map +0 -1
  217. package/dist/app-markdown.cjs.map +0 -1
  218. package/dist/cache.cjs.map +0 -1
  219. package/dist/chunk-75CGAL6E.mjs.map +0 -1
  220. package/dist/chunk-7MABZJIM.mjs.map +0 -1
  221. package/dist/chunk-A3636IHN.mjs.map +0 -1
  222. package/dist/chunk-AXVJCMVF.mjs.map +0 -1
  223. package/dist/chunk-D7QH7MDU.mjs.map +0 -1
  224. package/dist/chunk-DLBUAJTK.mjs.map +0 -1
  225. package/dist/chunk-EXCGBERG.mjs.map +0 -1
  226. package/dist/chunk-FLHLPB57.mjs.map +0 -1
  227. package/dist/chunk-HHZAOTQD.mjs.map +0 -1
  228. package/dist/chunk-KOTSX5JH.mjs.map +0 -1
  229. package/dist/chunk-KWCNQUH5.mjs.map +0 -1
  230. package/dist/chunk-MRVJCLYQ.mjs.map +0 -1
  231. package/dist/chunk-Q7GPJZCO.mjs.map +0 -1
  232. package/dist/chunk-RBRLLZL5.mjs.map +0 -1
  233. package/dist/chunk-SALMKQXH.mjs.map +0 -1
  234. package/dist/chunk-SCFX4UTD.mjs.map +0 -1
  235. package/dist/chunk-WB75GIX2.mjs.map +0 -1
  236. package/dist/chunk-XTLLHCWU.mjs.map +0 -1
  237. package/dist/chunk-ZFNK77WN.mjs.map +0 -1
  238. package/dist/chunk-ZRBCBOEX.mjs.map +0 -1
  239. package/dist/client/lifecycle.cjs.map +0 -1
  240. package/dist/client-cache-CopR_MaI.d.mts +0 -6
  241. package/dist/client-cache-Djy_TlE8.d.ts +0 -6
  242. package/dist/client-plugins.cjs.map +0 -1
  243. package/dist/client.cjs.map +0 -1
  244. package/dist/config.cjs.map +0 -1
  245. package/dist/cron.cjs.map +0 -1
  246. package/dist/deferred.cjs.map +0 -1
  247. package/dist/deployment.cjs.map +0 -1
  248. package/dist/devtools-client-3XRTBND5.mjs.map +0 -1
  249. package/dist/devtools-ui-NJKFORTG.mjs.map +0 -1
  250. package/dist/docs.cjs.map +0 -1
  251. package/dist/env-types.cjs.map +0 -1
  252. package/dist/env.cjs.map +0 -1
  253. package/dist/environment/vite.cjs.map +0 -1
  254. package/dist/environment.cjs.map +0 -1
  255. package/dist/font.cjs.map +0 -1
  256. package/dist/headers.cjs.map +0 -1
  257. package/dist/i18n/client.cjs.map +0 -1
  258. package/dist/i18n/index.cjs.map +0 -1
  259. package/dist/i18n/server.cjs.map +0 -1
  260. package/dist/image/server.cjs.map +0 -1
  261. package/dist/image/sharp.cjs.map +0 -1
  262. package/dist/image.cjs.map +0 -1
  263. package/dist/index.cjs.map +0 -1
  264. package/dist/instrumentation.cjs.map +0 -1
  265. package/dist/integrations.cjs.map +0 -1
  266. package/dist/internal/build-runtime.cjs.map +0 -1
  267. package/dist/internal/client-runtime.cjs.map +0 -1
  268. package/dist/internal/config-runtime.cjs.map +0 -1
  269. package/dist/internal/isolated-boundary.cjs.map +0 -1
  270. package/dist/internal/metadata-image-runtime.cjs.map +0 -1
  271. package/dist/internal/product-telemetry-runtime.cjs.map +0 -1
  272. package/dist/internal/production-node-env.cjs.map +0 -1
  273. package/dist/internal/production-runtime.cjs.map +0 -1
  274. package/dist/markdown.cjs.map +0 -1
  275. package/dist/middleware.cjs.map +0 -1
  276. package/dist/navigation.cjs.map +0 -1
  277. package/dist/observability.cjs.map +0 -1
  278. package/dist/plugin.cjs.map +0 -1
  279. package/dist/query/client.cjs.map +0 -1
  280. package/dist/query/index.cjs.map +0 -1
  281. package/dist/query/parsers.cjs.map +0 -1
  282. package/dist/query/server.cjs.map +0 -1
  283. package/dist/renderer/react/client.cjs.map +0 -1
  284. package/dist/renderer/react/server.cjs.map +0 -1
  285. package/dist/renderer/react/vite.cjs.map +0 -1
  286. package/dist/renderer-client.cjs.map +0 -1
  287. package/dist/renderer.cjs.map +0 -1
  288. package/dist/request.cjs.map +0 -1
  289. package/dist/router.cjs.map +0 -1
  290. package/dist/routes.cjs.map +0 -1
  291. package/dist/server-action-security.cjs.map +0 -1
  292. package/dist/server-fn-client.cjs.map +0 -1
  293. package/dist/server-fn.cjs.map +0 -1
  294. package/dist/server-plugins.cjs.map +0 -1
  295. package/dist/server-query-client.cjs.map +0 -1
  296. package/dist/server-query.cjs.map +0 -1
  297. package/dist/server.cjs.map +0 -1
  298. package/dist/storage.cjs.map +0 -1
  299. package/dist/testing.cjs.map +0 -1
  300. package/dist/theme/client.cjs.map +0 -1
  301. package/dist/theme/index.cjs.map +0 -1
  302. package/dist/theme/runtime.cjs.map +0 -1
  303. package/dist/theme/server.cjs.map +0 -1
  304. package/dist/version.cjs.map +0 -1
  305. package/dist/vite.cjs.map +0 -1
  306. package/dist/workflows.cjs.map +0 -1
  307. /package/dist/{chunk-VV24CC42.mjs.map → chunk-35NPLKQJ.mjs.map} +0 -0
  308. /package/dist/{chunk-RWYRFCLG.mjs.map → chunk-4X57GXQA.mjs.map} +0 -0
  309. /package/dist/{chunk-MOW47IF5.mjs.map → chunk-6UYVU46O.mjs.map} +0 -0
  310. /package/dist/{chunk-RLGUZ3HS.mjs.map → chunk-I3OOUWO5.mjs.map} +0 -0
  311. /package/dist/{chunk-2LS3KKE7.mjs.map → chunk-JV7JUD7Q.mjs.map} +0 -0
  312. /package/dist/{chunk-Q3OX763A.mjs.map → chunk-LXDASSTE.mjs.map} +0 -0
  313. /package/dist/{chunk-HVG3HLQZ.mjs.map → chunk-Q7WGOOAI.mjs.map} +0 -0
  314. /package/dist/{chunk-3INDBMUU.mjs.map → chunk-TGDIACZT.mjs.map} +0 -0
  315. /package/dist/{chunk-MH27UH72.mjs.map → chunk-TT3E2JOF.mjs.map} +0 -0
  316. /package/dist/{chunk-UWRGX3J3.mjs.map → chunk-UMUWR5XA.mjs.map} +0 -0
  317. /package/dist/{devtools-S52RRRMN.mjs.map → devtools-XWZX6CCL.mjs.map} +0 -0
package/dist/plugin.cjs CHANGED
@@ -893,11 +893,11 @@ function resolveFarmServerHealthConfig(config) {
893
893
  return Object.freeze({ enabled: true, livenessPath, readinessPath });
894
894
  }
895
895
  function normalizeHealthPath(value, optionName) {
896
- const path34 = value.trim();
897
- if (!path34.startsWith("/") || path34.includes("?") || path34.includes("#") || path34.includes("*")) {
896
+ const path35 = value.trim();
897
+ if (!path35.startsWith("/") || path35.includes("?") || path35.includes("#") || path35.includes("*")) {
898
898
  throw new TypeError(`${optionName} must be an absolute pathname without a query or wildcard`);
899
899
  }
900
- const normalized = path34.length > 1 ? path34.replace(/\/+$/, "") || "/" : path34;
900
+ const normalized = path35.length > 1 ? path35.replace(/\/+$/, "") || "/" : path35;
901
901
  assertBrowserStableRoutePath(normalized);
902
902
  return normalized;
903
903
  }
@@ -1278,8 +1278,8 @@ function toViteModuleId(filePath, root) {
1278
1278
  }
1279
1279
  async function fileExists(filePath) {
1280
1280
  try {
1281
- const fs13 = await import("fs/promises");
1282
- await fs13.access(filePath);
1281
+ const fs14 = await import("fs/promises");
1282
+ await fs14.access(filePath);
1283
1283
  return true;
1284
1284
  } catch {
1285
1285
  return false;
@@ -1676,35 +1676,35 @@ async function prepareFarmWorkflowsForNitro(config) {
1676
1676
  const workflowConfig = isResolvedWorkflowConfig(config.workflows) ? config.workflows : resolveWorkflowsConfig(config.workflows);
1677
1677
  const root = config.root || process.cwd();
1678
1678
  const distDir = config.distDir || ".farm";
1679
- const fs13 = await import("fs/promises");
1680
- const path34 = await import("path");
1681
- const generatedDir = path34.join(root, distDir, ".nitro", "farm-workflows");
1679
+ const fs14 = await import("fs/promises");
1680
+ const path35 = await import("path");
1681
+ const generatedDir = path35.join(root, distDir, ".nitro", "farm-workflows");
1682
1682
  const workflows = await discoverFarmWorkflows({
1683
1683
  root,
1684
1684
  workflows: workflowConfig
1685
1685
  });
1686
1686
  if (workflows.length === 0) {
1687
- await fs13.rm(generatedDir, { recursive: true, force: true });
1687
+ await fs14.rm(generatedDir, { recursive: true, force: true });
1688
1688
  return {
1689
1689
  workflows,
1690
1690
  tasks: {},
1691
1691
  scheduledTasks: {}
1692
1692
  };
1693
1693
  }
1694
- await fs13.rm(generatedDir, { recursive: true, force: true });
1695
- await fs13.mkdir(generatedDir, { recursive: true });
1694
+ await fs14.rm(generatedDir, { recursive: true, force: true });
1695
+ await fs14.mkdir(generatedDir, { recursive: true });
1696
1696
  const tasks = {};
1697
1697
  const scheduledTasks = createScheduledTasks(workflows);
1698
1698
  for (const workflow of workflows) {
1699
- const wrapperPath = toPosixPath(path34.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
1700
- await fs13.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1699
+ const wrapperPath = toPosixPath(path35.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
1700
+ await fs14.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1701
1701
  tasks[workflow.id] = {
1702
1702
  handler: wrapperPath,
1703
1703
  description: workflow.description || `Farm workflow ${workflow.id}`
1704
1704
  };
1705
1705
  }
1706
- const handlerPath = toPosixPath(path34.join(generatedDir, "http-handler.mjs"));
1707
- await fs13.writeFile(
1706
+ const handlerPath = toPosixPath(path35.join(generatedDir, "http-handler.mjs"));
1707
+ await fs14.writeFile(
1708
1708
  handlerPath,
1709
1709
  createNitroWorkflowHTTPHandler(
1710
1710
  workflowConfig,
@@ -1713,8 +1713,8 @@ async function prepareFarmWorkflowsForNitro(config) {
1713
1713
  ),
1714
1714
  "utf8"
1715
1715
  );
1716
- const manifestPath = path34.join(generatedDir, "manifest.json");
1717
- await fs13.writeFile(
1716
+ const manifestPath = path35.join(generatedDir, "manifest.json");
1717
+ await fs14.writeFile(
1718
1718
  manifestPath,
1719
1719
  JSON.stringify(
1720
1720
  {
@@ -1802,21 +1802,21 @@ function resolveWorkflowDefinition(module2) {
1802
1802
  return null;
1803
1803
  }
1804
1804
  async function findWorkflowFiles(root, dirs) {
1805
- const path34 = await import("path");
1805
+ const path35 = await import("path");
1806
1806
  const files = [];
1807
1807
  for (const dir of dirs) {
1808
- const absoluteDir = path34.isAbsolute(dir) ? dir : path34.join(root, dir);
1808
+ const absoluteDir = path35.isAbsolute(dir) ? dir : path35.join(root, dir);
1809
1809
  if (!await pathExists(absoluteDir)) continue;
1810
1810
  await walkWorkflowDir(absoluteDir, files);
1811
1811
  }
1812
1812
  return files.sort();
1813
1813
  }
1814
1814
  async function walkWorkflowDir(dir, files) {
1815
- const fs13 = await import("fs/promises");
1816
- const path34 = await import("path");
1817
- const entries = await fs13.readdir(dir, { withFileTypes: true });
1815
+ const fs14 = await import("fs/promises");
1816
+ const path35 = await import("path");
1817
+ const entries = await fs14.readdir(dir, { withFileTypes: true });
1818
1818
  for (const entry of entries) {
1819
- const filePath = path34.join(dir, entry.name);
1819
+ const filePath = path35.join(dir, entry.name);
1820
1820
  if (entry.isDirectory()) {
1821
1821
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
1822
1822
  await walkWorkflowDir(filePath, files);
@@ -1828,20 +1828,20 @@ async function walkWorkflowDir(dir, files) {
1828
1828
  }
1829
1829
  }
1830
1830
  async function pathExists(filePath) {
1831
- const fs13 = await import("fs/promises");
1832
- return fs13.access(filePath).then(() => true).catch(() => false);
1831
+ const fs14 = await import("fs/promises");
1832
+ return fs14.access(filePath).then(() => true).catch(() => false);
1833
1833
  }
1834
1834
  function isWorkflowFile(fileName) {
1835
1835
  return /\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName);
1836
1836
  }
1837
1837
  async function loadWorkflowModule(filePath, root) {
1838
- const fs13 = await import("fs/promises");
1839
- const path34 = await import("path");
1838
+ const fs14 = await import("fs/promises");
1839
+ const path35 = await import("path");
1840
1840
  const { pathToFileURL: pathToFileURL9 } = await import("url");
1841
1841
  const { build } = await import("esbuild");
1842
- const outDir = path34.join(root, ".farm", ".workflow-loader");
1843
- await fs13.mkdir(outDir, { recursive: true });
1844
- const outfile = path34.join(
1842
+ const outDir = path35.join(root, ".farm", ".workflow-loader");
1843
+ await fs14.mkdir(outDir, { recursive: true });
1844
+ const outfile = path35.join(
1845
1845
  outDir,
1846
1846
  `workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
1847
1847
  );
@@ -1865,7 +1865,7 @@ async function loadWorkflowModule(filePath, root) {
1865
1865
  `${pathToFileURL9(outfile).href}?t=${Date.now()}`
1866
1866
  );
1867
1867
  } finally {
1868
- await fs13.unlink(outfile).catch(() => void 0);
1868
+ await fs14.unlink(outfile).catch(() => void 0);
1869
1869
  }
1870
1870
  }
1871
1871
  function workflowIdFromFile(root, dirs, filePath) {
@@ -2160,7 +2160,7 @@ function normalizeCronJob(name2, job) {
2160
2160
  if (!job || typeof job !== "object" || Array.isArray(job)) {
2161
2161
  throw new TypeError(`Farm cron ${JSON.stringify(name2)} must be a configuration object.`);
2162
2162
  }
2163
- const path34 = normalizeCronPath(name2, job.path);
2163
+ const path35 = normalizeCronPath(name2, job.path);
2164
2164
  const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
2165
2165
  const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name2, value)))];
2166
2166
  if (schedule.length === 0) {
@@ -2169,7 +2169,7 @@ function normalizeCronJob(name2, job) {
2169
2169
  return {
2170
2170
  name: name2,
2171
2171
  schedule,
2172
- path: path34,
2172
+ path: path35,
2173
2173
  description: job.description?.trim() || void 0
2174
2174
  };
2175
2175
  }
@@ -2186,13 +2186,13 @@ function normalizeCronPath(name2, value) {
2186
2186
  `Farm cron ${JSON.stringify(name2)} path cannot contain backslashes or control characters.`
2187
2187
  );
2188
2188
  }
2189
- const path34 = value.trim();
2190
- if (path34.startsWith("//") || path34.includes("?") || path34.includes("#")) {
2189
+ const path35 = value.trim();
2190
+ if (path35.startsWith("//") || path35.includes("?") || path35.includes("#")) {
2191
2191
  throw new TypeError(
2192
2192
  `Farm cron ${JSON.stringify(name2)} path must be an application pathname without a host, query, or hash.`
2193
2193
  );
2194
2194
  }
2195
- for (const segment of path34.split("/")) {
2195
+ for (const segment of path35.split("/")) {
2196
2196
  let decoded = segment;
2197
2197
  try {
2198
2198
  decoded = decodeURIComponent(segment);
@@ -2214,7 +2214,7 @@ function normalizeCronPath(name2, value) {
2214
2214
  );
2215
2215
  }
2216
2216
  }
2217
- return path34.length > 1 ? path34.replace(/\/+$/, "") : path34;
2217
+ return path35.length > 1 ? path35.replace(/\/+$/, "") : path35;
2218
2218
  }
2219
2219
  function normalizeCronExpression(name2, value) {
2220
2220
  if (typeof value !== "string") {
@@ -2893,7 +2893,13 @@ function recordFarmEventTrace(event) {
2893
2893
  activeSpan.addEvent(event.type, toEventAttributes(event), event.timestamp);
2894
2894
  }
2895
2895
  const error = event.type === "request.error" ? void 0 : getEventError(event);
2896
- if (error !== void 0) recordSpanError(activeSpan, error);
2896
+ if (error !== void 0) {
2897
+ if (event.type === "render.error") {
2898
+ recordSpanException(activeSpan, error);
2899
+ } else {
2900
+ recordSpanError(activeSpan, error);
2901
+ }
2902
+ }
2897
2903
  }
2898
2904
  const completedTraceContext = recordCompletedEventSpan(event, activeContext);
2899
2905
  return traceContext ?? completedTraceContext;
@@ -2987,12 +2993,25 @@ function getCompletedSpanDescriptor(event) {
2987
2993
  return void 0;
2988
2994
  }
2989
2995
  }
2996
+ function hashFarmCacheKey(value) {
2997
+ let hash = 2166136261;
2998
+ for (let index = 0; index < value.length; index++) {
2999
+ hash ^= value.charCodeAt(index);
3000
+ hash = Math.imul(hash, 16777619);
3001
+ }
3002
+ return (hash >>> 0).toString(16).padStart(8, "0");
3003
+ }
2990
3004
  function toEventAttributes(event) {
2991
3005
  const attributes = {};
3006
+ const redactKey = typeof event.type === "string" && event.type.startsWith("cache.");
2992
3007
  for (const [key, value] of Object.entries(event)) {
2993
3008
  if (key === "timestamp" || key === "level" || key === "error" || key === "traceId" || key === "spanId" || key === "traceSampled" || value === void 0) {
2994
3009
  continue;
2995
3010
  }
3011
+ if (redactKey && key === "key" && typeof value === "string") {
3012
+ attributes["farm.key_hash"] = hashFarmCacheKey(value);
3013
+ continue;
3014
+ }
2996
3015
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2997
3016
  attributes[`farm.${key}`] = value;
2998
3017
  } else if (Array.isArray(value)) {
@@ -3010,9 +3029,13 @@ function toEventAttributes(event) {
3010
3029
  function getEventError(event) {
3011
3030
  return "error" in event ? event.error : void 0;
3012
3031
  }
3013
- function recordSpanError(span, error) {
3032
+ function recordSpanException(span, error) {
3014
3033
  const normalized = error instanceof Error ? error : new Error(String(error));
3015
3034
  span.recordException(normalized);
3035
+ return normalized;
3036
+ }
3037
+ function recordSpanError(span, error) {
3038
+ const normalized = recordSpanException(span, error);
3016
3039
  span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: normalized.message });
3017
3040
  }
3018
3041
  function setResponseStatus(span, status) {
@@ -3070,8 +3093,10 @@ var init_tracing = __esm({
3070
3093
  __name(recordFarmEventTrace, "recordFarmEventTrace");
3071
3094
  __name(recordCompletedEventSpan, "recordCompletedEventSpan");
3072
3095
  __name(getCompletedSpanDescriptor, "getCompletedSpanDescriptor");
3096
+ __name(hashFarmCacheKey, "hashFarmCacheKey");
3073
3097
  __name(toEventAttributes, "toEventAttributes");
3074
3098
  __name(getEventError, "getEventError");
3099
+ __name(recordSpanException, "recordSpanException");
3075
3100
  __name(recordSpanError, "recordSpanError");
3076
3101
  __name(setResponseStatus, "setResponseStatus");
3077
3102
  __name(resolveResultStatus, "resolveResultStatus");
@@ -3494,15 +3519,27 @@ function getFarmCacheInvalidationState() {
3494
3519
  taskListeners: /* @__PURE__ */ new Set()
3495
3520
  });
3496
3521
  }
3522
+ function warnFarmCacheListenerError(scope, error) {
3523
+ const detail = error instanceof Error ? error.stack ?? error.message : String(error);
3524
+ console.warn(`[farm:cache] ${scope} listener failed: ${detail}`);
3525
+ }
3497
3526
  function notifyFarmCacheInvalidation(key) {
3498
3527
  if (typeof key !== "string" || key.length === 0) return;
3499
3528
  for (const listener of getFarmCacheInvalidationState().listeners) {
3500
- listener(key);
3529
+ try {
3530
+ listener(key);
3531
+ } catch (error) {
3532
+ warnFarmCacheListenerError("invalidation", error);
3533
+ }
3501
3534
  }
3502
3535
  }
3503
3536
  function notifyFarmCacheTask(task) {
3504
3537
  for (const listener of getFarmCacheInvalidationState().taskListeners) {
3505
- listener(task);
3538
+ try {
3539
+ listener(task);
3540
+ } catch (error) {
3541
+ warnFarmCacheListenerError("task", error);
3542
+ }
3506
3543
  }
3507
3544
  }
3508
3545
  function encodeFarmCacheInvalidations(keys) {
@@ -3541,6 +3578,7 @@ var init_cache_invalidation = __esm({
3541
3578
  FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationState");
3542
3579
  globalState = globalThis;
3543
3580
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
3581
+ __name(warnFarmCacheListenerError, "warnFarmCacheListenerError");
3544
3582
  __name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
3545
3583
  __name(notifyFarmCacheTask, "notifyFarmCacheTask");
3546
3584
  __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
@@ -3640,7 +3678,7 @@ var init_server_action_security = __esm({
3640
3678
 
3641
3679
  // src/image-config.ts
3642
3680
  function resolveFarmImageConfig(config) {
3643
- const path34 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
3681
+ const path35 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
3644
3682
  const deviceSizes = normalizeIntegerList(
3645
3683
  config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
3646
3684
  "images.deviceSizes"
@@ -3668,7 +3706,7 @@ function resolveFarmImageConfig(config) {
3668
3706
  );
3669
3707
  return Object.freeze({
3670
3708
  provider: config?.provider ?? "auto",
3671
- path: path34,
3709
+ path: path35,
3672
3710
  domains: Object.freeze([
3673
3711
  ...new Set(
3674
3712
  (config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
@@ -3714,11 +3752,11 @@ function normalizeImagePath(value) {
3714
3752
  if (hasUnstableCharacters(value)) {
3715
3753
  throw new TypeError("images.path cannot contain backslashes or control characters");
3716
3754
  }
3717
- const path34 = value.trim().replace(/\/+$/, "") || "/";
3718
- if (!path34.startsWith("/") || path34.startsWith("//") || path34.includes("?") || path34.includes("#")) {
3755
+ const path35 = value.trim().replace(/\/+$/, "") || "/";
3756
+ if (!path35.startsWith("/") || path35.startsWith("//") || path35.includes("?") || path35.includes("#")) {
3719
3757
  throw new TypeError("images.path must be an absolute pathname without a query or hash");
3720
3758
  }
3721
- for (const segment of path34.split("/")) {
3759
+ for (const segment of path35.split("/")) {
3722
3760
  let decoded = segment;
3723
3761
  try {
3724
3762
  decoded = decodeURIComponent(segment);
@@ -3734,7 +3772,7 @@ function normalizeImagePath(value) {
3734
3772
  throw new TypeError('images.path cannot contain "." or ".." path segments');
3735
3773
  }
3736
3774
  }
3737
- return path34;
3775
+ return path35;
3738
3776
  }
3739
3777
  function normalizeIntegerList(values, name2, max) {
3740
3778
  if (values.length === 0) {
@@ -4815,7 +4853,7 @@ function getProgrammaticRouteSearchClientOptions2(search) {
4815
4853
  if (search.temporary?.length) options.temporary = [...search.temporary];
4816
4854
  return Object.keys(options).length > 0 ? options : void 0;
4817
4855
  }
4818
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path34, routePath) {
4856
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path35, routePath) {
4819
4857
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
4820
4858
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
4821
4859
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -4824,7 +4862,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path34, routePa
4824
4862
  schema,
4825
4863
  rawSearch,
4826
4864
  parsedSearch: search,
4827
- path: path34
4865
+ path: path35
4828
4866
  });
4829
4867
  return { search, canonicalPath };
4830
4868
  }
@@ -4903,8 +4941,8 @@ function normalizeComparableValue(value) {
4903
4941
  }
4904
4942
  return value;
4905
4943
  }
4906
- function createRoute(path34, options) {
4907
- return routesBuilder.page(path34, options);
4944
+ function createRoute(path35, options) {
4945
+ return routesBuilder.page(path35, options);
4908
4946
  }
4909
4947
  function isProgrammaticRoutesFileName2(fileName) {
4910
4948
  const normalized = fileName.replace(/\\/g, "/");
@@ -4987,7 +5025,7 @@ function createRouteModuleFromProgrammaticPage(route, rendererRuntime) {
4987
5025
  mod.__farmRouteData = route.data;
4988
5026
  mod.__farmRouteParsesProps = true;
4989
5027
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
4990
- mod.__farmResolveRouteCanonicalPath = (rawSearch, path34) => resolveProgrammaticRouteSearch(route.search, rawSearch, path34, route.path).canonicalPath;
5028
+ mod.__farmResolveRouteCanonicalPath = (rawSearch, path35) => resolveProgrammaticRouteSearch(route.search, rawSearch, path35, route.path).canonicalPath;
4991
5029
  }
4992
5030
  if (route.pending || route.error || route.notFound) {
4993
5031
  mod.__farmRouteComponents = {
@@ -5397,25 +5435,25 @@ var init_routes = __esm({
5397
5435
  ];
5398
5436
  __name(defineRoutes, "defineRoutes");
5399
5437
  routesBuilder = {
5400
- page(path34, options) {
5438
+ page(path35, options) {
5401
5439
  return normalizeProgrammaticRoute({
5402
5440
  kind: "page",
5403
- path: path34,
5441
+ path: path35,
5404
5442
  ...options
5405
5443
  });
5406
5444
  },
5407
- layout(path34, options) {
5445
+ layout(path35, options) {
5408
5446
  return normalizeProgrammaticRoute({
5409
5447
  kind: "layout",
5410
- path: path34,
5448
+ path: path35,
5411
5449
  ...options
5412
5450
  });
5413
5451
  },
5414
- api(path34, options) {
5452
+ api(path35, options) {
5415
5453
  const { render, runtime, regions, maxDuration, ...methods } = options;
5416
5454
  return normalizeProgrammaticRoute({
5417
5455
  kind: "api",
5418
- path: path34,
5456
+ path: path35,
5419
5457
  render,
5420
5458
  runtime,
5421
5459
  regions,
@@ -5802,9 +5840,9 @@ function getFarmIntegrationPluginOwner(plugin) {
5802
5840
  const value = plugin[FARM_INTEGRATION_PLUGIN_OWNER];
5803
5841
  return value && typeof value === "object" ? value : void 0;
5804
5842
  }
5805
- function defineTypedIntegrationRoute(method, path34, input) {
5843
+ function defineTypedIntegrationRoute(method, path35, input) {
5806
5844
  return {
5807
- path: path34,
5845
+ path: path35,
5808
5846
  method,
5809
5847
  middleware: input.middleware,
5810
5848
  before: input.before,
@@ -5814,7 +5852,7 @@ function defineTypedIntegrationRoute(method, path34, input) {
5814
5852
  input: normalizeIntegrationRouteInputSchemas(input),
5815
5853
  handler: input.handler,
5816
5854
  __operation: defineIntegrationAPIOperation({
5817
- path: path34,
5855
+ path: path35,
5818
5856
  method,
5819
5857
  bodyFormat: input.bodyFormat,
5820
5858
  responseFormat: input.responseFormat,
@@ -5826,58 +5864,58 @@ function defineTypedIntegrationRoute(method, path34, input) {
5826
5864
  }
5827
5865
  function createIntegrationRouteFactory() {
5828
5866
  return {
5829
- get(path34, input) {
5867
+ get(path35, input) {
5830
5868
  return defineTypedIntegrationRoute(
5831
5869
  "GET",
5832
- path34,
5870
+ path35,
5833
5871
  input
5834
5872
  );
5835
5873
  },
5836
- post(path34, input) {
5874
+ post(path35, input) {
5837
5875
  return defineTypedIntegrationRoute(
5838
5876
  "POST",
5839
- path34,
5877
+ path35,
5840
5878
  {
5841
5879
  bodyFormat: "json",
5842
5880
  ...input
5843
5881
  }
5844
5882
  );
5845
5883
  },
5846
- query(path34, input) {
5847
- return defineTypedIntegrationRoute("QUERY", path34, {
5884
+ query(path35, input) {
5885
+ return defineTypedIntegrationRoute("QUERY", path35, {
5848
5886
  bodyFormat: "json",
5849
5887
  ...input
5850
5888
  });
5851
5889
  },
5852
- put(path34, input) {
5890
+ put(path35, input) {
5853
5891
  return defineTypedIntegrationRoute(
5854
5892
  "PUT",
5855
- path34,
5893
+ path35,
5856
5894
  {
5857
5895
  bodyFormat: "json",
5858
5896
  ...input
5859
5897
  }
5860
5898
  );
5861
5899
  },
5862
- patch(path34, input) {
5863
- return defineTypedIntegrationRoute("PATCH", path34, {
5900
+ patch(path35, input) {
5901
+ return defineTypedIntegrationRoute("PATCH", path35, {
5864
5902
  bodyFormat: "json",
5865
5903
  ...input
5866
5904
  });
5867
5905
  },
5868
- delete(path34, input) {
5869
- return defineTypedIntegrationRoute("DELETE", path34, {
5906
+ delete(path35, input) {
5907
+ return defineTypedIntegrationRoute("DELETE", path35, {
5870
5908
  bodyFormat: "json",
5871
5909
  ...input
5872
5910
  });
5873
5911
  },
5874
- options(path34, input) {
5875
- return defineTypedIntegrationRoute("OPTIONS", path34, input);
5912
+ options(path35, input) {
5913
+ return defineTypedIntegrationRoute("OPTIONS", path35, input);
5876
5914
  },
5877
- head(path34, input) {
5915
+ head(path35, input) {
5878
5916
  return defineTypedIntegrationRoute(
5879
5917
  "HEAD",
5880
- path34,
5918
+ path35,
5881
5919
  input
5882
5920
  );
5883
5921
  }
@@ -6248,8 +6286,8 @@ function normalizeIntegrationValidationIssues(source, error) {
6248
6286
  }
6249
6287
  ];
6250
6288
  }
6251
- function normalizeIntegrationValidationPath(path34) {
6252
- return (path34 || []).map((segment) => {
6289
+ function normalizeIntegrationValidationPath(path35) {
6290
+ return (path35 || []).map((segment) => {
6253
6291
  const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
6254
6292
  return typeof key === "symbol" ? key.description || key.toString() : key;
6255
6293
  });
@@ -7060,8 +7098,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
7060
7098
  }
7061
7099
  );
7062
7100
  }
7063
- function createFarmDeploymentCookie(deploymentId, path34 = "/", secure = false) {
7064
- const normalizedPath = path34.startsWith("/") ? path34 : `/${path34}`;
7101
+ function createFarmDeploymentCookie(deploymentId, path35 = "/", secure = false) {
7102
+ const normalizedPath = path35.startsWith("/") ? path35 : `/${path35}`;
7065
7103
  return [
7066
7104
  `${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
7067
7105
  `Path=${normalizedPath}`,
@@ -7893,17 +7931,17 @@ function normalizeFarmAPIBasePath(value) {
7893
7931
  if (hasUnstableCharacters(value)) {
7894
7932
  throw new Error("Farm api.basePath cannot contain backslashes or control characters.");
7895
7933
  }
7896
- const path34 = value.trim();
7897
- if (!path34) {
7934
+ const path35 = value.trim();
7935
+ if (!path35) {
7898
7936
  throw new Error("Farm api.basePath cannot be empty.");
7899
7937
  }
7900
- if (path34.includes("?") || path34.includes("#")) {
7938
+ if (path35.includes("?") || path35.includes("#")) {
7901
7939
  throw new Error("Farm api.basePath cannot contain a query string or hash.");
7902
7940
  }
7903
- if (path34.startsWith("//")) {
7941
+ if (path35.startsWith("//")) {
7904
7942
  throw new Error('Farm api.basePath must be a pathname such as "/api", not a URL.');
7905
7943
  }
7906
- for (const segment of path34.split("/")) {
7944
+ for (const segment of path35.split("/")) {
7907
7945
  let decoded = segment;
7908
7946
  try {
7909
7947
  decoded = decodeURIComponent(segment);
@@ -7919,7 +7957,7 @@ function normalizeFarmAPIBasePath(value) {
7919
7957
  throw new Error('Farm api.basePath cannot contain "." or ".." path segments.');
7920
7958
  }
7921
7959
  }
7922
- const normalized = `/${path34.replace(/^\/+|\/+$/g, "")}`;
7960
+ const normalized = `/${path35.replace(/^\/+|\/+$/g, "")}`;
7923
7961
  return normalized === "/" ? "/" : normalized;
7924
7962
  }
7925
7963
  function parseRootRelativeBaseURL(value) {
@@ -7976,7 +8014,7 @@ var init_route_files = __esm({
7976
8014
  // src/write-file-if-changed.ts
7977
8015
  function writeFileIfChanged(filePath, content) {
7978
8016
  try {
7979
- if ((0, import_node_fs5.readFileSync)(filePath, "utf8") === content) {
8017
+ if ((0, import_node_fs6.readFileSync)(filePath, "utf8") === content) {
7980
8018
  return false;
7981
8019
  }
7982
8020
  } catch (error) {
@@ -7984,14 +8022,14 @@ function writeFileIfChanged(filePath, content) {
7984
8022
  throw error;
7985
8023
  }
7986
8024
  }
7987
- (0, import_node_fs5.writeFileSync)(filePath, content, "utf8");
8025
+ (0, import_node_fs6.writeFileSync)(filePath, content, "utf8");
7988
8026
  return true;
7989
8027
  }
7990
- var import_node_fs5;
8028
+ var import_node_fs6;
7991
8029
  var init_write_file_if_changed = __esm({
7992
8030
  "src/write-file-if-changed.ts"() {
7993
8031
  "use strict";
7994
- import_node_fs5 = require("fs");
8032
+ import_node_fs6 = require("fs");
7995
8033
  __name(writeFileIfChanged, "writeFileIfChanged");
7996
8034
  }
7997
8035
  });
@@ -8169,9 +8207,9 @@ var init_type_generator = __esm({
8169
8207
  }
8170
8208
  const nestedStructure = {};
8171
8209
  const usedRouteNames = /* @__PURE__ */ new Map();
8172
- for (const [path34, routeList] of routeGroups) {
8173
- const routeName = this.uniqueRouteName(path34, usedRouteNames);
8174
- const cleanPath = path34 === "/api" ? "" : path34.replace(/^\/api\//, "");
8210
+ for (const [path35, routeList] of routeGroups) {
8211
+ const routeName = this.uniqueRouteName(path35, usedRouteNames);
8212
+ const cleanPath = path35 === "/api" ? "" : path35.replace(/^\/api\//, "");
8175
8213
  const parts = cleanPath ? cleanPath.split("/") : [];
8176
8214
  const methodSources = /* @__PURE__ */ new Map();
8177
8215
  for (const route of routeList) {
@@ -8235,11 +8273,11 @@ var init_type_generator = __esm({
8235
8273
  methods.add(route.method);
8236
8274
  manifest.set(route.path, methods);
8237
8275
  }
8238
- const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path34, methods]) => ({ path: path34, methods: [...methods].sort() }));
8276
+ const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path35, methods]) => ({ path: path35, methods: [...methods].sort() }));
8239
8277
  const manifestSource = routeManifest.length ? `[
8240
8278
  ${routeManifest.map(
8241
- ({ path: path34, methods }) => ` {
8242
- path: ${JSON.stringify(path34)},
8279
+ ({ path: path35, methods }) => ` {
8280
+ path: ${JSON.stringify(path35)},
8243
8281
  methods: [${methods.map((method) => JSON.stringify(method)).join(", ")}],
8244
8282
  },`
8245
8283
  ).join("\n")}
@@ -8269,11 +8307,11 @@ export const apiRoutes = ${manifestSource} as const;
8269
8307
  const relativeImport = (0, import_path8.relative)((0, import_path8.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
8270
8308
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
8271
8309
  }
8272
- pathToRouteName(path34) {
8273
- return (path34 === "/api" ? "root" : path34.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
8310
+ pathToRouteName(path35) {
8311
+ return (path35 === "/api" ? "root" : path35.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
8274
8312
  }
8275
- uniqueRouteName(path34, usedNames) {
8276
- const base = this.pathToRouteName(path34);
8313
+ uniqueRouteName(path35, usedNames) {
8314
+ const base = this.pathToRouteName(path35);
8277
8315
  const seen = usedNames.get(base);
8278
8316
  usedNames.set(base, (seen ?? 0) + 1);
8279
8317
  return seen ? `${base}_${seen + 1}` : base;
@@ -8296,15 +8334,15 @@ export const apiRoutes = ${manifestSource} as const;
8296
8334
  toTypePropertyKey(key) {
8297
8335
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
8298
8336
  }
8299
- getBaseExportName(path34) {
8300
- const cleanPath = path34.replace(/^\/api\//, "");
8337
+ getBaseExportName(path35) {
8338
+ const cleanPath = path35.replace(/^\/api\//, "");
8301
8339
  if (cleanPath === "") {
8302
8340
  return "api";
8303
8341
  }
8304
8342
  return cleanPath;
8305
8343
  }
8306
- getExportName(path34, method) {
8307
- const cleanPath = path34.replace(/^\/api\//, "");
8344
+ getExportName(path35, method) {
8345
+ const cleanPath = path35.replace(/^\/api\//, "");
8308
8346
  if (cleanPath === "") {
8309
8347
  return method.toLowerCase();
8310
8348
  }
@@ -8796,12 +8834,12 @@ var init_image_server = __esm({
8796
8834
  // src/docs/fonts.ts
8797
8835
  function resolveFarmDocsFontAssets(root) {
8798
8836
  return FARM_DOCS_FONT_SOURCES.flatMap(({ family, packagePath }) => {
8799
- const sourcePath = import_node_path14.default.join(root, "node_modules", packagePath);
8800
- if (!(0, import_node_fs8.existsSync)(sourcePath)) return [];
8801
- const source = (0, import_node_fs8.readFileSync)(sourcePath);
8837
+ const sourcePath = import_node_path15.default.join(root, "node_modules", packagePath);
8838
+ if (!(0, import_node_fs9.existsSync)(sourcePath)) return [];
8839
+ const source = (0, import_node_fs9.readFileSync)(sourcePath);
8802
8840
  const fingerprint = (0, import_node_crypto3.createHash)("sha256").update(source).digest("hex").slice(0, 12);
8803
- const extension = import_node_path14.default.extname(packagePath);
8804
- const baseName = import_node_path14.default.basename(packagePath, extension);
8841
+ const extension = import_node_path15.default.extname(packagePath);
8842
+ const baseName = import_node_path15.default.basename(packagePath, extension);
8805
8843
  return [
8806
8844
  {
8807
8845
  family,
@@ -8814,13 +8852,13 @@ function resolveFarmDocsFontAssets(root) {
8814
8852
  function toFarmDocsPublicFontAssets(assets) {
8815
8853
  return assets.map(({ family, url }) => ({ family, url }));
8816
8854
  }
8817
- var import_node_crypto3, import_node_fs8, import_node_path14, FARM_DOCS_FONT_SOURCES;
8855
+ var import_node_crypto3, import_node_fs9, import_node_path15, FARM_DOCS_FONT_SOURCES;
8818
8856
  var init_fonts = __esm({
8819
8857
  "src/docs/fonts.ts"() {
8820
8858
  "use strict";
8821
8859
  import_node_crypto3 = require("crypto");
8822
- import_node_fs8 = require("fs");
8823
- import_node_path14 = __toESM(require("path"));
8860
+ import_node_fs9 = require("fs");
8861
+ import_node_path15 = __toESM(require("path"));
8824
8862
  FARM_DOCS_FONT_SOURCES = [
8825
8863
  {
8826
8864
  family: "Geist Sans",
@@ -8873,22 +8911,22 @@ function normalizeRelativePath(value) {
8873
8911
  }
8874
8912
  function resolveExistingPath(filePath) {
8875
8913
  try {
8876
- return (0, import_node_fs9.realpathSync)(filePath);
8914
+ return (0, import_node_fs10.realpathSync)(filePath);
8877
8915
  } catch {
8878
- return import_node_path16.default.resolve(filePath);
8916
+ return import_node_path17.default.resolve(filePath);
8879
8917
  }
8880
8918
  }
8881
8919
  function isDocsSourceFile(filePath) {
8882
- return DOCS_FILE_EXTENSIONS.has(import_node_path16.default.extname(filePath).toLowerCase());
8920
+ return DOCS_FILE_EXTENSIONS.has(import_node_path17.default.extname(filePath).toLowerCase());
8883
8921
  }
8884
8922
  function discoverDocsSourceFiles(contentDir) {
8885
8923
  const files = [];
8886
8924
  const visit = /* @__PURE__ */ __name((dir) => {
8887
- for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true }).sort(
8925
+ for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true }).sort(
8888
8926
  (a, b) => a.name.localeCompare(b.name)
8889
8927
  )) {
8890
8928
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
8891
- const absolutePath = import_node_path16.default.join(dir, entry.name);
8929
+ const absolutePath = import_node_path17.default.join(dir, entry.name);
8892
8930
  if (entry.isDirectory()) {
8893
8931
  visit(absolutePath);
8894
8932
  } else if (entry.isFile() && isDocsSourceFile(absolutePath)) {
@@ -8896,7 +8934,7 @@ function discoverDocsSourceFiles(contentDir) {
8896
8934
  }
8897
8935
  }
8898
8936
  }, "visit");
8899
- if ((0, import_node_fs9.existsSync)(contentDir)) visit(contentDir);
8937
+ if ((0, import_node_fs10.existsSync)(contentDir)) visit(contentDir);
8900
8938
  return files;
8901
8939
  }
8902
8940
  function getGitLastModifiedDates(contentDir) {
@@ -8906,7 +8944,7 @@ function getGitLastModifiedDates(contentDir) {
8906
8944
  stdio: ["ignore", "pipe", "ignore"]
8907
8945
  }).trim();
8908
8946
  if (!gitRoot) return {};
8909
- const contentPathspec = normalizeRelativePath(import_node_path16.default.relative(gitRoot, contentDir)) || ".";
8947
+ const contentPathspec = normalizeRelativePath(import_node_path17.default.relative(gitRoot, contentDir)) || ".";
8910
8948
  const contentPrefix = contentPathspec === "." ? "" : `${contentPathspec}/`;
8911
8949
  const history = (0, import_node_child_process.execFileSync)(
8912
8950
  "git",
@@ -8948,11 +8986,11 @@ function getGitLastModifiedDates(contentDir) {
8948
8986
  }
8949
8987
  }
8950
8988
  function readManifest(contentDir) {
8951
- const manifestPath = import_node_path16.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
8952
- if (!(0, import_node_fs9.existsSync)(manifestPath)) return null;
8989
+ const manifestPath = import_node_path17.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
8990
+ if (!(0, import_node_fs10.existsSync)(manifestPath)) return null;
8953
8991
  try {
8954
8992
  const parsed = JSON.parse(
8955
- (0, import_node_fs9.readFileSync)(manifestPath, "utf8")
8993
+ (0, import_node_fs10.readFileSync)(manifestPath, "utf8")
8956
8994
  );
8957
8995
  if (parsed.version !== 1 || !parsed.pages || typeof parsed.pages !== "object") return null;
8958
8996
  const pages = Object.fromEntries(
@@ -8971,15 +9009,15 @@ function createFarmDocsLastModifiedManifest(contentDir, options = {}) {
8971
9009
  const fallbackDate = (options.now ?? /* @__PURE__ */ new Date()).toISOString();
8972
9010
  const pages = {};
8973
9011
  for (const sourcePath of discoverDocsSourceFiles(resolvedContentDir)) {
8974
- const relativePath2 = normalizeRelativePath(import_node_path16.default.relative(resolvedContentDir, sourcePath));
8975
- pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs9.statSync)(sourcePath).mtime.toISOString());
9012
+ const relativePath2 = normalizeRelativePath(import_node_path17.default.relative(resolvedContentDir, sourcePath));
9013
+ pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs10.statSync)(sourcePath).mtime.toISOString());
8976
9014
  }
8977
9015
  return { version: 1, pages };
8978
9016
  }
8979
9017
  function getLastModifiedManifest(contentDir) {
8980
9018
  const resolvedContentDir = resolveExistingPath(contentDir);
8981
- const manifestPath = import_node_path16.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
8982
- const manifestStat = (0, import_node_fs9.existsSync)(manifestPath) ? (0, import_node_fs9.statSync)(manifestPath) : null;
9019
+ const manifestPath = import_node_path17.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
9020
+ const manifestStat = (0, import_node_fs10.existsSync)(manifestPath) ? (0, import_node_fs10.statSync)(manifestPath) : null;
8983
9021
  const signature = manifestStat ? `file:${manifestStat.mtimeMs}:${manifestStat.size}` : "generated";
8984
9022
  const cached = manifestCache.get(resolvedContentDir);
8985
9023
  if (cached?.signature === signature) return cached.manifest;
@@ -8992,21 +9030,21 @@ function resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter) {
8992
9030
  if (configured) return configured;
8993
9031
  const resolvedContentDir = resolveExistingPath(contentDir);
8994
9032
  const resolvedSourcePath = resolveExistingPath(sourcePath);
8995
- const relativePath2 = normalizeRelativePath(import_node_path16.default.relative(resolvedContentDir, resolvedSourcePath));
8996
- const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path16.default.isAbsolute(relativePath2);
9033
+ const relativePath2 = normalizeRelativePath(import_node_path17.default.relative(resolvedContentDir, resolvedSourcePath));
9034
+ const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path17.default.isAbsolute(relativePath2);
8997
9035
  if (isInsideContentDir) {
8998
9036
  const generated = getLastModifiedManifest(resolvedContentDir).pages[relativePath2];
8999
9037
  if (generated) return generated;
9000
9038
  }
9001
- return (0, import_node_fs9.statSync)(resolvedSourcePath).mtime.toISOString();
9039
+ return (0, import_node_fs10.statSync)(resolvedSourcePath).mtime.toISOString();
9002
9040
  }
9003
- var import_node_child_process, import_node_fs9, import_node_path16, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
9041
+ var import_node_child_process, import_node_fs10, import_node_path17, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
9004
9042
  var init_last_modified = __esm({
9005
9043
  "src/docs/last-modified.ts"() {
9006
9044
  "use strict";
9007
9045
  import_node_child_process = require("child_process");
9008
- import_node_fs9 = require("fs");
9009
- import_node_path16 = __toESM(require("path"));
9046
+ import_node_fs10 = require("fs");
9047
+ import_node_path17 = __toESM(require("path"));
9010
9048
  FARM_DOCS_LAST_MODIFIED_MANIFEST = ".farm-docs-last-modified.json";
9011
9049
  COMMIT_MARKER = "__FARM_DOCS_COMMIT__";
9012
9050
  DOCS_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx"]);
@@ -9039,10 +9077,10 @@ function isFarmDocsSearchEnabled(docs) {
9039
9077
  }
9040
9078
  function resolveFarmDocsSearchClientModule(root) {
9041
9079
  try {
9042
- const requireFromApp = (0, import_node_module5.createRequire)(import_node_path17.default.join(import_node_path17.default.resolve(root), "package.json"));
9080
+ const requireFromApp = (0, import_node_module5.createRequire)(import_node_path18.default.join(import_node_path18.default.resolve(root), "package.json"));
9043
9081
  const themeEntry = requireFromApp.resolve("@farming-labs/theme");
9044
- const commandSearchModule = import_node_path17.default.join(import_node_path17.default.dirname(themeEntry), "docs-command-search.mjs");
9045
- if ((0, import_node_fs10.existsSync)(commandSearchModule)) return commandSearchModule;
9082
+ const commandSearchModule = import_node_path18.default.join(import_node_path18.default.dirname(themeEntry), "docs-command-search.mjs");
9083
+ if ((0, import_node_fs11.existsSync)(commandSearchModule)) return commandSearchModule;
9046
9084
  } catch {
9047
9085
  }
9048
9086
  return void 0;
@@ -9181,13 +9219,13 @@ async function mountFarmDocsSearch() {
9181
9219
  window.__FARM_MOUNT_DOCS_SEARCH__ = mountFarmDocsSearch;
9182
9220
  `;
9183
9221
  }
9184
- var import_node_fs10, import_node_module5, import_node_path17;
9222
+ var import_node_fs11, import_node_module5, import_node_path18;
9185
9223
  var init_search_client = __esm({
9186
9224
  "src/docs/search-client.ts"() {
9187
9225
  "use strict";
9188
- import_node_fs10 = require("fs");
9226
+ import_node_fs11 = require("fs");
9189
9227
  import_node_module5 = require("module");
9190
- import_node_path17 = __toESM(require("path"));
9228
+ import_node_path18 = __toESM(require("path"));
9191
9229
  __name(isFarmDocsSearchEnabled, "isFarmDocsSearchEnabled");
9192
9230
  __name(resolveFarmDocsSearchClientModule, "resolveFarmDocsSearchClientModule");
9193
9231
  __name(generateFarmDocsSearchBootstrapRuntime, "generateFarmDocsSearchBootstrapRuntime");
@@ -9625,10 +9663,10 @@ function resolveFarmDocsFavicon(docs, options) {
9625
9663
  if (typeof configuredFavicon === "string" && configuredFavicon.trim()) {
9626
9664
  return configuredFavicon.trim();
9627
9665
  }
9628
- const publicDir = import_node_path18.default.join(import_node_path18.default.resolve(options.root), "public");
9666
+ const publicDir = import_node_path19.default.join(import_node_path19.default.resolve(options.root), "public");
9629
9667
  for (const fileName of FARM_DOCS_FAVICON_FILES) {
9630
- const faviconPath = import_node_path18.default.join(publicDir, fileName);
9631
- if ((0, import_node_fs11.existsSync)(faviconPath) && (0, import_node_fs11.statSync)(faviconPath).isFile()) {
9668
+ const faviconPath = import_node_path19.default.join(publicDir, fileName);
9669
+ if ((0, import_node_fs12.existsSync)(faviconPath) && (0, import_node_fs12.statSync)(faviconPath).isFile()) {
9632
9670
  return `/${fileName}`;
9633
9671
  }
9634
9672
  }
@@ -9662,10 +9700,10 @@ function isSafeSegment(segment) {
9662
9700
  return segment !== ".." && !segment.includes("/") && !segment.includes("\\");
9663
9701
  }
9664
9702
  function resolveInside(root, target) {
9665
- const resolvedRoot = import_node_path18.default.resolve(root);
9666
- const resolvedTarget = import_node_path18.default.resolve(target);
9667
- const relative6 = import_node_path18.default.relative(resolvedRoot, resolvedTarget);
9668
- if (relative6 === "" || !relative6.startsWith("..") && !import_node_path18.default.isAbsolute(relative6)) {
9703
+ const resolvedRoot = import_node_path19.default.resolve(root);
9704
+ const resolvedTarget = import_node_path19.default.resolve(target);
9705
+ const relative6 = import_node_path19.default.relative(resolvedRoot, resolvedTarget);
9706
+ if (relative6 === "" || !relative6.startsWith("..") && !import_node_path19.default.isAbsolute(relative6)) {
9669
9707
  return resolvedTarget;
9670
9708
  }
9671
9709
  return null;
@@ -9674,10 +9712,10 @@ function resolveExistingFileInside(root, target) {
9674
9712
  const safePath = resolveInside(root, target);
9675
9713
  if (!safePath) return null;
9676
9714
  try {
9677
- const realRoot = (0, import_node_fs11.realpathSync)(root);
9678
- const realTarget = (0, import_node_fs11.realpathSync)(safePath);
9715
+ const realRoot = (0, import_node_fs12.realpathSync)(root);
9716
+ const realTarget = (0, import_node_fs12.realpathSync)(safePath);
9679
9717
  const containedTarget = resolveInside(realRoot, realTarget);
9680
- return containedTarget && (0, import_node_fs11.statSync)(containedTarget).isFile() ? containedTarget : null;
9718
+ return containedTarget && (0, import_node_fs12.statSync)(containedTarget).isFile() ? containedTarget : null;
9681
9719
  } catch {
9682
9720
  return null;
9683
9721
  }
@@ -9691,16 +9729,16 @@ function isFarmDocsRequest(docs, request) {
9691
9729
  return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
9692
9730
  }
9693
9731
  function resolveFarmDocsContentDir(docs, options) {
9694
- const root = import_node_path18.default.resolve(options.root);
9732
+ const root = import_node_path19.default.resolve(options.root);
9695
9733
  const srcDir = options.srcDir || "src";
9696
9734
  const configuredContentDir = docs.contentDir || docs.config.contentDir;
9697
9735
  if (configuredContentDir) {
9698
- return import_node_path18.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path18.default.join(root, configuredContentDir);
9736
+ return import_node_path19.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path19.default.join(root, configuredContentDir);
9699
9737
  }
9700
9738
  const entryDir = docs.config.entry || trimSlashes2(docs.entry) || "docs";
9701
- const appDocsDir = import_node_path18.default.join(root, srcDir, "app", entryDir);
9702
- if ((0, import_node_fs11.existsSync)(appDocsDir)) return appDocsDir;
9703
- return import_node_path18.default.join(root, entryDir);
9739
+ const appDocsDir = import_node_path19.default.join(root, srcDir, "app", entryDir);
9740
+ if ((0, import_node_fs12.existsSync)(appDocsDir)) return appDocsDir;
9741
+ return import_node_path19.default.join(root, entryDir);
9704
9742
  }
9705
9743
  function getFarmDocsRouteTypeEntries(docs) {
9706
9744
  if (!docs?.enabled) return [];
@@ -9723,10 +9761,10 @@ function getRequestSlug(docs, request) {
9723
9761
  function findDocsPageFile(contentDir, slug) {
9724
9762
  const segments = slug ? slug.split("/").filter(Boolean) : [];
9725
9763
  if (!segments.every(isSafeSegment)) return null;
9726
- const slugDir = import_node_path18.default.join(contentDir, ...segments);
9727
- const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path18.default.join(contentDir, filename)) : [
9728
- ...DOCS_FILE_NAMES.map((filename) => import_node_path18.default.join(slugDir, filename)),
9729
- ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path18.default.join(contentDir, `${slug}${extension}`))
9764
+ const slugDir = import_node_path19.default.join(contentDir, ...segments);
9765
+ const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path19.default.join(contentDir, filename)) : [
9766
+ ...DOCS_FILE_NAMES.map((filename) => import_node_path19.default.join(slugDir, filename)),
9767
+ ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path19.default.join(contentDir, `${slug}${extension}`))
9730
9768
  ];
9731
9769
  for (const candidate of candidates) {
9732
9770
  const safePath = resolveExistingFileInside(contentDir, candidate);
@@ -9765,7 +9803,7 @@ function titleFromMarkdown2(body, fallback) {
9765
9803
  function loadFarmDocsPage(contentDir, docs, slug) {
9766
9804
  const sourcePath = findDocsPageFile(contentDir, slug);
9767
9805
  if (!sourcePath) return null;
9768
- const source = (0, import_node_fs11.readFileSync)(sourcePath, "utf8");
9806
+ const source = (0, import_node_fs12.readFileSync)(sourcePath, "utf8");
9769
9807
  const { frontmatter, body } = parseFrontmatter(source);
9770
9808
  const title = frontmatter.title || titleFromMarkdown2(body, titleFromSlug(slug));
9771
9809
  const href = createDocsHref(docs.entry, slug);
@@ -9788,9 +9826,9 @@ function createDocsHref(entry, slug) {
9788
9826
  return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
9789
9827
  }
9790
9828
  function pathToSlug(contentDir, filePath) {
9791
- const relative6 = import_node_path18.default.relative(contentDir, filePath).replace(/\\/g, "/");
9829
+ const relative6 = import_node_path19.default.relative(contentDir, filePath).replace(/\\/g, "/");
9792
9830
  if (relative6.startsWith("..")) return null;
9793
- const extension = import_node_path18.default.extname(relative6);
9831
+ const extension = import_node_path19.default.extname(relative6);
9794
9832
  if (!DOCS_FILE_EXTENSIONS2.includes(extension)) return null;
9795
9833
  const withoutExtension = relative6.slice(0, -extension.length);
9796
9834
  if (withoutExtension === "page" || withoutExtension === "index") return "";
@@ -9803,12 +9841,12 @@ function loadPage(contentDir, docs, request) {
9803
9841
  return loadFarmDocsPage(contentDir, docs, getRequestSlug(docs, request));
9804
9842
  }
9805
9843
  function discoverFarmDocsPages(contentDir, docs) {
9806
- if (!(0, import_node_fs11.existsSync)(contentDir)) return [];
9844
+ if (!(0, import_node_fs12.existsSync)(contentDir)) return [];
9807
9845
  const pages = [];
9808
9846
  const visit = /* @__PURE__ */ __name((dir) => {
9809
- for (const entry of (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true })) {
9847
+ for (const entry of (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true })) {
9810
9848
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
9811
- const absolutePath = import_node_path18.default.join(dir, entry.name);
9849
+ const absolutePath = import_node_path19.default.join(dir, entry.name);
9812
9850
  if (entry.isDirectory()) {
9813
9851
  visit(absolutePath);
9814
9852
  continue;
@@ -9816,7 +9854,7 @@ function discoverFarmDocsPages(contentDir, docs) {
9816
9854
  if (!entry.isFile()) continue;
9817
9855
  const slug = pathToSlug(contentDir, absolutePath);
9818
9856
  if (slug === null) continue;
9819
- const source = (0, import_node_fs11.readFileSync)(absolutePath, "utf8");
9857
+ const source = (0, import_node_fs12.readFileSync)(absolutePath, "utf8");
9820
9858
  const { frontmatter, body } = parseFrontmatter(source);
9821
9859
  pages.push({
9822
9860
  slug,
@@ -10335,11 +10373,30 @@ function renderMarkdownHtml(body) {
10335
10373
  function extractTocItems(body, depth) {
10336
10374
  const slug = createSlugger();
10337
10375
  const maxLevel = Math.max(2, Math.min(depth, 6));
10338
- return body.split(/\r?\n/).map((line) => line.match(/^(#{2,6})\s+(.+)$/)).filter((match) => Boolean(match)).map((match) => ({
10339
- id: slug(match[2].trim()),
10340
- title: match[2].trim(),
10341
- level: match[1].length
10342
- })).filter((item) => item.level <= maxLevel);
10376
+ const items = [];
10377
+ let fence = null;
10378
+ for (const line of body.split(/\r?\n/)) {
10379
+ const nextFence = getCodeFence(line);
10380
+ if (fence) {
10381
+ if (nextFence && nextFence.marker === fence.marker && isClosingCodeFence(line, fence)) {
10382
+ fence = null;
10383
+ }
10384
+ continue;
10385
+ }
10386
+ if (nextFence) {
10387
+ fence = nextFence;
10388
+ continue;
10389
+ }
10390
+ const match = line.match(/^(#{2,6})\s+(.+)$/);
10391
+ if (!match) continue;
10392
+ const title = match[2].trim();
10393
+ const id = slug(title);
10394
+ const level = match[1].length;
10395
+ if (level <= maxLevel) {
10396
+ items.push({ id, title, level });
10397
+ }
10398
+ }
10399
+ return items;
10343
10400
  }
10344
10401
  function getThemeUI(docs) {
10345
10402
  const theme = docs.config.theme;
@@ -10828,12 +10885,12 @@ function createFarmDocsHandler(docs, options) {
10828
10885
  );
10829
10886
  }, "handleFarmDocsRequest");
10830
10887
  }
10831
- var import_node_fs11, import_node_path18, 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;
10888
+ var import_node_fs12, import_node_path19, 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;
10832
10889
  var init_handler = __esm({
10833
10890
  "src/docs/handler.ts"() {
10834
10891
  "use strict";
10835
- import_node_fs11 = require("fs");
10836
- import_node_path18 = __toESM(require("path"));
10892
+ import_node_fs12 = require("fs");
10893
+ import_node_path19 = __toESM(require("path"));
10837
10894
  import_docs = require("@farming-labs/docs");
10838
10895
  import_marked = require("marked");
10839
10896
  import_sugar_high = require("sugar-high");
@@ -11092,13 +11149,13 @@ var init_adapter = __esm({
11092
11149
  });
11093
11150
 
11094
11151
  // src/docs/framework-detect.ts
11095
- var import_promises8, import_node_module6, import_node_path19, import_node_url7;
11152
+ var import_promises8, import_node_module6, import_node_path20, import_node_url7;
11096
11153
  var init_framework_detect = __esm({
11097
11154
  "src/docs/framework-detect.ts"() {
11098
11155
  "use strict";
11099
11156
  import_promises8 = require("fs/promises");
11100
11157
  import_node_module6 = require("module");
11101
- import_node_path19 = __toESM(require("path"));
11158
+ import_node_path20 = __toESM(require("path"));
11102
11159
  import_node_url7 = require("url");
11103
11160
  }
11104
11161
  });
@@ -11198,19 +11255,19 @@ async function findDocsConfigPath(rootDir, configPath) {
11198
11255
  return void 0;
11199
11256
  }
11200
11257
  async function loadDocsConfig(rootDir, configPath) {
11201
- const fs13 = await import("fs/promises");
11258
+ const fs14 = await import("fs/promises");
11202
11259
  const { pathToFileURL: pathToFileURL9 } = await import("url");
11203
11260
  const root = import_path10.default.resolve(rootDir || process.cwd());
11204
11261
  const resolvedPath = await findDocsConfigPath(root, configPath);
11205
11262
  if (!resolvedPath) return void 0;
11206
11263
  try {
11207
11264
  if (resolvedPath.endsWith(".json")) {
11208
- const content = await fs13.readFile(resolvedPath, "utf8");
11265
+ const content = await fs14.readFile(resolvedPath, "utf8");
11209
11266
  return { config: JSON.parse(content), configPath: resolvedPath };
11210
11267
  }
11211
11268
  const { build } = await import("esbuild");
11212
11269
  const configCacheDir = import_path10.default.join(root, ".farm", ".config-loader");
11213
- await fs13.mkdir(configCacheDir, { recursive: true });
11270
+ await fs14.mkdir(configCacheDir, { recursive: true });
11214
11271
  const modulePath = import_path10.default.join(
11215
11272
  configCacheDir,
11216
11273
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -11236,7 +11293,7 @@ async function loadDocsConfig(rootDir, configPath) {
11236
11293
  moduleUrl
11237
11294
  );
11238
11295
  } finally {
11239
- await fs13.unlink(modulePath).catch(() => void 0);
11296
+ await fs14.unlink(modulePath).catch(() => void 0);
11240
11297
  }
11241
11298
  return {
11242
11299
  config: importedConfig.default || importedConfig,
@@ -12146,8 +12203,8 @@ var init_generator = __esm({
12146
12203
  }
12147
12204
  routeGroups.get(key).push(route);
12148
12205
  }
12149
- for (const [path34, routeList] of routeGroups) {
12150
- const openAPIPath = this.convertToOpenAPIPath(path34);
12206
+ for (const [path35, routeList] of routeGroups) {
12207
+ const openAPIPath = this.convertToOpenAPIPath(path35);
12151
12208
  spec.paths[openAPIPath] = {};
12152
12209
  for (const route of routeList) {
12153
12210
  for (const method of route.methods) {
@@ -12167,8 +12224,8 @@ var init_generator = __esm({
12167
12224
  /**
12168
12225
  * Convert Farm.js API path to OpenAPI path format
12169
12226
  */
12170
- convertToOpenAPIPath(path34) {
12171
- return path34.replace(/^\/api/, "");
12227
+ convertToOpenAPIPath(path35) {
12228
+ return path35.replace(/^\/api/, "");
12172
12229
  }
12173
12230
  /**
12174
12231
  * Extract request body schema from endpoint
@@ -12330,8 +12387,8 @@ var init_generator = __esm({
12330
12387
  /**
12331
12388
  * Generate operation summary
12332
12389
  */
12333
- generateSummary(path34, method) {
12334
- const cleanPath = path34.replace(/^\/api\//, "");
12390
+ generateSummary(path35, method) {
12391
+ const cleanPath = path35.replace(/^\/api\//, "");
12335
12392
  const pathParts = cleanPath.split("/");
12336
12393
  const lastPart = pathParts[pathParts.length - 1];
12337
12394
  const action = method === "GET" ? "Get" : method === "QUERY" ? "Query" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -12340,22 +12397,22 @@ var init_generator = __esm({
12340
12397
  /**
12341
12398
  * Generate operation description
12342
12399
  */
12343
- generateDescription(path34, method) {
12344
- const cleanPath = path34.replace(/^\/api\//, "");
12400
+ generateDescription(path35, method) {
12401
+ const cleanPath = path35.replace(/^\/api\//, "");
12345
12402
  return `${method} ${cleanPath} endpoint`;
12346
12403
  }
12347
12404
  /**
12348
12405
  * Generate operation ID
12349
12406
  */
12350
- generateOperationId(path34, method) {
12351
- const cleanPath = path34.replace(/^\/api\//, "").replace(/\//g, "_");
12407
+ generateOperationId(path35, method) {
12408
+ const cleanPath = path35.replace(/^\/api\//, "").replace(/\//g, "_");
12352
12409
  return `${method.toLowerCase()}_${cleanPath}`;
12353
12410
  }
12354
12411
  /**
12355
12412
  * Generate tags for grouping operations
12356
12413
  */
12357
- generateTags(path34) {
12358
- const cleanPath = path34.replace(/^\/api\//, "");
12414
+ generateTags(path35) {
12415
+ const cleanPath = path35.replace(/^\/api\//, "");
12359
12416
  const pathParts = cleanPath.split("/");
12360
12417
  if (pathParts.length > 1) {
12361
12418
  return [pathParts[0]];
@@ -12367,13 +12424,13 @@ var init_generator = __esm({
12367
12424
  */
12368
12425
  async generateSpecFile(routes, outputPath) {
12369
12426
  const spec = await this.generateSpec(routes);
12370
- const fs13 = require("fs");
12371
- const path34 = require("path");
12372
- const dir = path34.dirname(outputPath);
12373
- if (!fs13.existsSync(dir)) {
12374
- fs13.mkdirSync(dir, { recursive: true });
12427
+ const fs14 = require("fs");
12428
+ const path35 = require("path");
12429
+ const dir = path35.dirname(outputPath);
12430
+ if (!fs14.existsSync(dir)) {
12431
+ fs14.mkdirSync(dir, { recursive: true });
12375
12432
  }
12376
- fs13.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
12433
+ fs14.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
12377
12434
  }
12378
12435
  };
12379
12436
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -12801,7 +12858,7 @@ async function createFarmDevtoolsSnapshot(input) {
12801
12858
  generatedAt: (input.now?.() || /* @__PURE__ */ new Date()).toISOString(),
12802
12859
  health: resolveHealth(diagnostics),
12803
12860
  project: {
12804
- name: import_node_path20.default.basename(import_node_path20.default.resolve(input.root)),
12861
+ name: import_node_path21.default.basename(import_node_path21.default.resolve(input.root)),
12805
12862
  root: input.root,
12806
12863
  srcDir: input.srcDir,
12807
12864
  basePath: config.basePath || "/",
@@ -12850,11 +12907,11 @@ async function createFarmDevtoolsSnapshot(input) {
12850
12907
  diagnostics
12851
12908
  };
12852
12909
  }
12853
- var import_node_path20;
12910
+ var import_node_path21;
12854
12911
  var init_devtools = __esm({
12855
12912
  "src/devtools.ts"() {
12856
12913
  "use strict";
12857
- import_node_path20 = __toESM(require("path"));
12914
+ import_node_path21 = __toESM(require("path"));
12858
12915
  init_config4();
12859
12916
  init_cron();
12860
12917
  init_route_runtime();
@@ -13495,6 +13552,7 @@ function renderFarmDevtoolsHtml(snapshot) {
13495
13552
  .nav-item .icon { width: 13px; height: 13px; }
13496
13553
  .nav-item small { color: #666; font-size: 9px; font-weight: 400; }
13497
13554
  .topbar-meta { display: flex; flex: 0 0 auto; margin-left: auto; border-left: 1px solid var(--line); }
13555
+ .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; }
13498
13556
  .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; }
13499
13557
  .status-dot { width: 5px; height: 5px; background: #fff; box-shadow: 0 0 0 3px rgb(255 255 255 / 0.06); }
13500
13558
  .status-dot-attention { background: #909090; animation: status-pulse 1.8s ease-in-out infinite; }
@@ -14004,6 +14062,7 @@ function renderFarmDevtoolsHtml(snapshot) {
14004
14062
  ${renderNavigationItem("raw", "Raw")}
14005
14063
  </nav>
14006
14064
  <div class="topbar-meta">
14065
+ <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>
14007
14066
  <span class="project-select">${escapeHtml3(snapshot.project.name)} ${icon(
14008
14067
  "chevron"
14009
14068
  )}</span>
@@ -14259,23 +14318,26 @@ function generateFarmDevtoolsClientRuntime(config) {
14259
14318
  z-index: 2147483646;
14260
14319
  display: grid;
14261
14320
  place-items: center;
14321
+ box-sizing: border-box;
14262
14322
  padding: 20px;
14263
14323
  background: rgb(0 0 0 / 0);
14264
- backdrop-filter: blur(0);
14324
+ backdrop-filter: blur(6px);
14325
+ -webkit-backdrop-filter: blur(6px);
14326
+ overscroll-behavior: none;
14327
+ isolation: isolate;
14265
14328
  opacity: 0;
14266
14329
  pointer-events: none;
14267
- transition: background-color 150ms ease-out, backdrop-filter 150ms ease-out, opacity 150ms ease-out;
14330
+ transition: opacity 150ms ease-out;
14268
14331
  }
14269
14332
  #__farm_devtools_overlay__[data-open="true"] {
14270
- background: rgb(0 0 0 / 0.12);
14271
- backdrop-filter: blur(1px);
14333
+ background: rgb(0 0 0 / 0.32);
14272
14334
  opacity: 1;
14273
14335
  pointer-events: auto;
14274
14336
  }
14275
14337
  #__farm_devtools_overlay__ > iframe {
14276
14338
  display: block;
14277
- width: min(960px, calc(100vw - 40px));
14278
- height: min(560px, calc(100dvh - 40px));
14339
+ width: min(1100px, calc(100vw - 48px));
14340
+ height: min(720px, calc(100dvh - 48px));
14279
14341
  border: 0;
14280
14342
  border-radius: 12px;
14281
14343
  background: transparent;
@@ -14291,7 +14353,7 @@ function generateFarmDevtoolsClientRuntime(config) {
14291
14353
  #__farm_devtools_overlay__ > iframe {
14292
14354
  width: calc(100vw - 16px);
14293
14355
  height: calc(100dvh - 16px);
14294
- border-radius: 10px;
14356
+ border-radius: 12px;
14295
14357
  }
14296
14358
  }
14297
14359
  @media (prefers-reduced-motion: reduce) {
@@ -14305,10 +14367,32 @@ function generateFarmDevtoolsClientRuntime(config) {
14305
14367
  const runtimeKey = "__FARM_DEVTOOLS_RUNTIME__";
14306
14368
  const launchParam = ${JSON.stringify(FARM_DEVTOOLS_LAUNCH_PARAM)};
14307
14369
  const devtoolsPath = ${JSON.stringify(FARM_DEVTOOLS_PATH)};
14308
- const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw"]);
14370
+ const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw", "inspect", "diagnostics"]);
14309
14371
  const shortcut = ${JSON.stringify(shortcut)};
14310
14372
  const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform);
14311
14373
  let returnFocus = null;
14374
+ let restorePage = null;
14375
+ let closeTimer = null;
14376
+
14377
+ const lockPage = () => {
14378
+ const styles = [];
14379
+ for (const element of [document.documentElement, document.body]) {
14380
+ for (const [property, value] of [["overflow-x", "hidden"], ["overflow-y", "hidden"], ["overscroll-behavior", "none"]]) {
14381
+ const previous = element.style.getPropertyValue(property);
14382
+ const priority = element.style.getPropertyPriority(property);
14383
+ element.style.setProperty(property, value, "important");
14384
+ styles.push({ element, property, value, previous, priority });
14385
+ }
14386
+ }
14387
+ return () => {
14388
+ for (const { element, property, value, previous, priority } of styles) {
14389
+ // Do not overwrite a newer style set by the application while the panel was open.
14390
+ if (element.style.getPropertyValue(property) !== value || element.style.getPropertyPriority(property) !== "important") continue;
14391
+ if (previous) element.style.setProperty(property, previous, priority);
14392
+ else element.style.removeProperty(property);
14393
+ }
14394
+ };
14395
+ };
14312
14396
 
14313
14397
  const matchesShortcut = (event) => {
14314
14398
  if (!shortcut || event.repeat) return false;
@@ -14335,24 +14419,35 @@ function generateFarmDevtoolsClientRuntime(config) {
14335
14419
  document.head.appendChild(style);
14336
14420
  };
14337
14421
 
14338
- const close = () => {
14422
+ const finishClose = () => {
14423
+ if (closeTimer !== null) window.clearTimeout(closeTimer);
14424
+ closeTimer = null;
14339
14425
  const overlay = document.getElementById(overlayId);
14340
- if (!overlay) return;
14426
+ overlay?.remove();
14427
+ restorePage?.();
14428
+ restorePage = null;
14341
14429
  const focusTarget = returnFocus;
14342
14430
  returnFocus = null;
14431
+ focusTarget?.focus?.({ preventScroll: true });
14432
+ };
14433
+
14434
+ const close = () => {
14435
+ const overlay = document.getElementById(overlayId);
14436
+ if (!overlay || closeTimer !== null) return;
14343
14437
  overlay.dataset.open = "false";
14344
- window.setTimeout(() => {
14345
- overlay.remove();
14346
- focusTarget?.focus?.();
14347
- }, 160);
14438
+ closeTimer = window.setTimeout(finishClose, 160);
14348
14439
  };
14349
14440
 
14350
14441
  const open = (view = "overview") => {
14442
+ if (closeTimer !== null) finishClose();
14351
14443
  if (document.getElementById(overlayId)) return;
14352
14444
  ensureStyles();
14353
14445
  returnFocus = document.activeElement;
14446
+ restorePage = lockPage();
14354
14447
  const overlay = document.createElement("div");
14355
14448
  overlay.id = overlayId;
14449
+ overlay.setAttribute("role", "dialog");
14450
+ overlay.setAttribute("aria-modal", "true");
14356
14451
  overlay.setAttribute("aria-label", "Farm.js DevTools overlay");
14357
14452
  const frame = document.createElement("iframe");
14358
14453
  const resolvedView = validViews.has(view) ? view : "overview";
@@ -14363,9 +14458,11 @@ function generateFarmDevtoolsClientRuntime(config) {
14363
14458
  overlay.addEventListener("pointerdown", (event) => {
14364
14459
  if (event.target === overlay) close();
14365
14460
  });
14461
+ overlay.addEventListener("wheel", (event) => event.preventDefault(), { passive: false });
14462
+ overlay.addEventListener("touchmove", (event) => event.preventDefault(), { passive: false });
14366
14463
  document.body.appendChild(overlay);
14367
14464
  requestAnimationFrame(() => {
14368
- overlay.dataset.open = "true";
14465
+ if (overlay.isConnected && closeTimer === null) overlay.dataset.open = "true";
14369
14466
  });
14370
14467
  };
14371
14468
 
@@ -14399,6 +14496,7 @@ function generateFarmDevtoolsClientRuntime(config) {
14399
14496
  window.addEventListener("message", onMessage);
14400
14497
  window[runtimeKey] = {
14401
14498
  dispose() {
14499
+ finishClose();
14402
14500
  window.removeEventListener("keydown", onKeydown, true);
14403
14501
  window.removeEventListener("message", onMessage);
14404
14502
  },
@@ -14661,10 +14759,11 @@ var ROUTE_PROP_LABELS = /* @__PURE__ */ new Map([
14661
14759
  ["middlewareData", "middleware request data"],
14662
14760
  ["context", "request context"]
14663
14761
  ]);
14664
- function resolveConfiguredRouteRenderingConfig(mod, source) {
14762
+ function resolveConfiguredRouteRenderingConfig(mod, source, options) {
14763
+ const pprEnabled = options?.experimentalPPR === true;
14665
14764
  const directiveConfig = parseRouteRenderingDirective(source);
14666
14765
  let ssg = directiveConfig?.ssg ?? false;
14667
- let ppr = directiveConfig?.ppr ?? false;
14766
+ let requestedPPR = directiveConfig?.ppr ?? false;
14668
14767
  let revalidate = directiveConfig?.revalidate;
14669
14768
  const moduleDynamic = normalizeDynamicMode(mod?.dynamic);
14670
14769
  const dynamic = moduleDynamic ?? directiveConfig?.dynamic;
@@ -14674,12 +14773,12 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
14674
14773
  ssg = mod.ssg === true;
14675
14774
  }
14676
14775
  if (hasExplicitPPR) {
14677
- ppr = mod?.ppr === true || mod?.experimental_ppr === true;
14776
+ requestedPPR = mod?.ppr === true || mod?.experimental_ppr === true;
14678
14777
  }
14679
14778
  if (typeof mod?.revalidate === "number") {
14680
14779
  if (mod.revalidate > 0) {
14681
14780
  revalidate = mod.revalidate;
14682
- if (!hasExplicitSsg && !ppr) {
14781
+ if (!hasExplicitSsg && !requestedPPR) {
14683
14782
  ssg = true;
14684
14783
  }
14685
14784
  } else {
@@ -14693,23 +14792,24 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
14693
14792
  }
14694
14793
  if (moduleDynamic === "force-static" || moduleDynamic === "error") {
14695
14794
  ssg = true;
14696
- ppr = false;
14795
+ requestedPPR = false;
14697
14796
  } else if (moduleDynamic === "force-dynamic") {
14698
14797
  ssg = false;
14699
- ppr = false;
14798
+ requestedPPR = false;
14700
14799
  revalidate = void 0;
14701
14800
  }
14801
+ const ppr = pprEnabled && !ssg && requestedPPR;
14702
14802
  return {
14703
14803
  ssg,
14704
- ppr: ssg ? false : ppr,
14804
+ ppr,
14705
14805
  revalidate: ssg || ppr ? revalidate : void 0,
14706
14806
  dynamic,
14707
14807
  directive: directiveConfig?.directive
14708
14808
  };
14709
14809
  }
14710
14810
  __name(resolveConfiguredRouteRenderingConfig, "resolveConfiguredRouteRenderingConfig");
14711
- function resolveRouteRenderingConfig(mod, source) {
14712
- const rendering = resolveConfiguredRouteRenderingConfig(mod, source);
14811
+ function resolveRouteRenderingConfig(mod, source, options) {
14812
+ const rendering = resolveConfiguredRouteRenderingConfig(mod, source, options);
14713
14813
  if (!rendering.ssg || !source) {
14714
14814
  return rendering;
14715
14815
  }
@@ -14724,9 +14824,9 @@ function resolveRouteRenderingConfig(mod, source) {
14724
14824
  };
14725
14825
  }
14726
14826
  __name(resolveRouteRenderingConfig, "resolveRouteRenderingConfig");
14727
- async function resolveRouteRenderingConfigFromFile(mod, filePath) {
14827
+ async function resolveRouteRenderingConfigFromFile(mod, filePath, options) {
14728
14828
  const source = await (0, import_promises2.readFile)(filePath, "utf8").catch(() => void 0);
14729
- return resolveRouteRenderingConfig(mod, source);
14829
+ return resolveRouteRenderingConfig(mod, source, options);
14730
14830
  }
14731
14831
  __name(resolveRouteRenderingConfigFromFile, "resolveRouteRenderingConfigFromFile");
14732
14832
  function analyzeStaticRouteCandidate(mod, source, options = {}) {
@@ -15824,7 +15924,7 @@ function getIslandStrategyExport(content) {
15824
15924
  __name(getIslandStrategyExport, "getIslandStrategyExport");
15825
15925
  function stripUseClientDirective(content) {
15826
15926
  return content.replace(
15827
- /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*)(["'])use client\2\s*;?\s*/,
15927
+ /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/|(?:"[^"\n]*"|'[^'\n]*')\s*;?)*)(["'])use client\2\s*;?\s*/,
15828
15928
  "$1"
15829
15929
  );
15830
15930
  }
@@ -18979,7 +19079,7 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
18979
19079
  return this.resolveMessage(locale, key);
18980
19080
  }
18981
19081
  hasMessage(locale, key) {
18982
- return (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !== void 0;
19082
+ return this.readOwnMessage(locale, key) !== void 0;
18983
19083
  }
18984
19084
  getClientSnapshot(resolution) {
18985
19085
  return {
@@ -19007,8 +19107,19 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
19007
19107
  }
19008
19108
  return formatter.format(values);
19009
19109
  }
19110
+ // Look up a message by own-property only. A key named after an
19111
+ // Object.prototype member (toString, valueOf, constructor, ...) must resolve
19112
+ // to a real catalog entry or undefined, never the inherited prototype value
19113
+ // (mirrors the own-property handling added to catalog.ts in #454).
19114
+ readOwnMessage(locale, key) {
19115
+ const direct = this.catalogs[locale];
19116
+ if (direct && Object.prototype.hasOwnProperty.call(direct, key)) return direct[key];
19117
+ const fallback = this.catalogs[this.config.fallbackLocale];
19118
+ if (fallback && Object.prototype.hasOwnProperty.call(fallback, key)) return fallback[key];
19119
+ return void 0;
19120
+ }
19010
19121
  resolveMessage(locale, key) {
19011
- const message = this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];
19122
+ const message = this.readOwnMessage(locale, key);
19012
19123
  if (message !== void 0) return message;
19013
19124
  if (this.config.strict) {
19014
19125
  throw new Error(`Missing Farm i18n message "${key}" for locale "${locale}".`);
@@ -21357,7 +21468,7 @@ _setFarmThemeServerSnapshotResolver(() => {
21357
21468
  });
21358
21469
 
21359
21470
  // package.json
21360
- var version = "0.1.0-beta.95";
21471
+ var version = "0.1.0-beta.97";
21361
21472
 
21362
21473
  // src/version.ts
21363
21474
  var FARM_VERSION = version;
@@ -22285,7 +22396,8 @@ var _ServerRenderer = class _ServerRenderer {
22285
22396
  }
22286
22397
  const renderingConfig = await resolveRouteRenderingConfigFromFile(
22287
22398
  routeModule,
22288
- route.modulePath
22399
+ route.modulePath,
22400
+ { experimentalPPR: this.config.experimental?.ppr === true }
22289
22401
  );
22290
22402
  const pprBypassReason = renderingConfig.ppr ? this.getPPRShellBypassReason(req, middlewareMap, middlewareContext, pluginExposedContext) : void 0;
22291
22403
  const canCachePPRShell = renderingConfig.ppr && !pprBypassReason;
@@ -22990,6 +23102,11 @@ var _ServerRenderer = class _ServerRenderer {
22990
23102
  );
22991
23103
  res.statusCode = options.statusCode;
22992
23104
  res.setHeader("Content-Type", "text/html; charset=utf-8");
23105
+ res.setHeader("Cache-Control", "private, no-store");
23106
+ res.setHeader("X-Content-Type-Options", "nosniff");
23107
+ if (typeof res.removeHeader === "function") {
23108
+ res.removeHeader("X-Farm-PPR");
23109
+ }
22993
23110
  res.write(this.createFullHTML(html, false, options.pathname));
22994
23111
  res.end();
22995
23112
  return true;
@@ -23727,6 +23844,7 @@ var _FarmApp = class _FarmApp {
23727
23844
  serverComponents: config.experimental?.serverComponents ?? false,
23728
23845
  serverActions: config.experimental?.serverActions ?? false,
23729
23846
  isolatedClientHydration: config.experimental?.isolatedClientHydration ?? "off",
23847
+ ppr: config.experimental?.ppr ?? false,
23730
23848
  ...config.experimental
23731
23849
  },
23732
23850
  vite: config.vite || {}
@@ -24062,6 +24180,53 @@ function isArrayIndex(key) {
24062
24180
  }
24063
24181
  __name(isArrayIndex, "isArrayIndex");
24064
24182
 
24183
+ // src/client-cache-persistence-build.ts
24184
+ var import_node_fs5 = __toESM(require("fs"));
24185
+ var import_node_path10 = __toESM(require("path"));
24186
+ var ADAPTER_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
24187
+ function resolveFarmClientCacheAdapterEntry(root, cache) {
24188
+ const client = cache?.client;
24189
+ const adapter = client?.adapter;
24190
+ if (adapter === void 0) return void 0;
24191
+ if (typeof adapter !== "string" || adapter.trim().length === 0) {
24192
+ throw new Error(
24193
+ 'cache.client.adapter must be a module path string, for example "./src/cache-adapter".'
24194
+ );
24195
+ }
24196
+ const resolved = import_node_path10.default.resolve(root, adapter);
24197
+ const found = resolveAdapterFile(resolved);
24198
+ if (!found) {
24199
+ throw new Error(
24200
+ `cache.client.adapter was not found: ${adapter} (resolved to ${resolved}). Point it at a client module whose default export is created with defineClientCacheAdapter().`
24201
+ );
24202
+ }
24203
+ const options = {};
24204
+ if (client?.version !== void 0) options.version = client.version;
24205
+ if (client?.flushDelayMs !== void 0) options.flushDelayMs = client.flushDelayMs;
24206
+ return { importPath: found.replace(/\\/g, "/"), options };
24207
+ }
24208
+ __name(resolveFarmClientCacheAdapterEntry, "resolveFarmClientCacheAdapterEntry");
24209
+ function resolveAdapterFile(resolved) {
24210
+ if (import_node_fs5.default.existsSync(resolved) && import_node_fs5.default.statSync(resolved).isFile()) return resolved;
24211
+ for (const extension of ADAPTER_EXTENSIONS) {
24212
+ const candidate = `${resolved}.${extension}`;
24213
+ if (import_node_fs5.default.existsSync(candidate) && import_node_fs5.default.statSync(candidate).isFile()) return candidate;
24214
+ }
24215
+ return void 0;
24216
+ }
24217
+ __name(resolveAdapterFile, "resolveAdapterFile");
24218
+ function generateClientCachePersistenceCode(entry) {
24219
+ if (!entry) return { imports: "", init: "" };
24220
+ return {
24221
+ imports: [
24222
+ `import * as __farmClientCacheAdapterModule from ${JSON.stringify(entry.importPath)};`,
24223
+ `import { initConfiguredClientCachePersistence as __farmInitClientCachePersistence } from "@farm.js/core/client";`
24224
+ ].join("\n"),
24225
+ init: `__farmInitClientCachePersistence(__farmClientCacheAdapterModule, ${JSON.stringify(entry.options)});`
24226
+ };
24227
+ }
24228
+ __name(generateClientCachePersistenceCode, "generateClientCachePersistenceCode");
24229
+
24065
24230
  // src/api/endpoint.ts
24066
24231
  var import_better_call = require("better-call");
24067
24232
  init_cache();
@@ -24089,15 +24254,15 @@ function isEndpointFailure(value) {
24089
24254
  }
24090
24255
  __name(isEndpointFailure, "isEndpointFailure");
24091
24256
  function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
24092
- let path34;
24257
+ let path35;
24093
24258
  let options;
24094
24259
  let handler;
24095
24260
  if (typeof pathOrOptions === "string") {
24096
- path34 = pathOrOptions;
24261
+ path35 = pathOrOptions;
24097
24262
  options = optionsOrHandler;
24098
24263
  handler = maybeHandler;
24099
24264
  } else {
24100
- path34 = "";
24265
+ path35 = "";
24101
24266
  options = pathOrOptions;
24102
24267
  handler = optionsOrHandler;
24103
24268
  }
@@ -24124,13 +24289,13 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
24124
24289
  ...betterCallOptions
24125
24290
  } = options;
24126
24291
  const endpoint = (0, import_better_call.createEndpoint)(
24127
- path34 || "/__farm_auto_path__",
24292
+ path35 || "/__farm_auto_path__",
24128
24293
  betterCallOptions,
24129
24294
  wrappedHandler
24130
24295
  );
24131
- endpoint.__path = path34 || void 0;
24296
+ endpoint.__path = path35 || void 0;
24132
24297
  endpoint.__method = options.method || "GET";
24133
- endpoint.__autoPath = !path34;
24298
+ endpoint.__autoPath = !path35;
24134
24299
  endpoint.__handler = wrappedHandler;
24135
24300
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
24136
24301
  endpoint.__middleware = middleware;
@@ -24141,6 +24306,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
24141
24306
  body: options.body,
24142
24307
  inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
24143
24308
  query: options.query,
24309
+ inputQuery: options.query,
24144
24310
  headers: options.headers,
24145
24311
  response: null,
24146
24312
  errors
@@ -24337,10 +24503,10 @@ function createRouteFactoryAt(prefix) {
24337
24503
  "OPTIONS"
24338
24504
  ]) {
24339
24505
  factory[method.toLowerCase()] = (child, options) => {
24340
- const path34 = joinRoutePath(prefix, child);
24506
+ const path35 = joinRoutePath(prefix, child);
24341
24507
  const input = options.input ?? {};
24342
24508
  const endpoint = createEndpoint(
24343
- path34,
24509
+ path35,
24344
24510
  {
24345
24511
  method,
24346
24512
  body: input.body,
@@ -24356,7 +24522,7 @@ function createRouteFactoryAt(prefix) {
24356
24522
  );
24357
24523
  endpoint.__types.params = input.params;
24358
24524
  endpoint.__output = options.output;
24359
- return Object.freeze({ path: path34, method, endpoint });
24525
+ return Object.freeze({ path: path35, method, endpoint });
24360
24526
  };
24361
24527
  }
24362
24528
  return Object.freeze(factory);
@@ -24364,21 +24530,21 @@ function createRouteFactoryAt(prefix) {
24364
24530
  __name(createRouteFactoryAt, "createRouteFactoryAt");
24365
24531
  function joinRoutePath(prefix, child) {
24366
24532
  if (typeof child !== "string") throw new TypeError("Route paths must be strings.");
24367
- const path34 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
24368
- if (!(path34 === "/api" || path34.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path34)) {
24533
+ const path35 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
24534
+ if (!(path35 === "/api" || path35.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path35)) {
24369
24535
  throw new TypeError(
24370
- `Plugin route "${path34}" must be a canonical /api path without a query, hash, or empty segment.`
24536
+ `Plugin route "${path35}" must be a canonical /api path without a query, hash, or empty segment.`
24371
24537
  );
24372
24538
  }
24373
- assertBrowserStableRoutePath(path34);
24374
- assertUniqueRouteParameters(path34, "api");
24375
- getRoutePatternShape(path34, "api");
24376
- for (const segment of path34.split("/")) {
24539
+ assertBrowserStableRoutePath(path35);
24540
+ assertUniqueRouteParameters(path35, "api");
24541
+ getRoutePatternShape(path35, "api");
24542
+ for (const segment of path35.split("/")) {
24377
24543
  if (["__proto__", "constructor", "prototype", "$params"].includes(segment)) {
24378
24544
  throw new TypeError(`Route segment "${segment}" is reserved.`);
24379
24545
  }
24380
24546
  }
24381
- return path34;
24547
+ return path35;
24382
24548
  }
24383
24549
  __name(joinRoutePath, "joinRoutePath");
24384
24550
  function resolvePluginRoutes(plugins = []) {
@@ -24431,7 +24597,7 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
24431
24597
  }
24432
24598
  const result = [...routes.values()];
24433
24599
  if (expected) {
24434
- const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path34, methods }) => `${path34}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
24600
+ const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path35, methods }) => `${path35}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
24435
24601
  if (signature(result) !== signature(expected)) {
24436
24602
  throw new Error(
24437
24603
  "Plugin API routes changed between build and runtime. Route paths and methods must be stable across environments; rebuild the app."
@@ -24443,8 +24609,8 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
24443
24609
  __name(mergePluginAPIRoutes, "mergePluginAPIRoutes");
24444
24610
 
24445
24611
  // src/api/route-manager.ts
24446
- var fs6 = __toESM(require("fs"));
24447
- var path16 = __toESM(require("path"));
24612
+ var fs7 = __toESM(require("fs"));
24613
+ var path17 = __toESM(require("path"));
24448
24614
  init_utils();
24449
24615
  init_routes_shared();
24450
24616
  init_route_runtime();
@@ -24908,9 +25074,9 @@ var _APIRouteManager = class _APIRouteManager {
24908
25074
  this.routeShapes = /* @__PURE__ */ new Map();
24909
25075
  try {
24910
25076
  for (const appDir of this.appDirs) {
24911
- const apiDir = path16.join(appDir, "api");
25077
+ const apiDir = path17.join(appDir, "api");
24912
25078
  let routeFiles = [];
24913
- if (fs6.existsSync(apiDir)) {
25079
+ if (fs7.existsSync(apiDir)) {
24914
25080
  routeFiles = this.findRouteFiles(apiDir);
24915
25081
  }
24916
25082
  for (const filePath of routeFiles) {
@@ -24943,12 +25109,12 @@ var _APIRouteManager = class _APIRouteManager {
24943
25109
  */
24944
25110
  findRouteFiles(dir) {
24945
25111
  const files = [];
24946
- if (!fs6.existsSync(dir)) {
25112
+ if (!fs7.existsSync(dir)) {
24947
25113
  return files;
24948
25114
  }
24949
- const entries = fs6.readdirSync(dir, { withFileTypes: true });
25115
+ const entries = fs7.readdirSync(dir, { withFileTypes: true });
24950
25116
  for (const entry of entries) {
24951
- const fullPath = path16.join(dir, entry.name);
25117
+ const fullPath = path17.join(dir, entry.name);
24952
25118
  if (entry.isDirectory()) {
24953
25119
  files.push(...this.findRouteFiles(fullPath));
24954
25120
  } else if (isFarmAPIRouteFileName(entry.name)) {
@@ -24962,8 +25128,8 @@ var _APIRouteManager = class _APIRouteManager {
24962
25128
  */
24963
25129
  async loadRoute(filePath, appDir) {
24964
25130
  try {
24965
- const apiDir = path16.join(appDir, "api");
24966
- const relativePath2 = path16.relative(apiDir, path16.dirname(filePath));
25131
+ const apiDir = path17.join(appDir, "api");
25132
+ const relativePath2 = path17.relative(apiDir, path17.dirname(filePath));
24967
25133
  const routePath = "/api/" + (relativePath2 === "." ? "" : relativePath2.replace(/\\/g, "/"));
24968
25134
  const routeModule = await this.loadModule(filePath);
24969
25135
  const endpoints = {};
@@ -25036,7 +25202,7 @@ var _APIRouteManager = class _APIRouteManager {
25036
25202
  }
25037
25203
  }
25038
25204
  async loadProgrammaticApiRoutes(appDir) {
25039
- const candidateRoots = [path16.dirname(appDir), appDir];
25205
+ const candidateRoots = [path17.dirname(appDir), appDir];
25040
25206
  const routeFiles = Array.from(
25041
25207
  new Set(candidateRoots.flatMap((srcRoot) => findProgrammaticRouteFilesInDir(srcRoot)))
25042
25208
  );
@@ -25065,16 +25231,16 @@ var _APIRouteManager = class _APIRouteManager {
25065
25231
  }
25066
25232
  findRootRoutesFile(appDir) {
25067
25233
  const routeNames = ["routes.ts", "routes.tsx", "routes.js"];
25068
- const candidateDirs = [path16.dirname(appDir), appDir];
25234
+ const candidateDirs = [path17.dirname(appDir), appDir];
25069
25235
  const seen = /* @__PURE__ */ new Set();
25070
25236
  for (const dir of candidateDirs) {
25071
25237
  for (const routeName of routeNames) {
25072
- const routesFile = path16.join(dir, routeName);
25238
+ const routesFile = path17.join(dir, routeName);
25073
25239
  if (seen.has(routesFile)) {
25074
25240
  continue;
25075
25241
  }
25076
25242
  seen.add(routesFile);
25077
- if (fs6.existsSync(routesFile)) {
25243
+ if (fs7.existsSync(routesFile)) {
25078
25244
  return routesFile;
25079
25245
  }
25080
25246
  }
@@ -25208,8 +25374,8 @@ var APIRouteManager = _APIRouteManager;
25208
25374
  init_config3();
25209
25375
 
25210
25376
  // src/middleware/manager.ts
25211
- var fs7 = __toESM(require("fs"));
25212
- var path17 = __toESM(require("path"));
25377
+ var fs8 = __toESM(require("fs"));
25378
+ var path18 = __toESM(require("path"));
25213
25379
  init_decode();
25214
25380
 
25215
25381
  // src/middleware/cookie-header.ts
@@ -25610,7 +25776,7 @@ var _MiddlewareManager = class _MiddlewareManager {
25610
25776
  * Recursively discover middleware files
25611
25777
  */
25612
25778
  async discoverInDirectory(dir, routePath, discovered) {
25613
- if (!fs7.existsSync(dir)) {
25779
+ if (!fs8.existsSync(dir)) {
25614
25780
  return;
25615
25781
  }
25616
25782
  const middlewareFile = this.findMiddlewareFile(dir);
@@ -25620,10 +25786,10 @@ var _MiddlewareManager = class _MiddlewareManager {
25620
25786
  discovered.push(middleware);
25621
25787
  }
25622
25788
  }
25623
- const entries = fs7.readdirSync(dir, { withFileTypes: true });
25789
+ const entries = fs8.readdirSync(dir, { withFileTypes: true });
25624
25790
  for (const entry of entries) {
25625
25791
  if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
25626
- const subPath = path17.join(dir, entry.name);
25792
+ const subPath = path18.join(dir, entry.name);
25627
25793
  const subRoutePath = appendMiddlewareRoutePath(routePath, entry.name);
25628
25794
  await this.discoverInDirectory(subPath, subRoutePath, discovered);
25629
25795
  }
@@ -25635,8 +25801,8 @@ var _MiddlewareManager = class _MiddlewareManager {
25635
25801
  findMiddlewareFile(dir) {
25636
25802
  const extensions = [".ts", ".tsx", ".js", ".jsx"];
25637
25803
  for (const ext of extensions) {
25638
- const filePath = path17.join(dir, `middleware${ext}`);
25639
- if (fs7.existsSync(filePath)) {
25804
+ const filePath = path18.join(dir, `middleware${ext}`);
25805
+ if (fs8.existsSync(filePath)) {
25640
25806
  return filePath;
25641
25807
  }
25642
25808
  }
@@ -25976,8 +26142,8 @@ var import_path9 = require("path");
25976
26142
  init_type_generator();
25977
26143
 
25978
26144
  // src/routing/generate-route-types.ts
25979
- var path18 = __toESM(require("path"));
25980
- var fs8 = __toESM(require("fs"));
26145
+ var path19 = __toESM(require("path"));
26146
+ var fs9 = __toESM(require("fs"));
25981
26147
  init_utils();
25982
26148
  init_write_file_if_changed();
25983
26149
  init_renderer();
@@ -26030,12 +26196,12 @@ function createRoutePattern(route) {
26030
26196
  __name(createRoutePattern, "createRoutePattern");
26031
26197
  var DEFAULT_OUT_FILE = "farm-routes.d.ts";
26032
26198
  async function generateRouteTypes(options) {
26033
- const root = path18.resolve(options.root);
26199
+ const root = path19.resolve(options.root);
26034
26200
  const srcDir = options.srcDir || "src";
26035
26201
  const outFile = options.outFile || DEFAULT_OUT_FILE;
26036
- const outPath = path18.isAbsolute(outFile) ? outFile : path18.join(root, srcDir, outFile);
26202
+ const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
26037
26203
  const content = await createRouteTypeDeclarations(options, outPath);
26038
- fs8.mkdirSync(path18.dirname(outPath), { recursive: true });
26204
+ fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
26039
26205
  writeFileIfChanged(outPath, content);
26040
26206
  return outPath;
26041
26207
  }
@@ -26050,8 +26216,8 @@ async function createRouteTypeDeclarations(options, outPath) {
26050
26216
  const routeModulePatterns = /* @__PURE__ */ new Set();
26051
26217
  const glob = await import("fast-glob");
26052
26218
  for (const source of sourceRoots) {
26053
- const appDir = path18.join(source.root, source.srcDir, "app");
26054
- if (fs8.existsSync(appDir)) {
26219
+ const appDir = path19.join(source.root, source.srcDir, "app");
26220
+ if (fs9.existsSync(appDir)) {
26055
26221
  const routeModuleFiles = await glob.default(
26056
26222
  `**/{page,layout,loading,error}.{${componentExtensions.join(",")},md,mdx}`,
26057
26223
  {
@@ -26087,7 +26253,7 @@ async function createRouteTypeDeclarations(options, outPath) {
26087
26253
  const routePathType = suppressLintOnLink ? "string" : renderTypeUnion(typeLiterals);
26088
26254
  const routePatternType = suppressLintOnLink ? "string" : renderTypeUnion(patternLiterals);
26089
26255
  const routeModulePatternType = renderTypeUnion(routeModulePatternLiterals);
26090
- const routeTypesImportPath = `./${path18.basename(outPath).replace(/\.d\.ts$/, "")}`;
26256
+ const routeTypesImportPath = `./${path19.basename(outPath).replace(/\.d\.ts$/, "")}`;
26091
26257
  const linkAugmentationBlock = suppressLintOnLink ? "" : `
26092
26258
  declare module "@farm.js/core/client" {
26093
26259
  interface LinkDefaultRoute {
@@ -26137,8 +26303,8 @@ ${renderTypeAlias("RouteModulePattern", routeModulePatternType)}${linkAugmentati
26137
26303
  __name(createRouteTypeDeclarations, "createRouteTypeDeclarations");
26138
26304
 
26139
26305
  // src/env-types.ts
26140
- var fs9 = __toESM(require("fs"));
26141
- var path19 = __toESM(require("path"));
26306
+ var fs10 = __toESM(require("fs"));
26307
+ var path20 = __toESM(require("path"));
26142
26308
  init_write_file_if_changed();
26143
26309
  var DEFAULT_OUT_FILE2 = "farm-env.d.ts";
26144
26310
  var CONFIG_FILENAMES = [
@@ -26160,21 +26326,21 @@ var CONFIG_FILENAMES = [
26160
26326
  "config.cjs"
26161
26327
  ];
26162
26328
  async function generateEnvTypes(options) {
26163
- const root = path19.resolve(options.root);
26329
+ const root = path20.resolve(options.root);
26164
26330
  const srcDir = options.srcDir || "src";
26165
26331
  const outFile = options.outFile || DEFAULT_OUT_FILE2;
26166
- const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
26332
+ const outPath = path20.isAbsolute(outFile) ? outFile : path20.join(root, srcDir, outFile);
26167
26333
  const content = createEnvTypeDeclarations(options, outPath);
26168
- fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
26334
+ fs10.mkdirSync(path20.dirname(outPath), { recursive: true });
26169
26335
  writeFileIfChanged(outPath, content);
26170
26336
  return outPath;
26171
26337
  }
26172
26338
  __name(generateEnvTypes, "generateEnvTypes");
26173
26339
  function createEnvTypeDeclarations(options, outPath) {
26174
- const root = path19.resolve(options.root);
26340
+ const root = path20.resolve(options.root);
26175
26341
  const configPath = findConfigPath(root, options.configPath);
26176
26342
  const configPaths = [
26177
- ...(options.layerConfigPaths ?? []).filter((value) => fs9.existsSync(value)),
26343
+ ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
26178
26344
  ...configPath ? [configPath] : []
26179
26345
  ];
26180
26346
  const content = configPaths.length > 1 ? createLayeredConfigBackedEnvTypes(outPath, configPaths) : configPaths.length === 1 ? createConfigBackedEnvTypes(outPath, configPaths[0]) : createEmptyEnvTypes();
@@ -26236,12 +26402,12 @@ export {};
26236
26402
  __name(createLayeredConfigBackedEnvTypes, "createLayeredConfigBackedEnvTypes");
26237
26403
  function findConfigPath(root, configPath) {
26238
26404
  if (configPath) {
26239
- const resolvedPath = path19.isAbsolute(configPath) ? configPath : path19.join(root, configPath);
26240
- return fs9.existsSync(resolvedPath) ? resolvedPath : null;
26405
+ const resolvedPath = path20.isAbsolute(configPath) ? configPath : path20.join(root, configPath);
26406
+ return fs10.existsSync(resolvedPath) ? resolvedPath : null;
26241
26407
  }
26242
26408
  for (const filename of CONFIG_FILENAMES) {
26243
- const resolvedPath = path19.join(root, filename);
26244
- if (fs9.existsSync(resolvedPath)) {
26409
+ const resolvedPath = path20.join(root, filename);
26410
+ if (fs10.existsSync(resolvedPath)) {
26245
26411
  return resolvedPath;
26246
26412
  }
26247
26413
  }
@@ -26304,19 +26470,19 @@ export {};
26304
26470
  }
26305
26471
  __name(createEmptyEnvTypes, "createEmptyEnvTypes");
26306
26472
  function toTypeImportPath(outPath, targetPath) {
26307
- const relativePath2 = path19.relative(path19.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26473
+ const relativePath2 = path20.relative(path20.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26308
26474
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
26309
26475
  }
26310
26476
  __name(toTypeImportPath, "toTypeImportPath");
26311
26477
 
26312
26478
  // src/image-types.ts
26313
- var import_node_fs6 = require("fs");
26314
- var import_node_path10 = __toESM(require("path"));
26479
+ var import_node_fs7 = require("fs");
26480
+ var import_node_path11 = __toESM(require("path"));
26315
26481
  init_write_file_if_changed();
26316
26482
  var FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
26317
26483
  function generateFarmImageTypes(options) {
26318
- const outputPath = options.outFile ? import_node_path10.default.resolve(options.root, options.outFile) : import_node_path10.default.join(options.root, options.srcDir || "src", "farm-images.d.ts");
26319
- (0, import_node_fs6.mkdirSync)(import_node_path10.default.dirname(outputPath), { recursive: true });
26484
+ const outputPath = options.outFile ? import_node_path11.default.resolve(options.root, options.outFile) : import_node_path11.default.join(options.root, options.srcDir || "src", "farm-images.d.ts");
26485
+ (0, import_node_fs7.mkdirSync)(import_node_path11.default.dirname(outputPath), { recursive: true });
26320
26486
  writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
26321
26487
  return outputPath;
26322
26488
  }
@@ -26344,8 +26510,8 @@ declare module "*?url" {
26344
26510
  __name(createFarmImageTypeDeclarations, "createFarmImageTypeDeclarations");
26345
26511
 
26346
26512
  // src/content-types.ts
26347
- var fs10 = __toESM(require("fs"));
26348
- var path21 = __toESM(require("path"));
26513
+ var fs11 = __toESM(require("fs"));
26514
+ var path22 = __toESM(require("path"));
26349
26515
  var CONFIG_FILENAMES2 = [
26350
26516
  "farm.config.ts",
26351
26517
  "farm.config.tsx",
@@ -26365,10 +26531,10 @@ var CONFIG_FILENAMES2 = [
26365
26531
  "config.cjs"
26366
26532
  ];
26367
26533
  function createContentTypeDeclarations(options, outPath) {
26368
- const root = path21.resolve(options.root);
26534
+ const root = path22.resolve(options.root);
26369
26535
  const projectConfig = findConfigPath2(root, options.configPath);
26370
26536
  const configPaths = [
26371
- ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
26537
+ ...(options.layerConfigPaths ?? []).filter((value) => fs11.existsSync(value)),
26372
26538
  ...projectConfig ? [projectConfig] : []
26373
26539
  ];
26374
26540
  if (configPaths.length === 0) return createEmptyContentTypes();
@@ -26438,32 +26604,32 @@ export {};
26438
26604
  __name(createEmptyContentTypes, "createEmptyContentTypes");
26439
26605
  function findConfigPath2(root, configPath) {
26440
26606
  if (configPath) {
26441
- const resolvedPath = path21.isAbsolute(configPath) ? configPath : path21.join(root, configPath);
26442
- return fs10.existsSync(resolvedPath) ? resolvedPath : null;
26607
+ const resolvedPath = path22.isAbsolute(configPath) ? configPath : path22.join(root, configPath);
26608
+ return fs11.existsSync(resolvedPath) ? resolvedPath : null;
26443
26609
  }
26444
26610
  for (const filename of CONFIG_FILENAMES2) {
26445
- const resolvedPath = path21.join(root, filename);
26446
- if (fs10.existsSync(resolvedPath)) return resolvedPath;
26611
+ const resolvedPath = path22.join(root, filename);
26612
+ if (fs11.existsSync(resolvedPath)) return resolvedPath;
26447
26613
  }
26448
26614
  return null;
26449
26615
  }
26450
26616
  __name(findConfigPath2, "findConfigPath");
26451
26617
  function toTypeImportPath2(outPath, targetPath) {
26452
- const relativePath2 = path21.relative(path21.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26618
+ const relativePath2 = path22.relative(path22.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26453
26619
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
26454
26620
  }
26455
26621
  __name(toTypeImportPath2, "toTypeImportPath");
26456
26622
 
26457
26623
  // src/i18n/type-generator.ts
26458
- var import_node_fs7 = require("fs");
26459
- var import_node_path11 = require("path");
26624
+ var import_node_fs8 = require("fs");
26625
+ var import_node_path12 = require("path");
26460
26626
  init_write_file_if_changed();
26461
26627
  async function generateFarmI18nTypes(options) {
26462
26628
  if (!options.config.enabled) return void 0;
26463
26629
  const { signatures } = await readFarmI18nCatalogs(options.config);
26464
- const outFile = options.outFile ? (0, import_node_path11.resolve)(options.root, options.outFile) : (0, import_node_path11.join)((0, import_node_path11.resolve)(options.root), options.srcDir || "src", "farm-i18n.d.ts");
26630
+ const outFile = options.outFile ? (0, import_node_path12.resolve)(options.root, options.outFile) : (0, import_node_path12.join)((0, import_node_path12.resolve)(options.root), options.srcDir || "src", "farm-i18n.d.ts");
26465
26631
  const content = renderFarmI18nTypes(options.config.locales, signatures);
26466
- (0, import_node_fs7.mkdirSync)((0, import_node_path11.dirname)(outFile), { recursive: true });
26632
+ (0, import_node_fs8.mkdirSync)((0, import_node_path12.dirname)(outFile), { recursive: true });
26467
26633
  writeFileIfChanged(outFile, content);
26468
26634
  return outFile;
26469
26635
  }
@@ -26756,8 +26922,8 @@ init_integrations();
26756
26922
  init_route_context();
26757
26923
  init_devtools_config();
26758
26924
  init_dev_indicators();
26759
- var fs12 = __toESM(require("fs"));
26760
- var path33 = __toESM(require("path"));
26925
+ var fs13 = __toESM(require("fs"));
26926
+ var path34 = __toESM(require("path"));
26761
26927
  var import_node_url8 = require("url");
26762
26928
  init_layers();
26763
26929
 
@@ -26883,8 +27049,8 @@ function _runWithAPIRequestRuntime(runtime, run) {
26883
27049
  __name(_runWithAPIRequestRuntime, "_runWithAPIRequestRuntime");
26884
27050
 
26885
27051
  // src/dev-static.ts
26886
- var fs11 = __toESM(require("fs"));
26887
- var path22 = __toESM(require("path"));
27052
+ var fs12 = __toESM(require("fs"));
27053
+ var path23 = __toESM(require("path"));
26888
27054
  function shouldBypassFarmRouterForDottedPath(pathname, routeManager, baseDirs) {
26889
27055
  if (!pathname.includes(".") || pathname.endsWith(".html")) return false;
26890
27056
  const matchesAppRoute = Boolean(
@@ -26904,11 +27070,11 @@ function devServableFileExists(pathname, baseDirs) {
26904
27070
  if (!relativePathname) return false;
26905
27071
  for (const baseDir of baseDirs) {
26906
27072
  if (typeof baseDir !== "string" || baseDir.length === 0) continue;
26907
- const resolvedBase = path22.resolve(baseDir);
26908
- const candidate = path22.resolve(resolvedBase, relativePathname);
26909
- if (!candidate.startsWith(resolvedBase + path22.sep)) continue;
27073
+ const resolvedBase = path23.resolve(baseDir);
27074
+ const candidate = path23.resolve(resolvedBase, relativePathname);
27075
+ if (!candidate.startsWith(resolvedBase + path23.sep)) continue;
26910
27076
  try {
26911
- if (fs11.existsSync(candidate) && fs11.statSync(candidate).isFile()) {
27077
+ if (fs12.existsSync(candidate) && fs12.statSync(candidate).isFile()) {
26912
27078
  return true;
26913
27079
  }
26914
27080
  } catch {
@@ -26923,6 +27089,7 @@ var SERVER_FN_FACTORIES = ["createServerQuery", "createServerFn"];
26923
27089
  var FARM_CORE_IMPORT_RE = /import\s*(?!type\b)(?:[\w$]+\s*,\s*)?\{([^}]*)\}\s*from\s*(["'])@farm\.js\/core(?:\/[\w./-]+)?\2/g;
26924
27090
  function findClientServerFnViolation(code, id) {
26925
27091
  if (id.startsWith("\0") || id.startsWith("virtual:") || id.includes("node_modules")) return null;
27092
+ if (/\.(md|mdx)(\?|$)/.test(id)) return null;
26926
27093
  if (!code.includes("@farm.js/core")) return null;
26927
27094
  for (const match of code.matchAll(FARM_CORE_IMPORT_RE)) {
26928
27095
  const specifiers = match[1];
@@ -26952,7 +27119,7 @@ init_image_config();
26952
27119
 
26953
27120
  // src/image-vite.ts
26954
27121
  var import_promises7 = require("fs/promises");
26955
- var import_node_path12 = __toESM(require("path"));
27122
+ var import_node_path13 = __toESM(require("path"));
26956
27123
  var import_image_size2 = require("image-size");
26957
27124
  var FARM_IMAGE_ID_PREFIX = "\0farm:image:";
26958
27125
  var STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
@@ -27035,7 +27202,7 @@ init_image_server();
27035
27202
  init_routing();
27036
27203
 
27037
27204
  // src/server/vite-config.ts
27038
- var import_node_path13 = __toESM(require("path"));
27205
+ var import_node_path14 = __toESM(require("path"));
27039
27206
 
27040
27207
  // src/vite.ts
27041
27208
  init_fonts();
@@ -27050,7 +27217,7 @@ init_observability();
27050
27217
  init_renderer();
27051
27218
 
27052
27219
  // src/integration-provider-build.ts
27053
- var import_node_path15 = __toESM(require("path"));
27220
+ var import_node_path16 = __toESM(require("path"));
27054
27221
  init_integrations();
27055
27222
  init_utils();
27056
27223
  function generateFarmIntegrationProviderClientCode(providers, root) {
@@ -27107,7 +27274,7 @@ function wrapWithIntegrationProviders(element) {
27107
27274
  __name(generateFarmIntegrationProviderClientCode, "generateFarmIntegrationProviderClientCode");
27108
27275
  function resolveProviderModule(moduleId, root) {
27109
27276
  if (!moduleId.startsWith(".")) return moduleId;
27110
- return toViteModuleId(import_node_path15.default.resolve(root, moduleId), root);
27277
+ return toViteModuleId(import_node_path16.default.resolve(root, moduleId), root);
27111
27278
  }
27112
27279
  __name(resolveProviderModule, "resolveProviderModule");
27113
27280
 
@@ -27174,6 +27341,7 @@ var createEmptyTypeArtifactSelection = /* @__PURE__ */ __name(() => ({
27174
27341
  images: false,
27175
27342
  i18n: false
27176
27343
  }), "createEmptyTypeArtifactSelection");
27344
+ var warnedDeprecatedDevtoolsDashboard = false;
27177
27345
  var EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME = `
27178
27346
  function isFarmDocsSearchPage() {
27179
27347
  return false;
@@ -27575,11 +27743,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
27575
27743
  }
27576
27744
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
27577
27745
  function fileContainsProgrammaticPageRoute(file) {
27578
- if (!fs12.existsSync(file)) {
27746
+ if (!fs13.existsSync(file)) {
27579
27747
  return false;
27580
27748
  }
27581
27749
  try {
27582
- return scanProgrammaticPagePaths(fs12.readFileSync(file, "utf8")).length > 0;
27750
+ return scanProgrammaticPagePaths(fs13.readFileSync(file, "utf8")).length > 0;
27583
27751
  } catch {
27584
27752
  return false;
27585
27753
  }
@@ -27587,7 +27755,7 @@ function fileContainsProgrammaticPageRoute(file) {
27587
27755
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
27588
27756
  function rewriteEarlySsrRelativeImports(options) {
27589
27757
  const cleanId = options.id.split("?", 1)[0];
27590
- if (!path33.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
27758
+ if (!path34.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
27591
27759
  return null;
27592
27760
  }
27593
27761
  const replacements = [];
@@ -27607,7 +27775,7 @@ function rewriteEarlySsrRelativeImports(options) {
27607
27775
  const suffixIndex = source.value.search(/[?#]/);
27608
27776
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
27609
27777
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
27610
- const resolvedPath = path33.resolve(path33.dirname(cleanId), sourcePath);
27778
+ const resolvedPath = path34.resolve(path34.dirname(cleanId), sourcePath);
27611
27779
  replacements.push({
27612
27780
  start: source.start,
27613
27781
  end: source.end,
@@ -27769,7 +27937,7 @@ function farmPlugin(options = {}, initialPluginManager) {
27769
27937
  ...layerRoots.length ? {
27770
27938
  server: {
27771
27939
  fs: {
27772
- allow: [path33.resolve(options.root || process.cwd()), ...layerRoots]
27940
+ allow: [path34.resolve(options.root || process.cwd()), ...layerRoots]
27773
27941
  }
27774
27942
  }
27775
27943
  } : {}
@@ -27800,13 +27968,13 @@ function farmPlugin(options = {}, initialPluginManager) {
27800
27968
  },
27801
27969
  server
27802
27970
  );
27803
- const globalsCSSPath = path33.join(server.config.root, "src/app/globals.css");
27804
- if (!fs12.existsSync(globalsCSSPath)) {
27805
- const appDir = path33.join(server.config.root, "src/app");
27806
- if (!fs12.existsSync(appDir)) {
27807
- fs12.mkdirSync(appDir, { recursive: true });
27971
+ const globalsCSSPath = path34.join(server.config.root, "src/app/globals.css");
27972
+ if (!fs13.existsSync(globalsCSSPath)) {
27973
+ const appDir = path34.join(server.config.root, "src/app");
27974
+ if (!fs13.existsSync(appDir)) {
27975
+ fs13.mkdirSync(appDir, { recursive: true });
27808
27976
  }
27809
- fs12.writeFileSync(globalsCSSPath, defaultGlobalCSS);
27977
+ fs13.writeFileSync(globalsCSSPath, defaultGlobalCSS);
27810
27978
  }
27811
27979
  await farmApp.initialize();
27812
27980
  const farmConfig = farmApp.getConfig();
@@ -27827,10 +27995,10 @@ function farmPlugin(options = {}, initialPluginManager) {
27827
27995
  });
27828
27996
  }
27829
27997
  const sourceRoots = getFarmSourceRoots(farmConfig);
27830
- server.watcher.add(sourceRoots.map((source) => path33.join(source.root, source.srcDir)));
27998
+ server.watcher.add(sourceRoots.map((source) => path34.join(source.root, source.srcDir)));
27831
27999
  if (farmConfig.i18n.enabled) {
27832
28000
  server.watcher.add(
27833
- farmConfig.i18n.messages.includes("{locale}") ? path33.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
28001
+ farmConfig.i18n.messages.includes("{locale}") ? path34.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
27834
28002
  );
27835
28003
  }
27836
28004
  const workflowConfig = farmConfig.workflows;
@@ -27840,7 +28008,7 @@ function farmPlugin(options = {}, initialPluginManager) {
27840
28008
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
27841
28009
  ], "getExtraRouteTypes");
27842
28010
  const appDirSlugs = sourceRoots.map(
27843
- (source) => path33.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
28011
+ (source) => path34.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
27844
28012
  );
27845
28013
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
27846
28014
  try {
@@ -27881,7 +28049,7 @@ function farmPlugin(options = {}, initialPluginManager) {
27881
28049
  }, "generateTypeArtifacts");
27882
28050
  await generateTypeArtifacts("startup");
27883
28051
  const srcDirSlugs = sourceRoots.map(
27884
- (source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")
28052
+ (source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")
27885
28053
  );
27886
28054
  const layerConfigFiles = new Set(
27887
28055
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -28002,7 +28170,7 @@ function farmPlugin(options = {}, initialPluginManager) {
28002
28170
  await apiRouteManager.discoverRoutes();
28003
28171
  let discoveredWorkflows = [];
28004
28172
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
28005
- (dir) => fs12.existsSync(path33.isAbsolute(dir) ? dir : path33.join(farmConfig.root, dir))
28173
+ (dir) => fs13.existsSync(path34.isAbsolute(dir) ? dir : path34.join(farmConfig.root, dir))
28006
28174
  );
28007
28175
  if (hasWorkflowDirectory) {
28008
28176
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -28267,12 +28435,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
28267
28435
  }
28268
28436
  }
28269
28437
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
28270
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs12.existsSync(farmDocsFontPath)) {
28438
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs13.existsSync(farmDocsFontPath)) {
28271
28439
  res.statusCode = 200;
28272
28440
  res.setHeader("Content-Type", "font/woff2");
28273
28441
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
28274
28442
  if (requestMethod === "HEAD") res.end();
28275
- else fs12.createReadStream(farmDocsFontPath).pipe(res);
28443
+ else fs13.createReadStream(farmDocsFontPath).pipe(res);
28276
28444
  return;
28277
28445
  }
28278
28446
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -28328,6 +28496,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
28328
28496
  if (requestPathname.endsWith(".json")) {
28329
28497
  res.end(JSON.stringify(snapshot, null, 2));
28330
28498
  } else {
28499
+ if (!warnedDeprecatedDevtoolsDashboard) {
28500
+ warnedDeprecatedDevtoolsDashboard = true;
28501
+ logger.warn(
28502
+ "The built-in DevTools dashboard is deprecated. Install @farm.js/devtools and add devtools() to plugins in farm.config.ts."
28503
+ );
28504
+ }
28331
28505
  const { renderFarmDevtoolsHtml: renderFarmDevtoolsHtml2 } = await loadFarmDevtoolsUIRuntime();
28332
28506
  res.end(renderFarmDevtoolsHtml2(snapshot));
28333
28507
  }
@@ -28370,7 +28544,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
28370
28544
  return null;
28371
28545
  }
28372
28546
  return {
28373
- source: await fs12.promises.readFile(sourcePath, "utf8"),
28547
+ source: await fs13.promises.readFile(sourcePath, "utf8"),
28374
28548
  filePath: sourcePath
28375
28549
  };
28376
28550
  }, "resolveSource")
@@ -29254,7 +29428,10 @@ ${generatedDevIndicatorsClientRuntime}`,
29254
29428
  renderer,
29255
29429
  isolatedHydrationMode === "enabled",
29256
29430
  resolvedConfig?.trailingSlash ?? false,
29257
- resolvedConfig?.basePath ?? "/"
29431
+ resolvedConfig?.basePath ?? "/",
29432
+ generateClientCachePersistenceCode(
29433
+ resolveFarmClientCacheAdapterEntry(root, resolvedConfig?.cache)
29434
+ )
29258
29435
  );
29259
29436
  }
29260
29437
  if (id === "/@farm/server") {
@@ -29393,7 +29570,7 @@ export const manifest = getManifest();
29393
29570
  const root = currentConfig.root || server?.config.root || process.cwd();
29394
29571
  const cleanId = id.split("?", 1)[0];
29395
29572
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
29396
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path33.resolve(cleanId)) === true;
29573
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path34.resolve(cleanId)) === true;
29397
29574
  if (isolatedHydrationEnabled && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
29398
29575
  isolatedModuleReference = toViteModuleId(cleanId, root);
29399
29576
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -29484,8 +29661,8 @@ if (import.meta.hot) {
29484
29661
  }
29485
29662
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
29486
29663
  logger.info("Pre-rendering SSG pages...");
29487
- const outDir = path33.join(server?.config.root || process.cwd(), options.outDir || "dist");
29488
- const clientDir = path33.join(outDir, "client");
29664
+ const outDir = path34.join(server?.config.root || process.cwd(), options.outDir || "dist");
29665
+ const clientDir = path34.join(outDir, "client");
29489
29666
  for (const page2 of ssgPages) {
29490
29667
  try {
29491
29668
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -29537,9 +29714,9 @@ if (import.meta.hot) {
29537
29714
  <script type="module" src="/assets/client.js"></script>
29538
29715
  </body>
29539
29716
  </html>`;
29540
- const outputPath = page2.urlPath === "/" ? path33.join(clientDir, "index.html") : path33.join(clientDir, page2.urlPath + ".html");
29541
- fs12.mkdirSync(path33.dirname(outputPath), { recursive: true });
29542
- fs12.writeFileSync(outputPath, fullHtml);
29717
+ const outputPath = page2.urlPath === "/" ? path34.join(clientDir, "index.html") : path34.join(clientDir, page2.urlPath + ".html");
29718
+ fs13.mkdirSync(path34.dirname(outputPath), { recursive: true });
29719
+ fs13.writeFileSync(outputPath, fullHtml);
29543
29720
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
29544
29721
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
29545
29722
  });
@@ -29547,8 +29724,8 @@ if (import.meta.hot) {
29547
29724
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
29548
29725
  }
29549
29726
  }
29550
- const manifestPath = path33.join(outDir, "__ssg_manifest.json");
29551
- fs12.writeFileSync(
29727
+ const manifestPath = path34.join(outDir, "__ssg_manifest.json");
29728
+ fs13.writeFileSync(
29552
29729
  manifestPath,
29553
29730
  JSON.stringify(
29554
29731
  ssgPages.map((p) => ({
@@ -29591,9 +29768,9 @@ if (import.meta.hot) {
29591
29768
  server2.ws.send({ type: "full-reload", path: "*" });
29592
29769
  return [];
29593
29770
  }
29594
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
29771
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
29595
29772
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
29596
- logUpdate("PAGE", `updated ${path33.basename(file)}`);
29773
+ logUpdate("PAGE", `updated ${path34.basename(file)}`);
29597
29774
  for (const mod of modules) {
29598
29775
  server2.moduleGraph.invalidateModule(mod);
29599
29776
  }
@@ -30016,7 +30193,7 @@ function parseRouteModuleSchema2(schema, value, label, routePath) {
30016
30193
  }
30017
30194
  }
30018
30195
  __name(parseRouteModuleSchema2, "parseRouteModuleSchema");
30019
- 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 = "/") {
30196
+ 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: "" }) {
30020
30197
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
30021
30198
  const clientPluginEntry = generateFarmClientPluginEntryCode(
30022
30199
  plugins,
@@ -30072,6 +30249,7 @@ import {
30072
30249
  } from '@farm.js/core/deployment'
30073
30250
  ${providerClientCode.imports}
30074
30251
  ${clientPluginEntry.imports}
30252
+ ${clientCachePersistence.imports}
30075
30253
  ${docsSearchClientRuntime}
30076
30254
  ${devtoolsClientRuntime}
30077
30255
  ${docsAdapterImportBlock}
@@ -30087,6 +30265,7 @@ const integrationDocumentNavigationMatchers = ${JSON.stringify(documentNavigatio
30087
30265
  setFarmBasePath(${JSON.stringify(basePath)});
30088
30266
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
30089
30267
  installChunkErrorRecovery();
30268
+ ${clientCachePersistence.init}
30090
30269
 
30091
30270
  let reactRoot = null;
30092
30271
  ${isolatedHydrationRuntime}