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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/dist/after.cjs +1 -1
  2. package/dist/after.mjs +1 -1
  3. package/dist/agent-runtime.d.mts +3 -2
  4. package/dist/agent-runtime.d.ts +3 -2
  5. package/dist/api/route-manager.cjs +43 -4
  6. package/dist/api/route-manager.d.mts +4 -3
  7. package/dist/api/route-manager.d.ts +4 -3
  8. package/dist/api/route-manager.mjs +6 -6
  9. package/dist/api/runtime.cjs +43 -4
  10. package/dist/api/runtime.d.mts +1 -1
  11. package/dist/api/runtime.d.ts +1 -1
  12. package/dist/api/runtime.mjs +4 -4
  13. package/dist/api.cjs +239 -70
  14. package/dist/api.d.mts +7 -6
  15. package/dist/api.d.ts +7 -6
  16. package/dist/api.mjs +17 -11
  17. package/dist/{app-CIIEvA4r.d.ts → app-CIOx3LvY.d.ts} +4 -4
  18. package/dist/{app-O4AEC1OH.d.mts → app-DBd6437H.d.mts} +4 -4
  19. package/dist/app-markdown.d.mts +4 -3
  20. package/dist/app-markdown.d.ts +4 -3
  21. package/dist/cache.cjs +42 -4
  22. package/dist/cache.d.mts +68 -1
  23. package/dist/cache.d.ts +68 -1
  24. package/dist/cache.mjs +3 -3
  25. package/dist/{chunk-AXVJCMVF.mjs → chunk-2HDOV47R.mjs} +3 -3
  26. package/dist/chunk-2HDOV47R.mjs.map +1 -0
  27. package/dist/{chunk-RBRLLZL5.mjs → chunk-34IAPZBG.mjs} +16 -3
  28. package/dist/chunk-34IAPZBG.mjs.map +1 -0
  29. package/dist/{chunk-VV24CC42.mjs → chunk-35NPLKQJ.mjs} +2 -2
  30. package/dist/{chunk-MM46HTX6.mjs → chunk-3TWQERDE.mjs} +4 -3
  31. package/dist/chunk-3TWQERDE.mjs.map +1 -0
  32. package/dist/{chunk-RWYRFCLG.mjs → chunk-4X57GXQA.mjs} +2 -2
  33. package/dist/{chunk-3I55IGXU.mjs → chunk-52BR7LTX.mjs} +14 -15
  34. package/dist/chunk-52BR7LTX.mjs.map +1 -0
  35. package/dist/{chunk-RAGSHKDC.mjs → chunk-6EJHNHH4.mjs} +38 -3
  36. package/dist/chunk-6EJHNHH4.mjs.map +1 -0
  37. package/dist/{chunk-ZFNK77WN.mjs → chunk-6JNGOC37.mjs} +2 -2
  38. package/dist/{after.cjs.map → chunk-6JNGOC37.mjs.map} +1 -1
  39. package/dist/{chunk-MOW47IF5.mjs → chunk-6UYVU46O.mjs} +2 -2
  40. package/dist/{chunk-7MABZJIM.mjs → chunk-7PYVLJ4J.mjs} +1 -1
  41. package/dist/chunk-7PYVLJ4J.mjs.map +1 -0
  42. package/dist/{chunk-54XSGLKT.mjs → chunk-D7F7YZ7L.mjs} +93 -67
  43. package/dist/chunk-D7F7YZ7L.mjs.map +1 -0
  44. package/dist/{chunk-SCFX4UTD.mjs → chunk-EHTUKVSW.mjs} +1 -1
  45. package/dist/chunk-EHTUKVSW.mjs.map +1 -0
  46. package/dist/{chunk-LZTGDH3H.mjs → chunk-EPDIF432.mjs} +424 -10
  47. package/dist/chunk-EPDIF432.mjs.map +1 -0
  48. package/dist/{chunk-GZHKWHCH.mjs → chunk-FP5Q67FO.mjs} +167 -96
  49. package/dist/chunk-FP5Q67FO.mjs.map +1 -0
  50. package/dist/{chunk-HHZAOTQD.mjs → chunk-GJ7W6LNK.mjs} +7 -6
  51. package/dist/chunk-GJ7W6LNK.mjs.map +1 -0
  52. package/dist/{chunk-RLGUZ3HS.mjs → chunk-I3OOUWO5.mjs} +3 -3
  53. package/dist/{chunk-LKKMI7JG.mjs → chunk-IZBX2TEU.mjs} +153 -68
  54. package/dist/chunk-IZBX2TEU.mjs.map +1 -0
  55. package/dist/{chunk-74QPONAN.mjs → chunk-J3MPQ4MQ.mjs} +2 -2
  56. package/dist/{chunk-74QPONAN.mjs.map → chunk-J3MPQ4MQ.mjs.map} +1 -1
  57. package/dist/{chunk-ODJGAWDH.mjs → chunk-JV7JUD7Q.mjs} +4 -4
  58. package/dist/{chunk-Q3OX763A.mjs → chunk-LXDASSTE.mjs} +2 -2
  59. package/dist/{chunk-ZRBCBOEX.mjs → chunk-N2FY2QZ7.mjs} +28 -3
  60. package/dist/chunk-N2FY2QZ7.mjs.map +1 -0
  61. package/dist/{chunk-MRVJCLYQ.mjs → chunk-PSQ7N4XP.mjs} +4 -2
  62. package/dist/chunk-PSQ7N4XP.mjs.map +1 -0
  63. package/dist/{chunk-HVG3HLQZ.mjs → chunk-Q7WGOOAI.mjs} +3 -3
  64. package/dist/{chunk-WTYAPO5I.mjs → chunk-RCNWMEBT.mjs} +3 -2
  65. package/dist/{chunk-WTYAPO5I.mjs.map → chunk-RCNWMEBT.mjs.map} +1 -1
  66. package/dist/{chunk-3INDBMUU.mjs → chunk-TGDIACZT.mjs} +2 -2
  67. package/dist/{chunk-WB75GIX2.mjs → chunk-TQTB33JS.mjs} +14 -3
  68. package/dist/chunk-TQTB33JS.mjs.map +1 -0
  69. package/dist/{chunk-WMAYETRD.mjs → chunk-TT3E2JOF.mjs} +3 -3
  70. package/dist/{chunk-FVAM43KI.mjs → chunk-UMUWR5XA.mjs} +2 -2
  71. package/dist/{chunk-VOUJW4FL.mjs → chunk-WD2EBM3I.mjs} +70 -15
  72. package/dist/chunk-WD2EBM3I.mjs.map +1 -0
  73. package/dist/{chunk-ZPG6SNHH.mjs → chunk-WMJGA32P.mjs} +47 -5
  74. package/dist/chunk-WMJGA32P.mjs.map +1 -0
  75. package/dist/{chunk-TKQCJMY7.mjs → chunk-X4SFHKFH.mjs} +7 -4
  76. package/dist/{chunk-TKQCJMY7.mjs.map → chunk-X4SFHKFH.mjs.map} +1 -1
  77. package/dist/{chunk-Q7GPJZCO.mjs → chunk-YIBV77KZ.mjs} +26 -7
  78. package/dist/chunk-YIBV77KZ.mjs.map +1 -0
  79. package/dist/client/lifecycle.mjs +2 -2
  80. package/dist/{client-mcMC334J.d.mts → client-DWoLZ3QU.d.mts} +52 -5
  81. package/dist/{client-d5ONQ-Pd.d.ts → client-DuQuQC1h.d.ts} +52 -5
  82. package/dist/client-cache-BMxuFqwH.d.ts +18 -0
  83. package/dist/client-cache-CCK-fCe0.d.mts +18 -0
  84. package/dist/{client-plugins-BvClItiL.d.mts → client-plugins-B6-07YmP.d.mts} +52 -99
  85. package/dist/{client-plugins-B9Sq-iMg.d.ts → client-plugins-By6MVUX-.d.ts} +52 -99
  86. package/dist/client-plugins.cjs +1 -1
  87. package/dist/client-plugins.d.mts +3 -2
  88. package/dist/client-plugins.d.ts +3 -2
  89. package/dist/client-plugins.mjs +2 -2
  90. package/dist/client.cjs +757 -104
  91. package/dist/client.d.mts +124 -16
  92. package/dist/client.d.ts +124 -16
  93. package/dist/client.mjs +28 -14
  94. package/dist/config.d.mts +3 -2
  95. package/dist/config.d.ts +3 -2
  96. package/dist/{devtools-S52RRRMN.mjs → devtools-XWZX6CCL.mjs} +5 -5
  97. package/dist/{devtools-client-EOVDBPOI.mjs → devtools-client-Z7QQA3Q2.mjs} +2 -2
  98. package/dist/{devtools-ui-NJKFORTG.mjs → devtools-ui-2HG5M4EL.mjs} +3 -1
  99. package/dist/devtools-ui-2HG5M4EL.mjs.map +1 -0
  100. package/dist/docs.cjs +24 -5
  101. package/dist/docs.mjs +5 -5
  102. package/dist/i18n/server.cjs +13 -2
  103. package/dist/i18n/server.d.mts +2 -2
  104. package/dist/i18n/server.d.ts +2 -2
  105. package/dist/i18n/server.mjs +1 -1
  106. package/dist/index.cjs +1578 -772
  107. package/dist/index.d.mts +28 -20
  108. package/dist/index.d.ts +28 -20
  109. package/dist/index.mjs +53 -33
  110. package/dist/index.mjs.map +1 -1
  111. package/dist/integration-api-BT024nuJ.d.mts +97 -0
  112. package/dist/integration-api-BT024nuJ.d.ts +97 -0
  113. package/dist/integrations.d.mts +3 -2
  114. package/dist/integrations.d.ts +3 -2
  115. package/dist/internal/build-runtime.cjs +710 -532
  116. package/dist/internal/build-runtime.d.mts +5 -4
  117. package/dist/internal/build-runtime.d.ts +5 -4
  118. package/dist/internal/build-runtime.mjs +15 -15
  119. package/dist/internal/client-runtime.cjs +1 -1
  120. package/dist/internal/client-runtime.mjs +2 -2
  121. package/dist/internal/config-runtime.cjs +4 -1
  122. package/dist/internal/config-runtime.d.mts +4 -3
  123. package/dist/internal/config-runtime.d.ts +4 -3
  124. package/dist/internal/config-runtime.mjs +4 -4
  125. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  126. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  127. package/dist/internal/production-runtime.cjs +29 -3
  128. package/dist/internal/production-runtime.d.mts +8 -7
  129. package/dist/internal/production-runtime.d.ts +8 -7
  130. package/dist/internal/production-runtime.mjs +5 -5
  131. package/dist/{metadata-route-yV4U6X8h.d.ts → metadata-route-8_V3UonT.d.ts} +1 -1
  132. package/dist/{metadata-route-p4K1l92V.d.mts → metadata-route-CWP_HjGU.d.mts} +1 -1
  133. package/dist/middleware.cjs +28 -2
  134. package/dist/middleware.d.mts +5 -4
  135. package/dist/middleware.d.ts +5 -4
  136. package/dist/middleware.mjs +4 -4
  137. package/dist/navigation.cjs +3 -1
  138. package/dist/navigation.mjs +3 -3
  139. package/dist/observability.cjs +27 -2
  140. package/dist/observability.mjs +1 -1
  141. package/dist/plugin.cjs +474 -334
  142. package/dist/plugin.d.mts +3 -2
  143. package/dist/plugin.d.ts +3 -2
  144. package/dist/plugin.mjs +12 -12
  145. package/dist/{production-runtime-IkB0Qj4i.d.mts → production-runtime-BGRH1dKG.d.mts} +1 -1
  146. package/dist/{production-runtime-0JTch4_d.d.ts → production-runtime-CdmzsDax.d.ts} +1 -1
  147. package/dist/query/client.cjs +11 -3
  148. package/dist/query/client.mjs +12 -4
  149. package/dist/query/client.mjs.map +1 -1
  150. package/dist/{render-plan-Dc8CjNI7.d.ts → render-plan-0GeHiGVZ.d.ts} +1 -1
  151. package/dist/{render-plan-CU31j-Jk.d.mts → render-plan-DLxJYAA5.d.mts} +1 -1
  152. package/dist/renderer-client.cjs +140 -26
  153. package/dist/renderer-client.d.mts +7 -6
  154. package/dist/renderer-client.d.ts +7 -6
  155. package/dist/renderer-client.mjs +16 -19
  156. package/dist/renderer-client.mjs.map +1 -1
  157. package/dist/{request-BXa1KY8i.d.mts → request-BCNXSXLh.d.mts} +1 -1
  158. package/dist/{request-CUUBujZt.d.ts → request-BstWbZ6O.d.ts} +1 -1
  159. package/dist/request.d.mts +4 -3
  160. package/dist/request.d.ts +4 -3
  161. package/dist/{route-Y8lfz1wF.d.ts → route-4pd-EVtw.d.ts} +45 -50
  162. package/dist/{route-Cq3aObmj.d.mts → route-CvEr4Uc9.d.mts} +45 -50
  163. package/dist/routes.cjs +27 -2
  164. package/dist/routes.d.mts +3 -2
  165. package/dist/routes.d.ts +3 -2
  166. package/dist/routes.mjs +4 -4
  167. package/dist/{runtime-j1S3sDTh.d.ts → runtime-BgDQzBiu.d.ts} +1 -0
  168. package/dist/{runtime-DDwvDtS4.d.mts → runtime-CV2UCV-5.d.mts} +1 -0
  169. package/dist/server-action-security.mjs +2 -2
  170. package/dist/server-fn-client.cjs +34 -2
  171. package/dist/server-fn-client.d.mts +6 -0
  172. package/dist/server-fn-client.d.ts +6 -0
  173. package/dist/server-fn-client.mjs +1 -1
  174. package/dist/server-fn.cjs +42 -4
  175. package/dist/server-fn.mjs +5 -5
  176. package/dist/server-plugins.d.mts +4 -3
  177. package/dist/server-plugins.d.ts +4 -3
  178. package/dist/server-query-client.cjs +146 -27
  179. package/dist/server-query-client.d.mts +3 -3
  180. package/dist/server-query-client.d.ts +3 -3
  181. package/dist/server-query-client.mjs +7 -7
  182. package/dist/{server-query-runtime-3zAj77yv.d.ts → server-query-runtime-DXRNhX_3.d.ts} +2 -0
  183. package/dist/{server-query-runtime-B50KAcj5.d.mts → server-query-runtime-aP52iuL5.d.mts} +2 -0
  184. package/dist/server-query.cjs +44 -5
  185. package/dist/server-query.d.mts +4 -0
  186. package/dist/server-query.d.ts +4 -0
  187. package/dist/server-query.mjs +7 -7
  188. package/dist/server.cjs +499 -355
  189. package/dist/server.d.mts +11 -10
  190. package/dist/server.d.ts +11 -10
  191. package/dist/server.mjs +16 -16
  192. package/dist/{spa-router-CyLkwst6.d.mts → spa-router-BeyAVSc6.d.mts} +1 -1
  193. package/dist/{spa-router-BkqGXaV_.d.ts → spa-router-COgu4txb.d.ts} +1 -1
  194. package/dist/testing.cjs +27 -2
  195. package/dist/testing.d.mts +3 -2
  196. package/dist/testing.d.ts +3 -2
  197. package/dist/testing.mjs +8 -8
  198. package/dist/{utils-NKR6SoNv.d.mts → utils-DL2VwDQl.d.mts} +1 -1
  199. package/dist/{utils-B2OHrb9F.d.ts → utils-DkU2c_1B.d.ts} +1 -1
  200. package/dist/version.cjs +1 -1
  201. package/dist/version.mjs +1 -1
  202. package/dist/vite.cjs +482 -338
  203. package/dist/vite.d.mts +3 -2
  204. package/dist/vite.d.ts +3 -2
  205. package/dist/vite.mjs +16 -12
  206. package/package.json +17 -17
  207. package/types/client.d.ts +87 -1
  208. package/dist/agent-runtime.cjs.map +0 -1
  209. package/dist/api/route-manager.cjs.map +0 -1
  210. package/dist/api/runtime.cjs.map +0 -1
  211. package/dist/api.cjs.map +0 -1
  212. package/dist/app-markdown.cjs.map +0 -1
  213. package/dist/cache.cjs.map +0 -1
  214. package/dist/chunk-3I55IGXU.mjs.map +0 -1
  215. package/dist/chunk-54XSGLKT.mjs.map +0 -1
  216. package/dist/chunk-7MABZJIM.mjs.map +0 -1
  217. package/dist/chunk-AXVJCMVF.mjs.map +0 -1
  218. package/dist/chunk-GZHKWHCH.mjs.map +0 -1
  219. package/dist/chunk-HHZAOTQD.mjs.map +0 -1
  220. package/dist/chunk-LKKMI7JG.mjs.map +0 -1
  221. package/dist/chunk-LZTGDH3H.mjs.map +0 -1
  222. package/dist/chunk-MM46HTX6.mjs.map +0 -1
  223. package/dist/chunk-MRVJCLYQ.mjs.map +0 -1
  224. package/dist/chunk-Q7GPJZCO.mjs.map +0 -1
  225. package/dist/chunk-RAGSHKDC.mjs.map +0 -1
  226. package/dist/chunk-RBRLLZL5.mjs.map +0 -1
  227. package/dist/chunk-SCFX4UTD.mjs.map +0 -1
  228. package/dist/chunk-VOUJW4FL.mjs.map +0 -1
  229. package/dist/chunk-WB75GIX2.mjs.map +0 -1
  230. package/dist/chunk-ZFNK77WN.mjs.map +0 -1
  231. package/dist/chunk-ZPG6SNHH.mjs.map +0 -1
  232. package/dist/chunk-ZRBCBOEX.mjs.map +0 -1
  233. package/dist/client/lifecycle.cjs.map +0 -1
  234. package/dist/client-cache-CopR_MaI.d.mts +0 -6
  235. package/dist/client-cache-Djy_TlE8.d.ts +0 -6
  236. package/dist/client-plugins.cjs.map +0 -1
  237. package/dist/client.cjs.map +0 -1
  238. package/dist/config.cjs.map +0 -1
  239. package/dist/cron.cjs.map +0 -1
  240. package/dist/deferred.cjs.map +0 -1
  241. package/dist/deployment.cjs.map +0 -1
  242. package/dist/devtools-ui-NJKFORTG.mjs.map +0 -1
  243. package/dist/docs.cjs.map +0 -1
  244. package/dist/env-types.cjs.map +0 -1
  245. package/dist/env.cjs.map +0 -1
  246. package/dist/environment/vite.cjs.map +0 -1
  247. package/dist/environment.cjs.map +0 -1
  248. package/dist/font.cjs.map +0 -1
  249. package/dist/headers.cjs.map +0 -1
  250. package/dist/i18n/client.cjs.map +0 -1
  251. package/dist/i18n/index.cjs.map +0 -1
  252. package/dist/i18n/server.cjs.map +0 -1
  253. package/dist/image/server.cjs.map +0 -1
  254. package/dist/image/sharp.cjs.map +0 -1
  255. package/dist/image.cjs.map +0 -1
  256. package/dist/index.cjs.map +0 -1
  257. package/dist/instrumentation.cjs.map +0 -1
  258. package/dist/integrations.cjs.map +0 -1
  259. package/dist/internal/build-runtime.cjs.map +0 -1
  260. package/dist/internal/client-runtime.cjs.map +0 -1
  261. package/dist/internal/config-runtime.cjs.map +0 -1
  262. package/dist/internal/isolated-boundary.cjs.map +0 -1
  263. package/dist/internal/metadata-image-runtime.cjs.map +0 -1
  264. package/dist/internal/product-telemetry-runtime.cjs.map +0 -1
  265. package/dist/internal/production-node-env.cjs.map +0 -1
  266. package/dist/internal/production-runtime.cjs.map +0 -1
  267. package/dist/markdown.cjs.map +0 -1
  268. package/dist/middleware.cjs.map +0 -1
  269. package/dist/navigation.cjs.map +0 -1
  270. package/dist/observability.cjs.map +0 -1
  271. package/dist/plugin.cjs.map +0 -1
  272. package/dist/query/client.cjs.map +0 -1
  273. package/dist/query/index.cjs.map +0 -1
  274. package/dist/query/parsers.cjs.map +0 -1
  275. package/dist/query/server.cjs.map +0 -1
  276. package/dist/renderer/react/client.cjs.map +0 -1
  277. package/dist/renderer/react/server.cjs.map +0 -1
  278. package/dist/renderer/react/vite.cjs.map +0 -1
  279. package/dist/renderer-client.cjs.map +0 -1
  280. package/dist/renderer.cjs.map +0 -1
  281. package/dist/request.cjs.map +0 -1
  282. package/dist/router.cjs.map +0 -1
  283. package/dist/routes.cjs.map +0 -1
  284. package/dist/server-action-security.cjs.map +0 -1
  285. package/dist/server-fn-client.cjs.map +0 -1
  286. package/dist/server-fn.cjs.map +0 -1
  287. package/dist/server-plugins.cjs.map +0 -1
  288. package/dist/server-query-client.cjs.map +0 -1
  289. package/dist/server-query.cjs.map +0 -1
  290. package/dist/server.cjs.map +0 -1
  291. package/dist/storage.cjs.map +0 -1
  292. package/dist/testing.cjs.map +0 -1
  293. package/dist/theme/client.cjs.map +0 -1
  294. package/dist/theme/index.cjs.map +0 -1
  295. package/dist/theme/runtime.cjs.map +0 -1
  296. package/dist/theme/server.cjs.map +0 -1
  297. package/dist/version.cjs.map +0 -1
  298. package/dist/vite.cjs.map +0 -1
  299. package/dist/workflows.cjs.map +0 -1
  300. /package/dist/{chunk-VV24CC42.mjs.map → chunk-35NPLKQJ.mjs.map} +0 -0
  301. /package/dist/{chunk-RWYRFCLG.mjs.map → chunk-4X57GXQA.mjs.map} +0 -0
  302. /package/dist/{chunk-MOW47IF5.mjs.map → chunk-6UYVU46O.mjs.map} +0 -0
  303. /package/dist/{chunk-RLGUZ3HS.mjs.map → chunk-I3OOUWO5.mjs.map} +0 -0
  304. /package/dist/{chunk-ODJGAWDH.mjs.map → chunk-JV7JUD7Q.mjs.map} +0 -0
  305. /package/dist/{chunk-Q3OX763A.mjs.map → chunk-LXDASSTE.mjs.map} +0 -0
  306. /package/dist/{chunk-HVG3HLQZ.mjs.map → chunk-Q7WGOOAI.mjs.map} +0 -0
  307. /package/dist/{chunk-3INDBMUU.mjs.map → chunk-TGDIACZT.mjs.map} +0 -0
  308. /package/dist/{chunk-WMAYETRD.mjs.map → chunk-TT3E2JOF.mjs.map} +0 -0
  309. /package/dist/{chunk-FVAM43KI.mjs.map → chunk-UMUWR5XA.mjs.map} +0 -0
  310. /package/dist/{devtools-S52RRRMN.mjs.map → devtools-XWZX6CCL.mjs.map} +0 -0
  311. /package/dist/{devtools-client-EOVDBPOI.mjs.map → devtools-client-Z7QQA3Q2.mjs.map} +0 -0
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>
@@ -17122,10 +17184,11 @@ var ROUTE_PROP_LABELS = /* @__PURE__ */ new Map([
17122
17184
  ["middlewareData", "middleware request data"],
17123
17185
  ["context", "request context"]
17124
17186
  ]);
