@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/server.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 path36 = value.trim();
692
- if (!path36.startsWith("/") || path36.includes("?") || path36.includes("#") || path36.includes("*")) {
691
+ const path37 = value.trim();
692
+ if (!path37.startsWith("/") || path37.includes("?") || path37.includes("#") || path37.includes("*")) {
693
693
  throw new TypeError(`${optionName} must be an absolute pathname without a query or wildcard`);
694
694
  }
695
- const normalized = path36.length > 1 ? path36.replace(/\/+$/, "") || "/" : path36;
695
+ const normalized = path37.length > 1 ? path37.replace(/\/+$/, "") || "/" : path37;
696
696
  assertBrowserStableRoutePath(normalized);
697
697
  return normalized;
698
698
  }
@@ -1083,8 +1083,8 @@ function toViteModuleId(filePath, root) {
1083
1083
  }
1084
1084
  async function fileExists(filePath) {
1085
1085
  try {
1086
- const fs15 = await import("fs/promises");
1087
- await fs15.access(filePath);
1086
+ const fs16 = await import("fs/promises");
1087
+ await fs16.access(filePath);
1088
1088
  return true;
1089
1089
  } catch {
1090
1090
  return false;
@@ -1598,35 +1598,35 @@ async function prepareFarmWorkflowsForNitro(config) {
1598
1598
  const workflowConfig = isResolvedWorkflowConfig(config.workflows) ? config.workflows : resolveWorkflowsConfig(config.workflows);
1599
1599
  const root = config.root || process.cwd();
1600
1600
  const distDir = config.distDir || ".farm";
1601
- const fs15 = await import("fs/promises");
1602
- const path36 = await import("path");
1603
- const generatedDir = path36.join(root, distDir, ".nitro", "farm-workflows");
1601
+ const fs16 = await import("fs/promises");
1602
+ const path37 = await import("path");
1603
+ const generatedDir = path37.join(root, distDir, ".nitro", "farm-workflows");
1604
1604
  const workflows = await discoverFarmWorkflows({
1605
1605
  root,
1606
1606
  workflows: workflowConfig
1607
1607
  });
1608
1608
  if (workflows.length === 0) {
1609
- await fs15.rm(generatedDir, { recursive: true, force: true });
1609
+ await fs16.rm(generatedDir, { recursive: true, force: true });
1610
1610
  return {
1611
1611
  workflows,
1612
1612
  tasks: {},
1613
1613
  scheduledTasks: {}
1614
1614
  };
1615
1615
  }
1616
- await fs15.rm(generatedDir, { recursive: true, force: true });
1617
- await fs15.mkdir(generatedDir, { recursive: true });
1616
+ await fs16.rm(generatedDir, { recursive: true, force: true });
1617
+ await fs16.mkdir(generatedDir, { recursive: true });
1618
1618
  const tasks = {};
1619
1619
  const scheduledTasks = createScheduledTasks(workflows);
1620
1620
  for (const workflow of workflows) {
1621
- const wrapperPath = toPosixPath(path36.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
1622
- await fs15.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1621
+ const wrapperPath = toPosixPath(path37.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
1622
+ await fs16.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1623
1623
  tasks[workflow.id] = {
1624
1624
  handler: wrapperPath,
1625
1625
  description: workflow.description || `Farm workflow ${workflow.id}`
1626
1626
  };
1627
1627
  }
1628
- const handlerPath = toPosixPath(path36.join(generatedDir, "http-handler.mjs"));
1629
- await fs15.writeFile(
1628
+ const handlerPath = toPosixPath(path37.join(generatedDir, "http-handler.mjs"));
1629
+ await fs16.writeFile(
1630
1630
  handlerPath,
1631
1631
  createNitroWorkflowHTTPHandler(
1632
1632
  workflowConfig,
@@ -1635,8 +1635,8 @@ async function prepareFarmWorkflowsForNitro(config) {
1635
1635
  ),
1636
1636
  "utf8"
1637
1637
  );
1638
- const manifestPath = path36.join(generatedDir, "manifest.json");
1639
- await fs15.writeFile(
1638
+ const manifestPath = path37.join(generatedDir, "manifest.json");
1639
+ await fs16.writeFile(
1640
1640
  manifestPath,
1641
1641
  JSON.stringify(
1642
1642
  {
@@ -1724,21 +1724,21 @@ function resolveWorkflowDefinition(module2) {
1724
1724
  return null;
1725
1725
  }
1726
1726
  async function findWorkflowFiles(root, dirs) {
1727
- const path36 = await import("path");
1727
+ const path37 = await import("path");
1728
1728
  const files = [];
1729
1729
  for (const dir of dirs) {
1730
- const absoluteDir = path36.isAbsolute(dir) ? dir : path36.join(root, dir);
1730
+ const absoluteDir = path37.isAbsolute(dir) ? dir : path37.join(root, dir);
1731
1731
  if (!await pathExists(absoluteDir)) continue;
1732
1732
  await walkWorkflowDir(absoluteDir, files);
1733
1733
  }
1734
1734
  return files.sort();
1735
1735
  }
1736
1736
  async function walkWorkflowDir(dir, files) {
1737
- const fs15 = await import("fs/promises");
1738
- const path36 = await import("path");
1739
- const entries = await fs15.readdir(dir, { withFileTypes: true });
1737
+ const fs16 = await import("fs/promises");
1738
+ const path37 = await import("path");
1739
+ const entries = await fs16.readdir(dir, { withFileTypes: true });
1740
1740
  for (const entry of entries) {
1741
- const filePath = path36.join(dir, entry.name);
1741
+ const filePath = path37.join(dir, entry.name);
1742
1742
  if (entry.isDirectory()) {
1743
1743
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
1744
1744
  await walkWorkflowDir(filePath, files);
@@ -1750,20 +1750,20 @@ async function walkWorkflowDir(dir, files) {
1750
1750
  }
1751
1751
  }
1752
1752
  async function pathExists(filePath) {
1753
- const fs15 = await import("fs/promises");
1754
- return fs15.access(filePath).then(() => true).catch(() => false);
1753
+ const fs16 = await import("fs/promises");
1754
+ return fs16.access(filePath).then(() => true).catch(() => false);
1755
1755
  }
1756
1756
  function isWorkflowFile(fileName) {
1757
1757
  return /\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName);
1758
1758
  }
1759
1759
  async function loadWorkflowModule(filePath, root) {
1760
- const fs15 = await import("fs/promises");
1761
- const path36 = await import("path");
1760
+ const fs16 = await import("fs/promises");
1761
+ const path37 = await import("path");
1762
1762
  const { pathToFileURL: pathToFileURL10 } = await import("url");
1763
1763
  const { build: build2 } = await import("esbuild");
1764
- const outDir = path36.join(root, ".farm", ".workflow-loader");
1765
- await fs15.mkdir(outDir, { recursive: true });
1766
- const outfile = path36.join(
1764
+ const outDir = path37.join(root, ".farm", ".workflow-loader");
1765
+ await fs16.mkdir(outDir, { recursive: true });
1766
+ const outfile = path37.join(
1767
1767
  outDir,
1768
1768
  `workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
1769
1769
  );
@@ -1787,7 +1787,7 @@ async function loadWorkflowModule(filePath, root) {
1787
1787
  `${pathToFileURL10(outfile).href}?t=${Date.now()}`
1788
1788
  );
1789
1789
  } finally {
1790
- await fs15.unlink(outfile).catch(() => void 0);
1790
+ await fs16.unlink(outfile).catch(() => void 0);
1791
1791
  }
1792
1792
  }
1793
1793
  function workflowIdFromFile(root, dirs, filePath) {
@@ -2082,7 +2082,7 @@ function normalizeCronJob(name2, job) {
2082
2082
  if (!job || typeof job !== "object" || Array.isArray(job)) {
2083
2083
  throw new TypeError(`Farm cron ${JSON.stringify(name2)} must be a configuration object.`);
2084
2084
  }
2085
- const path36 = normalizeCronPath(name2, job.path);
2085
+ const path37 = normalizeCronPath(name2, job.path);
2086
2086
  const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
2087
2087
  const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name2, value)))];
2088
2088
  if (schedule.length === 0) {
@@ -2091,7 +2091,7 @@ function normalizeCronJob(name2, job) {
2091
2091
  return {
2092
2092
  name: name2,
2093
2093
  schedule,
2094
- path: path36,
2094
+ path: path37,
2095
2095
  description: job.description?.trim() || void 0
2096
2096
  };
2097
2097
  }
@@ -2108,13 +2108,13 @@ function normalizeCronPath(name2, value) {
2108
2108
  `Farm cron ${JSON.stringify(name2)} path cannot contain backslashes or control characters.`
2109
2109
  );
2110
2110
  }
2111
- const path36 = value.trim();
2112
- if (path36.startsWith("//") || path36.includes("?") || path36.includes("#")) {
2111
+ const path37 = value.trim();
2112
+ if (path37.startsWith("//") || path37.includes("?") || path37.includes("#")) {
2113
2113
  throw new TypeError(
2114
2114
  `Farm cron ${JSON.stringify(name2)} path must be an application pathname without a host, query, or hash.`
2115
2115
  );
2116
2116
  }
2117
- for (const segment of path36.split("/")) {
2117
+ for (const segment of path37.split("/")) {
2118
2118
  let decoded = segment;
2119
2119
  try {
2120
2120
  decoded = decodeURIComponent(segment);
@@ -2136,7 +2136,7 @@ function normalizeCronPath(name2, value) {
2136
2136
  );
2137
2137
  }
2138
2138
  }
2139
- return path36.length > 1 ? path36.replace(/\/+$/, "") : path36;
2139
+ return path37.length > 1 ? path37.replace(/\/+$/, "") : path37;
2140
2140
  }
2141
2141
  function normalizeCronExpression(name2, value) {
2142
2142
  if (typeof value !== "string") {
@@ -2815,7 +2815,13 @@ function recordFarmEventTrace(event) {
2815
2815
  activeSpan.addEvent(event.type, toEventAttributes(event), event.timestamp);
2816
2816
  }
2817
2817
  const error = event.type === "request.error" ? void 0 : getEventError(event);
2818
- if (error !== void 0) recordSpanError(activeSpan, error);
2818
+ if (error !== void 0) {
2819
+ if (event.type === "render.error") {
2820
+ recordSpanException(activeSpan, error);
2821
+ } else {
2822
+ recordSpanError(activeSpan, error);
2823
+ }
2824
+ }
2819
2825
  }
2820
2826
  const completedTraceContext = recordCompletedEventSpan(event, activeContext);
2821
2827
  return traceContext ?? completedTraceContext;
@@ -2909,12 +2915,25 @@ function getCompletedSpanDescriptor(event) {
2909
2915
  return void 0;
2910
2916
  }
2911
2917
  }
2918
+ function hashFarmCacheKey(value) {
2919
+ let hash = 2166136261;
2920
+ for (let index = 0; index < value.length; index++) {
2921
+ hash ^= value.charCodeAt(index);
2922
+ hash = Math.imul(hash, 16777619);
2923
+ }
2924
+ return (hash >>> 0).toString(16).padStart(8, "0");
2925
+ }
2912
2926
  function toEventAttributes(event) {
2913
2927
  const attributes = {};
2928
+ const redactKey = typeof event.type === "string" && event.type.startsWith("cache.");
2914
2929
  for (const [key, value] of Object.entries(event)) {
2915
2930
  if (key === "timestamp" || key === "level" || key === "error" || key === "traceId" || key === "spanId" || key === "traceSampled" || value === void 0) {
2916
2931
  continue;
2917
2932
  }
2933
+ if (redactKey && key === "key" && typeof value === "string") {
2934
+ attributes["farm.key_hash"] = hashFarmCacheKey(value);
2935
+ continue;
2936
+ }
2918
2937
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2919
2938
  attributes[`farm.${key}`] = value;
2920
2939
  } else if (Array.isArray(value)) {
@@ -2932,9 +2951,13 @@ function toEventAttributes(event) {
2932
2951
  function getEventError(event) {
2933
2952
  return "error" in event ? event.error : void 0;
2934
2953
  }
2935
- function recordSpanError(span, error) {
2954
+ function recordSpanException(span, error) {
2936
2955
  const normalized = error instanceof Error ? error : new Error(String(error));
2937
2956
  span.recordException(normalized);
2957
+ return normalized;
2958
+ }
2959
+ function recordSpanError(span, error) {
2960
+ const normalized = recordSpanException(span, error);
2938
2961
  span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: normalized.message });
2939
2962
  }
2940
2963
  function setResponseStatus(span, status) {
@@ -2992,8 +3015,10 @@ var init_tracing = __esm({
2992
3015
  __name(recordFarmEventTrace, "recordFarmEventTrace");
2993
3016
  __name(recordCompletedEventSpan, "recordCompletedEventSpan");
2994
3017
  __name(getCompletedSpanDescriptor, "getCompletedSpanDescriptor");
3018
+ __name(hashFarmCacheKey, "hashFarmCacheKey");
2995
3019
  __name(toEventAttributes, "toEventAttributes");
2996
3020
  __name(getEventError, "getEventError");
3021
+ __name(recordSpanException, "recordSpanException");
2997
3022
  __name(recordSpanError, "recordSpanError");
2998
3023
  __name(setResponseStatus, "setResponseStatus");
2999
3024
  __name(resolveResultStatus, "resolveResultStatus");
@@ -3468,15 +3493,27 @@ function getFarmCacheInvalidationState() {
3468
3493
  taskListeners: /* @__PURE__ */ new Set()
3469
3494
  });
3470
3495
  }
3496
+ function warnFarmCacheListenerError(scope, error) {
3497
+ const detail = error instanceof Error ? error.stack ?? error.message : String(error);
3498
+ console.warn(`[farm:cache] ${scope} listener failed: ${detail}`);
3499
+ }
3471
3500
  function notifyFarmCacheInvalidation(key) {
3472
3501
  if (typeof key !== "string" || key.length === 0) return;
3473
3502
  for (const listener of getFarmCacheInvalidationState().listeners) {
3474
- listener(key);
3503
+ try {
3504
+ listener(key);
3505
+ } catch (error) {
3506
+ warnFarmCacheListenerError("invalidation", error);
3507
+ }
3475
3508
  }
3476
3509
  }
3477
3510
  function notifyFarmCacheTask(task) {
3478
3511
  for (const listener of getFarmCacheInvalidationState().taskListeners) {
3479
- listener(task);
3512
+ try {
3513
+ listener(task);
3514
+ } catch (error) {
3515
+ warnFarmCacheListenerError("task", error);
3516
+ }
3480
3517
  }
3481
3518
  }
3482
3519
  function applyFarmCacheInvalidations(keys) {
@@ -3523,6 +3560,7 @@ var init_cache_invalidation = __esm({
3523
3560
  FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationState");
3524
3561
  globalState = globalThis;
3525
3562
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
3563
+ __name(warnFarmCacheListenerError, "warnFarmCacheListenerError");
3526
3564
  __name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
3527
3565
  __name(notifyFarmCacheTask, "notifyFarmCacheTask");
3528
3566
  __name(applyFarmCacheInvalidations, "applyFarmCacheInvalidations");
@@ -3995,7 +4033,7 @@ var init_server_action_security = __esm({
3995
4033
 
3996
4034
  // src/image-config.ts
3997
4035
  function resolveFarmImageConfig(config) {
3998
- const path36 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
4036
+ const path37 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
3999
4037
  const deviceSizes = normalizeIntegerList(
4000
4038
  config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
4001
4039
  "images.deviceSizes"
@@ -4023,7 +4061,7 @@ function resolveFarmImageConfig(config) {
4023
4061
  );
4024
4062
  return Object.freeze({
4025
4063
  provider: config?.provider ?? "auto",
4026
- path: path36,
4064
+ path: path37,
4027
4065
  domains: Object.freeze([
4028
4066
  ...new Set(
4029
4067
  (config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
@@ -4069,11 +4107,11 @@ function normalizeImagePath(value) {
4069
4107
  if (hasUnstableCharacters(value)) {
4070
4108
  throw new TypeError("images.path cannot contain backslashes or control characters");
4071
4109
  }
4072
- const path36 = value.trim().replace(/\/+$/, "") || "/";
4073
- if (!path36.startsWith("/") || path36.startsWith("//") || path36.includes("?") || path36.includes("#")) {
4110
+ const path37 = value.trim().replace(/\/+$/, "") || "/";
4111
+ if (!path37.startsWith("/") || path37.startsWith("//") || path37.includes("?") || path37.includes("#")) {
4074
4112
  throw new TypeError("images.path must be an absolute pathname without a query or hash");
4075
4113
  }
4076
- for (const segment of path36.split("/")) {
4114
+ for (const segment of path37.split("/")) {
4077
4115
  let decoded = segment;
4078
4116
  try {
4079
4117
  decoded = decodeURIComponent(segment);
@@ -4089,7 +4127,7 @@ function normalizeImagePath(value) {
4089
4127
  throw new TypeError('images.path cannot contain "." or ".." path segments');
4090
4128
  }
4091
4129
  }
4092
- return path36;
4130
+ return path37;
4093
4131
  }
4094
4132
  function normalizeIntegerList(values, name2, max) {
4095
4133
  if (values.length === 0) {
@@ -5692,7 +5730,7 @@ function getProgrammaticRouteSearchClientOptions2(search) {
5692
5730
  if (search.temporary?.length) options.temporary = [...search.temporary];
5693
5731
  return Object.keys(options).length > 0 ? options : void 0;
5694
5732
  }
5695
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path36, routePath) {
5733
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path37, routePath) {
5696
5734
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
5697
5735
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
5698
5736
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -5701,7 +5739,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path36, routePa
5701
5739
  schema,
5702
5740
  rawSearch,
5703
5741
  parsedSearch: search,
5704
- path: path36
5742
+ path: path37
5705
5743
  });
5706
5744
  return { search, canonicalPath };
5707
5745
  }
@@ -5780,8 +5818,8 @@ function normalizeComparableValue(value) {
5780
5818
  }
5781
5819
  return value;
5782
5820
  }
5783
- function createRoute(path36, options) {
5784
- return routesBuilder.page(path36, options);
5821
+ function createRoute(path37, options) {
5822
+ return routesBuilder.page(path37, options);
5785
5823
  }
5786
5824
  function isProgrammaticRoutesFileName2(fileName) {
5787
5825
  const normalized = fileName.replace(/\\/g, "/");
@@ -5864,7 +5902,7 @@ function createRouteModuleFromProgrammaticPage(route, rendererRuntime) {
5864
5902
  mod.__farmRouteData = route.data;
5865
5903
  mod.__farmRouteParsesProps = true;
5866
5904
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
5867
- mod.__farmResolveRouteCanonicalPath = (rawSearch, path36) => resolveProgrammaticRouteSearch(route.search, rawSearch, path36, route.path).canonicalPath;
5905
+ mod.__farmResolveRouteCanonicalPath = (rawSearch, path37) => resolveProgrammaticRouteSearch(route.search, rawSearch, path37, route.path).canonicalPath;
5868
5906
  }
5869
5907
  if (route.pending || route.error || route.notFound) {
5870
5908
  mod.__farmRouteComponents = {
@@ -6274,25 +6312,25 @@ var init_routes = __esm({
6274
6312
  ];
6275
6313
  __name(defineRoutes, "defineRoutes");
6276
6314
  routesBuilder = {
6277
- page(path36, options) {
6315
+ page(path37, options) {
6278
6316
  return normalizeProgrammaticRoute({
6279
6317
  kind: "page",
6280
- path: path36,
6318
+ path: path37,
6281
6319
  ...options
6282
6320
  });
6283
6321
  },
6284
- layout(path36, options) {
6322
+ layout(path37, options) {
6285
6323
  return normalizeProgrammaticRoute({
6286
6324
  kind: "layout",
6287
- path: path36,
6325
+ path: path37,
6288
6326
  ...options
6289
6327
  });
6290
6328
  },
6291
- api(path36, options) {
6329
+ api(path37, options) {
6292
6330
  const { render, runtime, regions, maxDuration, ...methods } = options;
6293
6331
  return normalizeProgrammaticRoute({
6294
6332
  kind: "api",
6295
- path: path36,
6333
+ path: path37,
6296
6334
  render,
6297
6335
  runtime,
6298
6336
  regions,
@@ -6776,9 +6814,9 @@ function getFarmIntegrationPluginOwner(plugin) {
6776
6814
  const value = plugin[FARM_INTEGRATION_PLUGIN_OWNER];
6777
6815
  return value && typeof value === "object" ? value : void 0;
6778
6816
  }
6779
- function defineTypedIntegrationRoute(method, path36, input) {
6817
+ function defineTypedIntegrationRoute(method, path37, input) {
6780
6818
  return {
6781
- path: path36,
6819
+ path: path37,
6782
6820
  method,
6783
6821
  middleware: input.middleware,
6784
6822
  before: input.before,
@@ -6788,7 +6826,7 @@ function defineTypedIntegrationRoute(method, path36, input) {
6788
6826
  input: normalizeIntegrationRouteInputSchemas(input),
6789
6827
  handler: input.handler,
6790
6828
  __operation: defineIntegrationAPIOperation({
6791
- path: path36,
6829
+ path: path37,
6792
6830
  method,
6793
6831
  bodyFormat: input.bodyFormat,
6794
6832
  responseFormat: input.responseFormat,
@@ -6800,58 +6838,58 @@ function defineTypedIntegrationRoute(method, path36, input) {
6800
6838
  }
6801
6839
  function createIntegrationRouteFactory() {
6802
6840
  return {
6803
- get(path36, input) {
6841
+ get(path37, input) {
6804
6842
  return defineTypedIntegrationRoute(
6805
6843
  "GET",
6806
- path36,
6844
+ path37,
6807
6845
  input
6808
6846
  );
6809
6847
  },
6810
- post(path36, input) {
6848
+ post(path37, input) {
6811
6849
  return defineTypedIntegrationRoute(
6812
6850
  "POST",
6813
- path36,
6851
+ path37,
6814
6852
  {
6815
6853
  bodyFormat: "json",
6816
6854
  ...input
6817
6855
  }
6818
6856
  );
6819
6857
  },
6820
- query(path36, input) {
6821
- return defineTypedIntegrationRoute("QUERY", path36, {
6858
+ query(path37, input) {
6859
+ return defineTypedIntegrationRoute("QUERY", path37, {
6822
6860
  bodyFormat: "json",
6823
6861
  ...input
6824
6862
  });
6825
6863
  },
6826
- put(path36, input) {
6864
+ put(path37, input) {
6827
6865
  return defineTypedIntegrationRoute(
6828
6866
  "PUT",
6829
- path36,
6867
+ path37,
6830
6868
  {
6831
6869
  bodyFormat: "json",
6832
6870
  ...input
6833
6871
  }
6834
6872
  );
6835
6873
  },
6836
- patch(path36, input) {
6837
- return defineTypedIntegrationRoute("PATCH", path36, {
6874
+ patch(path37, input) {
6875
+ return defineTypedIntegrationRoute("PATCH", path37, {
6838
6876
  bodyFormat: "json",
6839
6877
  ...input
6840
6878
  });
6841
6879
  },
6842
- delete(path36, input) {
6843
- return defineTypedIntegrationRoute("DELETE", path36, {
6880
+ delete(path37, input) {
6881
+ return defineTypedIntegrationRoute("DELETE", path37, {
6844
6882
  bodyFormat: "json",
6845
6883
  ...input
6846
6884
  });
6847
6885
  },
6848
- options(path36, input) {
6849
- return defineTypedIntegrationRoute("OPTIONS", path36, input);
6886
+ options(path37, input) {
6887
+ return defineTypedIntegrationRoute("OPTIONS", path37, input);
6850
6888
  },
6851
- head(path36, input) {
6889
+ head(path37, input) {
6852
6890
  return defineTypedIntegrationRoute(
6853
6891
  "HEAD",
6854
- path36,
6892
+ path37,
6855
6893
  input
6856
6894
  );
6857
6895
  }
@@ -7132,8 +7170,8 @@ async function parseIntegrationConfigSchema(integration, schema, value) {
7132
7170
  function createIntegrationConfigValidationError(integration, error) {
7133
7171
  const issues = Array.isArray(error.issues) && error.issues.length > 0 ? error.issues.map((issue) => {
7134
7172
  const normalizedPath = normalizeIntegrationValidationPath(issue.path);
7135
- const path36 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
7136
- return `${path36}${issue.message || "Invalid config"}`;
7173
+ const path37 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
7174
+ return `${path37}${issue.message || "Invalid config"}`;
7137
7175
  }).join("; ") : error.message || "Invalid config";
7138
7176
  return new Error(`Integration "${integration.type}" config validation failed: ${issues}`);
7139
7177
  }
@@ -7857,8 +7895,8 @@ function normalizeIntegrationValidationIssues(source, error) {
7857
7895
  }
7858
7896
  ];
7859
7897
  }
7860
- function normalizeIntegrationValidationPath(path36) {
7861
- return (path36 || []).map((segment) => {
7898
+ function normalizeIntegrationValidationPath(path37) {
7899
+ return (path37 || []).map((segment) => {
7862
7900
  const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
7863
7901
  return typeof key === "symbol" ? key.description || key.toString() : key;
7864
7902
  });
@@ -8781,8 +8819,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
8781
8819
  }
8782
8820
  );
8783
8821
  }
8784
- function createFarmDeploymentCookie(deploymentId, path36 = "/", secure = false) {
8785
- const normalizedPath = path36.startsWith("/") ? path36 : `/${path36}`;
8822
+ function createFarmDeploymentCookie(deploymentId, path37 = "/", secure = false) {
8823
+ const normalizedPath = path37.startsWith("/") ? path37 : `/${path37}`;
8786
8824
  return [
8787
8825
  `${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
8788
8826
  `Path=${normalizedPath}`,
@@ -9656,17 +9694,17 @@ function normalizeFarmAPIBasePath(value) {
9656
9694
  if (hasUnstableCharacters(value)) {
9657
9695
  throw new Error("Farm api.basePath cannot contain backslashes or control characters.");
9658
9696
  }
9659
- const path36 = value.trim();
9660
- if (!path36) {
9697
+ const path37 = value.trim();
9698
+ if (!path37) {
9661
9699
  throw new Error("Farm api.basePath cannot be empty.");
9662
9700
  }
9663
- if (path36.includes("?") || path36.includes("#")) {
9701
+ if (path37.includes("?") || path37.includes("#")) {
9664
9702
  throw new Error("Farm api.basePath cannot contain a query string or hash.");
9665
9703
  }
9666
- if (path36.startsWith("//")) {
9704
+ if (path37.startsWith("//")) {
9667
9705
  throw new Error('Farm api.basePath must be a pathname such as "/api", not a URL.');
9668
9706
  }
9669
- for (const segment of path36.split("/")) {
9707
+ for (const segment of path37.split("/")) {
9670
9708
  let decoded = segment;
9671
9709
  try {
9672
9710
  decoded = decodeURIComponent(segment);
@@ -9682,7 +9720,7 @@ function normalizeFarmAPIBasePath(value) {
9682
9720
  throw new Error('Farm api.basePath cannot contain "." or ".." path segments.');
9683
9721
  }
9684
9722
  }
9685
- const normalized = `/${path36.replace(/^\/+|\/+$/g, "")}`;
9723
+ const normalized = `/${path37.replace(/^\/+|\/+$/g, "")}`;
9686
9724
  return normalized === "/" ? "/" : normalized;
9687
9725
  }
9688
9726
  async function resolveConfigValue(value, context2, name2) {
@@ -9914,7 +9952,7 @@ var init_route_files = __esm({
9914
9952
  // src/write-file-if-changed.ts
9915
9953
  function writeFileIfChanged(filePath, content) {
9916
9954
  try {
9917
- if ((0, import_node_fs5.readFileSync)(filePath, "utf8") === content) {
9955
+ if ((0, import_node_fs6.readFileSync)(filePath, "utf8") === content) {
9918
9956
  return false;
9919
9957
  }
9920
9958
  } catch (error) {
@@ -9922,14 +9960,14 @@ function writeFileIfChanged(filePath, content) {
9922
9960
  throw error;
9923
9961
  }
9924
9962
  }
9925
- (0, import_node_fs5.writeFileSync)(filePath, content, "utf8");
9963
+ (0, import_node_fs6.writeFileSync)(filePath, content, "utf8");
9926
9964
  return true;
9927
9965
  }
9928
- var import_node_fs5;
9966
+ var import_node_fs6;
9929
9967
  var init_write_file_if_changed = __esm({
9930
9968
  "src/write-file-if-changed.ts"() {
9931
9969
  "use strict";
9932
- import_node_fs5 = require("fs");
9970
+ import_node_fs6 = require("fs");
9933
9971
  __name(writeFileIfChanged, "writeFileIfChanged");
9934
9972
  }
9935
9973
  });
@@ -10107,9 +10145,9 @@ var init_type_generator = __esm({
10107
10145
  }
10108
10146
  const nestedStructure = {};
10109
10147
  const usedRouteNames = /* @__PURE__ */ new Map();
10110
- for (const [path36, routeList] of routeGroups) {
10111
- const routeName = this.uniqueRouteName(path36, usedRouteNames);
10112
- const cleanPath = path36 === "/api" ? "" : path36.replace(/^\/api\//, "");
10148
+ for (const [path37, routeList] of routeGroups) {
10149
+ const routeName = this.uniqueRouteName(path37, usedRouteNames);
10150
+ const cleanPath = path37 === "/api" ? "" : path37.replace(/^\/api\//, "");
10113
10151
  const parts = cleanPath ? cleanPath.split("/") : [];
10114
10152
  const methodSources = /* @__PURE__ */ new Map();
10115
10153
  for (const route of routeList) {
@@ -10173,11 +10211,11 @@ var init_type_generator = __esm({
10173
10211
  methods.add(route.method);
10174
10212
  manifest.set(route.path, methods);
10175
10213
  }
10176
- const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path36, methods]) => ({ path: path36, methods: [...methods].sort() }));
10214
+ const routeManifest = [...manifest].sort(([a], [b]) => a.localeCompare(b)).map(([path37, methods]) => ({ path: path37, methods: [...methods].sort() }));
10177
10215
  const manifestSource = routeManifest.length ? `[
10178
10216
  ${routeManifest.map(
10179
- ({ path: path36, methods }) => ` {
10180
- path: ${JSON.stringify(path36)},
10217
+ ({ path: path37, methods }) => ` {
10218
+ path: ${JSON.stringify(path37)},
10181
10219
  methods: [${methods.map((method) => JSON.stringify(method)).join(", ")}],
10182
10220
  },`
10183
10221
  ).join("\n")}
@@ -10207,11 +10245,11 @@ export const apiRoutes = ${manifestSource} as const;
10207
10245
  const relativeImport = (0, import_path8.relative)((0, import_path8.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
10208
10246
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
10209
10247
  }
10210
- pathToRouteName(path36) {
10211
- return (path36 === "/api" ? "root" : path36.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
10248
+ pathToRouteName(path37) {
10249
+ return (path37 === "/api" ? "root" : path37.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "_");
10212
10250
  }
10213
- uniqueRouteName(path36, usedNames) {
10214
- const base = this.pathToRouteName(path36);
10251
+ uniqueRouteName(path37, usedNames) {
10252
+ const base = this.pathToRouteName(path37);
10215
10253
  const seen = usedNames.get(base);
10216
10254
  usedNames.set(base, (seen ?? 0) + 1);
10217
10255
  return seen ? `${base}_${seen + 1}` : base;
@@ -10234,15 +10272,15 @@ export const apiRoutes = ${manifestSource} as const;
10234
10272
  toTypePropertyKey(key) {
10235
10273
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
10236
10274
  }
10237
- getBaseExportName(path36) {
10238
- const cleanPath = path36.replace(/^\/api\//, "");
10275
+ getBaseExportName(path37) {
10276
+ const cleanPath = path37.replace(/^\/api\//, "");
10239
10277
  if (cleanPath === "") {
10240
10278
  return "api";
10241
10279
  }
10242
10280
  return cleanPath;
10243
10281
  }
10244
- getExportName(path36, method) {
10245
- const cleanPath = path36.replace(/^\/api\//, "");
10282
+ getExportName(path37, method) {
10283
+ const cleanPath = path37.replace(/^\/api\//, "");
10246
10284
  if (cleanPath === "") {
10247
10285
  return method.toLowerCase();
10248
10286
  }
@@ -10734,12 +10772,12 @@ var init_image_server = __esm({
10734
10772
  // src/docs/fonts.ts
10735
10773
  function resolveFarmDocsFontAssets(root) {
10736
10774
  return FARM_DOCS_FONT_SOURCES.flatMap(({ family, packagePath }) => {
10737
- const sourcePath = import_node_path14.default.join(root, "node_modules", packagePath);
10738
- if (!(0, import_node_fs8.existsSync)(sourcePath)) return [];
10739
- const source = (0, import_node_fs8.readFileSync)(sourcePath);
10775
+ const sourcePath = import_node_path15.default.join(root, "node_modules", packagePath);
10776
+ if (!(0, import_node_fs9.existsSync)(sourcePath)) return [];
10777
+ const source = (0, import_node_fs9.readFileSync)(sourcePath);
10740
10778
  const fingerprint = (0, import_node_crypto3.createHash)("sha256").update(source).digest("hex").slice(0, 12);
10741
- const extension = import_node_path14.default.extname(packagePath);
10742
- const baseName = import_node_path14.default.basename(packagePath, extension);
10779
+ const extension = import_node_path15.default.extname(packagePath);
10780
+ const baseName = import_node_path15.default.basename(packagePath, extension);
10743
10781
  return [
10744
10782
  {
10745
10783
  family,
@@ -10752,13 +10790,13 @@ function resolveFarmDocsFontAssets(root) {
10752
10790
  function toFarmDocsPublicFontAssets(assets) {
10753
10791
  return assets.map(({ family, url }) => ({ family, url }));
10754
10792
  }
10755
- var import_node_crypto3, import_node_fs8, import_node_path14, FARM_DOCS_FONT_SOURCES;
10793
+ var import_node_crypto3, import_node_fs9, import_node_path15, FARM_DOCS_FONT_SOURCES;
10756
10794
  var init_fonts = __esm({
10757
10795
  "src/docs/fonts.ts"() {
10758
10796
  "use strict";
10759
10797
  import_node_crypto3 = require("crypto");
10760
- import_node_fs8 = require("fs");
10761
- import_node_path14 = __toESM(require("path"));
10798
+ import_node_fs9 = require("fs");
10799
+ import_node_path15 = __toESM(require("path"));
10762
10800
  FARM_DOCS_FONT_SOURCES = [
10763
10801
  {
10764
10802
  family: "Geist Sans",
@@ -10811,22 +10849,22 @@ function normalizeRelativePath(value) {
10811
10849
  }
10812
10850
  function resolveExistingPath(filePath) {
10813
10851
  try {
10814
- return (0, import_node_fs9.realpathSync)(filePath);
10852
+ return (0, import_node_fs10.realpathSync)(filePath);
10815
10853
  } catch {
10816
- return import_node_path16.default.resolve(filePath);
10854
+ return import_node_path17.default.resolve(filePath);
10817
10855
  }
10818
10856
  }
10819
10857
  function isDocsSourceFile(filePath) {
10820
- return DOCS_FILE_EXTENSIONS.has(import_node_path16.default.extname(filePath).toLowerCase());
10858
+ return DOCS_FILE_EXTENSIONS.has(import_node_path17.default.extname(filePath).toLowerCase());
10821
10859
  }
10822
10860
  function discoverDocsSourceFiles(contentDir) {
10823
10861
  const files = [];
10824
10862
  const visit = /* @__PURE__ */ __name((dir) => {
10825
- for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true }).sort(
10863
+ for (const entry of (0, import_node_fs10.readdirSync)(dir, { withFileTypes: true }).sort(
10826
10864
  (a, b) => a.name.localeCompare(b.name)
10827
10865
  )) {
10828
10866
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
10829
- const absolutePath = import_node_path16.default.join(dir, entry.name);
10867
+ const absolutePath = import_node_path17.default.join(dir, entry.name);
10830
10868
  if (entry.isDirectory()) {
10831
10869
  visit(absolutePath);
10832
10870
  } else if (entry.isFile() && isDocsSourceFile(absolutePath)) {
@@ -10834,7 +10872,7 @@ function discoverDocsSourceFiles(contentDir) {
10834
10872
  }
10835
10873
  }
10836
10874
  }, "visit");
10837
- if ((0, import_node_fs9.existsSync)(contentDir)) visit(contentDir);
10875
+ if ((0, import_node_fs10.existsSync)(contentDir)) visit(contentDir);
10838
10876
  return files;
10839
10877
  }
10840
10878
  function getGitLastModifiedDates(contentDir) {
@@ -10844,7 +10882,7 @@ function getGitLastModifiedDates(contentDir) {
10844
10882
  stdio: ["ignore", "pipe", "ignore"]
10845
10883
  }).trim();
10846
10884
  if (!gitRoot) return {};
10847
- const contentPathspec = normalizeRelativePath(import_node_path16.default.relative(gitRoot, contentDir)) || ".";
10885
+ const contentPathspec = normalizeRelativePath(import_node_path17.default.relative(gitRoot, contentDir)) || ".";
10848
10886
  const contentPrefix = contentPathspec === "." ? "" : `${contentPathspec}/`;
10849
10887
  const history = (0, import_node_child_process.execFileSync)(
10850
10888
  "git",
@@ -10886,11 +10924,11 @@ function getGitLastModifiedDates(contentDir) {
10886
10924
  }
10887
10925
  }
10888
10926
  function readManifest(contentDir) {
10889
- const manifestPath = import_node_path16.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
10890
- if (!(0, import_node_fs9.existsSync)(manifestPath)) return null;
10927
+ const manifestPath = import_node_path17.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
10928
+ if (!(0, import_node_fs10.existsSync)(manifestPath)) return null;
10891
10929
  try {
10892
10930
  const parsed = JSON.parse(
10893
- (0, import_node_fs9.readFileSync)(manifestPath, "utf8")
10931
+ (0, import_node_fs10.readFileSync)(manifestPath, "utf8")
10894
10932
  );
10895
10933
  if (parsed.version !== 1 || !parsed.pages || typeof parsed.pages !== "object") return null;
10896
10934
  const pages = Object.fromEntries(
@@ -10909,15 +10947,15 @@ function createFarmDocsLastModifiedManifest(contentDir, options = {}) {
10909
10947
  const fallbackDate = (options.now ?? /* @__PURE__ */ new Date()).toISOString();
10910
10948
  const pages = {};
10911
10949
  for (const sourcePath of discoverDocsSourceFiles(resolvedContentDir)) {
10912
- const relativePath2 = normalizeRelativePath(import_node_path16.default.relative(resolvedContentDir, sourcePath));
10913
- pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs9.statSync)(sourcePath).mtime.toISOString());
10950
+ const relativePath2 = normalizeRelativePath(import_node_path17.default.relative(resolvedContentDir, sourcePath));
10951
+ pages[relativePath2] = gitDates[relativePath2] || (options.fallback === "now" ? fallbackDate : (0, import_node_fs10.statSync)(sourcePath).mtime.toISOString());
10914
10952
  }
10915
10953
  return { version: 1, pages };
10916
10954
  }
10917
10955
  function getLastModifiedManifest(contentDir) {
10918
10956
  const resolvedContentDir = resolveExistingPath(contentDir);
10919
- const manifestPath = import_node_path16.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
10920
- const manifestStat = (0, import_node_fs9.existsSync)(manifestPath) ? (0, import_node_fs9.statSync)(manifestPath) : null;
10957
+ const manifestPath = import_node_path17.default.join(resolvedContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
10958
+ const manifestStat = (0, import_node_fs10.existsSync)(manifestPath) ? (0, import_node_fs10.statSync)(manifestPath) : null;
10921
10959
  const signature = manifestStat ? `file:${manifestStat.mtimeMs}:${manifestStat.size}` : "generated";
10922
10960
  const cached = manifestCache.get(resolvedContentDir);
10923
10961
  if (cached?.signature === signature) return cached.manifest;
@@ -10930,21 +10968,21 @@ function resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter) {
10930
10968
  if (configured) return configured;
10931
10969
  const resolvedContentDir = resolveExistingPath(contentDir);
10932
10970
  const resolvedSourcePath = resolveExistingPath(sourcePath);
10933
- const relativePath2 = normalizeRelativePath(import_node_path16.default.relative(resolvedContentDir, resolvedSourcePath));
10934
- const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path16.default.isAbsolute(relativePath2);
10971
+ const relativePath2 = normalizeRelativePath(import_node_path17.default.relative(resolvedContentDir, resolvedSourcePath));
10972
+ const isInsideContentDir = relativePath2 !== ".." && !relativePath2.startsWith("../") && !import_node_path17.default.isAbsolute(relativePath2);
10935
10973
  if (isInsideContentDir) {
10936
10974
  const generated = getLastModifiedManifest(resolvedContentDir).pages[relativePath2];
10937
10975
  if (generated) return generated;
10938
10976
  }
10939
- return (0, import_node_fs9.statSync)(resolvedSourcePath).mtime.toISOString();
10977
+ return (0, import_node_fs10.statSync)(resolvedSourcePath).mtime.toISOString();
10940
10978
  }
10941
- var import_node_child_process, import_node_fs9, import_node_path16, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
10979
+ var import_node_child_process, import_node_fs10, import_node_path17, FARM_DOCS_LAST_MODIFIED_MANIFEST, COMMIT_MARKER, DOCS_FILE_EXTENSIONS, manifestCache;
10942
10980
  var init_last_modified = __esm({
10943
10981
  "src/docs/last-modified.ts"() {
10944
10982
  "use strict";
10945
10983
  import_node_child_process = require("child_process");
10946
- import_node_fs9 = require("fs");
10947
- import_node_path16 = __toESM(require("path"));
10984
+ import_node_fs10 = require("fs");
10985
+ import_node_path17 = __toESM(require("path"));
10948
10986
  FARM_DOCS_LAST_MODIFIED_MANIFEST = ".farm-docs-last-modified.json";
10949
10987
  COMMIT_MARKER = "__FARM_DOCS_COMMIT__";
10950
10988
  DOCS_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".mdx"]);
@@ -10977,10 +11015,10 @@ function isFarmDocsSearchEnabled(docs) {
10977
11015
  }
10978
11016
  function resolveFarmDocsSearchClientModule(root) {
10979
11017
  try {
10980
- const requireFromApp = (0, import_node_module5.createRequire)(import_node_path17.default.join(import_node_path17.default.resolve(root), "package.json"));
11018
+ const requireFromApp = (0, import_node_module5.createRequire)(import_node_path18.default.join(import_node_path18.default.resolve(root), "package.json"));
10981
11019
  const themeEntry = requireFromApp.resolve("@farming-labs/theme");
10982
- const commandSearchModule = import_node_path17.default.join(import_node_path17.default.dirname(themeEntry), "docs-command-search.mjs");
10983
- if ((0, import_node_fs10.existsSync)(commandSearchModule)) return commandSearchModule;
11020
+ const commandSearchModule = import_node_path18.default.join(import_node_path18.default.dirname(themeEntry), "docs-command-search.mjs");
11021
+ if ((0, import_node_fs11.existsSync)(commandSearchModule)) return commandSearchModule;
10984
11022
  } catch {
10985
11023
  }
10986
11024
  return void 0;
@@ -11119,13 +11157,13 @@ async function mountFarmDocsSearch() {
11119
11157
  window.__FARM_MOUNT_DOCS_SEARCH__ = mountFarmDocsSearch;
11120
11158
  `;
11121
11159
  }
11122
- var import_node_fs10, import_node_module5, import_node_path17;
11160
+ var import_node_fs11, import_node_module5, import_node_path18;
11123
11161
  var init_search_client = __esm({
11124
11162
  "src/docs/search-client.ts"() {
11125
11163
  "use strict";
11126
- import_node_fs10 = require("fs");
11164
+ import_node_fs11 = require("fs");
11127
11165
  import_node_module5 = require("module");
11128
- import_node_path17 = __toESM(require("path"));
11166
+ import_node_path18 = __toESM(require("path"));
11129
11167
  __name(isFarmDocsSearchEnabled, "isFarmDocsSearchEnabled");
11130
11168
  __name(resolveFarmDocsSearchClientModule, "resolveFarmDocsSearchClientModule");
11131
11169
  __name(generateFarmDocsSearchBootstrapRuntime, "generateFarmDocsSearchBootstrapRuntime");
@@ -11563,10 +11601,10 @@ function resolveFarmDocsFavicon(docs, options) {
11563
11601
  if (typeof configuredFavicon === "string" && configuredFavicon.trim()) {
11564
11602
  return configuredFavicon.trim();
11565
11603
  }
11566
- const publicDir = import_node_path18.default.join(import_node_path18.default.resolve(options.root), "public");
11604
+ const publicDir = import_node_path19.default.join(import_node_path19.default.resolve(options.root), "public");
11567
11605
  for (const fileName of FARM_DOCS_FAVICON_FILES) {
11568
- const faviconPath = import_node_path18.default.join(publicDir, fileName);
11569
- if ((0, import_node_fs11.existsSync)(faviconPath) && (0, import_node_fs11.statSync)(faviconPath).isFile()) {
11606
+ const faviconPath = import_node_path19.default.join(publicDir, fileName);
11607
+ if ((0, import_node_fs12.existsSync)(faviconPath) && (0, import_node_fs12.statSync)(faviconPath).isFile()) {
11570
11608
  return `/${fileName}`;
11571
11609
  }
11572
11610
  }
@@ -11600,10 +11638,10 @@ function isSafeSegment(segment) {
11600
11638
  return segment !== ".." && !segment.includes("/") && !segment.includes("\\");
11601
11639
  }
11602
11640
  function resolveInside(root, target) {
11603
- const resolvedRoot = import_node_path18.default.resolve(root);
11604
- const resolvedTarget = import_node_path18.default.resolve(target);
11605
- const relative6 = import_node_path18.default.relative(resolvedRoot, resolvedTarget);
11606
- if (relative6 === "" || !relative6.startsWith("..") && !import_node_path18.default.isAbsolute(relative6)) {
11641
+ const resolvedRoot = import_node_path19.default.resolve(root);
11642
+ const resolvedTarget = import_node_path19.default.resolve(target);
11643
+ const relative6 = import_node_path19.default.relative(resolvedRoot, resolvedTarget);
11644
+ if (relative6 === "" || !relative6.startsWith("..") && !import_node_path19.default.isAbsolute(relative6)) {
11607
11645
  return resolvedTarget;
11608
11646
  }
11609
11647
  return null;
@@ -11612,10 +11650,10 @@ function resolveExistingFileInside(root, target) {
11612
11650
  const safePath = resolveInside(root, target);
11613
11651
  if (!safePath) return null;
11614
11652
  try {
11615
- const realRoot = (0, import_node_fs11.realpathSync)(root);
11616
- const realTarget = (0, import_node_fs11.realpathSync)(safePath);
11653
+ const realRoot = (0, import_node_fs12.realpathSync)(root);
11654
+ const realTarget = (0, import_node_fs12.realpathSync)(safePath);
11617
11655
  const containedTarget = resolveInside(realRoot, realTarget);
11618
- return containedTarget && (0, import_node_fs11.statSync)(containedTarget).isFile() ? containedTarget : null;
11656
+ return containedTarget && (0, import_node_fs12.statSync)(containedTarget).isFile() ? containedTarget : null;
11619
11657
  } catch {
11620
11658
  return null;
11621
11659
  }
@@ -11629,16 +11667,16 @@ function isFarmDocsRequest(docs, request) {
11629
11667
  return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
11630
11668
  }
11631
11669
  function resolveFarmDocsContentDir(docs, options) {
11632
- const root = import_node_path18.default.resolve(options.root);
11670
+ const root = import_node_path19.default.resolve(options.root);
11633
11671
  const srcDir = options.srcDir || "src";
11634
11672
  const configuredContentDir = docs.contentDir || docs.config.contentDir;
11635
11673
  if (configuredContentDir) {
11636
- return import_node_path18.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path18.default.join(root, configuredContentDir);
11674
+ return import_node_path19.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path19.default.join(root, configuredContentDir);
11637
11675
  }
11638
11676
  const entryDir = docs.config.entry || trimSlashes2(docs.entry) || "docs";
11639
- const appDocsDir = import_node_path18.default.join(root, srcDir, "app", entryDir);
11640
- if ((0, import_node_fs11.existsSync)(appDocsDir)) return appDocsDir;
11641
- return import_node_path18.default.join(root, entryDir);
11677
+ const appDocsDir = import_node_path19.default.join(root, srcDir, "app", entryDir);
11678
+ if ((0, import_node_fs12.existsSync)(appDocsDir)) return appDocsDir;
11679
+ return import_node_path19.default.join(root, entryDir);
11642
11680
  }
11643
11681
  function getFarmDocsRouteTypeEntries(docs) {
11644
11682
  if (!docs?.enabled) return [];
@@ -11661,10 +11699,10 @@ function getRequestSlug(docs, request) {
11661
11699
  function findDocsPageFile(contentDir, slug) {
11662
11700
  const segments = slug ? slug.split("/").filter(Boolean) : [];
11663
11701
  if (!segments.every(isSafeSegment)) return null;
11664
- const slugDir = import_node_path18.default.join(contentDir, ...segments);
11665
- const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path18.default.join(contentDir, filename)) : [
11666
- ...DOCS_FILE_NAMES.map((filename) => import_node_path18.default.join(slugDir, filename)),
11667
- ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path18.default.join(contentDir, `${slug}${extension}`))
11702
+ const slugDir = import_node_path19.default.join(contentDir, ...segments);
11703
+ const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path19.default.join(contentDir, filename)) : [
11704
+ ...DOCS_FILE_NAMES.map((filename) => import_node_path19.default.join(slugDir, filename)),
11705
+ ...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path19.default.join(contentDir, `${slug}${extension}`))
11668
11706
  ];
11669
11707
  for (const candidate of candidates) {
11670
11708
  const safePath = resolveExistingFileInside(contentDir, candidate);
@@ -11703,7 +11741,7 @@ function titleFromMarkdown2(body, fallback) {
11703
11741
  function loadFarmDocsPage(contentDir, docs, slug) {
11704
11742
  const sourcePath = findDocsPageFile(contentDir, slug);
11705
11743
  if (!sourcePath) return null;
11706
- const source = (0, import_node_fs11.readFileSync)(sourcePath, "utf8");
11744
+ const source = (0, import_node_fs12.readFileSync)(sourcePath, "utf8");
11707
11745
  const { frontmatter, body } = parseFrontmatter(source);
11708
11746
  const title = frontmatter.title || titleFromMarkdown2(body, titleFromSlug(slug));
11709
11747
  const href = createDocsHref(docs.entry, slug);
@@ -11726,9 +11764,9 @@ function createDocsHref(entry, slug) {
11726
11764
  return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
11727
11765
  }
11728
11766
  function pathToSlug(contentDir, filePath) {
11729
- const relative6 = import_node_path18.default.relative(contentDir, filePath).replace(/\\/g, "/");
11767
+ const relative6 = import_node_path19.default.relative(contentDir, filePath).replace(/\\/g, "/");
11730
11768
  if (relative6.startsWith("..")) return null;
11731
- const extension = import_node_path18.default.extname(relative6);
11769
+ const extension = import_node_path19.default.extname(relative6);
11732
11770
  if (!DOCS_FILE_EXTENSIONS2.includes(extension)) return null;
11733
11771
  const withoutExtension = relative6.slice(0, -extension.length);
11734
11772
  if (withoutExtension === "page" || withoutExtension === "index") return "";
@@ -11741,12 +11779,12 @@ function loadPage(contentDir, docs, request) {
11741
11779
  return loadFarmDocsPage(contentDir, docs, getRequestSlug(docs, request));
11742
11780
  }
11743
11781
  function discoverFarmDocsPages(contentDir, docs) {
11744
- if (!(0, import_node_fs11.existsSync)(contentDir)) return [];
11782
+ if (!(0, import_node_fs12.existsSync)(contentDir)) return [];
11745
11783
  const pages = [];
11746
11784
  const visit = /* @__PURE__ */ __name((dir) => {
11747
- for (const entry of (0, import_node_fs11.readdirSync)(dir, { withFileTypes: true })) {
11785
+ for (const entry of (0, import_node_fs12.readdirSync)(dir, { withFileTypes: true })) {
11748
11786
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
11749
- const absolutePath = import_node_path18.default.join(dir, entry.name);
11787
+ const absolutePath = import_node_path19.default.join(dir, entry.name);
11750
11788
  if (entry.isDirectory()) {
11751
11789
  visit(absolutePath);
11752
11790
  continue;
@@ -11754,7 +11792,7 @@ function discoverFarmDocsPages(contentDir, docs) {
11754
11792
  if (!entry.isFile()) continue;
11755
11793
  const slug = pathToSlug(contentDir, absolutePath);
11756
11794
  if (slug === null) continue;
11757
- const source = (0, import_node_fs11.readFileSync)(absolutePath, "utf8");
11795
+ const source = (0, import_node_fs12.readFileSync)(absolutePath, "utf8");
11758
11796
  const { frontmatter, body } = parseFrontmatter(source);
11759
11797
  pages.push({
11760
11798
  slug,
@@ -12273,11 +12311,30 @@ function renderMarkdownHtml(body) {
12273
12311
  function extractTocItems(body, depth) {
12274
12312
  const slug = createSlugger();
12275
12313
  const maxLevel = Math.max(2, Math.min(depth, 6));
12276
- return body.split(/\r?\n/).map((line) => line.match(/^(#{2,6})\s+(.+)$/)).filter((match) => Boolean(match)).map((match) => ({
12277
- id: slug(match[2].trim()),
12278
- title: match[2].trim(),
12279
- level: match[1].length
12280
- })).filter((item) => item.level <= maxLevel);
12314
+ const items = [];
12315
+ let fence = null;
12316
+ for (const line of body.split(/\r?\n/)) {
12317
+ const nextFence = getCodeFence(line);
12318
+ if (fence) {
12319
+ if (nextFence && nextFence.marker === fence.marker && isClosingCodeFence(line, fence)) {
12320
+ fence = null;
12321
+ }
12322
+ continue;
12323
+ }
12324
+ if (nextFence) {
12325
+ fence = nextFence;
12326
+ continue;
12327
+ }
12328
+ const match = line.match(/^(#{2,6})\s+(.+)$/);
12329
+ if (!match) continue;
12330
+ const title = match[2].trim();
12331
+ const id = slug(title);
12332
+ const level = match[1].length;
12333
+ if (level <= maxLevel) {
12334
+ items.push({ id, title, level });
12335
+ }
12336
+ }
12337
+ return items;
12281
12338
  }
12282
12339
  function getThemeUI(docs) {
12283
12340
  const theme = docs.config.theme;
@@ -12766,12 +12823,12 @@ function createFarmDocsHandler(docs, options) {
12766
12823
  );
12767
12824
  }, "handleFarmDocsRequest");
12768
12825
  }
12769
- 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;
12826
+ 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;
12770
12827
  var init_handler = __esm({
12771
12828
  "src/docs/handler.ts"() {
12772
12829
  "use strict";
12773
- import_node_fs11 = require("fs");
12774
- import_node_path18 = __toESM(require("path"));
12830
+ import_node_fs12 = require("fs");
12831
+ import_node_path19 = __toESM(require("path"));
12775
12832
  import_docs = require("@farming-labs/docs");
12776
12833
  import_marked = require("marked");
12777
12834
  import_sugar_high = require("sugar-high");
@@ -13032,7 +13089,7 @@ var init_adapter = __esm({
13032
13089
  // src/docs/framework-detect.ts
13033
13090
  async function frameworkDeclaredByApp(root) {
13034
13091
  try {
13035
- const raw = await (0, import_promises8.readFile)(import_node_path19.default.join(root, "package.json"), "utf8");
13092
+ const raw = await (0, import_promises8.readFile)(import_node_path20.default.join(root, "package.json"), "utf8");
13036
13093
  const manifest = JSON.parse(raw);
13037
13094
  for (const field of ["dependencies", "devDependencies", "peerDependencies"]) {
13038
13095
  const section = manifest[field];
@@ -13065,7 +13122,7 @@ async function applyFarmDocsFrameworkAutoDetection(userConfig, options) {
13065
13122
  if (!docsWantsFrameworkDetection(userConfig.docs)) return userConfig;
13066
13123
  const log = options.log ?? ((message) => console.log(message));
13067
13124
  const warn = options.warn ?? ((message) => console.warn(message));
13068
- const root = import_node_path19.default.resolve(options.root || process.cwd());
13125
+ const root = import_node_path20.default.resolve(options.root || process.cwd());
13069
13126
  if (!await frameworkDeclaredByApp(root)) {
13070
13127
  noticeOnce(
13071
13128
  "embedded-fallback",
@@ -13076,7 +13133,7 @@ async function applyFarmDocsFrameworkAutoDetection(userConfig, options) {
13076
13133
  }
13077
13134
  let configEntryPath;
13078
13135
  try {
13079
- const requireFromApp = (0, import_node_module6.createRequire)(import_node_path19.default.join(root, "package.json"));
13136
+ const requireFromApp = (0, import_node_module6.createRequire)(import_node_path20.default.join(root, "package.json"));
13080
13137
  configEntryPath = requireFromApp.resolve(FRAMEWORK_CONFIG_ENTRY);
13081
13138
  } catch {
13082
13139
  noticeOnce(
@@ -13126,13 +13183,13 @@ async function applyFarmDocsFrameworkAutoDetection(userConfig, options) {
13126
13183
  return userConfig;
13127
13184
  }
13128
13185
  }
13129
- var import_promises8, import_node_module6, import_node_path19, import_node_url7, FRAMEWORK_PACKAGE, FRAMEWORK_CONFIG_ENTRY, SUPPORTED_ADAPTER_PROTOCOL, emittedNotices;
13186
+ var import_promises8, import_node_module6, import_node_path20, import_node_url7, FRAMEWORK_PACKAGE, FRAMEWORK_CONFIG_ENTRY, SUPPORTED_ADAPTER_PROTOCOL, emittedNotices;
13130
13187
  var init_framework_detect = __esm({
13131
13188
  "src/docs/framework-detect.ts"() {
13132
13189
  "use strict";
13133
13190
  import_promises8 = require("fs/promises");
13134
13191
  import_node_module6 = require("module");
13135
- import_node_path19 = __toESM(require("path"));
13192
+ import_node_path20 = __toESM(require("path"));
13136
13193
  import_node_url7 = require("url");
13137
13194
  FRAMEWORK_PACKAGE = "@farming-labs/farmjs";
13138
13195
  FRAMEWORK_CONFIG_ENTRY = "@farming-labs/farmjs/config";
@@ -13215,7 +13272,9 @@ function resolveDeployConfig(config, overrides = {}) {
13215
13272
  }
13216
13273
  }
13217
13274
  }
13218
- const preset = overrides.preset || deploy.preset || config.preset || getPresetForDeployTarget(target) || "node-server";
13275
+ const configuredPreset = deploy.preset || config.preset;
13276
+ const overrideTargetPreset = overrideTarget && getDeployTargetForPreset(configuredPreset) !== overrideTarget ? getPresetForDeployTarget(overrideTarget) : void 0;
13277
+ const preset = overrides.preset || overrideTargetPreset || configuredPreset || getPresetForDeployTarget(target) || "node-server";
13219
13278
  const resolvedTarget = target || getDeployTargetForPreset(preset);
13220
13279
  if (detectedTarget && resolvedTarget !== detectedTarget) {
13221
13280
  const mismatchKey = `mismatch:${resolvedTarget}:${detectedTarget}`;
@@ -13317,19 +13376,19 @@ async function findDocsConfigPath(rootDir, configPath) {
13317
13376
  return void 0;
13318
13377
  }
13319
13378
  async function loadDocsConfig(rootDir, configPath) {
13320
- const fs15 = await import("fs/promises");
13379
+ const fs16 = await import("fs/promises");
13321
13380
  const { pathToFileURL: pathToFileURL10 } = await import("url");
13322
13381
  const root = import_path10.default.resolve(rootDir || process.cwd());
13323
13382
  const resolvedPath = await findDocsConfigPath(root, configPath);
13324
13383
  if (!resolvedPath) return void 0;
13325
13384
  try {
13326
13385
  if (resolvedPath.endsWith(".json")) {
13327
- const content = await fs15.readFile(resolvedPath, "utf8");
13386
+ const content = await fs16.readFile(resolvedPath, "utf8");
13328
13387
  return { config: JSON.parse(content), configPath: resolvedPath };
13329
13388
  }
13330
13389
  const { build: build2 } = await import("esbuild");
13331
13390
  const configCacheDir = import_path10.default.join(root, ".farm", ".config-loader");
13332
- await fs15.mkdir(configCacheDir, { recursive: true });
13391
+ await fs16.mkdir(configCacheDir, { recursive: true });
13333
13392
  const modulePath = import_path10.default.join(
13334
13393
  configCacheDir,
13335
13394
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -13355,7 +13414,7 @@ async function loadDocsConfig(rootDir, configPath) {
13355
13414
  moduleUrl
13356
13415
  );
13357
13416
  } finally {
13358
- await fs15.unlink(modulePath).catch(() => void 0);
13417
+ await fs16.unlink(modulePath).catch(() => void 0);
13359
13418
  }
13360
13419
  return {
13361
13420
  config: importedConfig.default || importedConfig,
@@ -13548,6 +13607,7 @@ async function resolveConfig(userConfig, mode) {
13548
13607
  serverComponents: false,
13549
13608
  serverActions: false,
13550
13609
  isolatedClientHydration: "off",
13610
+ ppr: false,
13551
13611
  ...userConfig.experimental
13552
13612
  },
13553
13613
  plugins: [...resolveIntegrationPlugins(integrations), ...userConfig.plugins || []],
@@ -14480,8 +14540,8 @@ var init_generator = __esm({
14480
14540
  }
14481
14541
  routeGroups.get(key).push(route);
14482
14542
  }
14483
- for (const [path36, routeList] of routeGroups) {
14484
- const openAPIPath = this.convertToOpenAPIPath(path36);
14543
+ for (const [path37, routeList] of routeGroups) {
14544
+ const openAPIPath = this.convertToOpenAPIPath(path37);
14485
14545
  spec.paths[openAPIPath] = {};
14486
14546
  for (const route of routeList) {
14487
14547
  for (const method of route.methods) {
@@ -14501,8 +14561,8 @@ var init_generator = __esm({
14501
14561
  /**
14502
14562
  * Convert Farm.js API path to OpenAPI path format
14503
14563
  */
14504
- convertToOpenAPIPath(path36) {
14505
- return path36.replace(/^\/api/, "");
14564
+ convertToOpenAPIPath(path37) {
14565
+ return path37.replace(/^\/api/, "");
14506
14566
  }
14507
14567
  /**
14508
14568
  * Extract request body schema from endpoint
@@ -14664,8 +14724,8 @@ var init_generator = __esm({
14664
14724
  /**
14665
14725
  * Generate operation summary
14666
14726
  */
14667
- generateSummary(path36, method) {
14668
- const cleanPath = path36.replace(/^\/api\//, "");
14727
+ generateSummary(path37, method) {
14728
+ const cleanPath = path37.replace(/^\/api\//, "");
14669
14729
  const pathParts = cleanPath.split("/");
14670
14730
  const lastPart = pathParts[pathParts.length - 1];
14671
14731
  const action = method === "GET" ? "Get" : method === "QUERY" ? "Query" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -14674,22 +14734,22 @@ var init_generator = __esm({
14674
14734
  /**
14675
14735
  * Generate operation description
14676
14736
  */
14677
- generateDescription(path36, method) {
14678
- const cleanPath = path36.replace(/^\/api\//, "");
14737
+ generateDescription(path37, method) {
14738
+ const cleanPath = path37.replace(/^\/api\//, "");
14679
14739
  return `${method} ${cleanPath} endpoint`;
14680
14740
  }
14681
14741
  /**
14682
14742
  * Generate operation ID
14683
14743
  */
14684
- generateOperationId(path36, method) {
14685
- const cleanPath = path36.replace(/^\/api\//, "").replace(/\//g, "_");
14744
+ generateOperationId(path37, method) {
14745
+ const cleanPath = path37.replace(/^\/api\//, "").replace(/\//g, "_");
14686
14746
  return `${method.toLowerCase()}_${cleanPath}`;
14687
14747
  }
14688
14748
  /**
14689
14749
  * Generate tags for grouping operations
14690
14750
  */
14691
- generateTags(path36) {
14692
- const cleanPath = path36.replace(/^\/api\//, "");
14751
+ generateTags(path37) {
14752
+ const cleanPath = path37.replace(/^\/api\//, "");
14693
14753
  const pathParts = cleanPath.split("/");
14694
14754
  if (pathParts.length > 1) {
14695
14755
  return [pathParts[0]];
@@ -14701,13 +14761,13 @@ var init_generator = __esm({
14701
14761
  */
14702
14762
  async generateSpecFile(routes, outputPath) {
14703
14763
  const spec = await this.generateSpec(routes);
14704
- const fs15 = require("fs");
14705
- const path36 = require("path");
14706
- const dir = path36.dirname(outputPath);
14707
- if (!fs15.existsSync(dir)) {
14708
- fs15.mkdirSync(dir, { recursive: true });
14764
+ const fs16 = require("fs");
14765
+ const path37 = require("path");
14766
+ const dir = path37.dirname(outputPath);
14767
+ if (!fs16.existsSync(dir)) {
14768
+ fs16.mkdirSync(dir, { recursive: true });
14709
14769
  }
14710
- fs15.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
14770
+ fs16.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
14711
14771
  }
14712
14772
  };
14713
14773
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -15135,7 +15195,7 @@ async function createFarmDevtoolsSnapshot(input) {
15135
15195
  generatedAt: (input.now?.() || /* @__PURE__ */ new Date()).toISOString(),
15136
15196
  health: resolveHealth(diagnostics),
15137
15197
  project: {
15138
- name: import_node_path20.default.basename(import_node_path20.default.resolve(input.root)),
15198
+ name: import_node_path21.default.basename(import_node_path21.default.resolve(input.root)),
15139
15199
  root: input.root,
15140
15200
  srcDir: input.srcDir,
15141
15201
  basePath: config.basePath || "/",
@@ -15184,11 +15244,11 @@ async function createFarmDevtoolsSnapshot(input) {
15184
15244
  diagnostics
15185
15245
  };
15186
15246
  }
15187
- var import_node_path20;
15247
+ var import_node_path21;
15188
15248
  var init_devtools = __esm({
15189
15249
  "src/devtools.ts"() {
15190
15250
  "use strict";
15191
- import_node_path20 = __toESM(require("path"));
15251
+ import_node_path21 = __toESM(require("path"));
15192
15252
  init_config4();
15193
15253
  init_cron();
15194
15254
  init_route_runtime();
@@ -15829,6 +15889,7 @@ function renderFarmDevtoolsHtml(snapshot) {
15829
15889
  .nav-item .icon { width: 13px; height: 13px; }
15830
15890
  .nav-item small { color: #666; font-size: 9px; font-weight: 400; }
15831
15891
  .topbar-meta { display: flex; flex: 0 0 auto; margin-left: auto; border-left: 1px solid var(--line); }
15892
+ .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; }
15832
15893
  .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; }
15833
15894
  .status-dot { width: 5px; height: 5px; background: #fff; box-shadow: 0 0 0 3px rgb(255 255 255 / 0.06); }
15834
15895
  .status-dot-attention { background: #909090; animation: status-pulse 1.8s ease-in-out infinite; }
@@ -16338,6 +16399,7 @@ function renderFarmDevtoolsHtml(snapshot) {
16338
16399
  ${renderNavigationItem("raw", "Raw")}
16339
16400
  </nav>
16340
16401
  <div class="topbar-meta">
16402
+ <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>
16341
16403
  <span class="project-select">${escapeHtml3(snapshot.project.name)} ${icon(
16342
16404
  "chevron"
16343
16405
  )}</span>
@@ -16593,23 +16655,26 @@ function generateFarmDevtoolsClientRuntime(config) {
16593
16655
  z-index: 2147483646;
16594
16656
  display: grid;
16595
16657
  place-items: center;
16658
+ box-sizing: border-box;
16596
16659
  padding: 20px;
16597
16660
  background: rgb(0 0 0 / 0);
16598
- backdrop-filter: blur(0);
16661
+ backdrop-filter: blur(6px);
16662
+ -webkit-backdrop-filter: blur(6px);
16663
+ overscroll-behavior: none;
16664
+ isolation: isolate;
16599
16665
  opacity: 0;
16600
16666
  pointer-events: none;
16601
- transition: background-color 150ms ease-out, backdrop-filter 150ms ease-out, opacity 150ms ease-out;
16667
+ transition: opacity 150ms ease-out;
16602
16668
  }
16603
16669
  #__farm_devtools_overlay__[data-open="true"] {
16604
- background: rgb(0 0 0 / 0.12);
16605
- backdrop-filter: blur(1px);
16670
+ background: rgb(0 0 0 / 0.32);
16606
16671
  opacity: 1;
16607
16672
  pointer-events: auto;
16608
16673
  }
16609
16674
  #__farm_devtools_overlay__ > iframe {
16610
16675
  display: block;
16611
- width: min(960px, calc(100vw - 40px));
16612
- height: min(560px, calc(100dvh - 40px));
16676
+ width: min(1100px, calc(100vw - 48px));
16677
+ height: min(720px, calc(100dvh - 48px));
16613
16678
  border: 0;
16614
16679
  border-radius: 12px;
16615
16680
  background: transparent;
@@ -16625,7 +16690,7 @@ function generateFarmDevtoolsClientRuntime(config) {
16625
16690
  #__farm_devtools_overlay__ > iframe {
16626
16691
  width: calc(100vw - 16px);
16627
16692
  height: calc(100dvh - 16px);
16628
- border-radius: 10px;
16693
+ border-radius: 12px;
16629
16694
  }
16630
16695
  }
16631
16696
  @media (prefers-reduced-motion: reduce) {
@@ -16639,10 +16704,32 @@ function generateFarmDevtoolsClientRuntime(config) {
16639
16704
  const runtimeKey = "__FARM_DEVTOOLS_RUNTIME__";
16640
16705
  const launchParam = ${JSON.stringify(FARM_DEVTOOLS_LAUNCH_PARAM)};
16641
16706
  const devtoolsPath = ${JSON.stringify(FARM_DEVTOOLS_PATH)};
16642
- const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw"]);
16707
+ const validViews = new Set(["overview", "routes", "api", "systems", "runtime", "raw", "inspect", "diagnostics"]);
16643
16708
  const shortcut = ${JSON.stringify(shortcut)};
16644
16709
  const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform);
16645
16710
  let returnFocus = null;
16711
+ let restorePage = null;
16712
+ let closeTimer = null;
16713
+
16714
+ const lockPage = () => {
16715
+ const styles = [];
16716
+ for (const element of [document.documentElement, document.body]) {
16717
+ for (const [property, value] of [["overflow-x", "hidden"], ["overflow-y", "hidden"], ["overscroll-behavior", "none"]]) {
16718
+ const previous = element.style.getPropertyValue(property);
16719
+ const priority = element.style.getPropertyPriority(property);
16720
+ element.style.setProperty(property, value, "important");
16721
+ styles.push({ element, property, value, previous, priority });
16722
+ }
16723
+ }
16724
+ return () => {
16725
+ for (const { element, property, value, previous, priority } of styles) {
16726
+ // Do not overwrite a newer style set by the application while the panel was open.
16727
+ if (element.style.getPropertyValue(property) !== value || element.style.getPropertyPriority(property) !== "important") continue;
16728
+ if (previous) element.style.setProperty(property, previous, priority);
16729
+ else element.style.removeProperty(property);
16730
+ }
16731
+ };
16732
+ };
16646
16733
 
16647
16734
  const matchesShortcut = (event) => {
16648
16735
  if (!shortcut || event.repeat) return false;
@@ -16669,24 +16756,35 @@ function generateFarmDevtoolsClientRuntime(config) {
16669
16756
  document.head.appendChild(style);
16670
16757
  };
16671
16758
 
16672
- const close = () => {
16759
+ const finishClose = () => {
16760
+ if (closeTimer !== null) window.clearTimeout(closeTimer);
16761
+ closeTimer = null;
16673
16762
  const overlay = document.getElementById(overlayId);
16674
- if (!overlay) return;
16763
+ overlay?.remove();
16764
+ restorePage?.();
16765
+ restorePage = null;
16675
16766
  const focusTarget = returnFocus;
16676
16767
  returnFocus = null;
16768
+ focusTarget?.focus?.({ preventScroll: true });
16769
+ };
16770
+
16771
+ const close = () => {
16772
+ const overlay = document.getElementById(overlayId);
16773
+ if (!overlay || closeTimer !== null) return;
16677
16774
  overlay.dataset.open = "false";
16678
- window.setTimeout(() => {
16679
- overlay.remove();
16680
- focusTarget?.focus?.();
16681
- }, 160);
16775
+ closeTimer = window.setTimeout(finishClose, 160);
16682
16776
  };
16683
16777
 
16684
16778
  const open = (view = "overview") => {
16779
+ if (closeTimer !== null) finishClose();
16685
16780
  if (document.getElementById(overlayId)) return;
16686
16781
  ensureStyles();
16687
16782
  returnFocus = document.activeElement;
16783
+ restorePage = lockPage();
16688
16784
  const overlay = document.createElement("div");
16689
16785
  overlay.id = overlayId;
16786
+ overlay.setAttribute("role", "dialog");
16787
+ overlay.setAttribute("aria-modal", "true");
16690
16788
  overlay.setAttribute("aria-label", "Farm.js DevTools overlay");
16691
16789
  const frame = document.createElement("iframe");
16692
16790
  const resolvedView = validViews.has(view) ? view : "overview";
@@ -16697,9 +16795,11 @@ function generateFarmDevtoolsClientRuntime(config) {
16697
16795
  overlay.addEventListener("pointerdown", (event) => {
16698
16796
  if (event.target === overlay) close();
16699
16797
  });
16798
+ overlay.addEventListener("wheel", (event) => event.preventDefault(), { passive: false });
16799
+ overlay.addEventListener("touchmove", (event) => event.preventDefault(), { passive: false });
16700
16800
  document.body.appendChild(overlay);
16701
16801
  requestAnimationFrame(() => {
16702
- overlay.dataset.open = "true";
16802
+ if (overlay.isConnected && closeTimer === null) overlay.dataset.open = "true";
16703
16803
  });
16704
16804
  };
16705
16805
 
@@ -16733,6 +16833,7 @@ function generateFarmDevtoolsClientRuntime(config) {
16733
16833
  window.addEventListener("message", onMessage);
16734
16834
  window[runtimeKey] = {
16735
16835
  dispose() {
16836
+ finishClose();
16736
16837
  window.removeEventListener("keydown", onKeydown, true);
16737
16838
  window.removeEventListener("message", onMessage);
16738
16839
  },
@@ -17083,10 +17184,11 @@ var ROUTE_PROP_LABELS = /* @__PURE__ */ new Map([
17083
17184
  ["middlewareData", "middleware request data"],
17084
17185
  ["context", "request context"]
17085
17186
  ]);
17086
- function resolveConfiguredRouteRenderingConfig(mod, source) {
17187
+ function resolveConfiguredRouteRenderingConfig(mod, source, options) {
17188
+ const pprEnabled = options?.experimentalPPR === true;
17087
17189
  const directiveConfig = parseRouteRenderingDirective(source);
17088
17190
  let ssg = directiveConfig?.ssg ?? false;
17089
- let ppr = directiveConfig?.ppr ?? false;
17191
+ let requestedPPR = directiveConfig?.ppr ?? false;
17090
17192
  let revalidate = directiveConfig?.revalidate;
17091
17193
  const moduleDynamic = normalizeDynamicMode(mod?.dynamic);
17092
17194
  const dynamic = moduleDynamic ?? directiveConfig?.dynamic;
@@ -17096,12 +17198,12 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
17096
17198
  ssg = mod.ssg === true;
17097
17199
  }
17098
17200
  if (hasExplicitPPR) {
17099
- ppr = mod?.ppr === true || mod?.experimental_ppr === true;
17201
+ requestedPPR = mod?.ppr === true || mod?.experimental_ppr === true;
17100
17202
  }
17101
17203
  if (typeof mod?.revalidate === "number") {
17102
17204
  if (mod.revalidate > 0) {
17103
17205
  revalidate = mod.revalidate;
17104
- if (!hasExplicitSsg && !ppr) {
17206
+ if (!hasExplicitSsg && !requestedPPR) {
17105
17207
  ssg = true;
17106
17208
  }
17107
17209
  } else {
@@ -17115,23 +17217,24 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
17115
17217
  }
17116
17218
  if (moduleDynamic === "force-static" || moduleDynamic === "error") {
17117
17219
  ssg = true;
17118
- ppr = false;
17220
+ requestedPPR = false;
17119
17221
  } else if (moduleDynamic === "force-dynamic") {
17120
17222
  ssg = false;
17121
- ppr = false;
17223
+ requestedPPR = false;
17122
17224
  revalidate = void 0;
17123
17225
  }
17226
+ const ppr = pprEnabled && !ssg && requestedPPR;
17124
17227
  return {
17125
17228
  ssg,
17126
- ppr: ssg ? false : ppr,
17229
+ ppr,
17127
17230
  revalidate: ssg || ppr ? revalidate : void 0,
17128
17231
  dynamic,
17129
17232
  directive: directiveConfig?.directive
17130
17233
  };
17131
17234
  }
17132
17235
  __name(resolveConfiguredRouteRenderingConfig, "resolveConfiguredRouteRenderingConfig");
17133
- function resolveRouteRenderingConfig(mod, source) {
17134
- const rendering = resolveConfiguredRouteRenderingConfig(mod, source);
17236
+ function resolveRouteRenderingConfig(mod, source, options) {
17237
+ const rendering = resolveConfiguredRouteRenderingConfig(mod, source, options);
17135
17238
  if (!rendering.ssg || !source) {
17136
17239
  return rendering;
17137
17240
  }
@@ -17146,9 +17249,9 @@ function resolveRouteRenderingConfig(mod, source) {
17146
17249
  };
17147
17250
  }
17148
17251
  __name(resolveRouteRenderingConfig, "resolveRouteRenderingConfig");
17149
- async function resolveRouteRenderingConfigFromFile(mod, filePath) {
17252
+ async function resolveRouteRenderingConfigFromFile(mod, filePath, options) {
17150
17253
  const source = await (0, import_promises2.readFile)(filePath, "utf8").catch(() => void 0);
17151
- return resolveRouteRenderingConfig(mod, source);
17254
+ return resolveRouteRenderingConfig(mod, source, options);
17152
17255
  }
17153
17256
  __name(resolveRouteRenderingConfigFromFile, "resolveRouteRenderingConfigFromFile");
17154
17257
  function analyzeStaticRouteCandidate(mod, source, options = {}) {
@@ -18246,7 +18349,7 @@ function getIslandStrategyExport(content) {
18246
18349
  __name(getIslandStrategyExport, "getIslandStrategyExport");
18247
18350
  function stripUseClientDirective(content) {
18248
18351
  return content.replace(
18249
- /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*)(["'])use client\2\s*;?\s*/,
18352
+ /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/|(?:"[^"\n]*"|'[^'\n]*')\s*;?)*)(["'])use client\2\s*;?\s*/,
18250
18353
  "$1"
18251
18354
  );
18252
18355
  }
@@ -21415,7 +21518,7 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
21415
21518
  return this.resolveMessage(locale, key);
21416
21519
  }
21417
21520
  hasMessage(locale, key) {
21418
- return (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !== void 0;
21521
+ return this.readOwnMessage(locale, key) !== void 0;
21419
21522
  }
21420
21523
  getClientSnapshot(resolution) {
21421
21524
  return {
@@ -21443,8 +21546,19 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
21443
21546
  }
21444
21547
  return formatter.format(values);
21445
21548
  }
21549
+ // Look up a message by own-property only. A key named after an
21550
+ // Object.prototype member (toString, valueOf, constructor, ...) must resolve
21551
+ // to a real catalog entry or undefined, never the inherited prototype value
21552
+ // (mirrors the own-property handling added to catalog.ts in #454).
21553
+ readOwnMessage(locale, key) {
21554
+ const direct = this.catalogs[locale];
21555
+ if (direct && Object.prototype.hasOwnProperty.call(direct, key)) return direct[key];
21556
+ const fallback = this.catalogs[this.config.fallbackLocale];
21557
+ if (fallback && Object.prototype.hasOwnProperty.call(fallback, key)) return fallback[key];
21558
+ return void 0;
21559
+ }
21446
21560
  resolveMessage(locale, key) {
21447
- const message = this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];
21561
+ const message = this.readOwnMessage(locale, key);
21448
21562
  if (message !== void 0) return message;
21449
21563
  if (this.config.strict) {
21450
21564
  throw new Error(`Missing Farm i18n message "${key}" for locale "${locale}".`);
@@ -23793,7 +23907,7 @@ _setFarmThemeServerSnapshotResolver(() => {
23793
23907
  });
23794
23908
 
23795
23909
  // package.json
23796
- var version = "0.1.0-beta.95";
23910
+ var version = "0.1.0-beta.97";
23797
23911
 
23798
23912
  // src/version.ts
23799
23913
  var FARM_VERSION = version;
@@ -24721,7 +24835,8 @@ var _ServerRenderer = class _ServerRenderer {
24721
24835
  }
24722
24836
  const renderingConfig = await resolveRouteRenderingConfigFromFile(
24723
24837
  routeModule,
24724
- route.modulePath
24838
+ route.modulePath,
24839
+ { experimentalPPR: this.config.experimental?.ppr === true }
24725
24840
  );
24726
24841
  const pprBypassReason = renderingConfig.ppr ? this.getPPRShellBypassReason(req, middlewareMap, middlewareContext, pluginExposedContext) : void 0;
24727
24842
  const canCachePPRShell = renderingConfig.ppr && !pprBypassReason;
@@ -25426,6 +25541,11 @@ var _ServerRenderer = class _ServerRenderer {
25426
25541
  );
25427
25542
  res.statusCode = options.statusCode;
25428
25543
  res.setHeader("Content-Type", "text/html; charset=utf-8");
25544
+ res.setHeader("Cache-Control", "private, no-store");
25545
+ res.setHeader("X-Content-Type-Options", "nosniff");
25546
+ if (typeof res.removeHeader === "function") {
25547
+ res.removeHeader("X-Farm-PPR");
25548
+ }
25429
25549
  res.write(this.createFullHTML(html, false, options.pathname));
25430
25550
  res.end();
25431
25551
  return true;
@@ -26163,6 +26283,7 @@ var _FarmApp = class _FarmApp {
26163
26283
  serverComponents: config.experimental?.serverComponents ?? false,
26164
26284
  serverActions: config.experimental?.serverActions ?? false,
26165
26285
  isolatedClientHydration: config.experimental?.isolatedClientHydration ?? "off",
26286
+ ppr: config.experimental?.ppr ?? false,
26166
26287
  ...config.experimental
26167
26288
  },
26168
26289
  vite: config.vite || {}
@@ -27157,6 +27278,53 @@ function isArrayIndex(key) {
27157
27278
  }
27158
27279
  __name(isArrayIndex, "isArrayIndex");
27159
27280
 
27281
+ // src/client-cache-persistence-build.ts
27282
+ var import_node_fs5 = __toESM(require("fs"));
27283
+ var import_node_path10 = __toESM(require("path"));
27284
+ var ADAPTER_EXTENSIONS = ["ts", "tsx", "js", "jsx", "mts", "mjs"];
27285
+ function resolveFarmClientCacheAdapterEntry(root, cache) {
27286
+ const client = cache?.client;
27287
+ const adapter = client?.adapter;
27288
+ if (adapter === void 0) return void 0;
27289
+ if (typeof adapter !== "string" || adapter.trim().length === 0) {
27290
+ throw new Error(
27291
+ 'cache.client.adapter must be a module path string, for example "./src/cache-adapter".'
27292
+ );
27293
+ }
27294
+ const resolved = import_node_path10.default.resolve(root, adapter);
27295
+ const found = resolveAdapterFile(resolved);
27296
+ if (!found) {
27297
+ throw new Error(
27298
+ `cache.client.adapter was not found: ${adapter} (resolved to ${resolved}). Point it at a client module whose default export is created with defineClientCacheAdapter().`
27299
+ );
27300
+ }
27301
+ const options = {};
27302
+ if (client?.version !== void 0) options.version = client.version;
27303
+ if (client?.flushDelayMs !== void 0) options.flushDelayMs = client.flushDelayMs;
27304
+ return { importPath: found.replace(/\\/g, "/"), options };
27305
+ }
27306
+ __name(resolveFarmClientCacheAdapterEntry, "resolveFarmClientCacheAdapterEntry");
27307
+ function resolveAdapterFile(resolved) {
27308
+ if (import_node_fs5.default.existsSync(resolved) && import_node_fs5.default.statSync(resolved).isFile()) return resolved;
27309
+ for (const extension of ADAPTER_EXTENSIONS) {
27310
+ const candidate = `${resolved}.${extension}`;
27311
+ if (import_node_fs5.default.existsSync(candidate) && import_node_fs5.default.statSync(candidate).isFile()) return candidate;
27312
+ }
27313
+ return void 0;
27314
+ }
27315
+ __name(resolveAdapterFile, "resolveAdapterFile");
27316
+ function generateClientCachePersistenceCode(entry) {
27317
+ if (!entry) return { imports: "", init: "" };
27318
+ return {
27319
+ imports: [
27320
+ `import * as __farmClientCacheAdapterModule from ${JSON.stringify(entry.importPath)};`,
27321
+ `import { initConfiguredClientCachePersistence as __farmInitClientCachePersistence } from "@farm.js/core/client";`
27322
+ ].join("\n"),
27323
+ init: `__farmInitClientCachePersistence(__farmClientCacheAdapterModule, ${JSON.stringify(entry.options)});`
27324
+ };
27325
+ }
27326
+ __name(generateClientCachePersistenceCode, "generateClientCachePersistenceCode");
27327
+
27160
27328
  // src/api/endpoint.ts
27161
27329
  var import_better_call = require("better-call");
27162
27330
  init_cache();
@@ -27184,15 +27352,15 @@ function isEndpointFailure(value) {
27184
27352
  }
27185
27353
  __name(isEndpointFailure, "isEndpointFailure");
27186
27354
  function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
27187
- let path36;
27355
+ let path37;
27188
27356
  let options;
27189
27357
  let handler;
27190
27358
  if (typeof pathOrOptions === "string") {
27191
- path36 = pathOrOptions;
27359
+ path37 = pathOrOptions;
27192
27360
  options = optionsOrHandler;
27193
27361
  handler = maybeHandler;
27194
27362
  } else {
27195
- path36 = "";
27363
+ path37 = "";
27196
27364
  options = pathOrOptions;
27197
27365
  handler = optionsOrHandler;
27198
27366
  }
@@ -27219,13 +27387,13 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
27219
27387
  ...betterCallOptions
27220
27388
  } = options;
27221
27389
  const endpoint = (0, import_better_call.createEndpoint)(
27222
- path36 || "/__farm_auto_path__",
27390
+ path37 || "/__farm_auto_path__",
27223
27391
  betterCallOptions,
27224
27392
  wrappedHandler
27225
27393
  );
27226
- endpoint.__path = path36 || void 0;
27394
+ endpoint.__path = path37 || void 0;
27227
27395
  endpoint.__method = options.method || "GET";
27228
- endpoint.__autoPath = !path36;
27396
+ endpoint.__autoPath = !path37;
27229
27397
  endpoint.__handler = wrappedHandler;
27230
27398
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
27231
27399
  endpoint.__middleware = middleware;
@@ -27236,6 +27404,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
27236
27404
  body: options.body,
27237
27405
  inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
27238
27406
  query: options.query,
27407
+ inputQuery: options.query,
27239
27408
  headers: options.headers,
27240
27409
  response: null,
27241
27410
  errors
@@ -27432,10 +27601,10 @@ function createRouteFactoryAt(prefix) {
27432
27601
  "OPTIONS"
27433
27602
  ]) {
27434
27603
  factory[method.toLowerCase()] = (child, options) => {
27435
- const path36 = joinRoutePath(prefix, child);
27604
+ const path37 = joinRoutePath(prefix, child);
27436
27605
  const input = options.input ?? {};
27437
27606
  const endpoint = createEndpoint(
27438
- path36,
27607
+ path37,
27439
27608
  {
27440
27609
  method,
27441
27610
  body: input.body,
@@ -27451,7 +27620,7 @@ function createRouteFactoryAt(prefix) {
27451
27620
  );
27452
27621
  endpoint.__types.params = input.params;
27453
27622
  endpoint.__output = options.output;
27454
- return Object.freeze({ path: path36, method, endpoint });
27623
+ return Object.freeze({ path: path37, method, endpoint });
27455
27624
  };
27456
27625
  }
27457
27626
  return Object.freeze(factory);
@@ -27459,21 +27628,21 @@ function createRouteFactoryAt(prefix) {
27459
27628
  __name(createRouteFactoryAt, "createRouteFactoryAt");
27460
27629
  function joinRoutePath(prefix, child) {
27461
27630
  if (typeof child !== "string") throw new TypeError("Route paths must be strings.");
27462
- const path36 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
27463
- if (!(path36 === "/api" || path36.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path36)) {
27631
+ const path37 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
27632
+ if (!(path37 === "/api" || path37.startsWith("/api/")) || /[?#]|\/\/|\/$/.test(path37)) {
27464
27633
  throw new TypeError(
27465
- `Plugin route "${path36}" must be a canonical /api path without a query, hash, or empty segment.`
27634
+ `Plugin route "${path37}" must be a canonical /api path without a query, hash, or empty segment.`
27466
27635
  );
27467
27636
  }
27468
- assertBrowserStableRoutePath(path36);
27469
- assertUniqueRouteParameters(path36, "api");
27470
- getRoutePatternShape(path36, "api");
27471
- for (const segment of path36.split("/")) {
27637
+ assertBrowserStableRoutePath(path37);
27638
+ assertUniqueRouteParameters(path37, "api");
27639
+ getRoutePatternShape(path37, "api");
27640
+ for (const segment of path37.split("/")) {
27472
27641
  if (["__proto__", "constructor", "prototype", "$params"].includes(segment)) {
27473
27642
  throw new TypeError(`Route segment "${segment}" is reserved.`);
27474
27643
  }
27475
27644
  }
27476
- return path36;
27645
+ return path37;
27477
27646
  }
27478
27647
  __name(joinRoutePath, "joinRoutePath");
27479
27648
  function resolvePluginRoutes(plugins = []) {
@@ -27526,7 +27695,7 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
27526
27695
  }
27527
27696
  const result = [...routes.values()];
27528
27697
  if (expected) {
27529
- const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path36, methods }) => `${path36}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
27698
+ const signature = /* @__PURE__ */ __name((entries) => entries.map(({ path: path37, methods }) => `${path37}:${[...methods].sort().join(",")}`).sort().join("\n"), "signature");
27530
27699
  if (signature(result) !== signature(expected)) {
27531
27700
  throw new Error(
27532
27701
  "Plugin API routes changed between build and runtime. Route paths and methods must be stable across environments; rebuild the app."
@@ -27538,8 +27707,8 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
27538
27707
  __name(mergePluginAPIRoutes, "mergePluginAPIRoutes");
27539
27708
 
27540
27709
  // src/api/route-manager.ts
27541
- var fs6 = __toESM(require("fs"));
27542
- var path16 = __toESM(require("path"));
27710
+ var fs7 = __toESM(require("fs"));
27711
+ var path17 = __toESM(require("path"));
27543
27712
  init_utils();
27544
27713
  init_routes_shared();
27545
27714
  init_route_runtime();
@@ -28003,9 +28172,9 @@ var _APIRouteManager = class _APIRouteManager {
28003
28172
  this.routeShapes = /* @__PURE__ */ new Map();
28004
28173
  try {
28005
28174
  for (const appDir of this.appDirs) {
28006
- const apiDir = path16.join(appDir, "api");
28175
+ const apiDir = path17.join(appDir, "api");
28007
28176
  let routeFiles = [];
28008
- if (fs6.existsSync(apiDir)) {
28177
+ if (fs7.existsSync(apiDir)) {
28009
28178
  routeFiles = this.findRouteFiles(apiDir);
28010
28179
  }
28011
28180
  for (const filePath of routeFiles) {
@@ -28038,12 +28207,12 @@ var _APIRouteManager = class _APIRouteManager {
28038
28207
  */
28039
28208
  findRouteFiles(dir) {
28040
28209
  const files = [];
28041
- if (!fs6.existsSync(dir)) {
28210
+ if (!fs7.existsSync(dir)) {
28042
28211
  return files;
28043
28212
  }
28044
- const entries = fs6.readdirSync(dir, { withFileTypes: true });
28213
+ const entries = fs7.readdirSync(dir, { withFileTypes: true });
28045
28214
  for (const entry of entries) {
28046
- const fullPath = path16.join(dir, entry.name);
28215
+ const fullPath = path17.join(dir, entry.name);
28047
28216
  if (entry.isDirectory()) {
28048
28217
  files.push(...this.findRouteFiles(fullPath));
28049
28218
  } else if (isFarmAPIRouteFileName(entry.name)) {
@@ -28057,8 +28226,8 @@ var _APIRouteManager = class _APIRouteManager {
28057
28226
  */
28058
28227
  async loadRoute(filePath, appDir) {
28059
28228
  try {
28060
- const apiDir = path16.join(appDir, "api");
28061
- const relativePath2 = path16.relative(apiDir, path16.dirname(filePath));
28229
+ const apiDir = path17.join(appDir, "api");
28230
+ const relativePath2 = path17.relative(apiDir, path17.dirname(filePath));
28062
28231
  const routePath = "/api/" + (relativePath2 === "." ? "" : relativePath2.replace(/\\/g, "/"));
28063
28232
  const routeModule = await this.loadModule(filePath);
28064
28233
  const endpoints = {};
@@ -28131,7 +28300,7 @@ var _APIRouteManager = class _APIRouteManager {
28131
28300
  }
28132
28301
  }
28133
28302
  async loadProgrammaticApiRoutes(appDir) {
28134
- const candidateRoots = [path16.dirname(appDir), appDir];
28303
+ const candidateRoots = [path17.dirname(appDir), appDir];
28135
28304
  const routeFiles = Array.from(
28136
28305
  new Set(candidateRoots.flatMap((srcRoot) => findProgrammaticRouteFilesInDir(srcRoot)))
28137
28306
  );
@@ -28160,16 +28329,16 @@ var _APIRouteManager = class _APIRouteManager {
28160
28329
  }
28161
28330
  findRootRoutesFile(appDir) {
28162
28331
  const routeNames = ["routes.ts", "routes.tsx", "routes.js"];
28163
- const candidateDirs = [path16.dirname(appDir), appDir];
28332
+ const candidateDirs = [path17.dirname(appDir), appDir];
28164
28333
  const seen = /* @__PURE__ */ new Set();
28165
28334
  for (const dir of candidateDirs) {
28166
28335
  for (const routeName of routeNames) {
28167
- const routesFile = path16.join(dir, routeName);
28336
+ const routesFile = path17.join(dir, routeName);
28168
28337
  if (seen.has(routesFile)) {
28169
28338
  continue;
28170
28339
  }
28171
28340
  seen.add(routesFile);
28172
- if (fs6.existsSync(routesFile)) {
28341
+ if (fs7.existsSync(routesFile)) {
28173
28342
  return routesFile;
28174
28343
  }
28175
28344
  }
@@ -28303,8 +28472,8 @@ var APIRouteManager = _APIRouteManager;
28303
28472
  init_config3();
28304
28473
 
28305
28474
  // src/middleware/manager.ts
28306
- var fs7 = __toESM(require("fs"));
28307
- var path17 = __toESM(require("path"));
28475
+ var fs8 = __toESM(require("fs"));
28476
+ var path18 = __toESM(require("path"));
28308
28477
  init_decode();
28309
28478
 
28310
28479
  // src/middleware/cookie-header.ts
@@ -28705,7 +28874,7 @@ var _MiddlewareManager = class _MiddlewareManager {
28705
28874
  * Recursively discover middleware files
28706
28875
  */
28707
28876
  async discoverInDirectory(dir, routePath, discovered) {
28708
- if (!fs7.existsSync(dir)) {
28877
+ if (!fs8.existsSync(dir)) {
28709
28878
  return;
28710
28879
  }
28711
28880
  const middlewareFile = this.findMiddlewareFile(dir);
@@ -28715,10 +28884,10 @@ var _MiddlewareManager = class _MiddlewareManager {
28715
28884
  discovered.push(middleware);
28716
28885
  }
28717
28886
  }
28718
- const entries = fs7.readdirSync(dir, { withFileTypes: true });
28887
+ const entries = fs8.readdirSync(dir, { withFileTypes: true });
28719
28888
  for (const entry of entries) {
28720
28889
  if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
28721
- const subPath = path17.join(dir, entry.name);
28890
+ const subPath = path18.join(dir, entry.name);
28722
28891
  const subRoutePath = appendMiddlewareRoutePath(routePath, entry.name);
28723
28892
  await this.discoverInDirectory(subPath, subRoutePath, discovered);
28724
28893
  }
@@ -28730,8 +28899,8 @@ var _MiddlewareManager = class _MiddlewareManager {
28730
28899
  findMiddlewareFile(dir) {
28731
28900
  const extensions = [".ts", ".tsx", ".js", ".jsx"];
28732
28901
  for (const ext of extensions) {
28733
- const filePath = path17.join(dir, `middleware${ext}`);
28734
- if (fs7.existsSync(filePath)) {
28902
+ const filePath = path18.join(dir, `middleware${ext}`);
28903
+ if (fs8.existsSync(filePath)) {
28735
28904
  return filePath;
28736
28905
  }
28737
28906
  }
@@ -29071,8 +29240,8 @@ var import_path9 = require("path");
29071
29240
  init_type_generator();
29072
29241
 
29073
29242
  // src/routing/generate-route-types.ts
29074
- var path18 = __toESM(require("path"));
29075
- var fs8 = __toESM(require("fs"));
29243
+ var path19 = __toESM(require("path"));
29244
+ var fs9 = __toESM(require("fs"));
29076
29245
  init_utils();
29077
29246
  init_write_file_if_changed();
29078
29247
  init_renderer();
@@ -29125,12 +29294,12 @@ function createRoutePattern(route) {
29125
29294
  __name(createRoutePattern, "createRoutePattern");
29126
29295
  var DEFAULT_OUT_FILE = "farm-routes.d.ts";
29127
29296
  async function generateRouteTypes(options) {
29128
- const root = path18.resolve(options.root);
29297
+ const root = path19.resolve(options.root);
29129
29298
  const srcDir = options.srcDir || "src";
29130
29299
  const outFile = options.outFile || DEFAULT_OUT_FILE;
29131
- const outPath = path18.isAbsolute(outFile) ? outFile : path18.join(root, srcDir, outFile);
29300
+ const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
29132
29301
  const content = await createRouteTypeDeclarations(options, outPath);
29133
- fs8.mkdirSync(path18.dirname(outPath), { recursive: true });
29302
+ fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
29134
29303
  writeFileIfChanged(outPath, content);
29135
29304
  return outPath;
29136
29305
  }
@@ -29145,8 +29314,8 @@ async function createRouteTypeDeclarations(options, outPath) {
29145
29314
  const routeModulePatterns = /* @__PURE__ */ new Set();
29146
29315
  const glob = await import("fast-glob");
29147
29316
  for (const source of sourceRoots) {
29148
- const appDir = path18.join(source.root, source.srcDir, "app");
29149
- if (fs8.existsSync(appDir)) {
29317
+ const appDir = path19.join(source.root, source.srcDir, "app");
29318
+ if (fs9.existsSync(appDir)) {
29150
29319
  const routeModuleFiles = await glob.default(
29151
29320
  `**/{page,layout,loading,error}.{${componentExtensions.join(",")},md,mdx}`,
29152
29321
  {
@@ -29182,7 +29351,7 @@ async function createRouteTypeDeclarations(options, outPath) {
29182
29351
  const routePathType = suppressLintOnLink ? "string" : renderTypeUnion(typeLiterals);
29183
29352
  const routePatternType = suppressLintOnLink ? "string" : renderTypeUnion(patternLiterals);
29184
29353
  const routeModulePatternType = renderTypeUnion(routeModulePatternLiterals);
29185
- const routeTypesImportPath = `./${path18.basename(outPath).replace(/\.d\.ts$/, "")}`;
29354
+ const routeTypesImportPath = `./${path19.basename(outPath).replace(/\.d\.ts$/, "")}`;
29186
29355
  const linkAugmentationBlock = suppressLintOnLink ? "" : `
29187
29356
  declare module "@farm.js/core/client" {
29188
29357
  interface LinkDefaultRoute {
@@ -29232,8 +29401,8 @@ ${renderTypeAlias("RouteModulePattern", routeModulePatternType)}${linkAugmentati
29232
29401
  __name(createRouteTypeDeclarations, "createRouteTypeDeclarations");
29233
29402
 
29234
29403
  // src/env-types.ts
29235
- var fs9 = __toESM(require("fs"));
29236
- var path19 = __toESM(require("path"));
29404
+ var fs10 = __toESM(require("fs"));
29405
+ var path20 = __toESM(require("path"));
29237
29406
  init_write_file_if_changed();
29238
29407
  var DEFAULT_OUT_FILE2 = "farm-env.d.ts";
29239
29408
  var CONFIG_FILENAMES2 = [
@@ -29255,21 +29424,21 @@ var CONFIG_FILENAMES2 = [
29255
29424
  "config.cjs"
29256
29425
  ];
29257
29426
  async function generateEnvTypes(options) {
29258
- const root = path19.resolve(options.root);
29427
+ const root = path20.resolve(options.root);
29259
29428
  const srcDir = options.srcDir || "src";
29260
29429
  const outFile = options.outFile || DEFAULT_OUT_FILE2;
29261
- const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
29430
+ const outPath = path20.isAbsolute(outFile) ? outFile : path20.join(root, srcDir, outFile);
29262
29431
  const content = createEnvTypeDeclarations(options, outPath);
29263
- fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
29432
+ fs10.mkdirSync(path20.dirname(outPath), { recursive: true });
29264
29433
  writeFileIfChanged(outPath, content);
29265
29434
  return outPath;
29266
29435
  }
29267
29436
  __name(generateEnvTypes, "generateEnvTypes");
29268
29437
  function createEnvTypeDeclarations(options, outPath) {
29269
- const root = path19.resolve(options.root);
29438
+ const root = path20.resolve(options.root);
29270
29439
  const configPath = findConfigPath(root, options.configPath);
29271
29440
  const configPaths = [
29272
- ...(options.layerConfigPaths ?? []).filter((value) => fs9.existsSync(value)),
29441
+ ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
29273
29442
  ...configPath ? [configPath] : []
29274
29443
  ];
29275
29444
  const content = configPaths.length > 1 ? createLayeredConfigBackedEnvTypes(outPath, configPaths) : configPaths.length === 1 ? createConfigBackedEnvTypes(outPath, configPaths[0]) : createEmptyEnvTypes();
@@ -29331,12 +29500,12 @@ export {};
29331
29500
  __name(createLayeredConfigBackedEnvTypes, "createLayeredConfigBackedEnvTypes");
29332
29501
  function findConfigPath(root, configPath) {
29333
29502
  if (configPath) {
29334
- const resolvedPath = path19.isAbsolute(configPath) ? configPath : path19.join(root, configPath);
29335
- return fs9.existsSync(resolvedPath) ? resolvedPath : null;
29503
+ const resolvedPath = path20.isAbsolute(configPath) ? configPath : path20.join(root, configPath);
29504
+ return fs10.existsSync(resolvedPath) ? resolvedPath : null;
29336
29505
  }
29337
29506
  for (const filename of CONFIG_FILENAMES2) {
29338
- const resolvedPath = path19.join(root, filename);
29339
- if (fs9.existsSync(resolvedPath)) {
29507
+ const resolvedPath = path20.join(root, filename);
29508
+ if (fs10.existsSync(resolvedPath)) {
29340
29509
  return resolvedPath;
29341
29510
  }
29342
29511
  }
@@ -29399,19 +29568,19 @@ export {};
29399
29568
  }
29400
29569
  __name(createEmptyEnvTypes, "createEmptyEnvTypes");
29401
29570
  function toTypeImportPath(outPath, targetPath) {
29402
- const relativePath2 = path19.relative(path19.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
29571
+ const relativePath2 = path20.relative(path20.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
29403
29572
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
29404
29573
  }
29405
29574
  __name(toTypeImportPath, "toTypeImportPath");
29406
29575
 
29407
29576
  // src/image-types.ts
29408
- var import_node_fs6 = require("fs");
29409
- var import_node_path10 = __toESM(require("path"));
29577
+ var import_node_fs7 = require("fs");
29578
+ var import_node_path11 = __toESM(require("path"));
29410
29579
  init_write_file_if_changed();
29411
29580
  var FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
29412
29581
  function generateFarmImageTypes(options) {
29413
- 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");
29414
- (0, import_node_fs6.mkdirSync)(import_node_path10.default.dirname(outputPath), { recursive: true });
29582
+ 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");
29583
+ (0, import_node_fs7.mkdirSync)(import_node_path11.default.dirname(outputPath), { recursive: true });
29415
29584
  writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
29416
29585
  return outputPath;
29417
29586
  }
@@ -29439,8 +29608,8 @@ declare module "*?url" {
29439
29608
  __name(createFarmImageTypeDeclarations, "createFarmImageTypeDeclarations");
29440
29609
 
29441
29610
  // src/content-types.ts
29442
- var fs10 = __toESM(require("fs"));
29443
- var path21 = __toESM(require("path"));
29611
+ var fs11 = __toESM(require("fs"));
29612
+ var path22 = __toESM(require("path"));
29444
29613
  var CONFIG_FILENAMES3 = [
29445
29614
  "farm.config.ts",
29446
29615
  "farm.config.tsx",
@@ -29460,10 +29629,10 @@ var CONFIG_FILENAMES3 = [
29460
29629
  "config.cjs"
29461
29630
  ];
29462
29631
  function createContentTypeDeclarations(options, outPath) {
29463
- const root = path21.resolve(options.root);
29632
+ const root = path22.resolve(options.root);
29464
29633
  const projectConfig = findConfigPath2(root, options.configPath);
29465
29634
  const configPaths = [
29466
- ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
29635
+ ...(options.layerConfigPaths ?? []).filter((value) => fs11.existsSync(value)),
29467
29636
  ...projectConfig ? [projectConfig] : []
29468
29637
  ];
29469
29638
  if (configPaths.length === 0) return createEmptyContentTypes();
@@ -29533,32 +29702,32 @@ export {};
29533
29702
  __name(createEmptyContentTypes, "createEmptyContentTypes");
29534
29703
  function findConfigPath2(root, configPath) {
29535
29704
  if (configPath) {
29536
- const resolvedPath = path21.isAbsolute(configPath) ? configPath : path21.join(root, configPath);
29537
- return fs10.existsSync(resolvedPath) ? resolvedPath : null;
29705
+ const resolvedPath = path22.isAbsolute(configPath) ? configPath : path22.join(root, configPath);
29706
+ return fs11.existsSync(resolvedPath) ? resolvedPath : null;
29538
29707
  }
29539
29708
  for (const filename of CONFIG_FILENAMES3) {
29540
- const resolvedPath = path21.join(root, filename);
29541
- if (fs10.existsSync(resolvedPath)) return resolvedPath;
29709
+ const resolvedPath = path22.join(root, filename);
29710
+ if (fs11.existsSync(resolvedPath)) return resolvedPath;
29542
29711
  }
29543
29712
  return null;
29544
29713
  }
29545
29714
  __name(findConfigPath2, "findConfigPath");
29546
29715
  function toTypeImportPath2(outPath, targetPath) {
29547
- const relativePath2 = path21.relative(path21.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
29716
+ const relativePath2 = path22.relative(path22.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
29548
29717
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
29549
29718
  }
29550
29719
  __name(toTypeImportPath2, "toTypeImportPath");
29551
29720
 
29552
29721
  // src/i18n/type-generator.ts
29553
- var import_node_fs7 = require("fs");
29554
- var import_node_path11 = require("path");
29722
+ var import_node_fs8 = require("fs");
29723
+ var import_node_path12 = require("path");
29555
29724
  init_write_file_if_changed();
29556
29725
  async function generateFarmI18nTypes(options) {
29557
29726
  if (!options.config.enabled) return void 0;
29558
29727
  const { signatures } = await readFarmI18nCatalogs(options.config);
29559
- 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");
29728
+ 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");
29560
29729
  const content = renderFarmI18nTypes(options.config.locales, signatures);
29561
- (0, import_node_fs7.mkdirSync)((0, import_node_path11.dirname)(outFile), { recursive: true });
29730
+ (0, import_node_fs8.mkdirSync)((0, import_node_path12.dirname)(outFile), { recursive: true });
29562
29731
  writeFileIfChanged(outFile, content);
29563
29732
  return outFile;
29564
29733
  }
@@ -29851,8 +30020,8 @@ init_integrations();
29851
30020
  init_route_context();
29852
30021
  init_devtools_config();
29853
30022
  init_dev_indicators();
29854
- var fs12 = __toESM(require("fs"));
29855
- var path33 = __toESM(require("path"));
30023
+ var fs13 = __toESM(require("fs"));
30024
+ var path34 = __toESM(require("path"));
29856
30025
  var import_node_url8 = require("url");
29857
30026
  init_layers();
29858
30027
 
@@ -30359,7 +30528,7 @@ async function _runWithAfterRequest(request, handler, context2) {
30359
30528
  const response = await afterStorage.run(state, handler);
30360
30529
  return hasResponseHook ? response : wrapResponseBody(response, request, state);
30361
30530
  } catch (error) {
30362
- if (!hasResponseHook) finishSoon(state);
30531
+ finishSoon(state);
30363
30532
  throw error;
30364
30533
  }
30365
30534
  }
@@ -30412,8 +30581,8 @@ function _runWithAPIRequestRuntime(runtime, run) {
30412
30581
  __name(_runWithAPIRequestRuntime, "_runWithAPIRequestRuntime");
30413
30582
 
30414
30583
  // src/dev-static.ts
30415
- var fs11 = __toESM(require("fs"));
30416
- var path22 = __toESM(require("path"));
30584
+ var fs12 = __toESM(require("fs"));
30585
+ var path23 = __toESM(require("path"));
30417
30586
  function shouldBypassFarmRouterForDottedPath(pathname, routeManager, baseDirs) {
30418
30587
  if (!pathname.includes(".") || pathname.endsWith(".html")) return false;
30419
30588
  const matchesAppRoute = Boolean(
@@ -30433,11 +30602,11 @@ function devServableFileExists(pathname, baseDirs) {
30433
30602
  if (!relativePathname) return false;
30434
30603
  for (const baseDir of baseDirs) {
30435
30604
  if (typeof baseDir !== "string" || baseDir.length === 0) continue;
30436
- const resolvedBase = path22.resolve(baseDir);
30437
- const candidate = path22.resolve(resolvedBase, relativePathname);
30438
- if (!candidate.startsWith(resolvedBase + path22.sep)) continue;
30605
+ const resolvedBase = path23.resolve(baseDir);
30606
+ const candidate = path23.resolve(resolvedBase, relativePathname);
30607
+ if (!candidate.startsWith(resolvedBase + path23.sep)) continue;
30439
30608
  try {
30440
- if (fs11.existsSync(candidate) && fs11.statSync(candidate).isFile()) {
30609
+ if (fs12.existsSync(candidate) && fs12.statSync(candidate).isFile()) {
30441
30610
  return true;
30442
30611
  }
30443
30612
  } catch {
@@ -30452,6 +30621,7 @@ var SERVER_FN_FACTORIES = ["createServerQuery", "createServerFn"];
30452
30621
  var FARM_CORE_IMPORT_RE = /import\s*(?!type\b)(?:[\w$]+\s*,\s*)?\{([^}]*)\}\s*from\s*(["'])@farm\.js\/core(?:\/[\w./-]+)?\2/g;
30453
30622
  function findClientServerFnViolation(code, id) {
30454
30623
  if (id.startsWith("\0") || id.startsWith("virtual:") || id.includes("node_modules")) return null;
30624
+ if (/\.(md|mdx)(\?|$)/.test(id)) return null;
30455
30625
  if (!code.includes("@farm.js/core")) return null;
30456
30626
  for (const match of code.matchAll(FARM_CORE_IMPORT_RE)) {
30457
30627
  const specifiers = match[1];
@@ -30481,7 +30651,7 @@ init_image_config();
30481
30651
 
30482
30652
  // src/image-vite.ts
30483
30653
  var import_promises7 = require("fs/promises");
30484
- var import_node_path12 = __toESM(require("path"));
30654
+ var import_node_path13 = __toESM(require("path"));
30485
30655
  var import_image_size2 = require("image-size");
30486
30656
  var FARM_IMAGE_ID_PREFIX = "\0farm:image:";
30487
30657
  var STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
@@ -30564,7 +30734,7 @@ init_image_server();
30564
30734
  init_routing();
30565
30735
 
30566
30736
  // src/server/vite-config.ts
30567
- var import_node_path13 = __toESM(require("path"));
30737
+ var import_node_path14 = __toESM(require("path"));
30568
30738
  var FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
30569
30739
  var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
30570
30740
  "react",
@@ -30588,9 +30758,9 @@ function getFarmClientOptimizeDepsInclude(renderer) {
30588
30758
  }
30589
30759
  __name(getFarmClientOptimizeDepsInclude, "getFarmClientOptimizeDepsInclude");
30590
30760
  function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
30591
- const resolvedProjectRoot = import_node_path13.default.resolve(projectRoot);
30761
+ const resolvedProjectRoot = import_node_path14.default.resolve(projectRoot);
30592
30762
  return appDirectories.map((appDirectory) => {
30593
- const relativeAppDirectory = import_node_path13.default.relative(resolvedProjectRoot, import_node_path13.default.resolve(appDirectory)).replace(/\\/g, "/");
30763
+ const relativeAppDirectory = import_node_path14.default.relative(resolvedProjectRoot, import_node_path14.default.resolve(appDirectory)).replace(/\\/g, "/");
30594
30764
  const prefix = relativeAppDirectory || ".";
30595
30765
  return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
30596
30766
  });
@@ -30614,7 +30784,7 @@ function createFarmClientOptimizeDepsConfig(entries, renderer) {
30614
30784
  __name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
30615
30785
  function createFarmSourceAlias(projectRoot, srcDir = "src") {
30616
30786
  return {
30617
- "@": import_node_path13.default.resolve(projectRoot, srcDir)
30787
+ "@": import_node_path14.default.resolve(projectRoot, srcDir)
30618
30788
  };
30619
30789
  }
30620
30790
  __name(createFarmSourceAlias, "createFarmSourceAlias");
@@ -30717,7 +30887,7 @@ init_observability();
30717
30887
  init_renderer();
30718
30888
 
30719
30889
  // src/integration-provider-build.ts
30720
- var import_node_path15 = __toESM(require("path"));
30890
+ var import_node_path16 = __toESM(require("path"));
30721
30891
  init_integrations();
30722
30892
  init_utils();
30723
30893
  function generateFarmIntegrationProviderClientCode(providers, root) {
@@ -30774,7 +30944,7 @@ function wrapWithIntegrationProviders(element) {
30774
30944
  __name(generateFarmIntegrationProviderClientCode, "generateFarmIntegrationProviderClientCode");
30775
30945
  function resolveProviderModule(moduleId, root) {
30776
30946
  if (!moduleId.startsWith(".")) return moduleId;
30777
- return toViteModuleId(import_node_path15.default.resolve(root, moduleId), root);
30947
+ return toViteModuleId(import_node_path16.default.resolve(root, moduleId), root);
30778
30948
  }
30779
30949
  __name(resolveProviderModule, "resolveProviderModule");
30780
30950
 
@@ -30886,6 +31056,7 @@ var createEmptyTypeArtifactSelection = /* @__PURE__ */ __name(() => ({
30886
31056
  i18n: false
30887
31057
  }), "createEmptyTypeArtifactSelection");
30888
31058
  var FARM_I18N_CLIENT_BRIDGE_ID = "\0farm-i18n-client-bridge";
31059
+ var warnedDeprecatedDevtoolsDashboard = false;
30889
31060
  var EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME = `
30890
31061
  function isFarmDocsSearchPage() {
30891
31062
  return false;
@@ -31304,11 +31475,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
31304
31475
  }
31305
31476
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
31306
31477
  function fileContainsProgrammaticPageRoute(file) {
31307
- if (!fs12.existsSync(file)) {
31478
+ if (!fs13.existsSync(file)) {
31308
31479
  return false;
31309
31480
  }
31310
31481
  try {
31311
- return scanProgrammaticPagePaths(fs12.readFileSync(file, "utf8")).length > 0;
31482
+ return scanProgrammaticPagePaths(fs13.readFileSync(file, "utf8")).length > 0;
31312
31483
  } catch {
31313
31484
  return false;
31314
31485
  }
@@ -31316,7 +31487,7 @@ function fileContainsProgrammaticPageRoute(file) {
31316
31487
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
31317
31488
  function rewriteEarlySsrRelativeImports(options) {
31318
31489
  const cleanId = options.id.split("?", 1)[0];
31319
- if (!path33.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31490
+ if (!path34.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31320
31491
  return null;
31321
31492
  }
31322
31493
  const replacements = [];
@@ -31336,7 +31507,7 @@ function rewriteEarlySsrRelativeImports(options) {
31336
31507
  const suffixIndex = source.value.search(/[?#]/);
31337
31508
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
31338
31509
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
31339
- const resolvedPath = path33.resolve(path33.dirname(cleanId), sourcePath);
31510
+ const resolvedPath = path34.resolve(path34.dirname(cleanId), sourcePath);
31340
31511
  replacements.push({
31341
31512
  start: source.start,
31342
31513
  end: source.end,
@@ -31498,7 +31669,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31498
31669
  ...layerRoots.length ? {
31499
31670
  server: {
31500
31671
  fs: {
31501
- allow: [path33.resolve(options.root || process.cwd()), ...layerRoots]
31672
+ allow: [path34.resolve(options.root || process.cwd()), ...layerRoots]
31502
31673
  }
31503
31674
  }
31504
31675
  } : {}
@@ -31529,13 +31700,13 @@ function farmPlugin(options = {}, initialPluginManager) {
31529
31700
  },
31530
31701
  server
31531
31702
  );
31532
- const globalsCSSPath = path33.join(server.config.root, "src/app/globals.css");
31533
- if (!fs12.existsSync(globalsCSSPath)) {
31534
- const appDir = path33.join(server.config.root, "src/app");
31535
- if (!fs12.existsSync(appDir)) {
31536
- fs12.mkdirSync(appDir, { recursive: true });
31703
+ const globalsCSSPath = path34.join(server.config.root, "src/app/globals.css");
31704
+ if (!fs13.existsSync(globalsCSSPath)) {
31705
+ const appDir = path34.join(server.config.root, "src/app");
31706
+ if (!fs13.existsSync(appDir)) {
31707
+ fs13.mkdirSync(appDir, { recursive: true });
31537
31708
  }
31538
- fs12.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31709
+ fs13.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31539
31710
  }
31540
31711
  await farmApp.initialize();
31541
31712
  const farmConfig = farmApp.getConfig();
@@ -31556,10 +31727,10 @@ function farmPlugin(options = {}, initialPluginManager) {
31556
31727
  });
31557
31728
  }
31558
31729
  const sourceRoots = getFarmSourceRoots(farmConfig);
31559
- server.watcher.add(sourceRoots.map((source) => path33.join(source.root, source.srcDir)));
31730
+ server.watcher.add(sourceRoots.map((source) => path34.join(source.root, source.srcDir)));
31560
31731
  if (farmConfig.i18n.enabled) {
31561
31732
  server.watcher.add(
31562
- farmConfig.i18n.messages.includes("{locale}") ? path33.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
31733
+ farmConfig.i18n.messages.includes("{locale}") ? path34.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
31563
31734
  );
31564
31735
  }
31565
31736
  const workflowConfig = farmConfig.workflows;
@@ -31569,7 +31740,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31569
31740
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
31570
31741
  ], "getExtraRouteTypes");
31571
31742
  const appDirSlugs = sourceRoots.map(
31572
- (source) => path33.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31743
+ (source) => path34.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31573
31744
  );
31574
31745
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
31575
31746
  try {
@@ -31610,7 +31781,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31610
31781
  }, "generateTypeArtifacts");
31611
31782
  await generateTypeArtifacts("startup");
31612
31783
  const srcDirSlugs = sourceRoots.map(
31613
- (source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")
31784
+ (source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")
31614
31785
  );
31615
31786
  const layerConfigFiles = new Set(
31616
31787
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -31731,7 +31902,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31731
31902
  await apiRouteManager.discoverRoutes();
31732
31903
  let discoveredWorkflows = [];
31733
31904
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
31734
- (dir) => fs12.existsSync(path33.isAbsolute(dir) ? dir : path33.join(farmConfig.root, dir))
31905
+ (dir) => fs13.existsSync(path34.isAbsolute(dir) ? dir : path34.join(farmConfig.root, dir))
31735
31906
  );
31736
31907
  if (hasWorkflowDirectory) {
31737
31908
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -31996,12 +32167,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
31996
32167
  }
31997
32168
  }
31998
32169
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
31999
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs12.existsSync(farmDocsFontPath)) {
32170
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs13.existsSync(farmDocsFontPath)) {
32000
32171
  res.statusCode = 200;
32001
32172
  res.setHeader("Content-Type", "font/woff2");
32002
32173
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
32003
32174
  if (requestMethod === "HEAD") res.end();
32004
- else fs12.createReadStream(farmDocsFontPath).pipe(res);
32175
+ else fs13.createReadStream(farmDocsFontPath).pipe(res);
32005
32176
  return;
32006
32177
  }
32007
32178
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -32057,6 +32228,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
32057
32228
  if (requestPathname.endsWith(".json")) {
32058
32229
  res.end(JSON.stringify(snapshot, null, 2));
32059
32230
  } else {
32231
+ if (!warnedDeprecatedDevtoolsDashboard) {
32232
+ warnedDeprecatedDevtoolsDashboard = true;
32233
+ logger.warn(
32234
+ "The built-in DevTools dashboard is deprecated. Install @farm.js/devtools and add devtools() to plugins in farm.config.ts."
32235
+ );
32236
+ }
32060
32237
  const { renderFarmDevtoolsHtml: renderFarmDevtoolsHtml2 } = await loadFarmDevtoolsUIRuntime();
32061
32238
  res.end(renderFarmDevtoolsHtml2(snapshot));
32062
32239
  }
@@ -32099,7 +32276,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
32099
32276
  return null;
32100
32277
  }
32101
32278
  return {
32102
- source: await fs12.promises.readFile(sourcePath, "utf8"),
32279
+ source: await fs13.promises.readFile(sourcePath, "utf8"),
32103
32280
  filePath: sourcePath
32104
32281
  };
32105
32282
  }, "resolveSource")
@@ -32983,7 +33160,10 @@ ${generatedDevIndicatorsClientRuntime}`,
32983
33160
  renderer,
32984
33161
  isolatedHydrationMode === "enabled",
32985
33162
  resolvedConfig?.trailingSlash ?? false,
32986
- resolvedConfig?.basePath ?? "/"
33163
+ resolvedConfig?.basePath ?? "/",
33164
+ generateClientCachePersistenceCode(
33165
+ resolveFarmClientCacheAdapterEntry(root, resolvedConfig?.cache)
33166
+ )
32987
33167
  );
32988
33168
  }
32989
33169
  if (id === "/@farm/server") {
@@ -33122,7 +33302,7 @@ export const manifest = getManifest();
33122
33302
  const root = currentConfig.root || server?.config.root || process.cwd();
33123
33303
  const cleanId = id.split("?", 1)[0];
33124
33304
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
33125
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path33.resolve(cleanId)) === true;
33305
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path34.resolve(cleanId)) === true;
33126
33306
  if (isolatedHydrationEnabled && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
33127
33307
  isolatedModuleReference = toViteModuleId(cleanId, root);
33128
33308
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -33213,8 +33393,8 @@ if (import.meta.hot) {
33213
33393
  }
33214
33394
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
33215
33395
  logger.info("Pre-rendering SSG pages...");
33216
- const outDir = path33.join(server?.config.root || process.cwd(), options.outDir || "dist");
33217
- const clientDir = path33.join(outDir, "client");
33396
+ const outDir = path34.join(server?.config.root || process.cwd(), options.outDir || "dist");
33397
+ const clientDir = path34.join(outDir, "client");
33218
33398
  for (const page2 of ssgPages) {
33219
33399
  try {
33220
33400
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -33266,9 +33446,9 @@ if (import.meta.hot) {
33266
33446
  <script type="module" src="/assets/client.js"></script>
33267
33447
  </body>
33268
33448
  </html>`;
33269
- const outputPath = page2.urlPath === "/" ? path33.join(clientDir, "index.html") : path33.join(clientDir, page2.urlPath + ".html");
33270
- fs12.mkdirSync(path33.dirname(outputPath), { recursive: true });
33271
- fs12.writeFileSync(outputPath, fullHtml);
33449
+ const outputPath = page2.urlPath === "/" ? path34.join(clientDir, "index.html") : path34.join(clientDir, page2.urlPath + ".html");
33450
+ fs13.mkdirSync(path34.dirname(outputPath), { recursive: true });
33451
+ fs13.writeFileSync(outputPath, fullHtml);
33272
33452
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
33273
33453
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
33274
33454
  });
@@ -33276,8 +33456,8 @@ if (import.meta.hot) {
33276
33456
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
33277
33457
  }
33278
33458
  }
33279
- const manifestPath = path33.join(outDir, "__ssg_manifest.json");
33280
- fs12.writeFileSync(
33459
+ const manifestPath = path34.join(outDir, "__ssg_manifest.json");
33460
+ fs13.writeFileSync(
33281
33461
  manifestPath,
33282
33462
  JSON.stringify(
33283
33463
  ssgPages.map((p) => ({
@@ -33320,9 +33500,9 @@ if (import.meta.hot) {
33320
33500
  server2.ws.send({ type: "full-reload", path: "*" });
33321
33501
  return [];
33322
33502
  }
33323
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
33503
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
33324
33504
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
33325
- logUpdate("PAGE", `updated ${path33.basename(file)}`);
33505
+ logUpdate("PAGE", `updated ${path34.basename(file)}`);
33326
33506
  for (const mod of modules) {
33327
33507
  server2.moduleGraph.invalidateModule(mod);
33328
33508
  }
@@ -33745,7 +33925,7 @@ function parseRouteModuleSchema2(schema, value, label, routePath) {
33745
33925
  }
33746
33926
  }
33747
33927
  __name(parseRouteModuleSchema2, "parseRouteModuleSchema");
33748
- 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 = "/") {
33928
+ 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: "" }) {
33749
33929
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
33750
33930
  const clientPluginEntry = generateFarmClientPluginEntryCode(
33751
33931
  plugins,
@@ -33801,6 +33981,7 @@ import {
33801
33981
  } from '@farm.js/core/deployment'
33802
33982
  ${providerClientCode.imports}
33803
33983
  ${clientPluginEntry.imports}
33984
+ ${clientCachePersistence.imports}
33804
33985
  ${docsSearchClientRuntime}
33805
33986
  ${devtoolsClientRuntime}
33806
33987
  ${docsAdapterImportBlock}
@@ -33816,6 +33997,7 @@ const integrationDocumentNavigationMatchers = ${JSON.stringify(documentNavigatio
33816
33997
  setFarmBasePath(${JSON.stringify(basePath)});
33817
33998
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
33818
33999
  installChunkErrorRecovery();
34000
+ ${clientCachePersistence.init}
33819
34001
 
33820
34002
  let reactRoot = null;
33821
34003
  ${isolatedHydrationRuntime}
@@ -35199,7 +35381,7 @@ function generateClientManifest(bundle) {
35199
35381
  __name(generateClientManifest, "generateClientManifest");
35200
35382
  async function defineConfig2(config = {}) {
35201
35383
  const tailwindcss = (await import("@tailwindcss/vite")).default;
35202
- const appRoot = path33.resolve(config.root || process.cwd());
35384
+ const appRoot = path34.resolve(config.root || process.cwd());
35203
35385
  if (config.extends?.length) {
35204
35386
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
35205
35387
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
@@ -35747,7 +35929,8 @@ function createServerQuery(options) {
35747
35929
  return createFarmServerQueryResult(data, {
35748
35930
  key: clientKey,
35749
35931
  staleTime,
35750
- updatedAt
35932
+ updatedAt,
35933
+ ...options.persist === true ? { persist: true } : {}
35751
35934
  });
35752
35935
  }, "handler")
35753
35936
  });
@@ -36135,8 +36318,8 @@ init_layers();
36135
36318
 
36136
36319
  // src/instrumentation.ts
36137
36320
  var import_esbuild = require("esbuild");
36138
- var import_node_fs12 = __toESM(require("fs"));
36139
- var import_node_path21 = __toESM(require("path"));
36321
+ var import_node_fs13 = __toESM(require("fs"));
36322
+ var import_node_path22 = __toESM(require("path"));
36140
36323
  var import_node_url9 = require("url");
36141
36324
 
36142
36325
  // src/instrumentation-runtime.ts
@@ -36184,16 +36367,16 @@ var INSTRUMENTATION_EXTENSIONS = ["ts", "mts", "js", "mjs"];
36184
36367
  function resolveFarmInstrumentationFile(root, srcDir = "src") {
36185
36368
  const candidates = [
36186
36369
  ...INSTRUMENTATION_EXTENSIONS.map(
36187
- (extension) => import_node_path21.default.join(root, srcDir, `instrumentation.${extension}`)
36370
+ (extension) => import_node_path22.default.join(root, srcDir, `instrumentation.${extension}`)
36188
36371
  ),
36189
36372
  ...INSTRUMENTATION_EXTENSIONS.map(
36190
- (extension) => import_node_path21.default.join(root, `instrumentation.${extension}`)
36373
+ (extension) => import_node_path22.default.join(root, `instrumentation.${extension}`)
36191
36374
  )
36192
- ].filter((candidate) => import_node_fs12.default.existsSync(candidate));
36375
+ ].filter((candidate) => import_node_fs13.default.existsSync(candidate));
36193
36376
  if (candidates.length > 1) {
36194
36377
  throw new Error(
36195
36378
  `Farm.js found multiple instrumentation files:
36196
- ${candidates.map((candidate) => `- ${import_node_path21.default.relative(root, candidate)}`).join("\n")}
36379
+ ${candidates.map((candidate) => `- ${import_node_path22.default.relative(root, candidate)}`).join("\n")}
36197
36380
  Keep only one instrumentation file in the project root or ${srcDir}/.`
36198
36381
  );
36199
36382
  }
@@ -36202,9 +36385,9 @@ Keep only one instrumentation file in the project root or ${srcDir}/.`
36202
36385
  __name(resolveFarmInstrumentationFile, "resolveFarmInstrumentationFile");
36203
36386
  async function loadFarmInstrumentation(filePath, root) {
36204
36387
  if (!filePath) return null;
36205
- const outputDirectory = import_node_path21.default.join(root, ".farm", ".instrumentation-loader");
36206
- const outputFile = import_node_path21.default.join(outputDirectory, "instrumentation.mjs");
36207
- await import_node_fs12.default.promises.mkdir(outputDirectory, { recursive: true });
36388
+ const outputDirectory = import_node_path22.default.join(root, ".farm", ".instrumentation-loader");
36389
+ const outputFile = import_node_path22.default.join(outputDirectory, "instrumentation.mjs");
36390
+ await import_node_fs13.default.promises.mkdir(outputDirectory, { recursive: true });
36208
36391
  await (0, import_esbuild.build)({
36209
36392
  entryPoints: [filePath],
36210
36393
  outfile: outputFile,