@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/vite.cjs CHANGED
@@ -688,11 +688,11 @@ function resolveFarmServerHealthConfig(config) {
688
688
  return Object.freeze({ enabled: true, livenessPath, readinessPath });
689
689
  }
690
690
  function normalizeHealthPath(value, optionName) {
691
- const path34 = value.trim();
692
- if (!path34.startsWith("/") || path34.includes("?") || path34.includes("#") || path34.includes("*")) {
691
+ const path35 = value.trim();
692
+ if (!path35.startsWith("/") || path35.includes("?") || path35.includes("#") || path35.includes("*")) {
693
693
  throw new TypeError(`${optionName} must be an absolute pathname without a query or wildcard`);
694
694
  }
695
- const normalized = path34.length > 1 ? path34.replace(/\/+$/, "") || "/" : path34;
695
+ const normalized = path35.length > 1 ? path35.replace(/\/+$/, "") || "/" : path35;
696
696
  assertBrowserStableRoutePath(normalized);
697
697
  return normalized;
698
698
  }
@@ -1073,8 +1073,8 @@ function toViteModuleId(filePath, root) {
1073
1073
  }
1074
1074
  async function fileExists(filePath) {
1075
1075
  try {
1076
- const fs13 = await import("fs/promises");
1077
- await fs13.access(filePath);
1076
+ const fs14 = await import("fs/promises");
1077
+ await fs14.access(filePath);
1078
1078
  return true;
1079
1079
  } catch {
1080
1080
  return false;
@@ -1471,35 +1471,35 @@ async function prepareFarmWorkflowsForNitro(config) {
1471
1471
  const workflowConfig = isResolvedWorkflowConfig(config.workflows) ? config.workflows : resolveWorkflowsConfig(config.workflows);
1472
1472
  const root = config.root || process.cwd();
1473
1473
  const distDir = config.distDir || ".farm";
1474
- const fs13 = await import("fs/promises");
1475
- const path34 = await import("path");
1476
- const generatedDir = path34.join(root, distDir, ".nitro", "farm-workflows");
1474
+ const fs14 = await import("fs/promises");
1475
+ const path35 = await import("path");
1476
+ const generatedDir = path35.join(root, distDir, ".nitro", "farm-workflows");
1477
1477
  const workflows = await discoverFarmWorkflows({
1478
1478
  root,
1479
1479
  workflows: workflowConfig
1480
1480
  });
1481
1481
  if (workflows.length === 0) {
1482
- await fs13.rm(generatedDir, { recursive: true, force: true });
1482
+ await fs14.rm(generatedDir, { recursive: true, force: true });
1483
1483
  return {
1484
1484
  workflows,
1485
1485
  tasks: {},
1486
1486
  scheduledTasks: {}
1487
1487
  };
1488
1488
  }
1489
- await fs13.rm(generatedDir, { recursive: true, force: true });
1490
- await fs13.mkdir(generatedDir, { recursive: true });
1489
+ await fs14.rm(generatedDir, { recursive: true, force: true });
1490
+ await fs14.mkdir(generatedDir, { recursive: true });
1491
1491
  const tasks = {};
1492
1492
  const scheduledTasks = createScheduledTasks(workflows);
1493
1493
  for (const workflow of workflows) {
1494
- const wrapperPath = toPosixPath(path34.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
1495
- await fs13.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1494
+ const wrapperPath = toPosixPath(path35.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
1495
+ await fs14.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1496
1496
  tasks[workflow.id] = {
1497
1497
  handler: wrapperPath,
1498
1498
  description: workflow.description || `Farm workflow ${workflow.id}`
1499
1499
  };
1500
1500
  }
1501
- const handlerPath = toPosixPath(path34.join(generatedDir, "http-handler.mjs"));
1502
- await fs13.writeFile(
1501
+ const handlerPath = toPosixPath(path35.join(generatedDir, "http-handler.mjs"));
1502
+ await fs14.writeFile(
1503
1503
  handlerPath,
1504
1504
  createNitroWorkflowHTTPHandler(
1505
1505
  workflowConfig,
@@ -1508,8 +1508,8 @@ async function prepareFarmWorkflowsForNitro(config) {
1508
1508
  ),
1509
1509
  "utf8"
1510
1510
  );
1511
- const manifestPath = path34.join(generatedDir, "manifest.json");
1512
- await fs13.writeFile(
1511
+ const manifestPath = path35.join(generatedDir, "manifest.json");
1512
+ await fs14.writeFile(
1513
1513
  manifestPath,
1514
1514
  JSON.stringify(
1515
1515
  {
@@ -1597,21 +1597,21 @@ function resolveWorkflowDefinition(module2) {
1597
1597
  return null;
1598
1598
  }
1599
1599
  async function findWorkflowFiles(root, dirs) {
1600
- const path34 = await import("path");
1600
+ const path35 = await import("path");
1601
1601
  const files = [];
1602
1602
  for (const dir of dirs) {
1603
- const absoluteDir = path34.isAbsolute(dir) ? dir : path34.join(root, dir);
1603
+ const absoluteDir = path35.isAbsolute(dir) ? dir : path35.join(root, dir);
1604
1604
  if (!await pathExists(absoluteDir)) continue;
1605
1605
  await walkWorkflowDir(absoluteDir, files);
1606
1606
  }
1607
1607
  return files.sort();
1608
1608
  }
1609
1609
  async function walkWorkflowDir(dir, files) {
1610
- const fs13 = await import("fs/promises");
1611
- const path34 = await import("path");
1612
- const entries = await fs13.readdir(dir, { withFileTypes: true });
1610
+ const fs14 = await import("fs/promises");
1611
+ const path35 = await import("path");
1612
+ const entries = await fs14.readdir(dir, { withFileTypes: true });
1613
1613
  for (const entry of entries) {
1614
- const filePath = path34.join(dir, entry.name);
1614
+ const filePath = path35.join(dir, entry.name);
1615
1615
  if (entry.isDirectory()) {
1616
1616
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
1617
1617
  await walkWorkflowDir(filePath, files);
@@ -1623,20 +1623,20 @@ async function walkWorkflowDir(dir, files) {
1623
1623
  }
1624
1624
  }
1625
1625
  async function pathExists(filePath) {
1626
- const fs13 = await import("fs/promises");
1627
- return fs13.access(filePath).then(() => true).catch(() => false);
1626
+ const fs14 = await import("fs/promises");
1627
+ return fs14.access(filePath).then(() => true).catch(() => false);
1628
1628
  }
1629
1629
  function isWorkflowFile(fileName) {
1630
1630
  return /\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName);
1631
1631
  }
1632
1632
  async function loadWorkflowModule(filePath, root) {
1633
- const fs13 = await import("fs/promises");
1634
- const path34 = await import("path");
1633
+ const fs14 = await import("fs/promises");
1634
+ const path35 = await import("path");
1635
1635
  const { pathToFileURL: pathToFileURL9 } = await import("url");
1636
1636
  const { build } = await import("esbuild");
1637
- const outDir = path34.join(root, ".farm", ".workflow-loader");
1638
- await fs13.mkdir(outDir, { recursive: true });
1639
- const outfile = path34.join(
1637
+ const outDir = path35.join(root, ".farm", ".workflow-loader");
1638
+ await fs14.mkdir(outDir, { recursive: true });
1639
+ const outfile = path35.join(
1640
1640
  outDir,
1641
1641
  `workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
1642
1642
  );
@@ -1660,7 +1660,7 @@ async function loadWorkflowModule(filePath, root) {
1660
1660
  `${pathToFileURL9(outfile).href}?t=${Date.now()}`
1661
1661
  );
1662
1662
  } finally {
1663
- await fs13.unlink(outfile).catch(() => void 0);
1663
+ await fs14.unlink(outfile).catch(() => void 0);
1664
1664
  }
1665
1665
  }
1666
1666
  function workflowIdFromFile(root, dirs, filePath) {
@@ -1955,7 +1955,7 @@ function normalizeCronJob(name2, job) {
1955
1955
  if (!job || typeof job !== "object" || Array.isArray(job)) {
1956
1956
  throw new TypeError(`Farm cron ${JSON.stringify(name2)} must be a configuration object.`);
1957
1957
  }
1958
- const path34 = normalizeCronPath(name2, job.path);
1958
+ const path35 = normalizeCronPath(name2, job.path);
1959
1959
  const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
1960
1960
  const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name2, value)))];
1961
1961
  if (schedule.length === 0) {
@@ -1964,7 +1964,7 @@ function normalizeCronJob(name2, job) {
1964
1964
  return {
1965
1965
  name: name2,
1966
1966
  schedule,
1967
- path: path34,
1967
+ path: path35,
1968
1968
  description: job.description?.trim() || void 0
1969
1969
  };
1970
1970
  }
@@ -1981,13 +1981,13 @@ function normalizeCronPath(name2, value) {
1981
1981
  `Farm cron ${JSON.stringify(name2)} path cannot contain backslashes or control characters.`
1982
1982
  );
1983
1983
  }
1984
- const path34 = value.trim();
1985
- if (path34.startsWith("//") || path34.includes("?") || path34.includes("#")) {
1984
+ const path35 = value.trim();
1985
+ if (path35.startsWith("//") || path35.includes("?") || path35.includes("#")) {
1986
1986
  throw new TypeError(
1987
1987
  `Farm cron ${JSON.stringify(name2)} path must be an application pathname without a host, query, or hash.`
1988
1988
  );
1989
1989
  }
1990
- for (const segment of path34.split("/")) {
1990
+ for (const segment of path35.split("/")) {
1991
1991
  let decoded = segment;
1992
1992
  try {
1993
1993
  decoded = decodeURIComponent(segment);
@@ -2009,7 +2009,7 @@ function normalizeCronPath(name2, value) {
2009
2009
  );
2010
2010
  }
2011
2011
  }
2012
- return path34.length > 1 ? path34.replace(/\/+$/, "") : path34;
2012
+ return path35.length > 1 ? path35.replace(/\/+$/, "") : path35;
2013
2013
  }
2014
2014
  function normalizeCronExpression(name2, value) {
2015
2015
  if (typeof value !== "string") {
@@ -2688,7 +2688,13 @@ function recordFarmEventTrace(event) {
2688
2688
  activeSpan.addEvent(event.type, toEventAttributes(event), event.timestamp);
2689
2689
  }
2690
2690
  const error = event.type === "request.error" ? void 0 : getEventError(event);
2691
- if (error !== void 0) recordSpanError(activeSpan, error);
2691
+ if (error !== void 0) {
2692
+ if (event.type === "render.error") {
2693
+ recordSpanException(activeSpan, error);
2694
+ } else {
2695
+ recordSpanError(activeSpan, error);
2696
+ }
2697
+ }
2692
2698
  }
2693
2699
  const completedTraceContext = recordCompletedEventSpan(event, activeContext);
2694
2700
  return traceContext ?? completedTraceContext;
@@ -2782,12 +2788,25 @@ function getCompletedSpanDescriptor(event) {
2782
2788
  return void 0;
2783
2789
  }
2784
2790
  }
2791
+ function hashFarmCacheKey(value) {
2792
+ let hash = 2166136261;
2793
+ for (let index = 0; index < value.length; index++) {
2794
+ hash ^= value.charCodeAt(index);
2795
+ hash = Math.imul(hash, 16777619);
2796
+ }
2797
+ return (hash >>> 0).toString(16).padStart(8, "0");
2798
+ }
2785
2799
  function toEventAttributes(event) {
2786
2800
  const attributes = {};
2801
+ const redactKey = typeof event.type === "string" && event.type.startsWith("cache.");
2787
2802
  for (const [key, value] of Object.entries(event)) {
2788
2803
  if (key === "timestamp" || key === "level" || key === "error" || key === "traceId" || key === "spanId" || key === "traceSampled" || value === void 0) {
2789
2804
  continue;
2790
2805
  }
2806
+ if (redactKey && key === "key" && typeof value === "string") {
2807
+ attributes["farm.key_hash"] = hashFarmCacheKey(value);
2808
+ continue;
2809
+ }
2791
2810
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2792
2811
  attributes[`farm.${key}`] = value;
2793
2812
  } else if (Array.isArray(value)) {
@@ -2805,9 +2824,13 @@ function toEventAttributes(event) {
2805
2824
  function getEventError(event) {
2806
2825
  return "error" in event ? event.error : void 0;
2807
2826
  }
2808
- function recordSpanError(span, error) {
2827
+ function recordSpanException(span, error) {
2809
2828
  const normalized = error instanceof Error ? error : new Error(String(error));
2810
2829
  span.recordException(normalized);
2830
+ return normalized;
2831
+ }
2832
+ function recordSpanError(span, error) {
2833
+ const normalized = recordSpanException(span, error);
2811
2834
  span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: normalized.message });
2812
2835
  }
2813
2836
  function setResponseStatus(span, status) {
@@ -2865,8 +2888,10 @@ var init_tracing = __esm({
2865
2888
  __name(recordFarmEventTrace, "recordFarmEventTrace");
2866
2889
  __name(recordCompletedEventSpan, "recordCompletedEventSpan");
2867
2890
  __name(getCompletedSpanDescriptor, "getCompletedSpanDescriptor");
2891
+ __name(hashFarmCacheKey, "hashFarmCacheKey");
2868
2892
  __name(toEventAttributes, "toEventAttributes");
2869
2893
  __name(getEventError, "getEventError");
2894
+ __name(recordSpanException, "recordSpanException");
2870
2895
  __name(recordSpanError, "recordSpanError");
2871
2896
  __name(setResponseStatus, "setResponseStatus");
2872
2897
  __name(resolveResultStatus, "resolveResultStatus");
@@ -3289,15 +3314,27 @@ function getFarmCacheInvalidationState() {
3289
3314
  taskListeners: /* @__PURE__ */ new Set()
3290
3315
  });
3291
3316
  }
3317
+ function warnFarmCacheListenerError(scope, error) {
3318
+ const detail = error instanceof Error ? error.stack ?? error.message : String(error);
3319
+ console.warn(`[farm:cache] ${scope} listener failed: ${detail}`);
3320
+ }
3292
3321
  function notifyFarmCacheInvalidation(key) {
3293
3322
  if (typeof key !== "string" || key.length === 0) return;
3294
3323
  for (const listener of getFarmCacheInvalidationState().listeners) {
3295
- listener(key);
3324
+ try {
3325
+ listener(key);
3326
+ } catch (error) {
3327
+ warnFarmCacheListenerError("invalidation", error);
3328
+ }
3296
3329
  }
3297
3330
  }
3298
3331
  function notifyFarmCacheTask(task) {
3299
3332
  for (const listener of getFarmCacheInvalidationState().taskListeners) {
3300
- listener(task);
3333
+ try {
3334
+ listener(task);
3335
+ } catch (error) {
3336
+ warnFarmCacheListenerError("task", error);
3337
+ }
3301
3338
  }
3302
3339
  }
3303
3340
  function encodeFarmCacheInvalidations(keys) {
@@ -3336,6 +3373,7 @@ var init_cache_invalidation = __esm({
3336
3373
  FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationState");
3337
3374
  globalState = globalThis;
3338
3375
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
3376
+ __name(warnFarmCacheListenerError, "warnFarmCacheListenerError");
3339
3377
  __name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
3340
3378
  __name(notifyFarmCacheTask, "notifyFarmCacheTask");
3341
3379
  __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
@@ -3435,7 +3473,7 @@ var init_server_action_security = __esm({
3435
3473
 
3436
3474
  // src/image-config.ts
3437
3475
  function resolveFarmImageConfig(config) {
3438
- const path34 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
3476
+ const path35 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
3439
3477
  const deviceSizes = normalizeIntegerList(
3440
3478
  config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
3441
3479
  "images.deviceSizes"
@@ -3463,7 +3501,7 @@ function resolveFarmImageConfig(config) {
3463
3501
  );
3464
3502
  return Object.freeze({
3465
3503
  provider: config?.provider ?? "auto",
3466
- path: path34,
3504
+ path: path35,
3467
3505
  domains: Object.freeze([
3468
3506
  ...new Set(
3469
3507
  (config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
@@ -3509,11 +3547,11 @@ function normalizeImagePath(value) {
3509
3547
  if (hasUnstableCharacters(value)) {
3510
3548
  throw new TypeError("images.path cannot contain backslashes or control characters");
3511
3549
  }
3512
- const path34 = value.trim().replace(/\/+$/, "") || "/";
3513
- if (!path34.startsWith("/") || path34.startsWith("//") || path34.includes("?") || path34.includes("#")) {
3550
+ const path35 = value.trim().replace(/\/+$/, "") || "/";
3551
+ if (!path35.startsWith("/") || path35.startsWith("//") || path35.includes("?") || path35.includes("#")) {
3514
3552
  throw new TypeError("images.path must be an absolute pathname without a query or hash");
3515
3553
  }
3516
- for (const segment of path34.split("/")) {
3554
+ for (const segment of path35.split("/")) {
3517
3555
  let decoded = segment;
3518
3556
  try {
3519
3557
  decoded = decodeURIComponent(segment);
@@ -3529,7 +3567,7 @@ function normalizeImagePath(value) {
3529
3567
  throw new TypeError('images.path cannot contain "." or ".." path segments');
3530
3568
  }
3531
3569
  }
3532
- return path34;
3570
+ return path35;
3533
3571
  }
3534
3572
  function normalizeIntegerList(values, name2, max) {
3535
3573
  if (values.length === 0) {
@@ -5034,7 +5072,7 @@ function getProgrammaticRouteSearchClientOptions2(search) {
5034
5072
  if (search.temporary?.length) options.temporary = [...search.temporary];
5035
5073
  return Object.keys(options).length > 0 ? options : void 0;
5036
5074
  }
5037
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path34, routePath) {
5075
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path35, routePath) {
5038
5076
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
5039
5077
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
5040
5078
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -5043,7 +5081,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path34, routePa
5043
5081
  schema,
5044
5082
  rawSearch,
5045
5083
  parsedSearch: search,
5046
- path: path34
5084
+ path: path35
5047
5085
  });
5048
5086
  return { search, canonicalPath };
5049
5087
  }
@@ -5122,8 +5160,8 @@ function normalizeComparableValue(value) {
5122
5160
  }
5123
5161
  return value;
5124
5162
  }
5125
- function createRoute(path34, options) {
5126
- return routesBuilder.page(path34, options);
5163
+ function createRoute(path35, options) {
5164
+ return routesBuilder.page(path35, options);
5127
5165
  }
5128
5166
  function isProgrammaticRoutesFileName2(fileName) {
5129
5167
  const normalized = fileName.replace(/\\/g, "/");
@@ -5206,7 +5244,7 @@ function createRouteModuleFromProgrammaticPage(route, rendererRuntime) {
5206
5244
  mod.__farmRouteData = route.data;
5207
5245
  mod.__farmRouteParsesProps = true;
5208
5246
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
5209
- mod.__farmResolveRouteCanonicalPath = (rawSearch, path34) => resolveProgrammaticRouteSearch(route.search, rawSearch, path34, route.path).canonicalPath;
5247
+ mod.__farmResolveRouteCanonicalPath = (rawSearch, path35) => resolveProgrammaticRouteSearch(route.search, rawSearch, path35, route.path).canonicalPath;
5210
5248
  }
5211
5249
  if (route.pending || route.error || route.notFound) {
5212
5250
  mod.__farmRouteComponents = {
@@ -5616,25 +5654,25 @@ var init_routes = __esm({
5616
5654
  ];
5617
5655
  __name(defineRoutes, "defineRoutes");
5618
5656
  routesBuilder = {
5619
- page(path34, options) {
5657
+ page(path35, options) {
5620
5658
  return normalizeProgrammaticRoute({
5621
5659
  kind: "page",
5622
- path: path34,
5660
+ path: path35,
5623
5661
  ...options
5624
5662
  });
5625
5663
  },
5626
- layout(path34, options) {
5664
+ layout(path35, options) {
5627
5665
  return normalizeProgrammaticRoute({
5628
5666
  kind: "layout",
5629
- path: path34,
5667
+ path: path35,
5630
5668
  ...options
5631
5669
  });
5632
5670
  },
5633
- api(path34, options) {
5671
+ api(path35, options) {
5634
5672
  const { render, runtime, regions, maxDuration, ...methods } = options;
5635
5673
  return normalizeProgrammaticRoute({
5636
5674
  kind: "api",
5637
- path: path34,
5675
+ path: path35,
5638
5676
  render,
5639
5677
  runtime,
5640
5678
  regions,
@@ -6105,9 +6143,9 @@ function getFarmIntegrationPluginOwner(plugin) {
6105
6143
  const value = plugin[FARM_INTEGRATION_PLUGIN_OWNER];
6106
6144
  return value && typeof value === "object" ? value : void 0;
6107
6145
  }
6108
- function defineTypedIntegrationRoute(method, path34, input) {
6146
+ function defineTypedIntegrationRoute(method, path35, input) {
6109
6147
  return {
6110
- path: path34,
6148
+ path: path35,
6111
6149
  method,
6112
6150
  middleware: input.middleware,
6113
6151
  before: input.before,
@@ -6117,7 +6155,7 @@ function defineTypedIntegrationRoute(method, path34, input) {
6117
6155
  input: normalizeIntegrationRouteInputSchemas(input),
6118
6156
  handler: input.handler,
6119
6157
  __operation: defineIntegrationAPIOperation({
6120
- path: path34,
6158
+ path: path35,
6121
6159
  method,
6122
6160
  bodyFormat: input.bodyFormat,
6123
6161
  responseFormat: input.responseFormat,
@@ -6129,58 +6167,58 @@ function defineTypedIntegrationRoute(method, path34, input) {
6129
6167
  }
6130
6168
  function createIntegrationRouteFactory() {
6131
6169
  return {
6132
- get(path34, input) {
6170
+ get(path35, input) {
6133
6171
  return defineTypedIntegrationRoute(
6134
6172
  "GET",
6135
- path34,
6173
+ path35,
6136
6174
  input
6137
6175
  );
6138
6176
  },
6139
- post(path34, input) {
6177
+ post(path35, input) {
6140
6178
  return defineTypedIntegrationRoute(
6141
6179
  "POST",
6142
- path34,
6180
+ path35,
6143
6181
  {
6144
6182
  bodyFormat: "json",
6145
6183
  ...input
6146
6184
  }
6147
6185
  );
6148
6186
  },
6149
- query(path34, input) {
6150
- return defineTypedIntegrationRoute("QUERY", path34, {
6187
+ query(path35, input) {
6188
+ return defineTypedIntegrationRoute("QUERY", path35, {
6151
6189
  bodyFormat: "json",
6152
6190
  ...input
6153
6191
  });
6154
6192
  },
6155
- put(path34, input) {
6193
+ put(path35, input) {
6156
6194
  return defineTypedIntegrationRoute(
6157
6195
  "PUT",
6158
- path34,
6196
+ path35,
6159
6197
  {
6160
6198
  bodyFormat: "json",
6161
6199
  ...input
6162
6200
  }
6163
6201
  );
6164
6202
  },
6165
- patch(path34, input) {
6166
- return defineTypedIntegrationRoute("PATCH", path34, {
6203
+ patch(path35, input) {
6204
+ return defineTypedIntegrationRoute("PATCH", path35, {
6167
6205
  bodyFormat: "json",
6168
6206
  ...input
6169
6207
  });
6170
6208
  },
6171
- delete(path34, input) {
6172
- return defineTypedIntegrationRoute("DELETE", path34, {
6209
+ delete(path35, input) {
6210
+ return defineTypedIntegrationRoute("DELETE", path35, {
6173
6211
  bodyFormat: "json",
6174
6212
  ...input
6175
6213
  });
6176
6214
  },
6177
- options(path34, input) {
6178
- return defineTypedIntegrationRoute("OPTIONS", path34, input);
6215
+ options(path35, input) {
6216
+ return defineTypedIntegrationRoute("OPTIONS", path35, input);
6179
6217
  },
6180
- head(path34, input) {
6218
+ head(path35, input) {
6181
6219
  return defineTypedIntegrationRoute(
6182
6220
  "HEAD",
6183
- path34,
6221
+ path35,
6184
6222
  input
6185
6223
  );
6186
6224
  }
@@ -6551,8 +6589,8 @@ function normalizeIntegrationValidationIssues(source, error) {
6551
6589
  }
6552
6590
  ];
6553
6591
  }
6554
- function normalizeIntegrationValidationPath(path34) {
6555
- return (path34 || []).map((segment) => {
6592
+ function normalizeIntegrationValidationPath(path35) {
6593
+ return (path35 || []).map((segment) => {
6556
6594
  const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
6557
6595
  return typeof key === "symbol" ? key.description || key.toString() : key;
6558
6596
  });
@@ -7380,8 +7418,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
7380
7418
  }
7381
7419
  );
7382
7420
  }
7383
- function createFarmDeploymentCookie(deploymentId, path34 = "/", secure = false) {
7384
- const normalizedPath = path34.startsWith("/") ? path34 : `/${path34}`;
7421
+ function createFarmDeploymentCookie(deploymentId, path35 = "/", secure = false) {
7422
+ const normalizedPath = path35.startsWith("/") ? path35 : `/${path35}`;
7385
7423
  return [
7386
7424
  `${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
7387
7425
  `Path=${normalizedPath}`,
@@ -8213,17 +8251,17 @@ function normalizeFarmAPIBasePath(value) {
8213
8251
  if (hasUnstableCharacters(value)) {
8214
8252
  throw new Error("Farm api.basePath cannot contain backslashes or control characters.");
8215
8253
  }
8216
- const path34 = value.trim();
8217
- if (!path34) {
8254
+ const path35 = value.trim();
8255
+ if (!path35) {
8218
8256
  throw new Error("Farm api.basePath cannot be empty.");
8219
8257
  }
8220
- if (path34.includes("?") || path34.includes("#")) {
8258
+ if (path35.includes("?") || path35.includes("#")) {
8221
8259
  throw new Error("Farm api.basePath cannot contain a query string or hash.");
8222
8260
  }
8223
- if (path34.startsWith("//")) {
8261
+ if (path35.startsWith("//")) {
8224
8262
  throw new Error('Farm api.basePath must be a pathname such as "/api", not a URL.');
8225
8263
  }
8226
- for (const segment of path34.split("/")) {
8264
+ for (const segment of path35.split("/")) {
8227
8265
  let decoded = segment;
8228
8266
  try {
8229
8267
  decoded = decodeURIComponent(segment);
@@ -8239,7 +8277,7 @@ function normalizeFarmAPIBasePath(value) {
8239
8277
  throw new Error('Farm api.basePath cannot contain "." or ".." path segments.');
8240
8278
  }
8241
8279
  }
8242
- const normalized = `/${path34.replace(/^\/+|\/+$/g, "")}`;
8280
+ const normalized = `/${path35.replace(/^\/+|\/+$/g, "")}`;
8243
8281
  return normalized === "/" ? "/" : normalized;
8244
8282
  }
8245
8283
  function parseRootRelativeBaseURL(value) {
@@ -8406,7 +8444,7 @@ var init_route_files = __esm({
8406
8444
  // src/write-file-if-changed.ts
8407
8445
  function writeFileIfChanged(filePath, content) {
8408
8446
  try {
8409
- if ((0, import_node_fs5.readFileSync)(filePath, "utf8") === content) {
8447
+ if ((0, import_node_fs6.readFileSync)(filePath, "utf8") === content) {
8410
8448
  return false;
8411
8449
  }
8412
8450
  } catch (error) {
@@ -8414,14 +8452,14 @@ function writeFileIfChanged(filePath, content) {
8414
8452
  throw error;
8415
8453
  }
8416
8454
  }
8417
- (0, import_node_fs5.writeFileSync)(filePath, content, "utf8");
8455
+ (0, import_node_fs6.writeFileSync)(filePath, content, "utf8");
8418
8456
  return true;
8419
8457
  }
8420
- var import_node_fs5;
8458
+ var import_node_fs6;
8421
8459
  var init_write_file_if_changed = __esm({
8422
8460
  "src/write-file-if-changed.ts"() {
8423
8461
  "use strict";
8424
- import_node_fs5 = require("fs");
8462
+ import_node_fs6 = require("fs");
8425
8463
  __name(writeFileIfChanged, "writeFileIfChanged");
8426
8464
  }
8427
8465
  });
@@ -8599,9 +8637,9 @@ var init_type_generator = __esm({
8599
8637
  }
8600
8638
  const nestedStructure = {};
8601
8639
  const usedRouteNames = /* @__PURE__ */ new Map();
8602
- for (const [path34, routeList] of routeGroups) {
8603
- const routeName = this.uniqueRouteName(path34, usedRouteNames);
8604
- const cleanPath = path34 === "/api" ? "" : path34.replace(/^\/api\//, "");
8640
+ for (const [path35, routeList] of routeGroups) {
8641
+ const routeName = this.uniqueRouteName(path35, usedRouteNames);
8642
+ const cleanPath = path35 === "/api" ? "" : path35.replace(/^\/api\//, "");
8605
8643
  const parts = cleanPath ? cleanPath.split("/") : [];
8606
8644
  const methodSources = /* @__PURE__ */ new Map();
8607
8645
  for (const route of routeList) {
@@ -8665,11 +8703,11 @@ var init_type_generator = __esm({
8665
8703
  methods.add(route.method);
8666
8704
  manifest.set(route.path, methods);
8667
8705
  }
8668
- const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path34, methods]) => ({ path: path34, methods: [...methods].sort() }));
8706
+ const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path35, methods]) => ({ path: path35, methods: [...methods].sort() }));
8669
8707
  const manifestSource = routeManifest.length ? `[
8670
8708
  ${routeManifest.map(
8671
- ({ path: path34, methods }) => ` {
8672
- path: ${JSON.stringify(path34)},
8709
+ ({ path: path35, methods }) => ` {
8710
+ path: ${JSON.stringify(path35)},
8673
8711
  methods: [${methods.map((method) => JSON.stringify(method)).join(", ")}],
8674
8712
  },`
8675
8713
  ).join("\n")}
@@ -8699,11 +8737,11 @@ export const apiRoutes = ${manifestSource} as const;
8699
8737
  const relativeImport = (0, import_path8.relative)((0, import_path8.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
8700
8738
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
8701
8739
  }
8702
- pathToRouteName(path34) {
8703
- return (path34 === "/api" ? "root" : path34.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
8740
+ pathToRouteName(path35) {
8741
+ return (path35 === "/api" ? "root" : path35.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
8704
8742
  }
8705
- uniqueRouteName(path34, usedNames) {
8706
- const base = this.pathToRouteName(path34);
8743
+ uniqueRouteName(path35, usedNames) {
8744
+ const base = this.pathToRouteName(path35);
8707
8745
  const seen = usedNames.get(base);
8708
8746
  usedNames.set(base, (seen ?? 0) + 1);
8709
8747
  return seen ? `${base}_${seen + 1}` : base;
@@ -8726,15 +8764,15 @@ export const apiRoutes = ${manifestSource} as const;
8726
8764
  toTypePropertyKey(key) {
8727
8765
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
8728
8766
  }
8729
- getBaseExportName(path34) {
8730
- const cleanPath = path34.replace(/^\/api\//, "");
8767
+ getBaseExportName(path35) {
8768
+ const cleanPath = path35.replace(/^\/api\//, "");
8731
8769
  if (cleanPath === "") {
8732
8770
  return "api";
8733
8771
  }
8734
8772
  return cleanPath;
8735
8773
  }
8736
- getExportName(path34, method) {
8737
- const cleanPath = path34.replace(/^\/api\//, "");
8774
+ getExportName(path35, method) {
8775
+ const cleanPath = path35.replace(/^\/api\//, "");
8738
8776
  if (cleanPath === "") {
8739
8777
  return method.toLowerCase();
8740
8778
  }
@@ -9226,12 +9264,12 @@ var init_image_server = __esm({
9226
9264
  // src/docs/fonts.ts
9227
9265
  function resolveFarmDocsFontAssets(root) {
9228
9266
  return FARM_DOCS_FONT_SOURCES.flatMap(({ family, packagePath }) => {
9229
- const sourcePath = import_node_path14.default.join(root, "node_modules", packagePath);
9230
- if (!(0, import_node_fs8.existsSync)(sourcePath)) return [];
9231
- const source = (0, import_node_fs8.readFileSync)(sourcePath);
9267
+ const sourcePath = import_node_path15.default.join(root, "node_modules", packagePath);
9268
+ if (!(0, import_node_fs9.existsSync)(sourcePath)) return [];
9269
+ const source = (0, import_node_fs9.readFileSync)(sourcePath);
9232
9270
  const fingerprint = (0, import_node_crypto3.createHash)("sha256").update(source).digest("hex").slice(0, 12);
9233
- const extension = import_node_path14.default.extname(packagePath);
9234
- const baseName = import_node_path14.default.basename(packagePath, extension);
9271
+ const extension = import_node_path15.default.extname(packagePath);
9272
+ const baseName = import_node_path15.default.basename(packagePath, extension);
9235
9273
  return [
9236
9274
  {
9237
9275
  family,
@@ -9244,13 +9282,13 @@ function resolveFarmDocsFontAssets(root) {
9244
9282
  function toFarmDocsPublicFontAssets(assets) {
9245
9283
  return assets.map(({ family, url }) => ({ family, url }));
9246
9284
  }
9247
- var import_node_crypto3, import_node_fs8, import_node_path14, FARM_DOCS_FONT_SOURCES;
9285
+ var import_node_crypto3, import_node_fs9, import_node_path15, FARM_DOCS_FONT_SOURCES;
9248
9286
  var init_fonts = __esm({
9249
9287
  "src/docs/fonts.ts"() {
9250
9288
  "use strict";
9251
9289
  import_node_crypto3 = require("crypto");
9252
- import_node_fs8 = require("fs");
9253
- import_node_path14 = __toESM(require("path"));
9290
+ import_node_fs9 = require("fs");
9291
+ import_node_path15 = __toESM(require("path"));
9254
9292
  FARM_DOCS_FONT_SOURCES = [
9255
9293
  {
9256
9294
  family: "Geist Sans",
@@ -9303,22 +9341,22 @@ function normalizeRelativePath(value) {
9303
9341
  }
9304
9342
  function resolveExistingPath(filePath) {
9305
9343
  try {
9306
- return (0, import_node_fs9.realpathSync)(filePath);
9344
+ return (0, import_node_fs10.realpathSync)(filePath);
9307
9345
  } catch {
9308
- return import_node_path16.default.resolve(filePath);
9346
+ return import_node_path17.default.resolve(filePath);
9309
9347
  }
9310
9348
  }
9311
9349
  function isDocsSourceFile(filePath) {
9312
- return DOCS_FILE_EXTENSIONS.has(import_node_path16.default.extname(filePath).toLowerCase());
9350
+ return DOCS_FILE_EXTENSIONS.has(import_node_path17.default.extname(filePath).toLowerCase());
9313
9351
  }
9314
9352
  function discoverDocsSourceFiles(contentDir) {
9315
9353
  const files = [];
9316
9354
  const visit = /* @__PURE__ */ __name((dir) => {
9317
- for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true }).sort(
9355
+ for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true }).sort(
9318
9356
  (a, b) => a.name.localeCompare(b.name)
9319
9357
  )) {
9320
9358
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
9321
- const absolutePath = import_node_path16.default.join(dir, entry.name);
9359
+ const absolutePath = import_node_path17.default.join(dir, entry.name);
9322
9360
  if (entry.isDirectory()) {
9323
9361
  visit(absolutePath);
9324
9362
  } else if (entry.isFile() && isDocsSourceFile(absolutePath)) {
@@ -9326,7 +9364,7 @@ function discoverDocsSourceFiles(contentDir) {
9326
9364
  }
9327
9365
  }
9328
9366
  }, "visit");
9329
- if ((0, import_node_fs9.existsSync)(contentDir)) visit(contentDir);
9367
+ if ((0, import_node_fs10.existsSync)(contentDir)) visit(contentDir);
9330
9368
  return files;
9331
9369
  }
9332
9370
  function getGitLastModifiedDates(contentDir) {
@@ -9336,7 +9374,7 @@ function getGitLastModifiedDates(contentDir) {
9336
9374
  stdio: ["ignore", "pipe", "ignore"]
9337
9375
  }).trim();
9338
9376
  if (!gitRoot) return {};
9339
- const contentPathspec = normalizeRelativePath(import_node_path16.default.relative(gitRoot, contentDir)) || ".";
9377
+ const contentPathspec = normalizeRelativePath(import_node_path17.default.relative(gitRoot, contentDir)) || ".";
9340
9378
  const contentPrefix = contentPathspec === "." ? "" : `${contentPathspec}/`;
9341
9379
  const history = (0, import_node_child_process.execFileSync)(
9342
9380
  "git",
@@ -9378,11 +9416,11 @@ function getGitLastModifiedDates(contentDir) {
9378
9416
  }
9379
9417
  }
9380
9418
  function readManifest(contentDir) {
9381
- const manifestPath = import_node_path16.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
9382
- if (!(0, import_node_fs9.existsSync)(manifestPath)) return null;
9419
+ const manifestPath = import_node_path17.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
9420
+ if (!(0, import_node_fs10.existsSync)(manifestPath)) return null;
9383
9421
  try {
9384
9422
  const parsed = JSON.parse(
9385
- (0, import_node_fs9.readFileSync)(manifestPath, "utf8")
9423
+ (0, import_node_fs10.readFileSync)(manifestPath, "utf8")
9386
9424
  );
9387
9425
  if (parsed.version !== 1 || !parsed.pages || typeof parsed.pages !== "object") return null;
9388
9426
  const pages = Object.fromEntries(
@@ -9401,15 +9439,15 @@ function createFarmDocsLastModifiedManifest(contentDir, options = {}) {
9401
9439
  const fallbackDate = (options.now ?? /* @__PURE__ */ new Date()).toISOString();
9402
9440
  const pages = {};
9403
9441
  for (const sourcePath of discoverDocsSourceFiles(resolvedContentDir)) {
9404
- const relativePath2 = normalizeRelativePath(import_node_path16.default.relative(resolvedContentDir, sourcePath));
9405
- pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs9.statSync)(sourcePath).mtime.toISOString());
9442
+ const relativePath2 = normalizeRelativePath(import_node_path17.default.relative(resolvedContentDir, sourcePath));
9443
+ pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs10.statSync)(sourcePath).mtime.toISOString());
9406
9444
  }
9407
9445
  return { version: 1, pages };
9408
9446
  }
9409
9447
  function getLastModifiedManifest(contentDir) {
9410
9448
  const resolvedContentDir = resolveExistingPath(contentDir);
9411
- const manifestPath = import_node_path16.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
9412
- const manifestStat = (0, import_node_fs9.existsSync)(manifestPath) ? (0, import_node_fs9.statSync)(manifestPath) : null;
9449
+ const manifestPath = import_node_path17.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
9450
+ const manifestStat = (0, import_node_fs10.existsSync)(manifestPath) ? (0, import_node_fs10.statSync)(manifestPath) : null;
9413
9451
  const signature = manifestStat ? `file:${manifestStat.mtimeMs}:${manifestStat.size}` : "generated";
9414
9452
  const cached = manifestCache.get(resolvedContentDir);
9415
9453
  if (cached?.signature === signature) return cached.manifest;
@@ -9422,21 +9460,21 @@ function resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter) {
9422
9460
  if (configured) return configured;
9423
9461
  const resolvedContentDir = resolveExistingPath(contentDir);
9424
9462
  const resolvedSourcePath = resolveExistingPath(sourcePath);
9425
- const relativePath2 = normalizeRelativePath(import_node_path16.default.relative(resolvedContentDir, resolvedSourcePath));
9426
- const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path16.default.isAbsolute(relativePath2);
9463
+ const relativePath2 = normalizeRelativePath(import_node_path17.default.relative(resolvedContentDir, resolvedSourcePath));
9464
+ const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path17.default.isAbsolute(relativePath2);
9427
9465
  if (isInsideContentDir) {
9428
9466
  const generated = getLastModifiedManifest(resolvedContentDir).pages[relativePath2];
9429
9467
  if (generated) return generated;
9430
9468
  }
9431
- return (0, import_node_fs9.statSync)(resolvedSourcePath).mtime.toISOString();
9469
+ return (0, import_node_fs10.statSync)(resolvedSourcePath).mtime.toISOString();
9432
9470
  }
9433
- var import_node_child_process, import_node_fs9, import_node_path16, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
9471
+ var import_node_child_process, import_node_fs10, import_node_path17, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
9434
9472
  var init_last_modified = __esm({
9435
9473
  "src/docs/last-modified.ts"() {
9436
9474
  "use strict";
9437
9475
  import_node_child_process = require("child_process");
9438
- import_node_fs9 = require("fs");
9439
- import_node_path16 = __toESM(require("path"));
9476
+ import_node_fs10 = require("fs");
9477
+ import_node_path17 = __toESM(require("path"));
9440
9478
  FARM_DOCS_LAST_MODIFIED_MANIFEST = ".farm-docs-last-modified.json";
9441
9479
  COMMIT_MARKER = "__FARM_DOCS_COMMIT__";
9442
9480
  DOCS_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx"]);
@@ -9469,10 +9507,10 @@ function isFarmDocsSearchEnabled(docs) {
9469
9507
  }
9470
9508
  function resolveFarmDocsSearchClientModule(root) {
9471
9509
  try {
9472
- const requireFromApp = (0, import_node_module5.createRequire)(import_node_path17.default.join(import_node_path17.default.resolve(root), "package.json"));
9510
+ const requireFromApp = (0, import_node_module5.createRequire)(import_node_path18.default.join(import_node_path18.default.resolve(root), "package.json"));
9473
9511
  const themeEntry = requireFromApp.resolve("@farming-labs/theme");
9474
- const commandSearchModule = import_node_path17.default.join(import_node_path17.default.dirname(themeEntry), "docs-command-search.mjs");
9475
- if ((0, import_node_fs10.existsSync)(commandSearchModule)) return commandSearchModule;
9512
+ const commandSearchModule = import_node_path18.default.join(import_node_path18.default.dirname(themeEntry), "docs-command-search.mjs");
9513
+ if ((0, import_node_fs11.existsSync)(commandSearchModule)) return commandSearchModule;
9476
9514
  } catch {
9477
9515
  }
9478
9516
  return void 0;
@@ -9611,13 +9649,13 @@ async function mountFarmDocsSearch() {
9611
9649
  window.__FARM_MOUNT_DOCS_SEARCH__ = mountFarmDocsSearch;
9612
9650
  `;
9613
9651
  }
9614
- var import_node_fs10, import_node_module5, import_node_path17;
9652
+ var import_node_fs11, import_node_module5, import_node_path18;
9615
9653
  var init_search_client = __esm({
9616
9654
  "src/docs/search-client.ts"() {
9617
9655
  "use strict";
9618
- import_node_fs10 = require("fs");
9656
+ import_node_fs11 = require("fs");
9619
9657
  import_node_module5 = require("module");
9620
- import_node_path17 = __toESM(require("path"));
9658
+ import_node_path18 = __toESM(require("path"));
9621
9659
  __name(isFarmDocsSearchEnabled, "isFarmDocsSearchEnabled");
9622
9660
  __name(resolveFarmDocsSearchClientModule, "resolveFarmDocsSearchClientModule");
9623
9661
  __name(generateFarmDocsSearchBootstrapRuntime, "generateFarmDocsSearchBootstrapRuntime");
@@ -10055,10 +10093,10 @@ function resolveFarmDocsFavicon(docs, options) {
10055
10093
  if (typeof configuredFavicon === "string" && configuredFavicon.trim()) {
10056
10094
  return configuredFavicon.trim();
10057
10095
  }
10058
- const publicDir = import_node_path18.default.join(import_node_path18.default.resolve(options.root), "public");
10096
+ const publicDir = import_node_path19.default.join(import_node_path19.default.resolve(options.root), "public");
10059
10097
  for (const fileName of FARM_DOCS_FAVICON_FILES) {
10060
- const faviconPath = import_node_path18.default.join(publicDir, fileName);
10061
- if ((0, import_node_fs11.existsSync)(faviconPath) && (0, import_node_fs11.statSync)(faviconPath).isFile()) {
10098
+ const faviconPath = import_node_path19.default.join(publicDir, fileName);
10099
+ if ((0, import_node_fs12.existsSync)(faviconPath) && (0, import_node_fs12.statSync)(faviconPath).isFile()) {
10062
10100
  return `/${fileName}`;
10063
10101
  }
10064
10102
  }
@@ -10092,10 +10130,10 @@ function isSafeSegment(segment) {
10092
10130
  return segment !== ".." && !segment.includes("/") && !segment.includes("\\");
10093
10131
  }
10094
10132
  function resolveInside(root, target) {
10095
- const resolvedRoot = import_node_path18.default.resolve(root);
10096
- const resolvedTarget = import_node_path18.default.resolve(target);
10097
- const relative6 = import_node_path18.default.relative(resolvedRoot, resolvedTarget);
10098
- if (relative6 === "" || !relative6.startsWith("..") && !import_node_path18.default.isAbsolute(relative6)) {
10133
+ const resolvedRoot = import_node_path19.default.resolve(root);
10134
+ const resolvedTarget = import_node_path19.default.resolve(target);
10135
+ const relative6 = import_node_path19.default.relative(resolvedRoot, resolvedTarget);
10136
+ if (relative6 === "" || !relative6.startsWith("..") && !import_node_path19.default.isAbsolute(relative6)) {
10099
10137
  return resolvedTarget;
10100
10138
  }
10101
10139
  return null;
@@ -10104,10 +10142,10 @@ function resolveExistingFileInside(root, target) {
10104
10142
  const safePath = resolveInside(root, target);
10105
10143
  if (!safePath) return null;
10106
10144
  try {
10107
- const realRoot = (0, import_node_fs11.realpathSync)(root);
10108
- const realTarget = (0, import_node_fs11.realpathSync)(safePath);
10145
+ const realRoot = (0, import_node_fs12.realpathSync)(root);
10146
+ const realTarget = (0, import_node_fs12.realpathSync)(safePath);
10109
10147
  const containedTarget = resolveInside(realRoot, realTarget);
10110
- return containedTarget && (0, import_node_fs11.statSync)(containedTarget).isFile() ? containedTarget : null;
10148
+ return containedTarget && (0, import_node_fs12.statSync)(containedTarget).isFile() ? containedTarget : null;
10111
10149
  } catch {
10112
10150
  return null;
10113
10151
  }
@@ -10121,16 +10159,16 @@ function isFarmDocsRequest(docs, request) {
10121
10159
  return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
10122
10160
  }
10123
10161
  function resolveFarmDocsContentDir(docs, options) {
10124
- const root = import_node_path18.default.resolve(options.root);
10162
+ const root = import_node_path19.default.resolve(options.root);
10125
10163
  const srcDir = options.srcDir || "src";
10126
10164
  const configuredContentDir = docs.contentDir || docs.config.contentDir;
10127
10165
  if (configuredContentDir) {
10128
- return import_node_path18.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path18.default.join(root, configuredContentDir);
10166
+ return import_node_path19.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path19.default.join(root, configuredContentDir);
10129
10167
  }
10130
10168
  const entryDir = docs.config.entry || trimSlashes2(docs.entry) || "docs";
10131
- const appDocsDir = import_node_path18.default.join(root, srcDir, "app", entryDir);
10132
- if ((0, import_node_fs11.existsSync)(appDocsDir)) return appDocsDir;
10133
- return import_node_path18.default.join(root, entryDir);
10169
+ const appDocsDir = import_node_path19.default.join(root, srcDir, "app", entryDir);
10170
+ if ((0, import_node_fs12.existsSync)(appDocsDir)) return appDocsDir;
10171
+ return import_node_path19.default.join(root, entryDir);
10134
10172
  }
10135
10173
  function getFarmDocsRouteTypeEntries(docs) {
10136
10174
  if (!docs?.enabled) return [];
@@ -10153,10 +10191,10 @@ function getRequestSlug(docs, request) {
10153
10191
  function findDocsPageFile(contentDir, slug) {
10154
10192
  const segments = slug ? slug.split("/").filter(Boolean) : [];
10155
10193
  if (!segments.every(isSafeSegment)) return null;
10156
- const slugDir = import_node_path18.default.join(contentDir, ...segments);
10157
- const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path18.default.join(contentDir, filename)) : [
10158
- ...DOCS_FILE_NAMES.map((filename) => import_node_path18.default.join(slugDir, filename)),
10159
- ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path18.default.join(contentDir, `${slug}${extension}`))
10194
+ const slugDir = import_node_path19.default.join(contentDir, ...segments);
10195
+ const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path19.default.join(contentDir, filename)) : [
10196
+ ...DOCS_FILE_NAMES.map((filename) => import_node_path19.default.join(slugDir, filename)),
10197
+ ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path19.default.join(contentDir, `${slug}${extension}`))
10160
10198
  ];
10161
10199
  for (const candidate of candidates) {
10162
10200
  const safePath = resolveExistingFileInside(contentDir, candidate);
@@ -10195,7 +10233,7 @@ function titleFromMarkdown2(body, fallback) {
10195
10233
  function loadFarmDocsPage(contentDir, docs, slug) {
10196
10234
  const sourcePath = findDocsPageFile(contentDir, slug);
10197
10235
  if (!sourcePath) return null;
10198
- const source = (0, import_node_fs11.readFileSync)(sourcePath, "utf8");
10236
+ const source = (0, import_node_fs12.readFileSync)(sourcePath, "utf8");
10199
10237
  const { frontmatter, body } = parseFrontmatter(source);
10200
10238
  const title = frontmatter.title || titleFromMarkdown2(body, titleFromSlug(slug));
10201
10239
  const href = createDocsHref(docs.entry, slug);
@@ -10218,9 +10256,9 @@ function createDocsHref(entry, slug) {
10218
10256
  return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
10219
10257
  }
10220
10258
  function pathToSlug(contentDir, filePath) {
10221
- const relative6 = import_node_path18.default.relative(contentDir, filePath).replace(/\\/g, "/");
10259
+ const relative6 = import_node_path19.default.relative(contentDir, filePath).replace(/\\/g, "/");
10222
10260
  if (relative6.startsWith("..")) return null;
10223
- const extension = import_node_path18.default.extname(relative6);
10261
+ const extension = import_node_path19.default.extname(relative6);
10224
10262
  if (!DOCS_FILE_EXTENSIONS2.includes(extension)) return null;
10225
10263
  const withoutExtension = relative6.slice(0, -extension.length);
10226
10264
  if (withoutExtension === "page" || withoutExtension === "index") return "";
@@ -10233,12 +10271,12 @@ function loadPage(contentDir, docs, request) {
10233
10271
  return loadFarmDocsPage(contentDir, docs, getRequestSlug(docs, request));
10234
10272
  }
10235
10273
  function discoverFarmDocsPages(contentDir, docs) {
10236
- if (!(0, import_node_fs11.existsSync)(contentDir)) return [];
10274
+ if (!(0, import_node_fs12.existsSync)(contentDir)) return [];
10237
10275
  const pages = [];
10238
10276
  const visit = /* @__PURE__ */ __name((dir) => {
10239
- for (const entry of (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true })) {
10277
+ for (const entry of (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true })) {
10240
10278
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
10241
- const absolutePath = import_node_path18.default.join(dir, entry.name);
10279
+ const absolutePath = import_node_path19.default.join(dir, entry.name);
10242
10280
  if (entry.isDirectory()) {
10243
10281
  visit(absolutePath);
10244
10282
  continue;
@@ -10246,7 +10284,7 @@ function discoverFarmDocsPages(contentDir, docs) {
10246
10284
  if (!entry.isFile()) continue;
10247
10285
  const slug = pathToSlug(contentDir, absolutePath);
10248
10286
  if (slug === null) continue;
10249
- const source = (0, import_node_fs11.readFileSync)(absolutePath, "utf8");
10287
+ const source = (0, import_node_fs12.readFileSync)(absolutePath, "utf8");
10250
10288
  const { frontmatter, body } = parseFrontmatter(source);
10251
10289
  pages.push({
10252
10290
  slug,
@@ -10765,11 +10803,30 @@ function renderMarkdownHtml(body) {
10765
10803
  function extractTocItems(body, depth) {
10766
10804
  const slug = createSlugger();
10767
10805
  const maxLevel = Math.max(2, Math.min(depth, 6));
10768
- return body.split(/\r?\n/).map((line) => line.match(/^(#{2,6})\s+(.+)$/)).filter((match) => Boolean(match)).map((match) => ({
10769
- id: slug(match[2].trim()),
10770
- title: match[2].trim(),
10771
- level: match[1].length
10772
- })).filter((item) => item.level <= maxLevel);
10806
+ const items = [];
10807
+ let fence = null;
10808
+ for (const line of body.split(/\r?\n/)) {
10809
+ const nextFence = getCodeFence(line);
10810
+ if (fence) {
10811
+ if (nextFence && nextFence.marker === fence.marker && isClosingCodeFence(line, fence)) {
10812
+ fence = null;
10813
+ }
10814
+ continue;
10815
+ }
10816
+ if (nextFence) {
10817
+ fence = nextFence;
10818
+ continue;
10819
+ }
10820
+ const match = line.match(/^(#{2,6})\s+(.+)$/);
10821
+ if (!match) continue;
10822
+ const title = match[2].trim();
10823
+ const id = slug(title);
10824
+ const level = match[1].length;
10825
+ if (level <= maxLevel) {
10826
+ items.push({ id, title, level });
10827
+ }
10828
+ }
10829
+ return items;
10773
10830
  }
10774
10831
  function getThemeUI(docs) {
10775
10832
  const theme = docs.config.theme;
@@ -11258,12 +11315,12 @@ function createFarmDocsHandler(docs, options) {
11258
11315
  );
11259
11316
  }, "handleFarmDocsRequest");
11260
11317
  }
11261
- 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;
11318
+ 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;
11262
11319
  var init_handler = __esm({
11263
11320
  "src/docs/handler.ts"() {
11264
11321
  "use strict";
11265
- import_node_fs11 = require("fs");
11266
- import_node_path18 = __toESM(require("path"));
11322
+ import_node_fs12 = require("fs");
11323
+ import_node_path19 = __toESM(require("path"));
11267
11324
  import_docs = require("@farming-labs/docs");
11268
11325
  import_marked = require("marked");
11269
11326
  import_sugar_high = require("sugar-high");
@@ -11522,13 +11579,13 @@ var init_adapter = __esm({
11522
11579
  });
11523
11580
 
11524
11581
  // src/docs/framework-detect.ts
11525
- var import_promises8, import_node_module6, import_node_path19, import_node_url7;
11582
+ var import_promises8, import_node_module6, import_node_path20, import_node_url7;
11526
11583
  var init_framework_detect = __esm({
11527
11584
  "src/docs/framework-detect.ts"() {
11528
11585
  "use strict";
11529
11586
  import_promises8 = require("fs/promises");
11530
11587
  import_node_module6 = require("module");
11531
- import_node_path19 = __toESM(require("path"));
11588
+ import_node_path20 = __toESM(require("path"));
11532
11589
  import_node_url7 = require("url");
11533
11590
  }
11534
11591
  });
@@ -11628,19 +11685,19 @@ async function findDocsConfigPath(rootDir, configPath) {
11628
11685
  return void 0;
11629
11686
  }
11630
11687
  async function loadDocsConfig(rootDir, configPath) {
11631
- const fs13 = await import("fs/promises");
11688
+ const fs14 = await import("fs/promises");
11632
11689
  const { pathToFileURL: pathToFileURL9 } = await import("url");
11633
11690
  const root = import_path10.default.resolve(rootDir || process.cwd());
11634
11691
  const resolvedPath = await findDocsConfigPath(root, configPath);
11635
11692
  if (!resolvedPath) return void 0;
11636
11693
  try {
11637
11694
  if (resolvedPath.endsWith(".json")) {
11638
- const content = await fs13.readFile(resolvedPath, "utf8");
11695
+ const content = await fs14.readFile(resolvedPath, "utf8");
11639
11696
  return { config: JSON.parse(content), configPath: resolvedPath };
11640
11697
  }
11641
11698
  const { build } = await import("esbuild");
11642
11699
  const configCacheDir = import_path10.default.join(root, ".farm", ".config-loader");
11643
- await fs13.mkdir(configCacheDir, { recursive: true });
11700
+ await fs14.mkdir(configCacheDir, { recursive: true });
11644
11701
  const modulePath = import_path10.default.join(
11645
11702
  configCacheDir,
11646
11703
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -11666,7 +11723,7 @@ async function loadDocsConfig(rootDir, configPath) {
11666
11723
  moduleUrl
11667
11724
  );
11668
11725
  } finally {
11669
- await fs13.unlink(modulePath).catch(() => void 0);
11726
+ await fs14.unlink(modulePath).catch(() => void 0);
11670
11727
  }
11671
11728
  return {
11672
11729
  config: importedConfig.default || importedConfig,
@@ -12576,8 +12633,8 @@ var init_generator = __esm({
12576
12633
  }
12577
12634
  routeGroups.get(key).push(route);
12578
12635
  }
12579
- for (const [path34, routeList] of routeGroups) {
12580
- const openAPIPath = this.convertToOpenAPIPath(path34);
12636
+ for (const [path35, routeList] of routeGroups) {
12637
+ const openAPIPath = this.convertToOpenAPIPath(path35);
12581
12638
  spec.paths[openAPIPath] = {};
12582
12639
  for (const route of routeList) {
12583
12640
  for (const method of route.methods) {
@@ -12597,8 +12654,8 @@ var init_generator = __esm({
12597
12654
  /**
12598
12655
  * Convert Farm.js API path to OpenAPI path format
12599
12656
  */
12600
- convertToOpenAPIPath(path34) {
12601
- return path34.replace(/^\/api/, "");
12657
+ convertToOpenAPIPath(path35) {
12658
+ return path35.replace(/^\/api/, "");
12602
12659
  }
12603
12660
  /**
12604
12661
  * Extract request body schema from endpoint
@@ -12760,8 +12817,8 @@ var init_generator = __esm({
12760
12817
  /**
12761
12818
  * Generate operation summary
12762
12819
  */
12763
- generateSummary(path34, method) {
12764
- const cleanPath = path34.replace(/^\/api\//, "");
12820
+ generateSummary(path35, method) {
12821
+ const cleanPath = path35.replace(/^\/api\//, "");
12765
12822
  const pathParts = cleanPath.split("/");
12766
12823
  const lastPart = pathParts[pathParts.length - 1];
12767
12824
  const action = method === "GET" ? "Get" : method === "QUERY" ? "Query" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -12770,22 +12827,22 @@ var init_generator = __esm({
12770
12827
  /**
12771
12828
  * Generate operation description
12772
12829
  */
12773
- generateDescription(path34, method) {
12774
- const cleanPath = path34.replace(/^\/api\//, "");
12830
+ generateDescription(path35, method) {
12831
+ const cleanPath = path35.replace(/^\/api\//, "");
12775
12832
  return `${method} ${cleanPath} endpoint`;
12776
12833
  }
12777
12834
  /**
12778
12835
  * Generate operation ID
12779
12836
  */
12780
- generateOperationId(path34, method) {
12781
- const cleanPath = path34.replace(/^\/api\//, "").replace(/\//g, "_");
12837
+ generateOperationId(path35, method) {
12838
+ const cleanPath = path35.replace(/^\/api\//, "").replace(/\//g, "_");
12782
12839
  return `${method.toLowerCase()}_${cleanPath}`;
12783
12840
  }
12784
12841
  /**
12785
12842
  * Generate tags for grouping operations
12786
12843
  */
12787
- generateTags(path34) {
12788
- const cleanPath = path34.replace(/^\/api\//, "");
12844
+ generateTags(path35) {
12845
+ const cleanPath = path35.replace(/^\/api\//, "");
12789
12846
  const pathParts = cleanPath.split("/");
12790
12847
  if (pathParts.length > 1) {
12791
12848
  return [pathParts[0]];
@@ -12797,13 +12854,13 @@ var init_generator = __esm({
12797
12854
  */
12798
12855
  async generateSpecFile(routes, outputPath) {
12799
12856
  const spec = await this.generateSpec(routes);
12800
- const fs13 = require("fs");
12801
- const path34 = require("path");
12802
- const dir = path34.dirname(outputPath);
12803
- if (!fs13.existsSync(dir)) {
12804
- fs13.mkdirSync(dir, { recursive: true });
12857
+ const fs14 = require("fs");
12858
+ const path35 = require("path");
12859
+ const dir = path35.dirname(outputPath);
12860
+ if (!fs14.existsSync(dir)) {
12861
+ fs14.mkdirSync(dir, { recursive: true });
12805
12862
  }
12806
- fs13.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
12863
+ fs14.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
12807
12864
  }
12808
12865
  };
12809
12866
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -13231,7 +13288,7 @@ async function createFarmDevtoolsSnapshot(input) {
13231
13288
  generatedAt: (input.now?.() || /* @__PURE__ */ new Date()).toISOString(),
13232
13289
  health: resolveHealth(diagnostics),
13233
13290
  project: {
13234
- name: import_node_path20.default.basename(import_node_path20.default.resolve(input.root)),
13291
+ name: import_node_path21.default.basename(import_node_path21.default.resolve(input.root)),
13235
13292
  root: input.root,
13236
13293
  srcDir: input.srcDir,
13237
13294
  basePath: config.basePath || "/",
@@ -13280,11 +13337,11 @@ async function createFarmDevtoolsSnapshot(input) {
13280
13337
  diagnostics
13281
13338
  };
13282
13339
  }
13283
- var import_node_path20;
13340
+ var import_node_path21;
13284
13341
  var init_devtools = __esm({
13285
13342
  "src/devtools.ts"() {
13286
13343
  "use strict";
13287
- import_node_path20 = __toESM(require("path"));
13344
+ import_node_path21 = __toESM(require("path"));
13288
13345
  init_config4();
13289
13346
  init_cron();
13290
13347
  init_route_runtime();
@@ -13925,6 +13982,7 @@ function renderFarmDevtoolsHtml(snapshot) {
13925
13982
  .nav-item .icon { width: 13px; height: 13px; }
13926
13983
  .nav-item small { color: #666; font-size: 9px; font-weight: 400; }
13927
13984
  .topbar-meta { display: flex; flex: 0 0 auto; margin-left: auto; border-left: 1px solid var(--line); }
13985
+ .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; }
13928
13986
  .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; }
13929
13987
  .status-dot { width: 5px; height: 5px; background: #fff; box-shadow: 0 0 0 3px rgb(255 255 255 / 0.06); }
13930
13988
  .status-dot-attention { background: #909090; animation: status-pulse 1.8s ease-in-out infinite; }
@@ -14434,6 +14492,7 @@ function renderFarmDevtoolsHtml(snapshot) {
14434
14492
  ${renderNavigationItem("raw", "Raw")}
14435
14493
  </nav>
14436
14494
  <div class="topbar-meta">
14495
+ <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>
14437
14496
  <span class="project-select">${escapeHtml3(snapshot.project.name)} ${icon(
14438
14497
  "chevron"
14439
14498
  )}</span>
@@ -14689,23 +14748,26 @@ function generateFarmDevtoolsClientRuntime(config) {
14689
14748
  z-index: 2147483646;
14690
14749
  display: grid;
14691
14750
  place-items: center;
14751
+ box-sizing: border-box;
14692
14752
  padding: 20px;
14693
14753
  background: rgb(0 0 0 / 0);
14694
- backdrop-filter: blur(0);
14754
+ backdrop-filter: blur(6px);
14755
+ -webkit-backdrop-filter: blur(6px);
14756
+ overscroll-behavior: none;
14757
+ isolation: isolate;
14695
14758
  opacity: 0;
14696
14759
  pointer-events: none;
14697
- transition: background-color 150ms ease-out, backdrop-filter 150ms ease-out, opacity 150ms ease-out;
14760
+ transition: opacity 150ms ease-out;
14698
14761
  }
14699
14762
  #__farm_devtools_overlay__[data-open="true"] {
14700
- background: rgb(0 0 0 / 0.12);
14701
- backdrop-filter: blur(1px);
14763
+ background: rgb(0 0 0 / 0.32);
14702
14764
  opacity: 1;
14703
14765
  pointer-events: auto;
14704
14766
  }
14705
14767
  #__farm_devtools_overlay__ > iframe {
14706
14768
  display: block;
14707
- width: min(960px, calc(100vw - 40px));
14708
- height: min(560px, calc(100dvh - 40px));
14769
+ width: min(1100px, calc(100vw - 48px));
14770
+ height: min(720px, calc(100dvh - 48px));
14709
14771
  border: 0;
14710
14772
  border-radius: 12px;
14711
14773
  background: transparent;
@@ -14721,7 +14783,7 @@ function generateFarmDevtoolsClientRuntime(config) {
14721
14783
  #__farm_devtools_overlay__ > iframe {
14722
14784
  width: calc(100vw - 16px);
14723
14785
  height: calc(100dvh - 16px);
14724
- border-radius: 10px;
14786
+ border-radius: 12px;
14725
14787
  }
14726
14788
  }
14727
14789
  @media (prefers-reduced-motion: reduce) {
@@ -14735,10 +14797,32 @@ function generateFarmDevtoolsClientRuntime(config) {
14735
14797
  const runtimeKey = "__FARM_DEVTOOLS_RUNTIME__";
14736
14798
  const launchParam = ${JSON.stringify(FARM_DEVTOOLS_LAUNCH_PARAM)};
14737
14799
  const devtoolsPath = ${JSON.stringify(FARM_DEVTOOLS_PATH)};
14738
- const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw"]);
14800
+ const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw", "inspect", "diagnostics"]);
14739
14801
  const shortcut = ${JSON.stringify(shortcut)};
14740
14802
  const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform);
14741
14803
  let returnFocus = null;
14804
+ let restorePage = null;
14805
+ let closeTimer = null;
14806
+
14807
+ const lockPage = () => {
14808
+ const styles = [];
14809
+ for (const element of [document.documentElement, document.body]) {
14810
+ for (const [property, value] of [["overflow-x", "hidden"], ["overflow-y", "hidden"], ["overscroll-behavior", "none"]]) {
14811
+ const previous = element.style.getPropertyValue(property);
14812
+ const priority = element.style.getPropertyPriority(property);
14813
+ element.style.setProperty(property, value, "important");
14814
+ styles.push({ element, property, value, previous, priority });
14815
+ }
14816
+ }
14817
+ return () => {
14818
+ for (const { element, property, value, previous, priority } of styles) {
14819
+ // Do not overwrite a newer style set by the application while the panel was open.
14820
+ if (element.style.getPropertyValue(property) !== value || element.style.getPropertyPriority(property) !== "important") continue;
14821
+ if (previous) element.style.setProperty(property, previous, priority);
14822
+ else element.style.removeProperty(property);
14823
+ }
14824
+ };
14825
+ };
14742
14826
 
14743
14827
  const matchesShortcut = (event) => {
14744
14828
  if (!shortcut || event.repeat) return false;
@@ -14765,24 +14849,35 @@ function generateFarmDevtoolsClientRuntime(config) {
14765
14849
  document.head.appendChild(style);
14766
14850
  };
14767
14851
 
14768
- const close = () => {
14852
+ const finishClose = () => {
14853
+ if (closeTimer !== null) window.clearTimeout(closeTimer);
14854
+ closeTimer = null;
14769
14855
  const overlay = document.getElementById(overlayId);
14770
- if (!overlay) return;
14856
+ overlay?.remove();
14857
+ restorePage?.();
14858
+ restorePage = null;
14771
14859
  const focusTarget = returnFocus;
14772
14860
  returnFocus = null;
14861
+ focusTarget?.focus?.({ preventScroll: true });
14862
+ };
14863
+
14864
+ const close = () => {
14865
+ const overlay = document.getElementById(overlayId);
14866
+ if (!overlay || closeTimer !== null) return;
14773
14867
  overlay.dataset.open = "false";
14774
- window.setTimeout(() => {
14775
- overlay.remove();
14776
- focusTarget?.focus?.();
14777
- }, 160);
14868
+ closeTimer = window.setTimeout(finishClose, 160);
14778
14869
  };
14779
14870
 
14780
14871
  const open = (view = "overview") => {
14872
+ if (closeTimer !== null) finishClose();
14781
14873
  if (document.getElementById(overlayId)) return;
14782
14874
  ensureStyles();
14783
14875
  returnFocus = document.activeElement;
14876
+ restorePage = lockPage();
14784
14877
  const overlay = document.createElement("div");
14785
14878
  overlay.id = overlayId;
14879
+ overlay.setAttribute("role", "dialog");
14880
+ overlay.setAttribute("aria-modal", "true");
14786
14881
  overlay.setAttribute("aria-label", "Farm.js DevTools overlay");
14787
14882
  const frame = document.createElement("iframe");
14788
14883
  const resolvedView = validViews.has(view) ? view : "overview";
@@ -14793,9 +14888,11 @@ function generateFarmDevtoolsClientRuntime(config) {
14793
14888
  overlay.addEventListener("pointerdown", (event) => {
14794
14889
  if (event.target === overlay) close();
14795
14890
  });
14891
+ overlay.addEventListener("wheel", (event) => event.preventDefault(), { passive: false });
14892
+ overlay.addEventListener("touchmove", (event) => event.preventDefault(), { passive: false });
14796
14893
  document.body.appendChild(overlay);
14797
14894
  requestAnimationFrame(() => {
14798
- overlay.dataset.open = "true";
14895
+ if (overlay.isConnected && closeTimer === null) overlay.dataset.open = "true";
14799
14896
  });
14800
14897
  };
14801
14898
 
@@ -14829,6 +14926,7 @@ function generateFarmDevtoolsClientRuntime(config) {
14829
14926
  window.addEventListener("message", onMessage);
14830
14927
  window[runtimeKey] = {
14831
14928
  dispose() {
14929
+ finishClose();
14832
14930
  window.removeEventListener("keydown", onKeydown, true);
14833
14931
  window.removeEventListener("message", onMessage);
14834
14932
  },
@@ -15046,6 +15144,8 @@ __export(vite_exports, {
15046
15144
  defineConfig: () => defineConfig2,
15047
15145
  farmI18nClientBridgePlugin: () => farmI18nClientBridgePlugin,
15048
15146
  farmPlugin: () => farmPlugin,
15147
+ generateClientCachePersistenceCode: () => generateClientCachePersistenceCode,
15148
+ resolveFarmClientCacheAdapterEntry: () => resolveFarmClientCacheAdapterEntry,
15049
15149
  rewriteEarlySsrRelativeImports: () => rewriteEarlySsrRelativeImports,
15050
15150
  transformIsolatedClientBoundaryModule: () => transformIsolatedClientBoundaryModule,
15051
15151
  withFarmRequestTracing: () => withFarmRequestTracing
@@ -15090,10 +15190,11 @@ var ROUTE_PROP_LABELS = /* @__PURE__ */ new Map([
15090
15190
  ["middlewareData", "middleware request data"],
15091
15191
  ["context", "request context"]
15092
15192
  ]);
15093
- function resolveConfiguredRouteRenderingConfig(mod, source) {
15193
+ function resolveConfiguredRouteRenderingConfig(mod, source, options) {
15194
+ const pprEnabled = options?.experimentalPPR === true;
15094
15195
  const directiveConfig = parseRouteRenderingDirective(source);
15095
15196
  let ssg = directiveConfig?.ssg ?? false;
15096
- let ppr = directiveConfig?.ppr ?? false;
15197
+ let requestedPPR = directiveConfig?.ppr ?? false;
15097
15198
  let revalidate = directiveConfig?.revalidate;
15098
15199
  const moduleDynamic = normalizeDynamicMode(mod?.dynamic);
15099
15200
  const dynamic = moduleDynamic ?? directiveConfig?.dynamic;
@@ -15103,12 +15204,12 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
15103
15204
  ssg = mod.ssg === true;
15104
15205
  }
15105
15206
  if (hasExplicitPPR) {
15106
- ppr = mod?.ppr === true || mod?.experimental_ppr === true;
15207
+ requestedPPR = mod?.ppr === true || mod?.experimental_ppr === true;
15107
15208
  }
15108
15209
  if (typeof mod?.revalidate === "number") {
15109
15210
  if (mod.revalidate > 0) {
15110
15211
  revalidate = mod.revalidate;
15111
- if (!hasExplicitSsg && !ppr) {
15212
+ if (!hasExplicitSsg && !requestedPPR) {
15112
15213
  ssg = true;
15113
15214
  }
15114
15215
  } else {
@@ -15122,23 +15223,24 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
15122
15223
  }
15123
15224
  if (moduleDynamic === "force-static" || moduleDynamic === "error") {
15124
15225
  ssg = true;
15125
- ppr = false;
15226
+ requestedPPR = false;
15126
15227
  } else if (moduleDynamic === "force-dynamic") {
15127
15228
  ssg = false;
15128
- ppr = false;
15229
+ requestedPPR = false;
15129
15230
  revalidate = void 0;
15130
15231
  }
15232
+ const ppr = pprEnabled && !ssg && requestedPPR;
15131
15233
  return {
15132
15234
  ssg,
15133
- ppr: ssg ? false : ppr,
15235
+ ppr,
15134
15236
  revalidate: ssg || ppr ? revalidate : void 0,
15135
15237
  dynamic,
15136
15238
  directive: directiveConfig?.directive
15137
15239
  };
15138
15240
  }
15139
15241
  __name(resolveConfiguredRouteRenderingConfig, "resolveConfiguredRouteRenderingConfig");
15140
- function resolveRouteRenderingConfig(mod, source) {
15141
- const rendering = resolveConfiguredRouteRenderingConfig(mod, source);
15242
+ function resolveRouteRenderingConfig(mod, source, options) {
15243
+ const rendering = resolveConfiguredRouteRenderingConfig(mod, source, options);
15142
15244
  if (!rendering.ssg || !source) {
15143
15245
  return rendering;
15144
15246
  }
@@ -15153,9 +15255,9 @@ function resolveRouteRenderingConfig(mod, source) {
15153
15255
  };
15154
15256
  }
15155
15257
  __name(resolveRouteRenderingConfig, "resolveRouteRenderingConfig");
15156
- async function resolveRouteRenderingConfigFromFile(mod, filePath) {
15258
+ async function resolveRouteRenderingConfigFromFile(mod, filePath, options) {
15157
15259
  const source = await (0, import_promises2.readFile)(filePath, "utf8").catch(() => void 0);
15158
- return resolveRouteRenderingConfig(mod, source);
15260
+ return resolveRouteRenderingConfig(mod, source, options);
15159
15261
  }
15160
15262
  __name(resolveRouteRenderingConfigFromFile, "resolveRouteRenderingConfigFromFile");
15161
15263
  function analyzeStaticRouteCandidate(mod, source, options = {}) {
@@ -16253,7 +16355,7 @@ function getIslandStrategyExport(content) {
16253
16355
  __name(getIslandStrategyExport, "getIslandStrategyExport");
16254
16356
  function stripUseClientDirective(content) {
16255
16357
  return content.replace(
16256
- /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*)(["'])use client\2\s*;?\s*/,
16358
+ /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/|(?:"[^"\n]*"|'[^'\n]*')\s*;?)*)(["'])use client\2\s*;?\s*/,
16257
16359
  "$1"
16258
16360
  );
16259
16361
  }
@@ -19408,7 +19510,7 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
19408
19510
  return this.resolveMessage(locale, key);
19409
19511
  }
19410
19512
  hasMessage(locale, key) {
19411
- return (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !== void 0;
19513
+ return this.readOwnMessage(locale, key) !== void 0;
19412
19514
  }
19413
19515
  getClientSnapshot(resolution) {
19414
19516
  return {
@@ -19436,8 +19538,19 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
19436
19538
  }
19437
19539
  return formatter.format(values);
19438
19540
  }
19541
+ // Look up a message by own-property only. A key named after an
19542
+ // Object.prototype member (toString, valueOf, constructor, ...) must resolve
19543
+ // to a real catalog entry or undefined, never the inherited prototype value
19544
+ // (mirrors the own-property handling added to catalog.ts in #454).
19545
+ readOwnMessage(locale, key) {
19546
+ const direct = this.catalogs[locale];
19547
+ if (direct && Object.prototype.hasOwnProperty.call(direct, key)) return direct[key];
19548
+ const fallback = this.catalogs[this.config.fallbackLocale];
19549
+ if (fallback && Object.prototype.hasOwnProperty.call(fallback, key)) return fallback[key];
19550
+ return void 0;
19551
+ }
19439
19552
  resolveMessage(locale, key) {
19440
- const message = this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];
19553
+ const message = this.readOwnMessage(locale, key);
19441
19554
  if (message !== void 0) return message;
19442
19555
  if (this.config.strict) {
19443
19556
  throw new Error(`Missing Farm i18n message "${key}" for locale "${locale}".`);
@@ -21786,7 +21899,7 @@ _setFarmThemeServerSnapshotResolver(() => {
21786
21899
  });
21787
21900
 
21788
21901
  // package.json
21789
- var version = "0.1.0-beta.95";
21902
+ var version = "0.1.0-beta.97";
21790
21903
 
21791
21904
  // src/version.ts
21792
21905
  var FARM_VERSION = version;
@@ -22714,7 +22827,8 @@ var _ServerRenderer = class _ServerRenderer {
22714
22827
  }
22715
22828
  const renderingConfig = await resolveRouteRenderingConfigFromFile(
22716
22829
  routeModule,
22717
- route.modulePath
22830
+ route.modulePath,
22831
+ { experimentalPPR: this.config.experimental?.ppr === true }
22718
22832
  );
22719
22833
  const pprBypassReason = renderingConfig.ppr ? this.getPPRShellBypassReason(req, middlewareMap, middlewareContext, pluginExposedContext) : void 0;
22720
22834
  const canCachePPRShell = renderingConfig.ppr && !pprBypassReason;
@@ -23419,6 +23533,11 @@ var _ServerRenderer = class _ServerRenderer {
23419
23533
  );
23420
23534
  res.statusCode = options.statusCode;
23421
23535
  res.setHeader("Content-Type", "text/html; charset=utf-8");
23536
+ res.setHeader("Cache-Control", "private, no-store");
23537
+ res.setHeader("X-Content-Type-Options", "nosniff");
23538
+ if (typeof res.removeHeader === "function") {
23539
+ res.removeHeader("X-Farm-PPR");
23540
+ }
23422
23541
  res.write(this.createFullHTML(html, false, options.pathname));
23423
23542
  res.end();
23424
23543
  return true;
@@ -24156,6 +24275,7 @@ var _FarmApp = class _FarmApp {
24156
24275
  serverComponents: config.experimental?.serverComponents ?? false,
24157
24276
  serverActions: config.experimental?.serverActions ?? false,
24158
24277
  isolatedClientHydration: config.experimental?.isolatedClientHydration ?? "off",
24278
+ ppr: config.experimental?.ppr ?? false,
24159
24279
  ...config.experimental
24160
24280
  },
24161
24281
  vite: config.vite || {}
@@ -24510,6 +24630,53 @@ function isArrayIndex(key) {
24510
24630
  }
24511
24631
  __name(isArrayIndex, "isArrayIndex");
24512
24632
 
24633
+ // src/client-cache-persistence-build.ts
24634
+ var import_node_fs5 = __toESM(require("fs"));
24635
+ var import_node_path10 = __toESM(require("path"));
24636
+ var ADAPTER_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
24637
+ function resolveFarmClientCacheAdapterEntry(root, cache) {
24638
+ const client = cache?.client;
24639
+ const adapter = client?.adapter;
24640
+ if (adapter === void 0) return void 0;
24641
+ if (typeof adapter !== "string" || adapter.trim().length === 0) {
24642
+ throw new Error(
24643
+ 'cache.client.adapter must be a module path string, for example "./src/cache-adapter".'
24644
+ );
24645
+ }
24646
+ const resolved = import_node_path10.default.resolve(root, adapter);
24647
+ const found = resolveAdapterFile(resolved);
24648
+ if (!found) {
24649
+ throw new Error(
24650
+ `cache.client.adapter was not found: ${adapter} (resolved to ${resolved}). Point it at a client module whose default export is created with defineClientCacheAdapter().`
24651
+ );
24652
+ }
24653
+ const options = {};
24654
+ if (client?.version !== void 0) options.version = client.version;
24655
+ if (client?.flushDelayMs !== void 0) options.flushDelayMs = client.flushDelayMs;
24656
+ return { importPath: found.replace(/\\/g, "/"), options };
24657
+ }
24658
+ __name(resolveFarmClientCacheAdapterEntry, "resolveFarmClientCacheAdapterEntry");
24659
+ function resolveAdapterFile(resolved) {
24660
+ if (import_node_fs5.default.existsSync(resolved) && import_node_fs5.default.statSync(resolved).isFile()) return resolved;
24661
+ for (const extension of ADAPTER_EXTENSIONS) {
24662
+ const candidate = `${resolved}.${extension}`;
24663
+ if (import_node_fs5.default.existsSync(candidate) && import_node_fs5.default.statSync(candidate).isFile()) return candidate;
24664
+ }
24665
+ return void 0;
24666
+ }
24667
+ __name(resolveAdapterFile, "resolveAdapterFile");
24668
+ function generateClientCachePersistenceCode(entry) {
24669
+ if (!entry) return { imports: "", init: "" };
24670
+ return {
24671
+ imports: [
24672
+ `import * as __farmClientCacheAdapterModule from ${JSON.stringify(entry.importPath)};`,
24673
+ `import { initConfiguredClientCachePersistence as __farmInitClientCachePersistence } from "@farm.js/core/client";`
24674
+ ].join("\n"),
24675
+ init: `__farmInitClientCachePersistence(__farmClientCacheAdapterModule, ${JSON.stringify(entry.options)});`
24676
+ };
24677
+ }
24678
+ __name(generateClientCachePersistenceCode, "generateClientCachePersistenceCode");
24679
+
24513
24680
  // src/api/endpoint.ts
24514
24681
  var import_better_call = require("better-call");
24515
24682
  init_cache();
@@ -24537,15 +24704,15 @@ function isEndpointFailure(value) {
24537
24704
  }
24538
24705
  __name(isEndpointFailure, "isEndpointFailure");
24539
24706
  function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
24540
- let path34;
24707
+ let path35;
24541
24708
  let options;
24542
24709
  let handler;
24543
24710
  if (typeof pathOrOptions === "string") {
24544
- path34 = pathOrOptions;
24711
+ path35 = pathOrOptions;
24545
24712
  options = optionsOrHandler;
24546
24713
  handler = maybeHandler;
24547
24714
  } else {
24548
- path34 = "";
24715
+ path35 = "";
24549
24716
  options = pathOrOptions;
24550
24717
  handler = optionsOrHandler;
24551
24718
  }
@@ -24572,13 +24739,13 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
24572
24739
  ...betterCallOptions
24573
24740
  } = options;
24574
24741
  const endpoint = (0, import_better_call.createEndpoint)(
24575
- path34 || "/__farm_auto_path__",
24742
+ path35 || "/__farm_auto_path__",
24576
24743
  betterCallOptions,
24577
24744
  wrappedHandler
24578
24745
  );
24579
- endpoint.__path = path34 || void 0;
24746
+ endpoint.__path = path35 || void 0;
24580
24747
  endpoint.__method = options.method || "GET";
24581
- endpoint.__autoPath = !path34;
24748
+ endpoint.__autoPath = !path35;
24582
24749
  endpoint.__handler = wrappedHandler;
24583
24750
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
24584
24751
  endpoint.__middleware = middleware;
@@ -24589,6 +24756,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
24589
24756
  body: options.body,
24590
24757
  inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
24591
24758
  query: options.query,
24759
+ inputQuery: options.query,
24592
24760
  headers: options.headers,
24593
24761
  response: null,
24594
24762
  errors
@@ -24785,10 +24953,10 @@ function createRouteFactoryAt(prefix) {
24785
24953
  "OPTIONS"
24786
24954
  ]) {
24787
24955
  factory[method.toLowerCase()] = (child, options) => {
24788
- const path34 = joinRoutePath(prefix, child);
24956
+ const path35 = joinRoutePath(prefix, child);
24789
24957
  const input = options.input ?? {};
24790
24958
  const endpoint = createEndpoint(
24791
- path34,
24959
+ path35,
24792
24960
  {
24793
24961
  method,
24794
24962
  body: input.body,
@@ -24804,7 +24972,7 @@ function createRouteFactoryAt(prefix) {
24804
24972
  );
24805
24973
  endpoint.__types.params = input.params;
24806
24974
  endpoint.__output = options.output;
24807
- return Object.freeze({ path: path34, method, endpoint });
24975
+ return Object.freeze({ path: path35, method, endpoint });
24808
24976
  };
24809
24977
  }
24810
24978
  return Object.freeze(factory);
@@ -24812,21 +24980,21 @@ function createRouteFactoryAt(prefix) {
24812
24980
  __name(createRouteFactoryAt, "createRouteFactoryAt");
24813
24981
  function joinRoutePath(prefix, child) {
24814
24982
  if (typeof child !== "string") throw new TypeError("Route paths must be strings.");
24815
- const path34 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
24816
- if (!(path34 === "/api" || path34.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path34)) {
24983
+ const path35 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
24984
+ if (!(path35 === "/api" || path35.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path35)) {
24817
24985
  throw new TypeError(
24818
- `Plugin route "${path34}" must be a canonical /api path without a query, hash, or empty segment.`
24986
+ `Plugin route "${path35}" must be a canonical /api path without a query, hash, or empty segment.`
24819
24987
  );
24820
24988
  }
24821
- assertBrowserStableRoutePath(path34);
24822
- assertUniqueRouteParameters(path34, "api");
24823
- getRoutePatternShape(path34, "api");
24824
- for (const segment of path34.split("/")) {
24989
+ assertBrowserStableRoutePath(path35);
24990
+ assertUniqueRouteParameters(path35, "api");
24991
+ getRoutePatternShape(path35, "api");
24992
+ for (const segment of path35.split("/")) {
24825
24993
  if (["__proto__", "constructor", "prototype", "$params"].includes(segment)) {
24826
24994
  throw new TypeError(`Route segment "${segment}" is reserved.`);
24827
24995
  }
24828
24996
  }
24829
- return path34;
24997
+ return path35;
24830
24998
  }
24831
24999
  __name(joinRoutePath, "joinRoutePath");
24832
25000
  function resolvePluginRoutes(plugins = []) {
@@ -24879,7 +25047,7 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
24879
25047
  }
24880
25048
  const result = [...routes.values()];
24881
25049
  if (expected) {
24882
- const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path34, methods }) => `${path34}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
25050
+ const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path35, methods }) => `${path35}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
24883
25051
  if (signature(result) !== signature(expected)) {
24884
25052
  throw new Error(
24885
25053
  "Plugin API routes changed between build and runtime. Route paths and methods must be stable across environments; rebuild the app."
@@ -24891,8 +25059,8 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
24891
25059
  __name(mergePluginAPIRoutes, "mergePluginAPIRoutes");
24892
25060
 
24893
25061
  // src/api/route-manager.ts
24894
- var fs6 = __toESM(require("fs"));
24895
- var path16 = __toESM(require("path"));
25062
+ var fs7 = __toESM(require("fs"));
25063
+ var path17 = __toESM(require("path"));
24896
25064
  init_utils();
24897
25065
  init_routes_shared();
24898
25066
  init_route_runtime();
@@ -25356,9 +25524,9 @@ var _APIRouteManager = class _APIRouteManager {
25356
25524
  this.routeShapes = /* @__PURE__ */ new Map();
25357
25525
  try {
25358
25526
  for (const appDir of this.appDirs) {
25359
- const apiDir = path16.join(appDir, "api");
25527
+ const apiDir = path17.join(appDir, "api");
25360
25528
  let routeFiles = [];
25361
- if (fs6.existsSync(apiDir)) {
25529
+ if (fs7.existsSync(apiDir)) {
25362
25530
  routeFiles = this.findRouteFiles(apiDir);
25363
25531
  }
25364
25532
  for (const filePath of routeFiles) {
@@ -25391,12 +25559,12 @@ var _APIRouteManager = class _APIRouteManager {
25391
25559
  */
25392
25560
  findRouteFiles(dir) {
25393
25561
  const files = [];
25394
- if (!fs6.existsSync(dir)) {
25562
+ if (!fs7.existsSync(dir)) {
25395
25563
  return files;
25396
25564
  }
25397
- const entries = fs6.readdirSync(dir, { withFileTypes: true });
25565
+ const entries = fs7.readdirSync(dir, { withFileTypes: true });
25398
25566
  for (const entry of entries) {
25399
- const fullPath = path16.join(dir, entry.name);
25567
+ const fullPath = path17.join(dir, entry.name);
25400
25568
  if (entry.isDirectory()) {
25401
25569
  files.push(...this.findRouteFiles(fullPath));
25402
25570
  } else if (isFarmAPIRouteFileName(entry.name)) {
@@ -25410,8 +25578,8 @@ var _APIRouteManager = class _APIRouteManager {
25410
25578
  */
25411
25579
  async loadRoute(filePath, appDir) {
25412
25580
  try {
25413
- const apiDir = path16.join(appDir, "api");
25414
- const relativePath2 = path16.relative(apiDir, path16.dirname(filePath));
25581
+ const apiDir = path17.join(appDir, "api");
25582
+ const relativePath2 = path17.relative(apiDir, path17.dirname(filePath));
25415
25583
  const routePath = "/api/" + (relativePath2 === "." ? "" : relativePath2.replace(/\\/g, "/"));
25416
25584
  const routeModule = await this.loadModule(filePath);
25417
25585
  const endpoints = {};
@@ -25484,7 +25652,7 @@ var _APIRouteManager = class _APIRouteManager {
25484
25652
  }
25485
25653
  }
25486
25654
  async loadProgrammaticApiRoutes(appDir) {
25487
- const candidateRoots = [path16.dirname(appDir), appDir];
25655
+ const candidateRoots = [path17.dirname(appDir), appDir];
25488
25656
  const routeFiles = Array.from(
25489
25657
  new Set(candidateRoots.flatMap((srcRoot) => findProgrammaticRouteFilesInDir(srcRoot)))
25490
25658
  );
@@ -25513,16 +25681,16 @@ var _APIRouteManager = class _APIRouteManager {
25513
25681
  }
25514
25682
  findRootRoutesFile(appDir) {
25515
25683
  const routeNames = ["routes.ts", "routes.tsx", "routes.js"];
25516
- const candidateDirs = [path16.dirname(appDir), appDir];
25684
+ const candidateDirs = [path17.dirname(appDir), appDir];
25517
25685
  const seen = /* @__PURE__ */ new Set();
25518
25686
  for (const dir of candidateDirs) {
25519
25687
  for (const routeName of routeNames) {
25520
- const routesFile = path16.join(dir, routeName);
25688
+ const routesFile = path17.join(dir, routeName);
25521
25689
  if (seen.has(routesFile)) {
25522
25690
  continue;
25523
25691
  }
25524
25692
  seen.add(routesFile);
25525
- if (fs6.existsSync(routesFile)) {
25693
+ if (fs7.existsSync(routesFile)) {
25526
25694
  return routesFile;
25527
25695
  }
25528
25696
  }
@@ -25656,8 +25824,8 @@ var APIRouteManager = _APIRouteManager;
25656
25824
  init_config3();
25657
25825
 
25658
25826
  // src/middleware/manager.ts
25659
- var fs7 = __toESM(require("fs"));
25660
- var path17 = __toESM(require("path"));
25827
+ var fs8 = __toESM(require("fs"));
25828
+ var path18 = __toESM(require("path"));
25661
25829
  init_decode();
25662
25830
 
25663
25831
  // src/middleware/cookie-header.ts
@@ -26058,7 +26226,7 @@ var _MiddlewareManager = class _MiddlewareManager {
26058
26226
  * Recursively discover middleware files
26059
26227
  */
26060
26228
  async discoverInDirectory(dir, routePath, discovered) {
26061
- if (!fs7.existsSync(dir)) {
26229
+ if (!fs8.existsSync(dir)) {
26062
26230
  return;
26063
26231
  }
26064
26232
  const middlewareFile = this.findMiddlewareFile(dir);
@@ -26068,10 +26236,10 @@ var _MiddlewareManager = class _MiddlewareManager {
26068
26236
  discovered.push(middleware);
26069
26237
  }
26070
26238
  }
26071
- const entries = fs7.readdirSync(dir, { withFileTypes: true });
26239
+ const entries = fs8.readdirSync(dir, { withFileTypes: true });
26072
26240
  for (const entry of entries) {
26073
26241
  if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
26074
- const subPath = path17.join(dir, entry.name);
26242
+ const subPath = path18.join(dir, entry.name);
26075
26243
  const subRoutePath = appendMiddlewareRoutePath(routePath, entry.name);
26076
26244
  await this.discoverInDirectory(subPath, subRoutePath, discovered);
26077
26245
  }
@@ -26083,8 +26251,8 @@ var _MiddlewareManager = class _MiddlewareManager {
26083
26251
  findMiddlewareFile(dir) {
26084
26252
  const extensions = [".ts", ".tsx", ".js", ".jsx"];
26085
26253
  for (const ext of extensions) {
26086
- const filePath = path17.join(dir, `middleware${ext}`);
26087
- if (fs7.existsSync(filePath)) {
26254
+ const filePath = path18.join(dir, `middleware${ext}`);
26255
+ if (fs8.existsSync(filePath)) {
26088
26256
  return filePath;
26089
26257
  }
26090
26258
  }
@@ -26424,8 +26592,8 @@ var import_path9 = require("path");
26424
26592
  init_type_generator();
26425
26593
 
26426
26594
  // src/routing/generate-route-types.ts
26427
- var path18 = __toESM(require("path"));
26428
- var fs8 = __toESM(require("fs"));
26595
+ var path19 = __toESM(require("path"));
26596
+ var fs9 = __toESM(require("fs"));
26429
26597
  init_utils();
26430
26598
  init_write_file_if_changed();
26431
26599
  init_renderer();
@@ -26478,12 +26646,12 @@ function createRoutePattern(route) {
26478
26646
  __name(createRoutePattern, "createRoutePattern");
26479
26647
  var DEFAULT_OUT_FILE = "farm-routes.d.ts";
26480
26648
  async function generateRouteTypes(options) {
26481
- const root = path18.resolve(options.root);
26649
+ const root = path19.resolve(options.root);
26482
26650
  const srcDir = options.srcDir || "src";
26483
26651
  const outFile = options.outFile || DEFAULT_OUT_FILE;
26484
- const outPath = path18.isAbsolute(outFile) ? outFile : path18.join(root, srcDir, outFile);
26652
+ const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
26485
26653
  const content = await createRouteTypeDeclarations(options, outPath);
26486
- fs8.mkdirSync(path18.dirname(outPath), { recursive: true });
26654
+ fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
26487
26655
  writeFileIfChanged(outPath, content);
26488
26656
  return outPath;
26489
26657
  }
@@ -26498,8 +26666,8 @@ async function createRouteTypeDeclarations(options, outPath) {
26498
26666
  const routeModulePatterns = /* @__PURE__ */ new Set();
26499
26667
  const glob = await import("fast-glob");
26500
26668
  for (const source of sourceRoots) {
26501
- const appDir = path18.join(source.root, source.srcDir, "app");
26502
- if (fs8.existsSync(appDir)) {
26669
+ const appDir = path19.join(source.root, source.srcDir, "app");
26670
+ if (fs9.existsSync(appDir)) {
26503
26671
  const routeModuleFiles = await glob.default(
26504
26672
  `**/{page,layout,loading,error}.{${componentExtensions.join(",")},md,mdx}`,
26505
26673
  {
@@ -26535,7 +26703,7 @@ async function createRouteTypeDeclarations(options, outPath) {
26535
26703
  const routePathType = suppressLintOnLink ? "string" : renderTypeUnion(typeLiterals);
26536
26704
  const routePatternType = suppressLintOnLink ? "string" : renderTypeUnion(patternLiterals);
26537
26705
  const routeModulePatternType = renderTypeUnion(routeModulePatternLiterals);
26538
- const routeTypesImportPath = `./${path18.basename(outPath).replace(/\.d\.ts$/, "")}`;
26706
+ const routeTypesImportPath = `./${path19.basename(outPath).replace(/\.d\.ts$/, "")}`;
26539
26707
  const linkAugmentationBlock = suppressLintOnLink ? "" : `
26540
26708
  declare module "@farm.js/core/client" {
26541
26709
  interface LinkDefaultRoute {
@@ -26585,8 +26753,8 @@ ${renderTypeAlias("RouteModulePattern", routeModulePatternType)}${linkAugmentati
26585
26753
  __name(createRouteTypeDeclarations, "createRouteTypeDeclarations");
26586
26754
 
26587
26755
  // src/env-types.ts
26588
- var fs9 = __toESM(require("fs"));
26589
- var path19 = __toESM(require("path"));
26756
+ var fs10 = __toESM(require("fs"));
26757
+ var path20 = __toESM(require("path"));
26590
26758
  init_write_file_if_changed();
26591
26759
  var DEFAULT_OUT_FILE2 = "farm-env.d.ts";
26592
26760
  var CONFIG_FILENAMES2 = [
@@ -26608,21 +26776,21 @@ var CONFIG_FILENAMES2 = [
26608
26776
  "config.cjs"
26609
26777
  ];
26610
26778
  async function generateEnvTypes(options) {
26611
- const root = path19.resolve(options.root);
26779
+ const root = path20.resolve(options.root);
26612
26780
  const srcDir = options.srcDir || "src";
26613
26781
  const outFile = options.outFile || DEFAULT_OUT_FILE2;
26614
- const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
26782
+ const outPath = path20.isAbsolute(outFile) ? outFile : path20.join(root, srcDir, outFile);
26615
26783
  const content = createEnvTypeDeclarations(options, outPath);
26616
- fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
26784
+ fs10.mkdirSync(path20.dirname(outPath), { recursive: true });
26617
26785
  writeFileIfChanged(outPath, content);
26618
26786
  return outPath;
26619
26787
  }
26620
26788
  __name(generateEnvTypes, "generateEnvTypes");
26621
26789
  function createEnvTypeDeclarations(options, outPath) {
26622
- const root = path19.resolve(options.root);
26790
+ const root = path20.resolve(options.root);
26623
26791
  const configPath = findConfigPath(root, options.configPath);
26624
26792
  const configPaths = [
26625
- ...(options.layerConfigPaths ?? []).filter((value) => fs9.existsSync(value)),
26793
+ ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
26626
26794
  ...configPath ? [configPath] : []
26627
26795
  ];
26628
26796
  const content = configPaths.length > 1 ? createLayeredConfigBackedEnvTypes(outPath, configPaths) : configPaths.length === 1 ? createConfigBackedEnvTypes(outPath, configPaths[0]) : createEmptyEnvTypes();
@@ -26684,12 +26852,12 @@ export {};
26684
26852
  __name(createLayeredConfigBackedEnvTypes, "createLayeredConfigBackedEnvTypes");
26685
26853
  function findConfigPath(root, configPath) {
26686
26854
  if (configPath) {
26687
- const resolvedPath = path19.isAbsolute(configPath) ? configPath : path19.join(root, configPath);
26688
- return fs9.existsSync(resolvedPath) ? resolvedPath : null;
26855
+ const resolvedPath = path20.isAbsolute(configPath) ? configPath : path20.join(root, configPath);
26856
+ return fs10.existsSync(resolvedPath) ? resolvedPath : null;
26689
26857
  }
26690
26858
  for (const filename of CONFIG_FILENAMES2) {
26691
- const resolvedPath = path19.join(root, filename);
26692
- if (fs9.existsSync(resolvedPath)) {
26859
+ const resolvedPath = path20.join(root, filename);
26860
+ if (fs10.existsSync(resolvedPath)) {
26693
26861
  return resolvedPath;
26694
26862
  }
26695
26863
  }
@@ -26752,19 +26920,19 @@ export {};
26752
26920
  }
26753
26921
  __name(createEmptyEnvTypes, "createEmptyEnvTypes");
26754
26922
  function toTypeImportPath(outPath, targetPath) {
26755
- const relativePath2 = path19.relative(path19.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26923
+ const relativePath2 = path20.relative(path20.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26756
26924
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
26757
26925
  }
26758
26926
  __name(toTypeImportPath, "toTypeImportPath");
26759
26927
 
26760
26928
  // src/image-types.ts
26761
- var import_node_fs6 = require("fs");
26762
- var import_node_path10 = __toESM(require("path"));
26929
+ var import_node_fs7 = require("fs");
26930
+ var import_node_path11 = __toESM(require("path"));
26763
26931
  init_write_file_if_changed();
26764
26932
  var FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
26765
26933
  function generateFarmImageTypes(options) {
26766
- 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");
26767
- (0, import_node_fs6.mkdirSync)(import_node_path10.default.dirname(outputPath), { recursive: true });
26934
+ 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");
26935
+ (0, import_node_fs7.mkdirSync)(import_node_path11.default.dirname(outputPath), { recursive: true });
26768
26936
  writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
26769
26937
  return outputPath;
26770
26938
  }
@@ -26792,8 +26960,8 @@ declare module "*?url" {
26792
26960
  __name(createFarmImageTypeDeclarations, "createFarmImageTypeDeclarations");
26793
26961
 
26794
26962
  // src/content-types.ts
26795
- var fs10 = __toESM(require("fs"));
26796
- var path21 = __toESM(require("path"));
26963
+ var fs11 = __toESM(require("fs"));
26964
+ var path22 = __toESM(require("path"));
26797
26965
  var CONFIG_FILENAMES3 = [
26798
26966
  "farm.config.ts",
26799
26967
  "farm.config.tsx",
@@ -26813,10 +26981,10 @@ var CONFIG_FILENAMES3 = [
26813
26981
  "config.cjs"
26814
26982
  ];
26815
26983
  function createContentTypeDeclarations(options, outPath) {
26816
- const root = path21.resolve(options.root);
26984
+ const root = path22.resolve(options.root);
26817
26985
  const projectConfig = findConfigPath2(root, options.configPath);
26818
26986
  const configPaths = [
26819
- ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
26987
+ ...(options.layerConfigPaths ?? []).filter((value) => fs11.existsSync(value)),
26820
26988
  ...projectConfig ? [projectConfig] : []
26821
26989
  ];
26822
26990
  if (configPaths.length === 0) return createEmptyContentTypes();
@@ -26886,32 +27054,32 @@ export {};
26886
27054
  __name(createEmptyContentTypes, "createEmptyContentTypes");
26887
27055
  function findConfigPath2(root, configPath) {
26888
27056
  if (configPath) {
26889
- const resolvedPath = path21.isAbsolute(configPath) ? configPath : path21.join(root, configPath);
26890
- return fs10.existsSync(resolvedPath) ? resolvedPath : null;
27057
+ const resolvedPath = path22.isAbsolute(configPath) ? configPath : path22.join(root, configPath);
27058
+ return fs11.existsSync(resolvedPath) ? resolvedPath : null;
26891
27059
  }
26892
27060
  for (const filename of CONFIG_FILENAMES3) {
26893
- const resolvedPath = path21.join(root, filename);
26894
- if (fs10.existsSync(resolvedPath)) return resolvedPath;
27061
+ const resolvedPath = path22.join(root, filename);
27062
+ if (fs11.existsSync(resolvedPath)) return resolvedPath;
26895
27063
  }
26896
27064
  return null;
26897
27065
  }
26898
27066
  __name(findConfigPath2, "findConfigPath");
26899
27067
  function toTypeImportPath2(outPath, targetPath) {
26900
- const relativePath2 = path21.relative(path21.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
27068
+ const relativePath2 = path22.relative(path22.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
26901
27069
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
26902
27070
  }
26903
27071
  __name(toTypeImportPath2, "toTypeImportPath");
26904
27072
 
26905
27073
  // src/i18n/type-generator.ts
26906
- var import_node_fs7 = require("fs");
26907
- var import_node_path11 = require("path");
27074
+ var import_node_fs8 = require("fs");
27075
+ var import_node_path12 = require("path");
26908
27076
  init_write_file_if_changed();
26909
27077
  async function generateFarmI18nTypes(options) {
26910
27078
  if (!options.config.enabled) return void 0;
26911
27079
  const { signatures } = await readFarmI18nCatalogs(options.config);
26912
- 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");
27080
+ 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");
26913
27081
  const content = renderFarmI18nTypes(options.config.locales, signatures);
26914
- (0, import_node_fs7.mkdirSync)((0, import_node_path11.dirname)(outFile), { recursive: true });
27082
+ (0, import_node_fs8.mkdirSync)((0, import_node_path12.dirname)(outFile), { recursive: true });
26915
27083
  writeFileIfChanged(outFile, content);
26916
27084
  return outFile;
26917
27085
  }
@@ -27204,8 +27372,8 @@ init_integrations();
27204
27372
  init_route_context();
27205
27373
  init_devtools_config();
27206
27374
  init_dev_indicators();
27207
- var fs12 = __toESM(require("fs"));
27208
- var path33 = __toESM(require("path"));
27375
+ var fs13 = __toESM(require("fs"));
27376
+ var path34 = __toESM(require("path"));
27209
27377
  var import_node_url8 = require("url");
27210
27378
  init_layers();
27211
27379
 
@@ -27674,8 +27842,8 @@ function _runWithAPIRequestRuntime(runtime, run) {
27674
27842
  __name(_runWithAPIRequestRuntime, "_runWithAPIRequestRuntime");
27675
27843
 
27676
27844
  // src/dev-static.ts
27677
- var fs11 = __toESM(require("fs"));
27678
- var path22 = __toESM(require("path"));
27845
+ var fs12 = __toESM(require("fs"));
27846
+ var path23 = __toESM(require("path"));
27679
27847
  function shouldBypassFarmRouterForDottedPath(pathname, routeManager, baseDirs) {
27680
27848
  if (!pathname.includes(".") || pathname.endsWith(".html")) return false;
27681
27849
  const matchesAppRoute = Boolean(
@@ -27695,11 +27863,11 @@ function devServableFileExists(pathname, baseDirs) {
27695
27863
  if (!relativePathname) return false;
27696
27864
  for (const baseDir of baseDirs) {
27697
27865
  if (typeof baseDir !== "string" || baseDir.length === 0) continue;
27698
- const resolvedBase = path22.resolve(baseDir);
27699
- const candidate = path22.resolve(resolvedBase, relativePathname);
27700
- if (!candidate.startsWith(resolvedBase + path22.sep)) continue;
27866
+ const resolvedBase = path23.resolve(baseDir);
27867
+ const candidate = path23.resolve(resolvedBase, relativePathname);
27868
+ if (!candidate.startsWith(resolvedBase + path23.sep)) continue;
27701
27869
  try {
27702
- if (fs11.existsSync(candidate) && fs11.statSync(candidate).isFile()) {
27870
+ if (fs12.existsSync(candidate) && fs12.statSync(candidate).isFile()) {
27703
27871
  return true;
27704
27872
  }
27705
27873
  } catch {
@@ -27714,6 +27882,7 @@ var SERVER_FN_FACTORIES = ["createServerQuery", "createServerFn"];
27714
27882
  var FARM_CORE_IMPORT_RE = /import\s*(?!type\b)(?:[\w$]+\s*,\s*)?\{([^}]*)\}\s*from\s*(["'])@farm\.js\/core(?:\/[\w./-]+)?\2/g;
27715
27883
  function findClientServerFnViolation(code, id) {
27716
27884
  if (id.startsWith("\0") || id.startsWith("virtual:") || id.includes("node_modules")) return null;
27885
+ if (/\.(md|mdx)(\?|$)/.test(id)) return null;
27717
27886
  if (!code.includes("@farm.js/core")) return null;
27718
27887
  for (const match of code.matchAll(FARM_CORE_IMPORT_RE)) {
27719
27888
  const specifiers = match[1];
@@ -27743,7 +27912,7 @@ init_image_config();
27743
27912
 
27744
27913
  // src/image-vite.ts
27745
27914
  var import_promises7 = require("fs/promises");
27746
- var import_node_path12 = __toESM(require("path"));
27915
+ var import_node_path13 = __toESM(require("path"));
27747
27916
  var import_image_size2 = require("image-size");
27748
27917
  var FARM_IMAGE_ID_PREFIX = "\0farm:image:";
27749
27918
  var STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
@@ -27826,7 +27995,7 @@ init_image_server();
27826
27995
  init_routing();
27827
27996
 
27828
27997
  // src/server/vite-config.ts
27829
- var import_node_path13 = __toESM(require("path"));
27998
+ var import_node_path14 = __toESM(require("path"));
27830
27999
  var FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
27831
28000
  var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
27832
28001
  "react",
@@ -27850,9 +28019,9 @@ function getFarmClientOptimizeDepsInclude(renderer) {
27850
28019
  }
27851
28020
  __name(getFarmClientOptimizeDepsInclude, "getFarmClientOptimizeDepsInclude");
27852
28021
  function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
27853
- const resolvedProjectRoot = import_node_path13.default.resolve(projectRoot);
28022
+ const resolvedProjectRoot = import_node_path14.default.resolve(projectRoot);
27854
28023
  return appDirectories.map((appDirectory) => {
27855
- const relativeAppDirectory = import_node_path13.default.relative(resolvedProjectRoot, import_node_path13.default.resolve(appDirectory)).replace(/\\/g, "/");
28024
+ const relativeAppDirectory = import_node_path14.default.relative(resolvedProjectRoot, import_node_path14.default.resolve(appDirectory)).replace(/\\/g, "/");
27856
28025
  const prefix = relativeAppDirectory || ".";
27857
28026
  return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
27858
28027
  });
@@ -27876,7 +28045,7 @@ function createFarmClientOptimizeDepsConfig(entries, renderer) {
27876
28045
  __name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
27877
28046
  function createFarmSourceAlias(projectRoot, srcDir = "src") {
27878
28047
  return {
27879
- "@": import_node_path13.default.resolve(projectRoot, srcDir)
28048
+ "@": import_node_path14.default.resolve(projectRoot, srcDir)
27880
28049
  };
27881
28050
  }
27882
28051
  __name(createFarmSourceAlias, "createFarmSourceAlias");
@@ -27915,7 +28084,7 @@ init_observability();
27915
28084
  init_renderer();
27916
28085
 
27917
28086
  // src/integration-provider-build.ts
27918
- var import_node_path15 = __toESM(require("path"));
28087
+ var import_node_path16 = __toESM(require("path"));
27919
28088
  init_integrations();
27920
28089
  init_utils();
27921
28090
  function generateFarmIntegrationProviderClientCode(providers, root) {
@@ -27972,7 +28141,7 @@ function wrapWithIntegrationProviders(element) {
27972
28141
  __name(generateFarmIntegrationProviderClientCode, "generateFarmIntegrationProviderClientCode");
27973
28142
  function resolveProviderModule(moduleId, root) {
27974
28143
  if (!moduleId.startsWith(".")) return moduleId;
27975
- return toViteModuleId(import_node_path15.default.resolve(root, moduleId), root);
28144
+ return toViteModuleId(import_node_path16.default.resolve(root, moduleId), root);
27976
28145
  }
27977
28146
  __name(resolveProviderModule, "resolveProviderModule");
27978
28147
 
@@ -28040,6 +28209,7 @@ var createEmptyTypeArtifactSelection = /* @__PURE__ */ __name(() => ({
28040
28209
  i18n: false
28041
28210
  }), "createEmptyTypeArtifactSelection");
28042
28211
  var FARM_I18N_CLIENT_BRIDGE_ID = "\0farm-i18n-client-bridge";
28212
+ var warnedDeprecatedDevtoolsDashboard = false;
28043
28213
  var EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME = `
28044
28214
  function isFarmDocsSearchPage() {
28045
28215
  return false;
@@ -28458,11 +28628,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
28458
28628
  }
28459
28629
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
28460
28630
  function fileContainsProgrammaticPageRoute(file) {
28461
- if (!fs12.existsSync(file)) {
28631
+ if (!fs13.existsSync(file)) {
28462
28632
  return false;
28463
28633
  }
28464
28634
  try {
28465
- return scanProgrammaticPagePaths(fs12.readFileSync(file, "utf8")).length > 0;
28635
+ return scanProgrammaticPagePaths(fs13.readFileSync(file, "utf8")).length > 0;
28466
28636
  } catch {
28467
28637
  return false;
28468
28638
  }
@@ -28470,7 +28640,7 @@ function fileContainsProgrammaticPageRoute(file) {
28470
28640
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
28471
28641
  function rewriteEarlySsrRelativeImports(options) {
28472
28642
  const cleanId = options.id.split("?", 1)[0];
28473
- if (!path33.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
28643
+ if (!path34.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
28474
28644
  return null;
28475
28645
  }
28476
28646
  const replacements = [];
@@ -28490,7 +28660,7 @@ function rewriteEarlySsrRelativeImports(options) {
28490
28660
  const suffixIndex = source.value.search(/[?#]/);
28491
28661
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
28492
28662
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
28493
- const resolvedPath = path33.resolve(path33.dirname(cleanId), sourcePath);
28663
+ const resolvedPath = path34.resolve(path34.dirname(cleanId), sourcePath);
28494
28664
  replacements.push({
28495
28665
  start: source.start,
28496
28666
  end: source.end,
@@ -28652,7 +28822,7 @@ function farmPlugin(options = {}, initialPluginManager) {
28652
28822
  ...layerRoots.length ? {
28653
28823
  server: {
28654
28824
  fs: {
28655
- allow: [path33.resolve(options.root || process.cwd()), ...layerRoots]
28825
+ allow: [path34.resolve(options.root || process.cwd()), ...layerRoots]
28656
28826
  }
28657
28827
  }
28658
28828
  } : {}
@@ -28683,13 +28853,13 @@ function farmPlugin(options = {}, initialPluginManager) {
28683
28853
  },
28684
28854
  server
28685
28855
  );
28686
- const globalsCSSPath = path33.join(server.config.root, "src/app/globals.css");
28687
- if (!fs12.existsSync(globalsCSSPath)) {
28688
- const appDir = path33.join(server.config.root, "src/app");
28689
- if (!fs12.existsSync(appDir)) {
28690
- fs12.mkdirSync(appDir, { recursive: true });
28856
+ const globalsCSSPath = path34.join(server.config.root, "src/app/globals.css");
28857
+ if (!fs13.existsSync(globalsCSSPath)) {
28858
+ const appDir = path34.join(server.config.root, "src/app");
28859
+ if (!fs13.existsSync(appDir)) {
28860
+ fs13.mkdirSync(appDir, { recursive: true });
28691
28861
  }
28692
- fs12.writeFileSync(globalsCSSPath, defaultGlobalCSS);
28862
+ fs13.writeFileSync(globalsCSSPath, defaultGlobalCSS);
28693
28863
  }
28694
28864
  await farmApp.initialize();
28695
28865
  const farmConfig = farmApp.getConfig();
@@ -28710,10 +28880,10 @@ function farmPlugin(options = {}, initialPluginManager) {
28710
28880
  });
28711
28881
  }
28712
28882
  const sourceRoots = getFarmSourceRoots(farmConfig);
28713
- server.watcher.add(sourceRoots.map((source) => path33.join(source.root, source.srcDir)));
28883
+ server.watcher.add(sourceRoots.map((source) => path34.join(source.root, source.srcDir)));
28714
28884
  if (farmConfig.i18n.enabled) {
28715
28885
  server.watcher.add(
28716
- farmConfig.i18n.messages.includes("{locale}") ? path33.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
28886
+ farmConfig.i18n.messages.includes("{locale}") ? path34.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
28717
28887
  );
28718
28888
  }
28719
28889
  const workflowConfig = farmConfig.workflows;
@@ -28723,7 +28893,7 @@ function farmPlugin(options = {}, initialPluginManager) {
28723
28893
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
28724
28894
  ], "getExtraRouteTypes");
28725
28895
  const appDirSlugs = sourceRoots.map(
28726
- (source) => path33.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
28896
+ (source) => path34.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
28727
28897
  );
28728
28898
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
28729
28899
  try {
@@ -28764,7 +28934,7 @@ function farmPlugin(options = {}, initialPluginManager) {
28764
28934
  }, "generateTypeArtifacts");
28765
28935
  await generateTypeArtifacts("startup");
28766
28936
  const srcDirSlugs = sourceRoots.map(
28767
- (source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")
28937
+ (source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")
28768
28938
  );
28769
28939
  const layerConfigFiles = new Set(
28770
28940
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -28885,7 +29055,7 @@ function farmPlugin(options = {}, initialPluginManager) {
28885
29055
  await apiRouteManager.discoverRoutes();
28886
29056
  let discoveredWorkflows = [];
28887
29057
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
28888
- (dir) => fs12.existsSync(path33.isAbsolute(dir) ? dir : path33.join(farmConfig.root, dir))
29058
+ (dir) => fs13.existsSync(path34.isAbsolute(dir) ? dir : path34.join(farmConfig.root, dir))
28889
29059
  );
28890
29060
  if (hasWorkflowDirectory) {
28891
29061
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -29150,12 +29320,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
29150
29320
  }
29151
29321
  }
29152
29322
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
29153
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs12.existsSync(farmDocsFontPath)) {
29323
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs13.existsSync(farmDocsFontPath)) {
29154
29324
  res.statusCode = 200;
29155
29325
  res.setHeader("Content-Type", "font/woff2");
29156
29326
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
29157
29327
  if (requestMethod === "HEAD") res.end();
29158
- else fs12.createReadStream(farmDocsFontPath).pipe(res);
29328
+ else fs13.createReadStream(farmDocsFontPath).pipe(res);
29159
29329
  return;
29160
29330
  }
29161
29331
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -29211,6 +29381,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
29211
29381
  if (requestPathname.endsWith(".json")) {
29212
29382
  res.end(JSON.stringify(snapshot, null, 2));
29213
29383
  } else {
29384
+ if (!warnedDeprecatedDevtoolsDashboard) {
29385
+ warnedDeprecatedDevtoolsDashboard = true;
29386
+ logger.warn(
29387
+ "The built-in DevTools dashboard is deprecated. Install @farm.js/devtools and add devtools() to plugins in farm.config.ts."
29388
+ );
29389
+ }
29214
29390
  const { renderFarmDevtoolsHtml: renderFarmDevtoolsHtml2 } = await loadFarmDevtoolsUIRuntime();
29215
29391
  res.end(renderFarmDevtoolsHtml2(snapshot));
29216
29392
  }
@@ -29253,7 +29429,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
29253
29429
  return null;
29254
29430
  }
29255
29431
  return {
29256
- source: await fs12.promises.readFile(sourcePath, "utf8"),
29432
+ source: await fs13.promises.readFile(sourcePath, "utf8"),
29257
29433
  filePath: sourcePath
29258
29434
  };
29259
29435
  }, "resolveSource")
@@ -30137,7 +30313,10 @@ ${generatedDevIndicatorsClientRuntime}`,
30137
30313
  renderer,
30138
30314
  isolatedHydrationMode === "enabled",
30139
30315
  resolvedConfig?.trailingSlash ?? false,
30140
- resolvedConfig?.basePath ?? "/"
30316
+ resolvedConfig?.basePath ?? "/",
30317
+ generateClientCachePersistenceCode(
30318
+ resolveFarmClientCacheAdapterEntry(root, resolvedConfig?.cache)
30319
+ )
30141
30320
  );
30142
30321
  }
30143
30322
  if (id === "/@farm/server") {
@@ -30276,7 +30455,7 @@ export const manifest = getManifest();
30276
30455
  const root = currentConfig.root || server?.config.root || process.cwd();
30277
30456
  const cleanId = id.split("?", 1)[0];
30278
30457
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
30279
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path33.resolve(cleanId)) === true;
30458
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path34.resolve(cleanId)) === true;
30280
30459
  if (isolatedHydrationEnabled && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
30281
30460
  isolatedModuleReference = toViteModuleId(cleanId, root);
30282
30461
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -30367,8 +30546,8 @@ if (import.meta.hot) {
30367
30546
  }
30368
30547
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
30369
30548
  logger.info("Pre-rendering SSG pages...");
30370
- const outDir = path33.join(server?.config.root || process.cwd(), options.outDir || "dist");
30371
- const clientDir = path33.join(outDir, "client");
30549
+ const outDir = path34.join(server?.config.root || process.cwd(), options.outDir || "dist");
30550
+ const clientDir = path34.join(outDir, "client");
30372
30551
  for (const page2 of ssgPages) {
30373
30552
  try {
30374
30553
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -30420,9 +30599,9 @@ if (import.meta.hot) {
30420
30599
  <script type="module" src="/assets/client.js"></script>
30421
30600
  </body>
30422
30601
  </html>`;
30423
- const outputPath = page2.urlPath === "/" ? path33.join(clientDir, "index.html") : path33.join(clientDir, page2.urlPath + ".html");
30424
- fs12.mkdirSync(path33.dirname(outputPath), { recursive: true });
30425
- fs12.writeFileSync(outputPath, fullHtml);
30602
+ const outputPath = page2.urlPath === "/" ? path34.join(clientDir, "index.html") : path34.join(clientDir, page2.urlPath + ".html");
30603
+ fs13.mkdirSync(path34.dirname(outputPath), { recursive: true });
30604
+ fs13.writeFileSync(outputPath, fullHtml);
30426
30605
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
30427
30606
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
30428
30607
  });
@@ -30430,8 +30609,8 @@ if (import.meta.hot) {
30430
30609
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
30431
30610
  }
30432
30611
  }
30433
- const manifestPath = path33.join(outDir, "__ssg_manifest.json");
30434
- fs12.writeFileSync(
30612
+ const manifestPath = path34.join(outDir, "__ssg_manifest.json");
30613
+ fs13.writeFileSync(
30435
30614
  manifestPath,
30436
30615
  JSON.stringify(
30437
30616
  ssgPages.map((p) => ({
@@ -30474,9 +30653,9 @@ if (import.meta.hot) {
30474
30653
  server2.ws.send({ type: "full-reload", path: "*" });
30475
30654
  return [];
30476
30655
  }
30477
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
30656
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
30478
30657
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
30479
- logUpdate("PAGE", `updated ${path33.basename(file)}`);
30658
+ logUpdate("PAGE", `updated ${path34.basename(file)}`);
30480
30659
  for (const mod of modules) {
30481
30660
  server2.moduleGraph.invalidateModule(mod);
30482
30661
  }
@@ -30899,7 +31078,7 @@ function parseRouteModuleSchema2(schema, value, label, routePath) {
30899
31078
  }
30900
31079
  }
30901
31080
  __name(parseRouteModuleSchema2, "parseRouteModuleSchema");
30902
- 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 = "/") {
31081
+ 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: "" }) {
30903
31082
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
30904
31083
  const clientPluginEntry = generateFarmClientPluginEntryCode(
30905
31084
  plugins,
@@ -30955,6 +31134,7 @@ import {
30955
31134
  } from '@farm.js/core/deployment'
30956
31135
  ${providerClientCode.imports}
30957
31136
  ${clientPluginEntry.imports}
31137
+ ${clientCachePersistence.imports}
30958
31138
  ${docsSearchClientRuntime}
30959
31139
  ${devtoolsClientRuntime}
30960
31140
  ${docsAdapterImportBlock}
@@ -30970,6 +31150,7 @@ const integrationDocumentNavigationMatchers = ${JSON.stringify(documentNavigatio
30970
31150
  setFarmBasePath(${JSON.stringify(basePath)});
30971
31151
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
30972
31152
  installChunkErrorRecovery();
31153
+ ${clientCachePersistence.init}
30973
31154
 
30974
31155
  let reactRoot = null;
30975
31156
  ${isolatedHydrationRuntime}
@@ -32353,7 +32534,7 @@ function generateClientManifest(bundle) {
32353
32534
  __name(generateClientManifest, "generateClientManifest");
32354
32535
  async function defineConfig2(config = {}) {
32355
32536
  const tailwindcss = (await import("@tailwindcss/vite")).default;
32356
- const appRoot = path33.resolve(config.root || process.cwd());
32537
+ const appRoot = path34.resolve(config.root || process.cwd());
32357
32538
  if (config.extends?.length) {
32358
32539
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
32359
32540
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
@@ -32574,6 +32755,8 @@ __name(defineConfig2, "defineConfig");
32574
32755
  defineConfig,
32575
32756
  farmI18nClientBridgePlugin,
32576
32757
  farmPlugin,
32758
+ generateClientCachePersistenceCode,
32759
+ resolveFarmClientCacheAdapterEntry,
32577
32760
  rewriteEarlySsrRelativeImports,
32578
32761
  transformIsolatedClientBoundaryModule,
32579
32762
  withFarmRequestTracing