17125
- function resolveConfiguredRouteRenderingConfig(mod, source) {
17187
+ function resolveConfiguredRouteRenderingConfig(mod, source, options) {
17188
+ const pprEnabled = options?.experimentalPPR === true;
17126
17189
  const directiveConfig = parseRouteRenderingDirective(source);
17127
17190
  let ssg = directiveConfig?.ssg ?? false;
17128
- let ppr = directiveConfig?.ppr ?? false;
17191
+ let requestedPPR = directiveConfig?.ppr ?? false;
17129
17192
  let revalidate = directiveConfig?.revalidate;
17130
17193
  const moduleDynamic = normalizeDynamicMode(mod?.dynamic);
17131
17194
  const dynamic = moduleDynamic ?? directiveConfig?.dynamic;
@@ -17135,12 +17198,12 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
17135
17198
  ssg = mod.ssg === true;
17136
17199
  }
17137
17200
  if (hasExplicitPPR) {
17138
- ppr = mod?.ppr === true || mod?.experimental_ppr === true;
17201
+ requestedPPR = mod?.ppr === true || mod?.experimental_ppr === true;
17139
17202
  }
17140
17203
  if (typeof mod?.revalidate === "number") {
17141
17204
  if (mod.revalidate > 0) {
17142
17205
  revalidate = mod.revalidate;
17143
- if (!hasExplicitSsg && !ppr) {
17206
+ if (!hasExplicitSsg && !requestedPPR) {
17144
17207
  ssg = true;
17145
17208
  }
17146
17209
  } else {
@@ -17154,23 +17217,24 @@ function resolveConfiguredRouteRenderingConfig(mod, source) {
17154
17217
  }
17155
17218
  if (moduleDynamic === "force-static" || moduleDynamic === "error") {
17156
17219
  ssg = true;
17157
- ppr = false;
17220
+ requestedPPR = false;
17158
17221
  } else if (moduleDynamic === "force-dynamic") {
17159
17222
  ssg = false;
17160
- ppr = false;
17223
+ requestedPPR = false;
17161
17224
  revalidate = void 0;
17162
17225
  }
17226
+ const ppr = pprEnabled && !ssg && requestedPPR;
17163
17227
  return {
17164
17228
  ssg,
17165
- ppr: ssg ? false : ppr,
17229
+ ppr,
17166
17230
  revalidate: ssg || ppr ? revalidate : void 0,
17167
17231
  dynamic,
17168
17232
  directive: directiveConfig?.directive
17169
17233
  };
17170
17234
  }
17171
17235
  __name(resolveConfiguredRouteRenderingConfig, "resolveConfiguredRouteRenderingConfig");
17172
- function resolveRouteRenderingConfig(mod, source) {
17173
- const rendering = resolveConfiguredRouteRenderingConfig(mod, source);
17236
+ function resolveRouteRenderingConfig(mod, source, options) {
17237
+ const rendering = resolveConfiguredRouteRenderingConfig(mod, source, options);
17174
17238
  if (!rendering.ssg || !source) {
17175
17239
  return rendering;
17176
17240
  }
@@ -17185,9 +17249,9 @@ function resolveRouteRenderingConfig(mod, source) {
17185
17249
  };
17186
17250
  }
17187
17251
  __name(resolveRouteRenderingConfig, "resolveRouteRenderingConfig");
17188
- async function resolveRouteRenderingConfigFromFile(mod, filePath) {
17252
+ async function resolveRouteRenderingConfigFromFile(mod, filePath, options) {
17189
17253
  const source = await (0, import_promises2.readFile)(filePath, "utf8").catch(() => void 0);
17190
- return resolveRouteRenderingConfig(mod, source);
17254
+ return resolveRouteRenderingConfig(mod, source, options);
17191
17255
  }
17192
17256
  __name(resolveRouteRenderingConfigFromFile, "resolveRouteRenderingConfigFromFile");
17193
17257
  function analyzeStaticRouteCandidate(mod, source, options = {}) {
@@ -18285,7 +18349,7 @@ function getIslandStrategyExport(content) {
18285
18349
  __name(getIslandStrategyExport, "getIslandStrategyExport");
18286
18350
  function stripUseClientDirective(content) {
18287
18351
  return content.replace(
18288
- /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*)(["'])use client\2\s*;?\s*/,
18352
+ /^((?:\s|\/\/[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/|(?:"[^"\n]*"|'[^'\n]*')\s*;?)*)(["'])use client\2\s*;?\s*/,
18289
18353
  "$1"
18290
18354
  );
18291
18355
  }
@@ -21454,7 +21518,7 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
21454
21518
  return this.resolveMessage(locale, key);
21455
21519
  }
21456
21520
  hasMessage(locale, key) {
21457
- return (this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key]) !== void 0;
21521
+ return this.readOwnMessage(locale, key) !== void 0;
21458
21522
  }
21459
21523
  getClientSnapshot(resolution) {
21460
21524
  return {
@@ -21482,8 +21546,19 @@ var _FarmI18nRuntime = class _FarmI18nRuntime {
21482
21546
  }
21483
21547
  return formatter.format(values);
21484
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
+ }
21485
21560
  resolveMessage(locale, key) {
21486
- const message = this.catalogs[locale]?.[key] ?? this.catalogs[this.config.fallbackLocale]?.[key];
21561
+ const message = this.readOwnMessage(locale, key);
21487
21562
  if (message !== void 0) return message;
21488
21563
  if (this.config.strict) {
21489
21564
  throw new Error(`Missing Farm i18n message "${key}" for locale "${locale}".`);
@@ -23832,7 +23907,7 @@ _setFarmThemeServerSnapshotResolver(() => {
23832
23907
  });
23833
23908
 
23834
23909
  // package.json
23835
- var version = "0.1.0-beta.96";
23910
+ var version = "0.1.0-beta.97";
23836
23911
 
23837
23912
  // src/version.ts
23838
23913
  var FARM_VERSION = version;
@@ -24760,7 +24835,8 @@ var _ServerRenderer = class _ServerRenderer {
24760
24835
  }
24761
24836
  const renderingConfig = await resolveRouteRenderingConfigFromFile(
24762
24837
  routeModule,
24763
- route.modulePath
24838
+ route.modulePath,
24839
+ { experimentalPPR: this.config.experimental?.ppr === true }
24764
24840
  );
24765
24841
  const pprBypassReason = renderingConfig.ppr ? this.getPPRShellBypassReason(req, middlewareMap, middlewareContext, pluginExposedContext) : void 0;
24766
24842
  const canCachePPRShell = renderingConfig.ppr && !pprBypassReason;
@@ -25465,6 +25541,11 @@ var _ServerRenderer = class _ServerRenderer {
25465
25541
  );
25466
25542
  res.statusCode = options.statusCode;
25467
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
+ }
25468
25549
  res.write(this.createFullHTML(html, false, options.pathname));
25469
25550
  res.end();
25470
25551
  return true;
@@ -26202,6 +26283,7 @@ var _FarmApp = class _FarmApp {
26202
26283
  serverComponents: config.experimental?.serverComponents ?? false,
26203
26284
  serverActions: config.experimental?.serverActions ?? false,
26204
26285
  isolatedClientHydration: config.experimental?.isolatedClientHydration ?? "off",
26286
+ ppr: config.experimental?.ppr ?? false,
26205
26287
  ...config.experimental
26206
26288
  },
26207
26289
  vite: config.vite || {}
@@ -27196,6 +27278,53 @@ function isArrayIndex(key) {
27196
27278
  }
27197
27279
  __name(isArrayIndex, "isArrayIndex");
27198
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
+
27199
27328
  // src/api/endpoint.ts
27200
27329
  var import_better_call = require("better-call");
27201
27330
  init_cache();
@@ -27223,15 +27352,15 @@ function isEndpointFailure(value) {
27223
27352
  }
27224
27353
  __name(isEndpointFailure, "isEndpointFailure");
27225
27354
  function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
27226
- let path36;
27355
+ let path37;
27227
27356
  let options;
27228
27357
  let handler;
27229
27358
  if (typeof pathOrOptions === "string") {
27230
- path36 = pathOrOptions;
27359
+ path37 = pathOrOptions;
27231
27360
  options = optionsOrHandler;
27232
27361
  handler = maybeHandler;
27233
27362
  } else {
27234
- path36 = "";
27363
+ path37 = "";
27235
27364
  options = pathOrOptions;
27236
27365
  handler = optionsOrHandler;
27237
27366
  }
@@ -27258,13 +27387,13 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
27258
27387
  ...betterCallOptions
27259
27388
  } = options;
27260
27389
  const endpoint = (0, import_better_call.createEndpoint)(
27261
- path36 || "/__farm_auto_path__",
27390
+ path37 || "/__farm_auto_path__",
27262
27391
  betterCallOptions,
27263
27392
  wrappedHandler
27264
27393
  );
27265
- endpoint.__path = path36 || void 0;
27394
+ endpoint.__path = path37 || void 0;
27266
27395
  endpoint.__method = options.method || "GET";
27267
- endpoint.__autoPath = !path36;
27396
+ endpoint.__autoPath = !path37;
27268
27397
  endpoint.__handler = wrappedHandler;
27269
27398
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
27270
27399
  endpoint.__middleware = middleware;
@@ -27275,6 +27404,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
27275
27404
  body: options.body,
27276
27405
  inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
27277
27406
  query: options.query,
27407
+ inputQuery: options.query,
27278
27408
  headers: options.headers,
27279
27409
  response: null,
27280
27410
  errors
@@ -27471,10 +27601,10 @@ function createRouteFactoryAt(prefix) {
27471
27601
  "OPTIONS"
27472
27602
  ]) {
27473
27603
  factory[method.toLowerCase()] = (child, options) => {
27474
- const path36 = joinRoutePath(prefix, child);
27604
+ const path37 = joinRoutePath(prefix, child);
27475
27605
  const input = options.input ?? {};
27476
27606
  const endpoint = createEndpoint(
27477
- path36,
27607
+ path37,
27478
27608
  {
27479
27609
  method,
27480
27610
  body: input.body,
@@ -27490,7 +27620,7 @@ function createRouteFactoryAt(prefix) {
27490
27620
  );
27491
27621
  endpoint.__types.params = input.params;
27492
27622
  endpoint.__output = options.output;
27493
- return Object.freeze({ path: path36, method, endpoint });
27623
+ return Object.freeze({ path: path37, method, endpoint });
27494
27624
  };
27495
27625
  }
27496
27626
  return Object.freeze(factory);
@@ -27498,21 +27628,21 @@ function createRouteFactoryAt(prefix) {
27498
27628
  __name(createRouteFactoryAt, "createRouteFactoryAt");
27499
27629
  function joinRoutePath(prefix, child) {
27500
27630
  if (typeof child !== "string") throw new TypeError("Route paths must be strings.");
27501
- const path36 = child === "" ? prefix : `${prefix}/${child.replace(/^\//, "")}`;
27502
- 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)) {
27503
27633
  throw new TypeError(
27504
- `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.`
27505
27635
  );
27506
27636
  }
27507
- assertBrowserStableRoutePath(path36);
27508
- assertUniqueRouteParameters(path36, "api");
27509
- getRoutePatternShape(path36, "api");
27510
- for (const segment of path36.split("/")) {
27637
+ assertBrowserStableRoutePath(path37);
27638
+ assertUniqueRouteParameters(path37, "api");
27639
+ getRoutePatternShape(path37, "api");
27640
+ for (const segment of path37.split("/")) {
27511
27641
  if (["__proto__", "constructor", "prototype", "$params"].includes(segment)) {
27512
27642
  throw new TypeError(`Route segment "${segment}" is reserved.`);
27513
27643
  }
27514
27644
  }
27515
- return path36;
27645
+ return path37;
27516
27646
  }
27517
27647
  __name(joinRoutePath, "joinRoutePath");
27518
27648
  function resolvePluginRoutes(plugins = []) {
@@ -27565,7 +27695,7 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
27565
27695
  }
27566
27696
  const result = [...routes.values()];
27567
27697
  if (expected) {
27568
- 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");
27569
27699
  if (signature(result) !== signature(expected)) {
27570
27700
  throw new Error(
27571
27701
  "Plugin API routes changed between build and runtime. Route paths and methods must be stable across environments; rebuild the app."
@@ -27577,8 +27707,8 @@ function mergePluginAPIRoutes(existing, plugins, expected) {
27577
27707
  __name(mergePluginAPIRoutes, "mergePluginAPIRoutes");
27578
27708
 
27579
27709
  // src/api/route-manager.ts
27580
- var fs6 = __toESM(require("fs"));
27581
- var path16 = __toESM(require("path"));
27710
+ var fs7 = __toESM(require("fs"));
27711
+ var path17 = __toESM(require("path"));
27582
27712
  init_utils();
27583
27713
  init_routes_shared();
27584
27714
  init_route_runtime();
@@ -28042,9 +28172,9 @@ var _APIRouteManager = class _APIRouteManager {
28042
28172
  this.routeShapes = /* @__PURE__ */ new Map();
28043
28173
  try {
28044
28174
  for (const appDir of this.appDirs) {
28045
- const apiDir = path16.join(appDir, "api");
28175
+ const apiDir = path17.join(appDir, "api");
28046
28176
  let routeFiles = [];
28047
- if (fs6.existsSync(apiDir)) {
28177
+ if (fs7.existsSync(apiDir)) {
28048
28178
  routeFiles = this.findRouteFiles(apiDir);
28049
28179
  }
28050
28180
  for (const filePath of routeFiles) {
@@ -28077,12 +28207,12 @@ var _APIRouteManager = class _APIRouteManager {
28077
28207
  */
28078
28208
  findRouteFiles(dir) {
28079
28209
  const files = [];
28080
- if (!fs6.existsSync(dir)) {
28210
+ if (!fs7.existsSync(dir)) {
28081
28211
  return files;
28082
28212
  }
28083
- const entries = fs6.readdirSync(dir, { withFileTypes: true });
28213
+ const entries = fs7.readdirSync(dir, { withFileTypes: true });
28084
28214
  for (const entry of entries) {
28085
- const fullPath = path16.join(dir, entry.name);
28215
+ const fullPath = path17.join(dir, entry.name);
28086
28216
  if (entry.isDirectory()) {
28087
28217
  files.push(...this.findRouteFiles(fullPath));
28088
28218
  } else if (isFarmAPIRouteFileName(entry.name)) {
@@ -28096,8 +28226,8 @@ var _APIRouteManager = class _APIRouteManager {
28096
28226
  */
28097
28227
  async loadRoute(filePath, appDir) {
28098
28228
  try {
28099
- const apiDir = path16.join(appDir, "api");
28100
- const relativePath2 = path16.relative(apiDir, path16.dirname(filePath));
28229
+ const apiDir = path17.join(appDir, "api");
28230
+ const relativePath2 = path17.relative(apiDir, path17.dirname(filePath));
28101
28231
  const routePath = "/api/" + (relativePath2 === "." ? "" : relativePath2.replace(/\\/g, "/"));
28102
28232
  const routeModule = await this.loadModule(filePath);
28103
28233
  const endpoints = {};
@@ -28170,7 +28300,7 @@ var _APIRouteManager = class _APIRouteManager {
28170
28300
  }
28171
28301
  }
28172
28302
  async loadProgrammaticApiRoutes(appDir) {
28173
- const candidateRoots = [path16.dirname(appDir), appDir];
28303
+ const candidateRoots = [path17.dirname(appDir), appDir];
28174
28304
  const routeFiles = Array.from(
28175
28305
  new Set(candidateRoots.flatMap((srcRoot) => findProgrammaticRouteFilesInDir(srcRoot)))
28176
28306
  );
@@ -28199,16 +28329,16 @@ var _APIRouteManager = class _APIRouteManager {
28199
28329
  }
28200
28330
  findRootRoutesFile(appDir) {
28201
28331
  const routeNames = ["routes.ts", "routes.tsx", "routes.js"];
28202
- const candidateDirs = [path16.dirname(appDir), appDir];
28332
+ const candidateDirs = [path17.dirname(appDir), appDir];
28203
28333
  const seen = /* @__PURE__ */ new Set();
28204
28334
  for (const dir of candidateDirs) {
28205
28335
  for (const routeName of routeNames) {
28206
- const routesFile = path16.join(dir, routeName);
28336
+ const routesFile = path17.join(dir, routeName);
28207
28337
  if (seen.has(routesFile)) {
28208
28338
  continue;
28209
28339
  }
28210
28340
  seen.add(routesFile);
28211
- if (fs6.existsSync(routesFile)) {
28341
+ if (fs7.existsSync(routesFile)) {
28212
28342
  return routesFile;
28213
28343
  }
28214
28344
  }
@@ -28342,8 +28472,8 @@ var APIRouteManager = _APIRouteManager;
28342
28472
  init_config3();
28343
28473
 
28344
28474
  // src/middleware/manager.ts
28345
- var fs7 = __toESM(require("fs"));
28346
- var path17 = __toESM(require("path"));
28475
+ var fs8 = __toESM(require("fs"));
28476
+ var path18 = __toESM(require("path"));
28347
28477
  init_decode();
28348
28478
 
28349
28479
  // src/middleware/cookie-header.ts
@@ -28744,7 +28874,7 @@ var _MiddlewareManager = class _MiddlewareManager {
28744
28874
  * Recursively discover middleware files
28745
28875
  */
28746
28876
  async discoverInDirectory(dir, routePath, discovered) {
28747
- if (!fs7.existsSync(dir)) {
28877
+ if (!fs8.existsSync(dir)) {
28748
28878
  return;
28749
28879
  }
28750
28880
  const middlewareFile = this.findMiddlewareFile(dir);
@@ -28754,10 +28884,10 @@ var _MiddlewareManager = class _MiddlewareManager {
28754
28884
  discovered.push(middleware);
28755
28885
  }
28756
28886
  }
28757
- const entries = fs7.readdirSync(dir, { withFileTypes: true });
28887
+ const entries = fs8.readdirSync(dir, { withFileTypes: true });
28758
28888
  for (const entry of entries) {
28759
28889
  if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
28760
- const subPath = path17.join(dir, entry.name);
28890
+ const subPath = path18.join(dir, entry.name);
28761
28891
  const subRoutePath = appendMiddlewareRoutePath(routePath, entry.name);
28762
28892
  await this.discoverInDirectory(subPath, subRoutePath, discovered);
28763
28893
  }
@@ -28769,8 +28899,8 @@ var _MiddlewareManager = class _MiddlewareManager {
28769
28899
  findMiddlewareFile(dir) {
28770
28900
  const extensions = [".ts", ".tsx", ".js", ".jsx"];
28771
28901
  for (const ext of extensions) {
28772
- const filePath = path17.join(dir, `middleware${ext}`);
28773
- if (fs7.existsSync(filePath)) {
28902
+ const filePath = path18.join(dir, `middleware${ext}`);
28903
+ if (fs8.existsSync(filePath)) {
28774
28904
  return filePath;
28775
28905
  }
28776
28906
  }
@@ -29110,8 +29240,8 @@ var import_path9 = require("path");
29110
29240
  init_type_generator();
29111
29241
 
29112
29242
  // src/routing/generate-route-types.ts
29113
- var path18 = __toESM(require("path"));
29114
- var fs8 = __toESM(require("fs"));
29243
+ var path19 = __toESM(require("path"));
29244
+ var fs9 = __toESM(require("fs"));
29115
29245
  init_utils();
29116
29246
  init_write_file_if_changed();
29117
29247
  init_renderer();
@@ -29164,12 +29294,12 @@ function createRoutePattern(route) {
29164
29294
  __name(createRoutePattern, "createRoutePattern");
29165
29295
  var DEFAULT_OUT_FILE = "farm-routes.d.ts";
29166
29296
  async function generateRouteTypes(options) {
29167
- const root = path18.resolve(options.root);
29297
+ const root = path19.resolve(options.root);
29168
29298
  const srcDir = options.srcDir || "src";
29169
29299
  const outFile = options.outFile || DEFAULT_OUT_FILE;
29170
- const outPath = path18.isAbsolute(outFile) ? outFile : path18.join(root, srcDir, outFile);
29300
+ const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
29171
29301
  const content = await createRouteTypeDeclarations(options, outPath);
29172
- fs8.mkdirSync(path18.dirname(outPath), { recursive: true });
29302
+ fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
29173
29303
  writeFileIfChanged(outPath, content);
29174
29304
  return outPath;
29175
29305
  }
@@ -29184,8 +29314,8 @@ async function createRouteTypeDeclarations(options, outPath) {
29184
29314
  const routeModulePatterns = /* @__PURE__ */ new Set();
29185
29315
  const glob = await import("fast-glob");
29186
29316
  for (const source of sourceRoots) {
29187
- const appDir = path18.join(source.root, source.srcDir, "app");
29188
- if (fs8.existsSync(appDir)) {
29317
+ const appDir = path19.join(source.root, source.srcDir, "app");
29318
+ if (fs9.existsSync(appDir)) {
29189
29319
  const routeModuleFiles = await glob.default(
29190
29320
  `**/{page,layout,loading,error}.{${componentExtensions.join(",")},md,mdx}`,
29191
29321
  {
@@ -29221,7 +29351,7 @@ async function createRouteTypeDeclarations(options, outPath) {
29221
29351
  const routePathType = suppressLintOnLink ? "string" : renderTypeUnion(typeLiterals);
29222
29352
  const routePatternType = suppressLintOnLink ? "string" : renderTypeUnion(patternLiterals);
29223
29353
  const routeModulePatternType = renderTypeUnion(routeModulePatternLiterals);
29224
- const routeTypesImportPath = `./${path18.basename(outPath).replace(/\.d\.ts$/, "")}`;
29354
+ const routeTypesImportPath = `./${path19.basename(outPath).replace(/\.d\.ts$/, "")}`;
29225
29355
  const linkAugmentationBlock = suppressLintOnLink ? "" : `
29226
29356
  declare module "@farm.js/core/client" {
29227
29357
  interface LinkDefaultRoute {
@@ -29271,8 +29401,8 @@ ${renderTypeAlias("RouteModulePattern", routeModulePatternType)}${linkAugmentati
29271
29401
  __name(createRouteTypeDeclarations, "createRouteTypeDeclarations");
29272
29402
 
29273
29403
  // src/env-types.ts
29274
- var fs9 = __toESM(require("fs"));
29275
- var path19 = __toESM(require("path"));
29404
+ var fs10 = __toESM(require("fs"));
29405
+ var path20 = __toESM(require("path"));
29276
29406
  init_write_file_if_changed();
29277
29407
  var DEFAULT_OUT_FILE2 = "farm-env.d.ts";
29278
29408
  var CONFIG_FILENAMES2 = [
@@ -29294,21 +29424,21 @@ var CONFIG_FILENAMES2 = [
29294
29424
  "config.cjs"
29295
29425
  ];
29296
29426
  async function generateEnvTypes(options) {
29297
- const root = path19.resolve(options.root);
29427
+ const root = path20.resolve(options.root);
29298
29428
  const srcDir = options.srcDir || "src";
29299
29429
  const outFile = options.outFile || DEFAULT_OUT_FILE2;
29300
- const outPath = path19.isAbsolute(outFile) ? outFile : path19.join(root, srcDir, outFile);
29430
+ const outPath = path20.isAbsolute(outFile) ? outFile : path20.join(root, srcDir, outFile);
29301
29431
  const content = createEnvTypeDeclarations(options, outPath);
29302
- fs9.mkdirSync(path19.dirname(outPath), { recursive: true });
29432
+ fs10.mkdirSync(path20.dirname(outPath), { recursive: true });
29303
29433
  writeFileIfChanged(outPath, content);
29304
29434
  return outPath;
29305
29435
  }
29306
29436
  __name(generateEnvTypes, "generateEnvTypes");
29307
29437
  function createEnvTypeDeclarations(options, outPath) {
29308
- const root = path19.resolve(options.root);
29438
+ const root = path20.resolve(options.root);
29309
29439
  const configPath = findConfigPath(root, options.configPath);
29310
29440
  const configPaths = [
29311
- ...(options.layerConfigPaths ?? []).filter((value) => fs9.existsSync(value)),
29441
+ ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
29312
29442
  ...configPath ? [configPath] : []
29313
29443
  ];
29314
29444
  const content = configPaths.length > 1 ? createLayeredConfigBackedEnvTypes(outPath, configPaths) : configPaths.length === 1 ? createConfigBackedEnvTypes(outPath, configPaths[0]) : createEmptyEnvTypes();
@@ -29370,12 +29500,12 @@ export {};
29370
29500
  __name(createLayeredConfigBackedEnvTypes, "createLayeredConfigBackedEnvTypes");
29371
29501
  function findConfigPath(root, configPath) {
29372
29502
  if (configPath) {
29373
- const resolvedPath = path19.isAbsolute(configPath) ? configPath : path19.join(root, configPath);
29374
- return fs9.existsSync(resolvedPath) ? resolvedPath : null;
29503
+ const resolvedPath = path20.isAbsolute(configPath) ? configPath : path20.join(root, configPath);
29504
+ return fs10.existsSync(resolvedPath) ? resolvedPath : null;
29375
29505
  }
29376
29506
  for (const filename of CONFIG_FILENAMES2) {
29377
- const resolvedPath = path19.join(root, filename);
29378
- if (fs9.existsSync(resolvedPath)) {
29507
+ const resolvedPath = path20.join(root, filename);
29508
+ if (fs10.existsSync(resolvedPath)) {
29379
29509
  return resolvedPath;
29380
29510
  }
29381
29511
  }
@@ -29438,19 +29568,19 @@ export {};
29438
29568
  }
29439
29569
  __name(createEmptyEnvTypes, "createEmptyEnvTypes");
29440
29570
  function toTypeImportPath(outPath, targetPath) {
29441
- 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)$/, "");
29442
29572
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
29443
29573
  }
29444
29574
  __name(toTypeImportPath, "toTypeImportPath");
29445
29575
 
29446
29576
  // src/image-types.ts
29447
- var import_node_fs6 = require("fs");
29448
- var import_node_path10 = __toESM(require("path"));
29577
+ var import_node_fs7 = require("fs");
29578
+ var import_node_path11 = __toESM(require("path"));
29449
29579
  init_write_file_if_changed();
29450
29580
  var FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
29451
29581
  function generateFarmImageTypes(options) {
29452
- 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");
29453
- (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 });
29454
29584
  writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
29455
29585
  return outputPath;
29456
29586
  }
@@ -29478,8 +29608,8 @@ declare module "*?url" {
29478
29608
  __name(createFarmImageTypeDeclarations, "createFarmImageTypeDeclarations");
29479
29609
 
29480
29610
  // src/content-types.ts
29481
- var fs10 = __toESM(require("fs"));
29482
- var path21 = __toESM(require("path"));
29611
+ var fs11 = __toESM(require("fs"));
29612
+ var path22 = __toESM(require("path"));
29483
29613
  var CONFIG_FILENAMES3 = [
29484
29614
  "farm.config.ts",
29485
29615
  "farm.config.tsx",
@@ -29499,10 +29629,10 @@ var CONFIG_FILENAMES3 = [
29499
29629
  "config.cjs"
29500
29630
  ];
29501
29631
  function createContentTypeDeclarations(options, outPath) {
29502
- const root = path21.resolve(options.root);
29632
+ const root = path22.resolve(options.root);
29503
29633
  const projectConfig = findConfigPath2(root, options.configPath);
29504
29634
  const configPaths = [
29505
- ...(options.layerConfigPaths ?? []).filter((value) => fs10.existsSync(value)),
29635
+ ...(options.layerConfigPaths ?? []).filter((value) => fs11.existsSync(value)),
29506
29636
  ...projectConfig ? [projectConfig] : []
29507
29637
  ];
29508
29638
  if (configPaths.length === 0) return createEmptyContentTypes();
@@ -29572,32 +29702,32 @@ export {};
29572
29702
  __name(createEmptyContentTypes, "createEmptyContentTypes");
29573
29703
  function findConfigPath2(root, configPath) {
29574
29704
  if (configPath) {
29575
- const resolvedPath = path21.isAbsolute(configPath) ? configPath : path21.join(root, configPath);
29576
- return fs10.existsSync(resolvedPath) ? resolvedPath : null;
29705
+ const resolvedPath = path22.isAbsolute(configPath) ? configPath : path22.join(root, configPath);
29706
+ return fs11.existsSync(resolvedPath) ? resolvedPath : null;
29577
29707
  }
29578
29708
  for (const filename of CONFIG_FILENAMES3) {
29579
- const resolvedPath = path21.join(root, filename);
29580
- if (fs10.existsSync(resolvedPath)) return resolvedPath;
29709
+ const resolvedPath = path22.join(root, filename);
29710
+ if (fs11.existsSync(resolvedPath)) return resolvedPath;
29581
29711
  }
29582
29712
  return null;
29583
29713
  }
29584
29714
  __name(findConfigPath2, "findConfigPath");
29585
29715
  function toTypeImportPath2(outPath, targetPath) {
29586
- 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)$/, "");
29587
29717
  return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
29588
29718
  }
29589
29719
  __name(toTypeImportPath2, "toTypeImportPath");
29590
29720
 
29591
29721
  // src/i18n/type-generator.ts
29592
- var import_node_fs7 = require("fs");
29593
- var import_node_path11 = require("path");
29722
+ var import_node_fs8 = require("fs");
29723
+ var import_node_path12 = require("path");
29594
29724
  init_write_file_if_changed();
29595
29725
  async function generateFarmI18nTypes(options) {
29596
29726
  if (!options.config.enabled) return void 0;
29597
29727
  const { signatures } = await readFarmI18nCatalogs(options.config);
29598
- 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");
29599
29729
  const content = renderFarmI18nTypes(options.config.locales, signatures);
29600
- (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 });
29601
29731
  writeFileIfChanged(outFile, content);
29602
29732
  return outFile;
29603
29733
  }
@@ -29890,8 +30020,8 @@ init_integrations();
29890
30020
  init_route_context();
29891
30021
  init_devtools_config();
29892
30022
  init_dev_indicators();
29893
- var fs12 = __toESM(require("fs"));
29894
- var path33 = __toESM(require("path"));
30023
+ var fs13 = __toESM(require("fs"));
30024
+ var path34 = __toESM(require("path"));
29895
30025
  var import_node_url8 = require("url");
29896
30026
  init_layers();
29897
30027
 
@@ -30398,7 +30528,7 @@ async function _runWithAfterRequest(request, handler, context2) {
30398
30528
  const response = await afterStorage.run(state, handler);
30399
30529
  return hasResponseHook ? response : wrapResponseBody(response, request, state);
30400
30530
  } catch (error) {
30401
- if (!hasResponseHook) finishSoon(state);
30531
+ finishSoon(state);
30402
30532
  throw error;
30403
30533
  }
30404
30534
  }
@@ -30451,8 +30581,8 @@ function _runWithAPIRequestRuntime(runtime, run) {
30451
30581
  __name(_runWithAPIRequestRuntime, "_runWithAPIRequestRuntime");
30452
30582
 
30453
30583
  // src/dev-static.ts
30454
- var fs11 = __toESM(require("fs"));
30455
- var path22 = __toESM(require("path"));
30584
+ var fs12 = __toESM(require("fs"));
30585
+ var path23 = __toESM(require("path"));
30456
30586
  function shouldBypassFarmRouterForDottedPath(pathname, routeManager, baseDirs) {
30457
30587
  if (!pathname.includes(".") || pathname.endsWith(".html")) return false;
30458
30588
  const matchesAppRoute = Boolean(
@@ -30472,11 +30602,11 @@ function devServableFileExists(pathname, baseDirs) {
30472
30602
  if (!relativePathname) return false;
30473
30603
  for (const baseDir of baseDirs) {
30474
30604
  if (typeof baseDir !== "string" || baseDir.length === 0) continue;
30475
- const resolvedBase = path22.resolve(baseDir);
30476
- const candidate = path22.resolve(resolvedBase, relativePathname);
30477
- 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;
30478
30608
  try {
30479
- if (fs11.existsSync(candidate) && fs11.statSync(candidate).isFile()) {
30609
+ if (fs12.existsSync(candidate) && fs12.statSync(candidate).isFile()) {
30480
30610
  return true;
30481
30611
  }
30482
30612
  } catch {
@@ -30491,6 +30621,7 @@ var SERVER_FN_FACTORIES = ["createServerQuery", "createServerFn"];
30491
30621
  var FARM_CORE_IMPORT_RE = /import\s*(?!type\b)(?:[\w$]+\s*,\s*)?\{([^}]*)\}\s*from\s*(["'])@farm\.js\/core(?:\/[\w./-]+)?\2/g;
30492
30622
  function findClientServerFnViolation(code, id) {
30493
30623
  if (id.startsWith("\0") || id.startsWith("virtual:") || id.includes("node_modules")) return null;
30624
+ if (/\.(md|mdx)(\?|$)/.test(id)) return null;
30494
30625
  if (!code.includes("@farm.js/core")) return null;
30495
30626
  for (const match of code.matchAll(FARM_CORE_IMPORT_RE)) {
30496
30627
  const specifiers = match[1];
@@ -30520,7 +30651,7 @@ init_image_config();
30520
30651
 
30521
30652
  // src/image-vite.ts
30522
30653
  var import_promises7 = require("fs/promises");
30523
- var import_node_path12 = __toESM(require("path"));
30654
+ var import_node_path13 = __toESM(require("path"));
30524
30655
  var import_image_size2 = require("image-size");
30525
30656
  var FARM_IMAGE_ID_PREFIX = "\0farm:image:";
30526
30657
  var STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
@@ -30603,7 +30734,7 @@ init_image_server();
30603
30734
  init_routing();
30604
30735
 
30605
30736
  // src/server/vite-config.ts
30606
- var import_node_path13 = __toESM(require("path"));
30737
+ var import_node_path14 = __toESM(require("path"));
30607
30738
  var FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
30608
30739
  var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
30609
30740
  "react",
@@ -30627,9 +30758,9 @@ function getFarmClientOptimizeDepsInclude(renderer) {
30627
30758
  }
30628
30759
  __name(getFarmClientOptimizeDepsInclude, "getFarmClientOptimizeDepsInclude");
30629
30760
  function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
30630
- const resolvedProjectRoot = import_node_path13.default.resolve(projectRoot);
30761
+ const resolvedProjectRoot = import_node_path14.default.resolve(projectRoot);
30631
30762
  return appDirectories.map((appDirectory) => {
30632
- 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, "/");
30633
30764
  const prefix = relativeAppDirectory || ".";
30634
30765
  return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
30635
30766
  });
@@ -30653,7 +30784,7 @@ function createFarmClientOptimizeDepsConfig(entries, renderer) {
30653
30784
  __name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
30654
30785
  function createFarmSourceAlias(projectRoot, srcDir = "src") {
30655
30786
  return {
30656
- "@": import_node_path13.default.resolve(projectRoot, srcDir)
30787
+ "@": import_node_path14.default.resolve(projectRoot, srcDir)
30657
30788
  };
30658
30789
  }
30659
30790
  __name(createFarmSourceAlias, "createFarmSourceAlias");
@@ -30756,7 +30887,7 @@ init_observability();
30756
30887
  init_renderer();
30757
30888
 
30758
30889
  // src/integration-provider-build.ts
30759
- var import_node_path15 = __toESM(require("path"));
30890
+ var import_node_path16 = __toESM(require("path"));
30760
30891
  init_integrations();
30761
30892
  init_utils();
30762
30893
  function generateFarmIntegrationProviderClientCode(providers, root) {
@@ -30813,7 +30944,7 @@ function wrapWithIntegrationProviders(element) {
30813
30944
  __name(generateFarmIntegrationProviderClientCode, "generateFarmIntegrationProviderClientCode");
30814
30945
  function resolveProviderModule(moduleId, root) {
30815
30946
  if (!moduleId.startsWith(".")) return moduleId;
30816
- return toViteModuleId(import_node_path15.default.resolve(root, moduleId), root);
30947
+ return toViteModuleId(import_node_path16.default.resolve(root, moduleId), root);
30817
30948
  }
30818
30949
  __name(resolveProviderModule, "resolveProviderModule");
30819
30950
 
@@ -30925,6 +31056,7 @@ var createEmptyTypeArtifactSelection = /* @__PURE__ */ __name(() => ({
30925
31056
  i18n: false
30926
31057
  }), "createEmptyTypeArtifactSelection");
30927
31058
  var FARM_I18N_CLIENT_BRIDGE_ID = "\0farm-i18n-client-bridge";
31059
+ var warnedDeprecatedDevtoolsDashboard = false;
30928
31060
  var EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME = `
30929
31061
  function isFarmDocsSearchPage() {
30930
31062
  return false;
@@ -31343,11 +31475,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
31343
31475
  }
31344
31476
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
31345
31477
  function fileContainsProgrammaticPageRoute(file) {
31346
- if (!fs12.existsSync(file)) {
31478
+ if (!fs13.existsSync(file)) {
31347
31479
  return false;
31348
31480
  }
31349
31481
  try {
31350
- return scanProgrammaticPagePaths(fs12.readFileSync(file, "utf8")).length > 0;
31482
+ return scanProgrammaticPagePaths(fs13.readFileSync(file, "utf8")).length > 0;
31351
31483
  } catch {
31352
31484
  return false;
31353
31485
  }
@@ -31355,7 +31487,7 @@ function fileContainsProgrammaticPageRoute(file) {
31355
31487
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
31356
31488
  function rewriteEarlySsrRelativeImports(options) {
31357
31489
  const cleanId = options.id.split("?", 1)[0];
31358
- if (!path33.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31490
+ if (!path34.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
31359
31491
  return null;
31360
31492
  }
31361
31493
  const replacements = [];
@@ -31375,7 +31507,7 @@ function rewriteEarlySsrRelativeImports(options) {
31375
31507
  const suffixIndex = source.value.search(/[?#]/);
31376
31508
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
31377
31509
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
31378
- const resolvedPath = path33.resolve(path33.dirname(cleanId), sourcePath);
31510
+ const resolvedPath = path34.resolve(path34.dirname(cleanId), sourcePath);
31379
31511
  replacements.push({
31380
31512
  start: source.start,
31381
31513
  end: source.end,
@@ -31537,7 +31669,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31537
31669
  ...layerRoots.length ? {
31538
31670
  server: {
31539
31671
  fs: {
31540
- allow: [path33.resolve(options.root || process.cwd()), ...layerRoots]
31672
+ allow: [path34.resolve(options.root || process.cwd()), ...layerRoots]
31541
31673
  }
31542
31674
  }
31543
31675
  } : {}
@@ -31568,13 +31700,13 @@ function farmPlugin(options = {}, initialPluginManager) {
31568
31700
  },
31569
31701
  server
31570
31702
  );
31571
- const globalsCSSPath = path33.join(server.config.root, "src/app/globals.css");
31572
- if (!fs12.existsSync(globalsCSSPath)) {
31573
- const appDir = path33.join(server.config.root, "src/app");
31574
- if (!fs12.existsSync(appDir)) {
31575
- 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 });
31576
31708
  }
31577
- fs12.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31709
+ fs13.writeFileSync(globalsCSSPath, defaultGlobalCSS);
31578
31710
  }
31579
31711
  await farmApp.initialize();
31580
31712
  const farmConfig = farmApp.getConfig();
@@ -31595,10 +31727,10 @@ function farmPlugin(options = {}, initialPluginManager) {
31595
31727
  });
31596
31728
  }
31597
31729
  const sourceRoots = getFarmSourceRoots(farmConfig);
31598
- 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)));
31599
31731
  if (farmConfig.i18n.enabled) {
31600
31732
  server.watcher.add(
31601
- 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
31602
31734
  );
31603
31735
  }
31604
31736
  const workflowConfig = farmConfig.workflows;
@@ -31608,7 +31740,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31608
31740
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
31609
31741
  ], "getExtraRouteTypes");
31610
31742
  const appDirSlugs = sourceRoots.map(
31611
- (source) => path33.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31743
+ (source) => path34.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
31612
31744
  );
31613
31745
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
31614
31746
  try {
@@ -31649,7 +31781,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31649
31781
  }, "generateTypeArtifacts");
31650
31782
  await generateTypeArtifacts("startup");
31651
31783
  const srcDirSlugs = sourceRoots.map(
31652
- (source) => path33.join(source.root, source.srcDir).replace(/\\/g, "/")
31784
+ (source) => path34.join(source.root, source.srcDir).replace(/\\/g, "/")
31653
31785
  );
31654
31786
  const layerConfigFiles = new Set(
31655
31787
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -31770,7 +31902,7 @@ function farmPlugin(options = {}, initialPluginManager) {
31770
31902
  await apiRouteManager.discoverRoutes();
31771
31903
  let discoveredWorkflows = [];
31772
31904
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
31773
- (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))
31774
31906
  );
31775
31907
  if (hasWorkflowDirectory) {
31776
31908
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -32035,12 +32167,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
32035
32167
  }
32036
32168
  }
32037
32169
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
32038
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs12.existsSync(farmDocsFontPath)) {
32170
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs13.existsSync(farmDocsFontPath)) {
32039
32171
  res.statusCode = 200;
32040
32172
  res.setHeader("Content-Type", "font/woff2");
32041
32173
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
32042
32174
  if (requestMethod === "HEAD") res.end();
32043
- else fs12.createReadStream(farmDocsFontPath).pipe(res);
32175
+ else fs13.createReadStream(farmDocsFontPath).pipe(res);
32044
32176
  return;
32045
32177
  }
32046
32178
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -32096,6 +32228,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
32096
32228
  if (requestPathname.endsWith(".json")) {
32097
32229
  res.end(JSON.stringify(snapshot, null, 2));
32098
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
+ }
32099
32237
  const { renderFarmDevtoolsHtml: renderFarmDevtoolsHtml2 } = await loadFarmDevtoolsUIRuntime();
32100
32238
  res.end(renderFarmDevtoolsHtml2(snapshot));
32101
32239
  }
@@ -32138,7 +32276,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
32138
32276
  return null;
32139
32277
  }
32140
32278
  return {
32141
- source: await fs12.promises.readFile(sourcePath, "utf8"),
32279
+ source: await fs13.promises.readFile(sourcePath, "utf8"),
32142
32280
  filePath: sourcePath
32143
32281
  };
32144
32282
  }, "resolveSource")
@@ -33022,7 +33160,10 @@ ${generatedDevIndicatorsClientRuntime}`,
33022
33160
  renderer,
33023
33161
  isolatedHydrationMode === "enabled",
33024
33162
  resolvedConfig?.trailingSlash ?? false,
33025
- resolvedConfig?.basePath ?? "/"
33163
+ resolvedConfig?.basePath ?? "/",
33164
+ generateClientCachePersistenceCode(
33165
+ resolveFarmClientCacheAdapterEntry(root, resolvedConfig?.cache)
33166
+ )
33026
33167
  );
33027
33168
  }
33028
33169
  if (id === "/@farm/server") {
@@ -33161,7 +33302,7 @@ export const manifest = getManifest();
33161
33302
  const root = currentConfig.root || server?.config.root || process.cwd();
33162
33303
  const cleanId = id.split("?", 1)[0];
33163
33304
  const selectedIsolatedModules = options.isolatedClientBoundaryModules ?? farmApp?.getRouteManager().getIsolatedClientBoundaryModules(root);
33164
- const selectedForIsolatedHydration = selectedIsolatedModules?.has(path33.resolve(cleanId)) === true;
33305
+ const selectedForIsolatedHydration = selectedIsolatedModules?.has(path34.resolve(cleanId)) === true;
33165
33306
  if (isolatedHydrationEnabled && selectedForIsolatedHydration && isIsolatableClientBoundarySource(clientBoundarySource)) {
33166
33307
  isolatedModuleReference = toViteModuleId(cleanId, root);
33167
33308
  const transformedBoundary = transformIsolatedClientBoundaryModule({
@@ -33252,8 +33393,8 @@ if (import.meta.hot) {
33252
33393
  }
33253
33394
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
33254
33395
  logger.info("Pre-rendering SSG pages...");
33255
- const outDir = path33.join(server?.config.root || process.cwd(), options.outDir || "dist");
33256
- 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");
33257
33398
  for (const page2 of ssgPages) {
33258
33399
  try {
33259
33400
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -33305,9 +33446,9 @@ if (import.meta.hot) {
33305
33446
  <script type="module" src="/assets/client.js"></script>
33306
33447
  </body>
33307
33448
  </html>`;
33308
- const outputPath = page2.urlPath === "/" ? path33.join(clientDir, "index.html") : path33.join(clientDir, page2.urlPath + ".html");
33309
- fs12.mkdirSync(path33.dirname(outputPath), { recursive: true });
33310
- 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);
33311
33452
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
33312
33453
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
33313
33454
  });
@@ -33315,8 +33456,8 @@ if (import.meta.hot) {
33315
33456
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
33316
33457
  }
33317
33458
  }
33318
- const manifestPath = path33.join(outDir, "__ssg_manifest.json");
33319
- fs12.writeFileSync(
33459
+ const manifestPath = path34.join(outDir, "__ssg_manifest.json");
33460
+ fs13.writeFileSync(
33320
33461
  manifestPath,
33321
33462
  JSON.stringify(
33322
33463
  ssgPages.map((p) => ({
@@ -33359,9 +33500,9 @@ if (import.meta.hot) {
33359
33500
  server2.ws.send({ type: "full-reload", path: "*" });
33360
33501
  return [];
33361
33502
  }
33362
- 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;
33363
33504
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
33364
- logUpdate("PAGE", `updated ${path33.basename(file)}`);
33505
+ logUpdate("PAGE", `updated ${path34.basename(file)}`);
33365
33506
  for (const mod of modules) {
33366
33507
  server2.moduleGraph.invalidateModule(mod);
33367
33508
  }
@@ -33784,7 +33925,7 @@ function parseRouteModuleSchema2(schema, value, label, routePath) {
33784
33925
  }
33785
33926
  }
33786
33927
  __name(parseRouteModuleSchema2, "parseRouteModuleSchema");
33787
- 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: "" }) {
33788
33929
  const providerClientCode = generateFarmIntegrationProviderClientCode(integrationProviders, root);
33789
33930
  const clientPluginEntry = generateFarmClientPluginEntryCode(
33790
33931
  plugins,
@@ -33840,6 +33981,7 @@ import {
33840
33981
  } from '@farm.js/core/deployment'
33841
33982
  ${providerClientCode.imports}
33842
33983
  ${clientPluginEntry.imports}
33984
+ ${clientCachePersistence.imports}
33843
33985
  ${docsSearchClientRuntime}
33844
33986
  ${devtoolsClientRuntime}
33845
33987
  ${docsAdapterImportBlock}
@@ -33855,6 +33997,7 @@ const integrationDocumentNavigationMatchers = ${JSON.stringify(documentNavigatio
33855
33997
  setFarmBasePath(${JSON.stringify(basePath)});
33856
33998
  setFarmTrailingSlashPreference(${JSON.stringify(trailingSlash)});
33857
33999
  installChunkErrorRecovery();
34000
+ ${clientCachePersistence.init}
33858
34001
 
33859
34002
  let reactRoot = null;
33860
34003
  ${isolatedHydrationRuntime}
@@ -35238,7 +35381,7 @@ function generateClientManifest(bundle) {
35238
35381
  __name(generateClientManifest, "generateClientManifest");
35239
35382
  async function defineConfig2(config = {}) {
35240
35383
  const tailwindcss = (await import("@tailwindcss/vite")).default;
35241
- const appRoot = path33.resolve(config.root || process.cwd());
35384
+ const appRoot = path34.resolve(config.root || process.cwd());
35242
35385
  if (config.extends?.length) {
35243
35386
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
35244
35387
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
@@ -35786,7 +35929,8 @@ function createServerQuery(options) {
35786
35929
  return createFarmServerQueryResult(data, {
35787
35930
  key: clientKey,
35788
35931
  staleTime,
35789
- updatedAt
35932
+ updatedAt,
35933
+ ...options.persist === true ? { persist: true } : {}
35790
35934
  });
35791
35935
  }, "handler")
35792
35936
  });
@@ -36174,8 +36318,8 @@ init_layers();
36174
36318
 
36175
36319
  // src/instrumentation.ts
36176
36320
  var import_esbuild = require("esbuild");
36177
- var import_node_fs12 = __toESM(require("fs"));
36178
- var import_node_path21 = __toESM(require("path"));
36321
+ var import_node_fs13 = __toESM(require("fs"));
36322
+ var import_node_path22 = __toESM(require("path"));
36179
36323
  var import_node_url9 = require("url");
36180
36324
 
36181
36325
  // src/instrumentation-runtime.ts
@@ -36223,16 +36367,16 @@ var INSTRUMENTATION_EXTENSIONS = ["ts", "mts", "js", "mjs"];
36223
36367
  function resolveFarmInstrumentationFile(root, srcDir = "src") {
36224
36368
  const candidates = [
36225
36369
  ...INSTRUMENTATION_EXTENSIONS.map(
36226
- (extension) => import_node_path21.default.join(root, srcDir, `instrumentation.${extension}`)
36370
+ (extension) => import_node_path22.default.join(root, srcDir, `instrumentation.${extension}`)
36227
36371
  ),
36228
36372
  ...INSTRUMENTATION_EXTENSIONS.map(
36229
- (extension) => import_node_path21.default.join(root, `instrumentation.${extension}`)
36373
+ (extension) => import_node_path22.default.join(root, `instrumentation.${extension}`)
36230
36374
  )
36231
- ].filter((candidate) => import_node_fs12.default.existsSync(candidate));
36375
+ ].filter((candidate) => import_node_fs13.default.existsSync(candidate));
36232
36376
  if (candidates.length > 1) {
36233
36377
  throw new Error(
36234
36378
  `Farm.js found multiple instrumentation files:
36235
- ${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")}
36236
36380
  Keep only one instrumentation file in the project root or ${srcDir}/.`
36237
36381
  );
36238
36382
  }
@@ -36241,9 +36385,9 @@ Keep only one instrumentation file in the project root or ${srcDir}/.`
36241
36385
  __name(resolveFarmInstrumentationFile, "resolveFarmInstrumentationFile");
36242
36386
  async function loadFarmInstrumentation(filePath, root) {
36243
36387
  if (!filePath) return null;
36244
- const outputDirectory = import_node_path21.default.join(root, ".farm", ".instrumentation-loader");
36245
- const outputFile = import_node_path21.default.join(outputDirectory, "instrumentation.mjs");
36246
- 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 });
36247
36391
  await (0, import_esbuild.build)({
36248
36392
  entryPoints: [filePath],
36249
36393
  outfile: outputFile,