@farm.js/core 0.1.0-beta.14 → 0.1.0-beta.17

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 (271) hide show
  1. package/dist/after.d.mts +25 -0
  2. package/dist/after.d.ts +25 -0
  3. package/dist/agent-runtime.d.mts +96 -0
  4. package/dist/agent-runtime.d.ts +96 -0
  5. package/dist/api/route-manager.cjs.map +1 -1
  6. package/dist/api/route-manager.d.mts +66 -0
  7. package/dist/api/route-manager.d.ts +66 -0
  8. package/dist/api/route-manager.mjs +2 -2
  9. package/dist/api/runtime.cjs.map +1 -1
  10. package/dist/api/runtime.d.mts +3 -0
  11. package/dist/api/runtime.d.ts +3 -0
  12. package/dist/api/runtime.mjs +1 -1
  13. package/dist/api.cjs +18 -10
  14. package/dist/api.cjs.map +1 -1
  15. package/dist/api.d.mts +48 -0
  16. package/dist/api.d.ts +48 -0
  17. package/dist/api.mjs +3 -3
  18. package/dist/app-B0tE1I3o.d.ts +306 -0
  19. package/dist/app-Dv2JJb7X.d.mts +306 -0
  20. package/dist/app-markdown.d.mts +24 -0
  21. package/dist/app-markdown.d.ts +24 -0
  22. package/dist/cache.d.mts +192 -0
  23. package/dist/cache.d.ts +192 -0
  24. package/dist/{chunk-VUL55IAX.mjs → chunk-2FLBZFPG.mjs} +19 -19
  25. package/dist/chunk-2FLBZFPG.mjs.map +1 -0
  26. package/dist/{chunk-B232I2GP.mjs → chunk-3HIVDX7J.mjs} +12 -1
  27. package/dist/chunk-3HIVDX7J.mjs.map +1 -0
  28. package/dist/{chunk-JDEOUK5V.mjs → chunk-6YXKHAFU.mjs} +3 -3
  29. package/dist/{chunk-Z5CQMP54.mjs → chunk-ARRYKOI5.mjs} +2 -2
  30. package/dist/{chunk-KLA67WKG.mjs → chunk-B3FFOIWS.mjs} +2 -2
  31. package/dist/chunk-E257KFBU.mjs +227 -0
  32. package/dist/chunk-E257KFBU.mjs.map +1 -0
  33. package/dist/{chunk-PFE6GMNE.mjs → chunk-HMRFYJK6.mjs} +19 -11
  34. package/dist/chunk-HMRFYJK6.mjs.map +1 -0
  35. package/dist/{chunk-OPHK6OJN.mjs → chunk-JAEAE27K.mjs} +2 -2
  36. package/dist/{chunk-32W4QEJP.mjs → chunk-KFTGPFRD.mjs} +1 -1
  37. package/dist/chunk-KFTGPFRD.mjs.map +1 -0
  38. package/dist/{chunk-L2PE36GQ.mjs → chunk-PZXBQKCH.mjs} +15 -6
  39. package/dist/chunk-PZXBQKCH.mjs.map +1 -0
  40. package/dist/{chunk-UXUAWNO5.mjs → chunk-RIXKJPGI.mjs} +117 -55
  41. package/dist/chunk-RIXKJPGI.mjs.map +1 -0
  42. package/dist/{chunk-PNFQQSRA.mjs → chunk-T2M5QANG.mjs} +143 -41
  43. package/dist/chunk-T2M5QANG.mjs.map +1 -0
  44. package/dist/{chunk-WDU6QXNK.mjs → chunk-UCYWGN2P.mjs} +1 -1
  45. package/dist/chunk-UCYWGN2P.mjs.map +1 -0
  46. package/dist/{chunk-65A7QIKI.mjs → chunk-UMVLB3PN.mjs} +3 -3
  47. package/dist/chunk-UMVLB3PN.mjs.map +1 -0
  48. package/dist/{chunk-ARCGE2VT.mjs → chunk-VFDBC3W7.mjs} +2 -2
  49. package/dist/{chunk-ARCGE2VT.mjs.map → chunk-VFDBC3W7.mjs.map} +1 -1
  50. package/dist/{chunk-VY2UYN5R.mjs → chunk-VPCFICID.mjs} +82 -3
  51. package/dist/chunk-VPCFICID.mjs.map +1 -0
  52. package/dist/{chunk-H3TE3LOV.mjs → chunk-XMFTIVJH.mjs} +2 -2
  53. package/dist/{chunk-UB5UOSHB.mjs → chunk-ZVMV3THA.mjs} +71 -2
  54. package/dist/chunk-ZVMV3THA.mjs.map +1 -0
  55. package/dist/chunk-recovery-lnQFzcQP.d.mts +26 -0
  56. package/dist/chunk-recovery-lnQFzcQP.d.ts +26 -0
  57. package/dist/client-BT1mFQas.d.mts +447 -0
  58. package/dist/client-Nn0q4eO4.d.ts +447 -0
  59. package/dist/client-cache-CIlyBlmx.d.ts +6 -0
  60. package/dist/client-cache-D-EZ7XVW.d.mts +6 -0
  61. package/dist/client-plugins-278AvYHE.d.mts +2021 -0
  62. package/dist/client-plugins-CTQAkr7R.d.ts +2021 -0
  63. package/dist/client-plugins.d.mts +24 -0
  64. package/dist/client-plugins.d.ts +24 -0
  65. package/dist/client.cjs.map +1 -1
  66. package/dist/client.d.mts +452 -0
  67. package/dist/client.d.ts +452 -0
  68. package/dist/client.mjs +3 -3
  69. package/dist/config.d.mts +31 -0
  70. package/dist/config.d.ts +31 -0
  71. package/dist/cron.d.mts +78 -0
  72. package/dist/cron.d.ts +78 -0
  73. package/dist/deferred.d.mts +42 -0
  74. package/dist/deferred.d.ts +42 -0
  75. package/dist/deployment.cjs +12 -0
  76. package/dist/deployment.cjs.map +1 -1
  77. package/dist/deployment.d.mts +36 -0
  78. package/dist/deployment.d.ts +36 -0
  79. package/dist/deployment.mjs +3 -1
  80. package/dist/{devtools-GAZ7F3KL.mjs → devtools-K2ERKGNI.mjs} +5 -5
  81. package/dist/docs.cjs.map +1 -1
  82. package/dist/docs.d.mts +80 -0
  83. package/dist/docs.d.ts +80 -0
  84. package/dist/docs.mjs +5 -5
  85. package/dist/env-types.d.mts +12 -0
  86. package/dist/env-types.d.ts +12 -0
  87. package/dist/env.d.mts +45 -0
  88. package/dist/env.d.ts +45 -0
  89. package/dist/environment/vite.d.mts +22 -0
  90. package/dist/environment/vite.d.ts +22 -0
  91. package/dist/environment.d.mts +18 -0
  92. package/dist/environment.d.ts +18 -0
  93. package/dist/font.d.mts +95 -0
  94. package/dist/font.d.ts +95 -0
  95. package/dist/headers.d.mts +22 -0
  96. package/dist/headers.d.ts +22 -0
  97. package/dist/i18n/client.d.mts +32 -0
  98. package/dist/i18n/client.d.ts +32 -0
  99. package/dist/i18n/index.d.mts +20 -0
  100. package/dist/i18n/index.d.ts +20 -0
  101. package/dist/i18n/server.d.mts +30 -0
  102. package/dist/i18n/server.d.ts +30 -0
  103. package/dist/image/server.d.mts +37 -0
  104. package/dist/image/server.d.ts +37 -0
  105. package/dist/image/sharp.d.mts +7 -0
  106. package/dist/image/sharp.d.ts +7 -0
  107. package/dist/image-config-Duob7wER.d.mts +50 -0
  108. package/dist/image-config-Duob7wER.d.ts +50 -0
  109. package/dist/image.d.mts +39 -0
  110. package/dist/image.d.ts +39 -0
  111. package/dist/index.cjs +598 -109
  112. package/dist/index.cjs.map +1 -1
  113. package/dist/index.d.mts +477 -0
  114. package/dist/index.d.ts +477 -0
  115. package/dist/index.mjs +45 -29
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/integration-api-CHT2OKAf.d.mts +93 -0
  118. package/dist/integration-api-CHT2OKAf.d.ts +93 -0
  119. package/dist/integrations.d.mts +24 -0
  120. package/dist/integrations.d.ts +24 -0
  121. package/dist/internal/build-runtime.cjs +438 -176
  122. package/dist/internal/build-runtime.cjs.map +1 -1
  123. package/dist/internal/build-runtime.d.mts +41 -0
  124. package/dist/internal/build-runtime.d.ts +41 -0
  125. package/dist/internal/build-runtime.mjs +13 -13
  126. package/dist/internal/client-runtime.d.mts +17 -0
  127. package/dist/internal/client-runtime.d.ts +17 -0
  128. package/dist/internal/config-runtime.cjs +140 -1
  129. package/dist/internal/config-runtime.cjs.map +1 -1
  130. package/dist/internal/config-runtime.d.mts +41 -0
  131. package/dist/internal/config-runtime.d.ts +41 -0
  132. package/dist/internal/config-runtime.mjs +4 -4
  133. package/dist/internal/metadata-image-runtime.d.mts +25 -0
  134. package/dist/internal/metadata-image-runtime.d.ts +25 -0
  135. package/dist/internal/production-node-env.d.mts +12 -0
  136. package/dist/internal/production-node-env.d.ts +12 -0
  137. package/dist/internal/production-runtime.d.mts +44 -0
  138. package/dist/internal/production-runtime.d.ts +44 -0
  139. package/dist/island-CfGru1MO.d.mts +9 -0
  140. package/dist/island-CfGru1MO.d.ts +9 -0
  141. package/dist/markdown.d.mts +60 -0
  142. package/dist/markdown.d.ts +60 -0
  143. package/dist/metadata-DmCudMw_.d.mts +22 -0
  144. package/dist/metadata-xghtOlbR.d.ts +22 -0
  145. package/dist/middleware.cjs +116 -98
  146. package/dist/middleware.cjs.map +1 -1
  147. package/dist/middleware.d.mts +171 -0
  148. package/dist/middleware.d.ts +171 -0
  149. package/dist/middleware.mjs +5 -2
  150. package/dist/navigation-errors-Dvwpzaer.d.mts +13 -0
  151. package/dist/navigation-errors-Dvwpzaer.d.ts +13 -0
  152. package/dist/navigation.cjs.map +1 -1
  153. package/dist/navigation.d.mts +14 -0
  154. package/dist/navigation.d.ts +14 -0
  155. package/dist/navigation.mjs +3 -3
  156. package/dist/observability.d.mts +335 -0
  157. package/dist/observability.d.ts +335 -0
  158. package/dist/params-BALtrRim.d.ts +15 -0
  159. package/dist/params-ry-lxqmy.d.mts +15 -0
  160. package/dist/plugin-BJDf43dc.d.mts +165 -0
  161. package/dist/plugin-BJDf43dc.d.ts +165 -0
  162. package/dist/plugin.cjs +247 -28
  163. package/dist/plugin.cjs.map +1 -1
  164. package/dist/plugin.d.mts +24 -0
  165. package/dist/plugin.d.ts +24 -0
  166. package/dist/plugin.mjs +10 -10
  167. package/dist/production-runtime-BLxSv9cU.d.ts +79 -0
  168. package/dist/production-runtime-DFN2_RXq.d.mts +79 -0
  169. package/dist/query/client.d.mts +61 -0
  170. package/dist/query/client.d.ts +61 -0
  171. package/dist/query/index.d.mts +90 -0
  172. package/dist/query/index.d.ts +90 -0
  173. package/dist/query/parsers.d.mts +25 -0
  174. package/dist/query/parsers.d.ts +25 -0
  175. package/dist/query/server.d.mts +55 -0
  176. package/dist/query/server.d.ts +55 -0
  177. package/dist/request-Cq5d6qmE.d.mts +6 -0
  178. package/dist/request-LoxDW3lp.d.ts +6 -0
  179. package/dist/request.d.mts +25 -0
  180. package/dist/request.d.ts +25 -0
  181. package/dist/resolver-DJqjLMg_.d.mts +14 -0
  182. package/dist/resolver-IH4RmPEl.d.ts +14 -0
  183. package/dist/route-runtime-DoOHzCAD.d.mts +38 -0
  184. package/dist/route-runtime-DoOHzCAD.d.ts +38 -0
  185. package/dist/router.d.mts +36 -0
  186. package/dist/router.d.ts +36 -0
  187. package/dist/routes.d.mts +226 -0
  188. package/dist/routes.d.ts +226 -0
  189. package/dist/runtime-BA9TOSu1.d.mts +231 -0
  190. package/dist/runtime-Cxpq6xZN.d.mts +27 -0
  191. package/dist/runtime-DTAQ2HDv.d.ts +231 -0
  192. package/dist/runtime-bv63eUiO.d.ts +27 -0
  193. package/dist/server-action-security.cjs +23 -1
  194. package/dist/server-action-security.cjs.map +1 -1
  195. package/dist/server-action-security.d.mts +45 -0
  196. package/dist/server-action-security.d.ts +45 -0
  197. package/dist/server-action-security.mjs +1 -1
  198. package/dist/server-fn-client.cjs.map +1 -1
  199. package/dist/server-fn-client.d.mts +33 -0
  200. package/dist/server-fn-client.d.ts +33 -0
  201. package/dist/server-fn-client.mjs +1 -1
  202. package/dist/server-fn-error-DDh14a0V.d.mts +26 -0
  203. package/dist/server-fn-error-DDh14a0V.d.ts +26 -0
  204. package/dist/server-fn.cjs +140 -3
  205. package/dist/server-fn.cjs.map +1 -1
  206. package/dist/server-fn.d.mts +121 -0
  207. package/dist/server-fn.d.ts +121 -0
  208. package/dist/server-fn.mjs +14 -3
  209. package/dist/server-plugins.d.mts +57 -0
  210. package/dist/server-plugins.d.ts +57 -0
  211. package/dist/server-query-client.d.mts +51 -0
  212. package/dist/server-query-client.d.ts +51 -0
  213. package/dist/server-query.cjs +99 -1
  214. package/dist/server-query.cjs.map +1 -1
  215. package/dist/server-query.d.mts +37 -0
  216. package/dist/server-query.d.ts +37 -0
  217. package/dist/server-query.mjs +3 -3
  218. package/dist/server.cjs +403 -33
  219. package/dist/server.cjs.map +1 -1
  220. package/dist/server.d.mts +51 -0
  221. package/dist/server.d.ts +51 -0
  222. package/dist/server.mjs +14 -14
  223. package/dist/storage.d.mts +52 -0
  224. package/dist/storage.d.ts +52 -0
  225. package/dist/testing.cjs.map +1 -1
  226. package/dist/testing.d.mts +103 -0
  227. package/dist/testing.d.ts +103 -0
  228. package/dist/testing.mjs +3 -3
  229. package/dist/transport-BmbGTXA5.d.mts +49 -0
  230. package/dist/transport-BmbGTXA5.d.ts +49 -0
  231. package/dist/types-BMxWr97v.d.mts +81 -0
  232. package/dist/types-BMxWr97v.d.ts +81 -0
  233. package/dist/types-D1A6-XvH.d.mts +73 -0
  234. package/dist/types-D1A6-XvH.d.ts +73 -0
  235. package/dist/types-DTzm4TCl.d.mts +78 -0
  236. package/dist/types-DTzm4TCl.d.ts +78 -0
  237. package/dist/utils-B6GaYNJL.d.ts +23 -0
  238. package/dist/utils-CKSHiip6.d.mts +23 -0
  239. package/dist/version.cjs +1 -1
  240. package/dist/version.cjs.map +1 -1
  241. package/dist/version.d.mts +3 -0
  242. package/dist/version.d.ts +3 -0
  243. package/dist/version.mjs +1 -1
  244. package/dist/vite.cjs +255 -30
  245. package/dist/vite.cjs.map +1 -1
  246. package/dist/vite.d.mts +24 -0
  247. package/dist/vite.d.ts +24 -0
  248. package/dist/vite.mjs +10 -10
  249. package/dist/workflows.d.mts +110 -0
  250. package/dist/workflows.d.ts +110 -0
  251. package/package.json +1 -1
  252. package/types/middleware.d.ts +36 -11
  253. package/dist/chunk-32W4QEJP.mjs.map +0 -1
  254. package/dist/chunk-65A7QIKI.mjs.map +0 -1
  255. package/dist/chunk-B232I2GP.mjs.map +0 -1
  256. package/dist/chunk-I4CUBGVF.mjs +0 -93
  257. package/dist/chunk-I4CUBGVF.mjs.map +0 -1
  258. package/dist/chunk-L2PE36GQ.mjs.map +0 -1
  259. package/dist/chunk-PFE6GMNE.mjs.map +0 -1
  260. package/dist/chunk-PNFQQSRA.mjs.map +0 -1
  261. package/dist/chunk-UB5UOSHB.mjs.map +0 -1
  262. package/dist/chunk-UXUAWNO5.mjs.map +0 -1
  263. package/dist/chunk-VUL55IAX.mjs.map +0 -1
  264. package/dist/chunk-VY2UYN5R.mjs.map +0 -1
  265. package/dist/chunk-WDU6QXNK.mjs.map +0 -1
  266. /package/dist/{chunk-JDEOUK5V.mjs.map → chunk-6YXKHAFU.mjs.map} +0 -0
  267. /package/dist/{chunk-Z5CQMP54.mjs.map → chunk-ARRYKOI5.mjs.map} +0 -0
  268. /package/dist/{chunk-KLA67WKG.mjs.map → chunk-B3FFOIWS.mjs.map} +0 -0
  269. /package/dist/{chunk-OPHK6OJN.mjs.map → chunk-JAEAE27K.mjs.map} +0 -0
  270. /package/dist/{chunk-H3TE3LOV.mjs.map → chunk-XMFTIVJH.mjs.map} +0 -0
  271. /package/dist/{devtools-GAZ7F3KL.mjs.map → devtools-K2ERKGNI.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server-fn-client.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { ServerFn } from \"./server-fn\";\n\nexport type ServerFnActionStatus = \"idle\" | \"pending\" | \"success\" | \"error\";\n\nexport type ServerFnSubmit<TInput, TResult> = [unknown] extends [TInput]\n ? (input?: TInput | FormData) => Promise<TResult>\n : (input: TInput | FormData) => Promise<TResult>;\n\nexport type ServerFnOptimisticContext<TInput, TResult> = {\n input: TInput | FormData | undefined;\n formData?: FormData;\n current: TResult | null;\n};\n\nexport type UseServerFnOptions<TResult, TError extends Error = Error, TInput = unknown> = {\n initialResult?: TResult | null;\n resetOnSubmit?: boolean;\n throwOnFormError?: boolean;\n optimistic?: (context: ServerFnOptimisticContext<TInput, TResult>) => TResult | null | undefined;\n rollbackOnError?: boolean;\n onSuccess?: (result: TResult) => void;\n onError?: (error: TError) => void;\n onSettled?: (result: TResult | null, error: TError | null) => void;\n};\n\nexport type UseServerFnReturn<TInput, TResult, TError extends Error = Error> = {\n pending: boolean;\n status: ServerFnActionStatus;\n result: TResult | null;\n error: TError | null;\n submit: ServerFnSubmit<TInput, TResult>;\n formAction: (formData: FormData) => Promise<void>;\n reset: () => void;\n};\n\ntype ServerFnActionState<TResult, TError extends Error> = {\n pendingCount: number;\n status: ServerFnActionStatus;\n result: TResult | null;\n error: TError | null;\n};\n\ntype ServerFnActionCallbacks<TResult, TError extends Error> = Pick<\n UseServerFnOptions<TResult, TError, unknown>,\n \"onError\" | \"onSettled\" | \"onSuccess\" | \"throwOnFormError\"\n>;\n\nexport function useServerFn<TInput, TResult, TError extends Error = Error>(\n serverFn: ServerFn<TInput, TResult, TError>,\n options: UseServerFnOptions<TResult, TError, TInput> = {},\n): UseServerFnReturn<TInput, TResult, TError> {\n const { initialResult = null, resetOnSubmit = true } = options;\n const callbacksRef = useRef<ServerFnActionCallbacks<TResult, TError>>({});\n const requestIdRef = useRef(0);\n const initialState: ServerFnActionState<TResult, TError> = {\n pendingCount: 0,\n status: \"idle\",\n result: initialResult,\n error: null,\n };\n const stateRef = useRef<ServerFnActionState<TResult, TError>>(initialState);\n const [state, setState] = useState<ServerFnActionState<TResult, TError>>(initialState);\n const setActionState = useCallback(\n (\n value:\n | ServerFnActionState<TResult, TError>\n | ((current: ServerFnActionState<TResult, TError>) => ServerFnActionState<TResult, TError>),\n ) => {\n setState((current) => {\n const next = typeof value === \"function\" ? value(current) : value;\n stateRef.current = next;\n return next;\n });\n },\n [],\n );\n\n callbacksRef.current = {\n onError: options.onError,\n onSettled: options.onSettled,\n onSuccess: options.onSuccess,\n throwOnFormError: options.throwOnFormError,\n };\n\n const submit = useCallback(\n async (input?: TInput | FormData) => {\n const requestId = ++requestIdRef.current;\n const formData = isFormData(input) ? input : undefined;\n const previousResult = stateRef.current.result;\n const optimisticResult = options.optimistic?.({\n input,\n formData,\n current: previousResult,\n });\n const hasOptimisticResult = optimisticResult !== undefined;\n\n setActionState((current) => ({\n pendingCount: current.pendingCount + 1,\n status: \"pending\",\n result: hasOptimisticResult ? optimisticResult : resetOnSubmit ? null : current.result,\n error: null,\n }));\n\n try {\n const result = await serverFn(input as TInput | FormData);\n const isLatestRequest = requestId === requestIdRef.current;\n\n setActionState((current) => {\n const pendingCount = Math.max(0, current.pendingCount - 1);\n\n if (!isLatestRequest) {\n return {\n ...current,\n pendingCount,\n status: pendingCount > 0 ? \"pending\" : current.status,\n };\n }\n\n return {\n pendingCount,\n status: pendingCount > 0 ? \"pending\" : \"success\",\n result,\n error: null,\n };\n });\n\n if (isLatestRequest) {\n callbacksRef.current.onSuccess?.(result);\n callbacksRef.current.onSettled?.(result, null);\n }\n\n return result;\n } catch (cause) {\n const error = normalizeServerFnError(cause) as TError;\n const isLatestRequest = requestId === requestIdRef.current;\n\n setActionState((current) => {\n const pendingCount = Math.max(0, current.pendingCount - 1);\n\n if (!isLatestRequest) {\n return {\n ...current,\n pendingCount,\n status: pendingCount > 0 ? \"pending\" : current.status,\n };\n }\n\n return {\n pendingCount,\n status: pendingCount > 0 ? \"pending\" : \"error\",\n result:\n hasOptimisticResult && options.rollbackOnError\n ? previousResult\n : resetOnSubmit\n ? null\n : current.result,\n error,\n };\n });\n\n if (isLatestRequest) {\n callbacksRef.current.onError?.(error);\n callbacksRef.current.onSettled?.(null, error);\n }\n\n throw error;\n }\n },\n [options.optimistic, options.rollbackOnError, resetOnSubmit, serverFn, setActionState],\n ) as ServerFnSubmit<TInput, TResult>;\n\n const formAction = useCallback(\n async (formData: FormData) => {\n try {\n await submit(formData as TInput | FormData);\n } catch (error) {\n if (callbacksRef.current.throwOnFormError) {\n throw error;\n }\n }\n },\n [submit],\n );\n\n const reset = useCallback(() => {\n requestIdRef.current += 1;\n setActionState({\n pendingCount: 0,\n status: \"idle\",\n result: initialResult,\n error: null,\n });\n }, [initialResult, setActionState]);\n\n return useMemo(\n () => ({\n pending: state.pendingCount > 0,\n status: state.status,\n result: state.result,\n error: state.error,\n submit,\n formAction,\n reset,\n }),\n [formAction, reset, state.error, state.pendingCount, state.result, state.status, submit],\n );\n}\n\nfunction normalizeServerFnError(error: unknown) {\n if (error instanceof Error) return error;\n\n const normalized = new Error(typeof error === \"string\" ? error : \"Server function failed\");\n (normalized as Error & { cause?: unknown }).cause = error;\n return normalized;\n}\n\nfunction isFormData(value: unknown): value is FormData {\n if (!value || typeof value !== \"object\") return false;\n\n if (typeof FormData !== \"undefined\" && value instanceof FormData) {\n return true;\n }\n\n return (\n Object.prototype.toString.call(value) === \"[object FormData]\" &&\n typeof (value as { entries?: unknown }).entries === \"function\"\n );\n}\n"],"mappings":"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","names":[]}
@@ -3,9 +3,11 @@ import {
3
3
  setEnv
4
4
  } from "./chunk-RQ633A5I.mjs";
5
5
  import {
6
+ getFarmSecurityHeader,
6
7
  resolveFarmAuthConfig,
7
- resolveFarmAuthIntegration
8
- } from "./chunk-I4CUBGVF.mjs";
8
+ resolveFarmAuthIntegration,
9
+ resolveFarmSecurityConfig
10
+ } from "./chunk-E257KFBU.mjs";
9
11
  import {
10
12
  resolveFarmDevtoolsConfig
11
13
  } from "./chunk-7MABZJIM.mjs";
@@ -26,7 +28,7 @@ import {
26
28
  } from "./chunk-GY2STC2S.mjs";
27
29
  import {
28
30
  resolveServerActionsConfig
29
- } from "./chunk-UB5UOSHB.mjs";
31
+ } from "./chunk-ZVMV3THA.mjs";
30
32
  import {
31
33
  resolveMdxConfig
32
34
  } from "./chunk-ZVWA4ZQ3.mjs";
@@ -47,7 +49,7 @@ import {
47
49
  } from "./chunk-FQYDHKKU.mjs";
48
50
  import {
49
51
  normalizeFarmDeploymentId
50
- } from "./chunk-B232I2GP.mjs";
52
+ } from "./chunk-3HIVDX7J.mjs";
51
53
  import {
52
54
  __name
53
55
  } from "./chunk-CGILA3WO.mjs";
@@ -336,6 +338,8 @@ async function resolveConfig(userConfig, mode) {
336
338
  const routeRules = normalizeRouteRules(userConfig.routeRules);
337
339
  const routeRuleRedirects = routeRulesToRedirects(routeRules);
338
340
  const routeRuleHeaders = routeRulesToHeaders(routeRules);
341
+ const security = resolveFarmSecurityConfig(userConfig.security);
342
+ const securityHeader = getFarmSecurityHeader(security);
339
343
  const deploy = resolveDeployConfig(userConfig);
340
344
  const root = userConfig.root || process.cwd();
341
345
  const srcDir = userConfig.srcDir || "src";
@@ -391,7 +395,11 @@ async function resolveConfig(userConfig, mode) {
391
395
  trailingSlash: userConfig.trailingSlash ?? false,
392
396
  redirects: /* @__PURE__ */ __name(() => [...redirects, ...routeRuleRedirects], "redirects"),
393
397
  rewrites: /* @__PURE__ */ __name(() => rewrites, "rewrites"),
394
- headers: /* @__PURE__ */ __name(() => [...headers, ...routeRuleHeaders], "headers"),
398
+ headers: /* @__PURE__ */ __name(() => [
399
+ ...headers,
400
+ ...routeRuleHeaders,
401
+ ...securityHeader ? [{ source: "/*", headers: [securityHeader] }] : []
402
+ ], "headers"),
395
403
  routeRules,
396
404
  images: resolveFarmImageConfig(userConfig.images),
397
405
  performance: resolveFarmPerformanceConfig(userConfig.performance),
@@ -410,6 +418,7 @@ async function resolveConfig(userConfig, mode) {
410
418
  notFound: userConfig.notFound || {},
411
419
  context: userConfig.context || (() => void 0),
412
420
  serverActions: resolveServerActionsConfig(userConfig.serverActions),
421
+ security,
413
422
  deploymentId,
414
423
  output: userConfig.output || "standalone",
415
424
  distDir: userConfig.distDir || ".farm",
@@ -484,4 +493,4 @@ export {
484
493
  resolveConfig,
485
494
  loadConfig
486
495
  };
487
- //# sourceMappingURL=chunk-L2PE36GQ.mjs.map
496
+ //# sourceMappingURL=chunk-PZXBQKCH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import type {\n FarmConfig as BaseFarmConfig,\n FarmMigrationCommand,\n FarmMigrationsConfig,\n FarmMigrationsUserConfig,\n ResolvedFarmMigrationsConfig,\n} from \"./types\";\nimport type { DocsConfig } from \"@farming-labs/docs\";\nimport type { FarmDocsResolvedConfig, FarmDocsUserConfig } from \"./docs/types\";\nimport type { FarmIntegrationsUserConfig } from \"./integrations\";\nimport type { FarmMarkdownResolvedConfig, FarmMarkdownUserConfig } from \"./markdown\";\nimport type { FarmObservabilityUserConfig } from \"./observability\";\nimport type { FarmMiddlewareConfig } from \"./middleware/types\";\nimport type { FarmPlugin } from \"./plugin\";\nimport type { FarmWorkflowsResolvedConfig, FarmWorkflowsUserConfig } from \"./workflows\";\nimport type { FarmCronResolvedConfig, FarmCronUserConfig } from \"./cron\";\nimport type { FarmEnvConfig, ResolvedFarmEnv } from \"./env\";\nimport type { UserConfig as ViteUserConfig } from \"vite\";\nimport { resolveIntegrationPlugins } from \"./integrations\";\nimport { resolveMarkdownConfig } from \"./markdown\";\nimport { resolveWorkflowsConfig } from \"./workflows\";\nimport { resolveCronConfig } from \"./cron\";\nimport { resolveEnv, setEnv } from \"./env\";\nimport {\n resolveMdxConfig,\n type FarmMdxResolvedConfig,\n type FarmMdxUserConfig,\n} from \"./app-markdown\";\nimport {\n normalizeRouteRules,\n routeRulesToHeaders,\n routeRulesToRedirects,\n type FarmRouteRules,\n} from \"./route-rules\";\nimport {\n resolveServerActionsConfig,\n type FarmServerActionsConfig,\n type ResolvedFarmServerActionsConfig,\n} from \"./server-action-security\";\nimport {\n loadFarmConfigFile,\n resolveFarmLayers,\n type FarmLayerEntry,\n type ResolvedFarmLayer,\n} from \"./layers\";\nimport path from \"path\";\nimport { normalizeFarmDeploymentId } from \"./deployment\";\nimport { resolveFarmDevtoolsConfig, type ResolvedFarmDevtoolsConfig } from \"./devtools-config\";\nimport {\n resolveFarmImageConfig,\n type FarmImageConfig,\n type ResolvedFarmImageConfig,\n} from \"./image-config\";\nimport { resolveFarmI18nConfig } from \"./i18n/config\";\nimport type { FarmI18nUserConfig, ResolvedFarmI18nConfig } from \"./i18n/types\";\nimport type { FarmCacheUserConfig } from \"./cache\";\nimport {\n resolveFarmAuthConfig,\n resolveFarmAuthIntegration,\n type FarmAuthUserConfig,\n type ResolvedFarmAuthConfig,\n} from \"./auth-config\";\nimport { resolveFarmPerformanceConfig, type ResolvedFarmPerformanceConfig } from \"./preload\";\nimport {\n getFarmSecurityHeader,\n resolveFarmSecurityConfig,\n type FarmCspConfig,\n type FarmCspDirectives,\n type FarmCspDirectiveValue,\n type FarmCspOptions,\n type FarmSecurityConfig,\n type ResolvedFarmCspConfig,\n type ResolvedFarmSecurityConfig,\n} from \"./security\";\n\nconst FARM_RESOLVED_CUSTOM_CONTEXT = Symbol.for(\"farm.resolvedCustomContext\");\n\nexport type {\n FarmDocsConfigInput,\n FarmDocsNavigationConfig,\n FarmDocsResolvedConfig,\n FarmDocsSidebarItem,\n FarmDocsUserConfig,\n} from \"./docs/types\";\nexport type {\n FarmMarkdownResolvedConfig,\n FarmMarkdownRouteInput,\n FarmMarkdownUserConfig,\n} from \"./markdown\";\nexport type { FarmMdxComponents, FarmMdxResolvedConfig, FarmMdxUserConfig } from \"./app-markdown\";\nexport type {\n FarmMigrationCommand,\n FarmMigrationsConfig,\n FarmMigrationsUserConfig,\n ResolvedFarmMigrationsConfig,\n} from \"./types\";\nexport type { FarmWorkflowsResolvedConfig, FarmWorkflowsUserConfig } from \"./workflows\";\nexport type { FarmCronJobConfig, FarmCronResolvedConfig, FarmCronUserConfig } from \"./cron\";\nexport type {\n FarmRouteRule,\n FarmRouteRuleCors,\n FarmRouteRuleRedirect,\n FarmRouteRuleRenderMode,\n FarmRouteRules,\n} from \"./route-rules\";\nexport type {\n FarmServerActionsConfig,\n ResolvedFarmServerActionsConfig,\n} from \"./server-action-security\";\nexport type { FarmLayerEntry, ResolvedFarmLayer } from \"./layers\";\nexport type {\n FarmDevtoolsConfig,\n FarmDevtoolsUserConfig,\n ResolvedFarmDevtoolsConfig,\n} from \"./devtools-config\";\nexport type {\n FarmPerformanceConfig,\n FarmPreloadMode,\n FarmPreloadUserConfig,\n ResolvedFarmPerformanceConfig,\n ResolvedFarmPreloadConfig,\n} from \"./preload\";\nexport type {\n FarmImageConfig,\n FarmImageFormat,\n FarmImageLocalPattern,\n FarmImageProvider,\n FarmImageRemotePattern,\n ResolvedFarmImageConfig,\n} from \"./image-config\";\nexport type {\n FarmI18nCookieConfig,\n FarmI18nDetectionSignal,\n FarmI18nDirection,\n FarmI18nRouting,\n FarmI18nUserConfig,\n ResolvedFarmI18nConfig,\n} from \"./i18n/types\";\nexport type {\n FarmAuthConfig,\n FarmAuthDatabaseConfig,\n FarmAuthEmailAndPasswordConfig,\n FarmAuthSessionConfig,\n FarmAuthUserConfig,\n ResolvedFarmAuthConfig,\n} from \"./auth-config\";\nexport type {\n FarmCspConfig,\n FarmCspDirectives,\n FarmCspDirectiveValue,\n FarmCspOptions,\n FarmSecurityConfig,\n ResolvedFarmCspConfig,\n ResolvedFarmSecurityConfig,\n} from \"./security\";\n\nexport interface RedirectConfig {\n source: string;\n destination: string;\n permanent?: boolean;\n statusCode?: number;\n}\n\nexport interface HeaderConfig {\n source: string;\n headers: Array<{\n key: string;\n value: string;\n }>;\n}\n\nexport interface RewriteConfig {\n source: string;\n destination: string;\n}\n\n/** @deprecated Use FarmImageConfig. */\nexport type ImageConfig = FarmImageConfig;\n\n/** @deprecated Use FarmI18nUserConfig. */\nexport type I18nConfig = FarmI18nUserConfig;\n\nexport interface OpenAPIConfig {\n enabled?: boolean;\n route?: string;\n title?: string;\n description?: string;\n version?: string;\n servers?: Array<{\n url: string;\n description?: string;\n }>;\n contact?: {\n name?: string;\n email?: string;\n url?: string;\n };\n license?: {\n name: string;\n url?: string;\n };\n}\n\nexport type MiddlewareConfig = FarmMiddlewareConfig;\n\nexport interface NotFoundConfig {\n /** Path to a custom 404 page component (e.g., \"./src/app/not-found.tsx\") */\n component?: string;\n}\n\nexport type FarmDeployTarget = \"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | string;\n\nexport interface FarmDeployConfig {\n /**\n * Deployment platform. When present, Farm picks the matching Nitro preset and\n * output directory unless explicitly overridden.\n */\n target?: FarmDeployTarget;\n /** Nitro preset override. Usually inferred from target. */\n preset?: BaseFarmConfig[\"preset\"];\n /** Deployable output directory, relative to project root unless absolute. */\n outputDir?: string;\n /** Alias for outputDir for terser config. */\n output?: string;\n /** Cloudflare Pages project name used by `farm deploy --cloudflare`. */\n projectName?: string;\n vercel?: {\n outputDirectory?: string;\n buildCommand?: string;\n installCommand?: string;\n framework?: string | null;\n };\n cloudflare?: {\n outputDir?: string;\n projectName?: string;\n };\n netlify?: {\n outputDir?: string;\n site?: string;\n };\n}\n\nexport interface ResolvedFarmDeployConfig extends Omit<FarmDeployConfig, \"output\"> {\n target?: FarmDeployTarget;\n preset: BaseFarmConfig[\"preset\"];\n outputDir: string;\n}\n\nexport interface FarmUserConfig extends Omit<BaseFarmConfig, \"vite\" | \"docs\" | \"env\" | \"layers\"> {\n /** Reusable Farm directories or installed packages, applied from left to right. */\n extends?: readonly FarmLayerEntry[];\n plugins?: FarmPlugin[];\n integrations?: FarmIntegrationsUserConfig;\n /**\n * Farm-native authentication. `true` enables email/password auth with\n * server helpers from `@farm.js/auth/server` and React APIs from\n * `@farm.js/auth/client`.\n */\n auth?: FarmAuthUserConfig;\n /** Shared application data, route, ISR, and PPR cache. */\n cache?: FarmCacheUserConfig;\n migrations?: FarmMigrationsUserConfig;\n /** Map portable cron schedules to ordinary GET API routes. */\n cron?: FarmCronUserConfig | FarmCronResolvedConfig | false;\n workflows?: FarmWorkflowsUserConfig | boolean;\n preset?: BaseFarmConfig[\"preset\"];\n deploy?: FarmDeployConfig;\n docs?: FarmDocsUserConfig;\n md?: FarmMarkdownUserConfig | boolean;\n mdx?: FarmMdxUserConfig;\n observability?: FarmObservabilityUserConfig;\n\n trailingSlash?: boolean;\n redirects?: () => Promise<RedirectConfig[]> | RedirectConfig[];\n rewrites?: () => Promise<RewriteConfig[]> | RewriteConfig[];\n headers?: () => Promise<HeaderConfig[]> | HeaderConfig[];\n\n images?: ImageConfig;\n publicDir?: string;\n\n i18n?: FarmI18nUserConfig | false;\n openapi?: OpenAPIConfig;\n\n middleware?: FarmMiddlewareConfig;\n routeRules?: FarmRouteRules;\n context?: BaseFarmConfig[\"context\"];\n serverActions?: FarmServerActionsConfig;\n /** Build identifier used to detect and recover from deployment version skew. */\n deploymentId?: string;\n\n notFound?: NotFoundConfig;\n\n output?: \"standalone\" | \"static\" | \"export\";\n distDir?: string;\n generateBuildId?: () => string | Promise<string>;\n compress?: boolean;\n\n devIndicators?: {\n buildActivity?: boolean;\n buildActivityPosition?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n };\n\n serverRuntimeConfig?: Record<string, any>;\n publicRuntimeConfig?: Record<string, any>;\n\n env?: FarmEnvConfig<any, any>;\n\n typescript?: {\n tsconfigPath?: string;\n ignoreBuildErrors?: boolean;\n };\n\n vite?: ViteUserConfig | ((config: ViteUserConfig) => ViteUserConfig);\n\n [key: string]: any;\n}\n\nexport interface ResolvedFarmConfig extends Required<\n Omit<\n FarmUserConfig,\n | \"extends\"\n | \"plugins\"\n | \"vite\"\n | \"deploy\"\n | \"docs\"\n | \"md\"\n | \"mdx\"\n | \"migrations\"\n | \"cron\"\n | \"workflows\"\n | \"env\"\n | \"serverActions\"\n | \"devtools\"\n | \"images\"\n | \"i18n\"\n | \"auth\"\n | \"performance\"\n | \"security\"\n >\n> {\n /** @internal Tracks whether `context` came from user/layer config instead of the default noop. */\n [FARM_RESOLVED_CUSTOM_CONTEXT]?: boolean;\n extends: readonly FarmLayerEntry[];\n layers: ResolvedFarmLayer[];\n plugins: FarmPlugin[];\n vite: ViteUserConfig;\n deploy: ResolvedFarmDeployConfig;\n docs: FarmDocsResolvedConfig;\n md: FarmMarkdownResolvedConfig;\n mdx: FarmMdxResolvedConfig;\n migrations: ResolvedFarmMigrationsConfig;\n cron: FarmCronResolvedConfig;\n workflows: FarmWorkflowsResolvedConfig;\n env: ResolvedFarmEnv;\n serverActions: ResolvedFarmServerActionsConfig;\n devtools: ResolvedFarmDevtoolsConfig;\n images: ResolvedFarmImageConfig;\n i18n: ResolvedFarmI18nConfig;\n auth: ResolvedFarmAuthConfig;\n performance: ResolvedFarmPerformanceConfig;\n security: ResolvedFarmSecurityConfig;\n routeRules: FarmRouteRules;\n}\n\nexport function hasCustomFarmRouteContext(config: ResolvedFarmConfig): boolean {\n return config[FARM_RESOLVED_CUSTOM_CONTEXT] === true;\n}\n\nexport type FarmLayerConfig = Omit<\n FarmUserConfig,\n | \"root\"\n | \"outDir\"\n | \"distDir\"\n | \"deploy\"\n | \"output\"\n | \"preset\"\n | \"publicDir\"\n | \"generateBuildId\"\n | \"deploymentId\"\n>;\n\nexport { defineConfig, defineFarmConfig } from \"./config-entry\";\n\nexport function normalizeDeployTarget(target?: FarmDeployTarget): FarmDeployTarget | undefined {\n if (!target) return undefined;\n if (target === \"cloudflare-pages\" || target === \"cloudflare_pages\") return \"cloudflare\";\n if (target === \"node-server\" || target === \"nitro\") return \"node\";\n return target;\n}\n\nexport function getPresetForDeployTarget(\n target?: FarmDeployTarget,\n): BaseFarmConfig[\"preset\"] | undefined {\n switch (normalizeDeployTarget(target)) {\n case \"vercel\":\n return \"vercel\";\n case \"cloudflare\":\n return \"cloudflare-pages\";\n case \"netlify\":\n return \"netlify\";\n case \"node\":\n return \"node-server\";\n default:\n return undefined;\n }\n}\n\nexport function getDeployTargetForPreset(preset?: string): FarmDeployTarget | undefined {\n if (!preset) return undefined;\n if (preset === \"vercel\" || preset === \"vercel-edge\") return \"vercel\";\n if (preset === \"cloudflare\" || preset === \"cloudflare-pages\" || preset === \"cloudflare-module\") {\n return \"cloudflare\";\n }\n if (preset === \"netlify\" || preset === \"netlify-edge\") return \"netlify\";\n if (preset === \"node-server\") return \"node\";\n return undefined;\n}\n\nexport function getDefaultDeployOutputDir(\n target: FarmDeployTarget | undefined,\n preset: string | undefined,\n distDir: string,\n): string {\n const normalizedTarget = normalizeDeployTarget(target) || getDeployTargetForPreset(preset);\n if (normalizedTarget === \"vercel\") return \".vercel/output\";\n return `${distDir}/.output`;\n}\n\nexport function resolveDeployOutputPath(root: string, outputDir: string): string {\n return path.isAbsolute(outputDir) ? outputDir : path.join(root, outputDir);\n}\n\nexport function resolveDeployConfig(\n config: Pick<FarmUserConfig, \"deploy\" | \"preset\" | \"distDir\">,\n overrides: {\n target?: FarmDeployTarget;\n preset?: BaseFarmConfig[\"preset\"];\n outputDir?: string;\n } = {},\n): ResolvedFarmDeployConfig {\n const deploy = config.deploy || {};\n const distDir = config.distDir || \".farm\";\n const target = normalizeDeployTarget(overrides.target || deploy.target);\n const preset =\n overrides.preset ||\n deploy.preset ||\n config.preset ||\n getPresetForDeployTarget(target) ||\n \"node-server\";\n const resolvedTarget = target || getDeployTargetForPreset(preset);\n const platformOutput =\n resolvedTarget === \"vercel\"\n ? deploy.vercel?.outputDirectory\n : resolvedTarget === \"cloudflare\"\n ? deploy.cloudflare?.outputDir\n : resolvedTarget === \"netlify\"\n ? deploy.netlify?.outputDir\n : undefined;\n const outputDir =\n overrides.outputDir ||\n deploy.outputDir ||\n deploy.output ||\n platformOutput ||\n getDefaultDeployOutputDir(resolvedTarget, preset, distDir);\n\n return {\n ...deploy,\n target: resolvedTarget,\n preset,\n outputDir,\n };\n}\n\nexport function resolveMigrationsConfig(\n migrations: FarmMigrationsUserConfig | undefined,\n): ResolvedFarmMigrationsConfig {\n if (!migrations) return { commands: [] };\n if (Array.isArray(migrations)) return { commands: migrations };\n return { commands: migrations.commands || [] };\n}\n\nexport const DOCS_CONFIG_FILENAMES = [\n \"docs.config.ts\",\n \"docs.config.tsx\",\n \"docs.config.mts\",\n \"docs.config.cts\",\n \"docs.config.js\",\n \"docs.config.jsx\",\n \"docs.config.mjs\",\n \"docs.config.cjs\",\n \"docs.json\",\n];\n\nfunction normalizeDocsRoute(value: string | undefined, fallback = \"/docs\"): string {\n const raw = (value || fallback).trim();\n if (!raw || raw === \"/\") return \"/\";\n const normalized = raw\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+/g, \"/\")\n .replace(/^\\/?/, \"/\")\n .replace(/\\/+$/, \"\");\n return normalized || \"/\";\n}\n\nfunction docsRouteToEntry(route: string): string {\n const entry = route.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n return entry || \"docs\";\n}\n\nfunction normalizeDocsContentDir(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const normalized = value.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n return normalized || undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction cloneSerializable(value: unknown, seen = new WeakSet<object>()): any {\n if (value === null) return null;\n\n const valueType = typeof value;\n if (valueType === \"string\" || valueType === \"number\" || valueType === \"boolean\") {\n return value;\n }\n if (valueType === \"undefined\" || valueType === \"function\" || valueType === \"symbol\") {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value.map((item) => cloneSerializable(item, seen)).filter((item) => item !== undefined);\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (isRecord(value)) {\n if (seen.has(value)) return undefined;\n seen.add(value);\n\n const output: Record<string, any> = {};\n for (const [key, nestedValue] of Object.entries(value)) {\n const clonedValue = cloneSerializable(nestedValue, seen);\n if (clonedValue !== undefined) {\n output[key] = clonedValue;\n }\n }\n return output;\n }\n\n return undefined;\n}\n\nfunction sanitizeDocsConfig(config: Partial<DocsConfig>): Partial<DocsConfig> {\n return cloneSerializable(config) || {};\n}\n\nexport async function findDocsConfigPath(\n rootDir: string,\n configPath?: string,\n): Promise<string | undefined> {\n const { existsSync } = await import(\"fs\");\n const root = path.resolve(rootDir || process.cwd());\n\n if (configPath) {\n const resolvedPath = path.isAbsolute(configPath) ? configPath : path.join(root, configPath);\n if (!existsSync(resolvedPath)) {\n throw new Error(`Could not find docs config at ${configPath}.`);\n }\n return path.resolve(resolvedPath);\n }\n\n for (const filename of DOCS_CONFIG_FILENAMES) {\n const resolvedPath = path.join(root, filename);\n if (existsSync(resolvedPath)) {\n return resolvedPath;\n }\n }\n\n return undefined;\n}\n\nexport async function loadDocsConfig(\n rootDir: string,\n configPath?: string,\n): Promise<{ config: Partial<DocsConfig>; configPath: string } | undefined> {\n const fs = await import(\"fs/promises\");\n const { pathToFileURL } = await import(\"url\");\n const root = path.resolve(rootDir || process.cwd());\n const resolvedPath = await findDocsConfigPath(root, configPath);\n\n if (!resolvedPath) return undefined;\n\n try {\n if (resolvedPath.endsWith(\".json\")) {\n const content = await fs.readFile(resolvedPath, \"utf8\");\n return { config: JSON.parse(content), configPath: resolvedPath };\n }\n\n const { build } = await import(\"esbuild\");\n const configCacheDir = path.join(root, \".farm\", \".config-loader\");\n await fs.mkdir(configCacheDir, { recursive: true });\n const modulePath = path.join(\n configCacheDir,\n `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`,\n );\n\n await build({\n absWorkingDir: root,\n entryPoints: [resolvedPath],\n outfile: modulePath,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: `node${process.versions.node.split(\".\")[0]}`,\n packages: \"external\",\n jsx: \"automatic\",\n logLevel: \"silent\",\n sourcemap: \"inline\",\n });\n\n const moduleUrl = pathToFileURL(modulePath).href + `?t=${Date.now()}`;\n let importedConfig: any;\n\n try {\n importedConfig = await import(/* @vite-ignore */ moduleUrl);\n } finally {\n await fs.unlink(modulePath).catch(() => undefined);\n }\n\n return {\n config: importedConfig.default || importedConfig,\n configPath: resolvedPath,\n };\n } catch (error: any) {\n const relativePath = path.relative(root, resolvedPath) || resolvedPath;\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load docs config from ${relativePath}: ${message}`);\n }\n}\n\nexport async function resolveDocsConfig(\n userDocs: FarmDocsUserConfig | undefined,\n options: {\n root?: string;\n srcDir?: string;\n } = {},\n): Promise<FarmDocsResolvedConfig> {\n const root = options.root || process.cwd();\n\n if (userDocs === false) {\n return {\n enabled: false,\n entry: \"/docs\",\n config: { entry: \"docs\", docsPath: \"/docs\" },\n };\n }\n\n const docsOptions = isRecord(userDocs) ? userDocs : {};\n if (docsOptions.enabled === false) {\n return {\n enabled: false,\n entry: \"/docs\",\n config: { entry: \"docs\", docsPath: \"/docs\" },\n };\n }\n\n const loadedConfig = await loadDocsConfig(root, docsOptions.configPath);\n const hasExplicitDocsConfig = userDocs === true || isRecord(userDocs);\n\n if (!hasExplicitDocsConfig && !loadedConfig) {\n return {\n enabled: false,\n entry: \"/docs\",\n config: { entry: \"docs\", docsPath: \"/docs\" },\n };\n }\n\n const inlineDocsConfig = sanitizeDocsConfig(docsOptions.config || {});\n const directDocsConfig = sanitizeDocsConfig({\n ...docsOptions,\n enabled: undefined,\n config: undefined,\n configPath: undefined,\n } as Partial<DocsConfig>);\n const loadedDocsConfig = sanitizeDocsConfig(loadedConfig?.config || {});\n const mergedDocsConfig: Partial<DocsConfig> = {\n ...loadedDocsConfig,\n ...inlineDocsConfig,\n ...directDocsConfig,\n };\n\n const explicitRoute = typeof docsOptions.entry === \"string\" ? docsOptions.entry : undefined;\n const configuredDocsPath =\n typeof mergedDocsConfig.docsPath === \"string\" ? mergedDocsConfig.docsPath : undefined;\n const configuredEntry =\n typeof mergedDocsConfig.entry === \"string\" ? mergedDocsConfig.entry : undefined;\n const entryRoute = normalizeDocsRoute(\n configuredDocsPath || explicitRoute || (configuredEntry ? `/${configuredEntry}` : undefined),\n );\n const docsEntry =\n explicitRoute && explicitRoute.startsWith(\"/\")\n ? docsRouteToEntry(explicitRoute)\n : docsRouteToEntry(configuredEntry || entryRoute);\n const contentDir = normalizeDocsContentDir(docsOptions.contentDir || mergedDocsConfig.contentDir);\n\n return {\n enabled: true,\n entry: entryRoute,\n contentDir,\n configPath: loadedConfig?.configPath,\n config: {\n ...mergedDocsConfig,\n entry: docsEntry,\n docsPath: entryRoute,\n ...(contentDir ? { contentDir } : {}),\n },\n };\n}\n\nexport async function resolveConfig(\n userConfig: FarmUserConfig,\n mode: \"development\" | \"production\",\n): Promise<ResolvedFarmConfig> {\n const projectRoot = userConfig.root || process.cwd();\n const layerResolution = await resolveFarmLayers(userConfig, {\n root: projectRoot,\n mode,\n });\n userConfig = layerResolution.config;\n\n const redirects =\n typeof userConfig.redirects === \"function\"\n ? await userConfig.redirects()\n : userConfig.redirects || [];\n\n const rewrites =\n typeof userConfig.rewrites === \"function\"\n ? await userConfig.rewrites()\n : userConfig.rewrites || [];\n\n const headers =\n typeof userConfig.headers === \"function\"\n ? await userConfig.headers()\n : userConfig.headers || [];\n const routeRules = normalizeRouteRules(userConfig.routeRules);\n const routeRuleRedirects = routeRulesToRedirects(routeRules);\n const routeRuleHeaders = routeRulesToHeaders(routeRules);\n const security = resolveFarmSecurityConfig(userConfig.security);\n const securityHeader = getFarmSecurityHeader(security);\n\n const deploy = resolveDeployConfig(userConfig);\n const root = userConfig.root || process.cwd();\n const srcDir = userConfig.srcDir || \"src\";\n const docs = await resolveDocsConfig(userConfig.docs, { root, srcDir });\n const md = resolveMarkdownConfig(userConfig.md);\n const mdx = resolveMdxConfig(userConfig.mdx);\n const env = resolveEnv(userConfig.env, process.env);\n setEnv(env);\n const auth = resolveFarmAuthConfig(userConfig.auth);\n if (auth.enabled && userConfig.integrations?.auth) {\n throw new Error(\n \"Choose either the top-level `auth` config or `integrations.auth`; they cannot both own the auth route.\",\n );\n }\n const nativeAuthIntegration = await resolveFarmAuthIntegration(auth, {\n root,\n mode,\n });\n const integrations = nativeAuthIntegration\n ? { ...userConfig.integrations, auth: nativeAuthIntegration }\n : userConfig.integrations || {};\n const generateBuildId = userConfig.generateBuildId || (() => `build-${Date.now()}`);\n const deploymentId = normalizeFarmDeploymentId(\n userConfig.deploymentId ||\n process.env.FARM_DEPLOYMENT_ID ||\n process.env.VERCEL_GIT_COMMIT_SHA ||\n process.env.CF_PAGES_COMMIT_SHA ||\n (mode === \"production\" ? await generateBuildId() : \"development\"),\n );\n\n const resolved: ResolvedFarmConfig = {\n [FARM_RESOLVED_CUSTOM_CONTEXT]: typeof userConfig.context === \"function\",\n root,\n srcDir,\n extends: userConfig.extends || [],\n layers: layerResolution.layers,\n outDir: userConfig.outDir || \"dist\",\n basePath: userConfig.basePath || \"/\",\n preset: deploy.preset || \"node-server\",\n deploy,\n docs,\n md,\n mdx,\n migrations: resolveMigrationsConfig(userConfig.migrations),\n cron: resolveCronConfig(userConfig.cron),\n workflows: resolveWorkflowsConfig(userConfig.workflows),\n observability: userConfig.observability ?? false,\n devtools: resolveFarmDevtoolsConfig(userConfig.devtools, mode),\n storage: userConfig.storage || {},\n cache: userConfig.cache || {},\n auth,\n suppressLintOnLink: userConfig.suppressLintOnLink ?? false,\n experimental: {\n serverComponents: false,\n serverActions: false,\n ...userConfig.experimental,\n },\n plugins: [...resolveIntegrationPlugins(integrations), ...(userConfig.plugins || [])],\n integrations,\n trailingSlash: userConfig.trailingSlash ?? false,\n redirects: () => [...redirects, ...routeRuleRedirects],\n rewrites: () => rewrites,\n headers: () => [\n ...headers,\n ...routeRuleHeaders,\n ...(securityHeader ? [{ source: \"/*\", headers: [securityHeader] }] : []),\n ],\n routeRules,\n images: resolveFarmImageConfig(userConfig.images),\n performance: resolveFarmPerformanceConfig(userConfig.performance),\n publicDir: userConfig.publicDir || \"public\",\n i18n: resolveFarmI18nConfig(userConfig.i18n, { root, mode }),\n openapi: {\n enabled: false,\n route: \"/docs/reference\",\n title: \"API Documentation\",\n description: \"Auto-generated API documentation\",\n version: \"1.0.0\",\n servers: [{ url: \"http://localhost:3000\", description: \"Development server\" }],\n ...userConfig.openapi,\n },\n middleware: userConfig.middleware || {},\n notFound: userConfig.notFound || {},\n context: userConfig.context || (() => undefined),\n serverActions: resolveServerActionsConfig(userConfig.serverActions),\n security,\n deploymentId,\n output: userConfig.output || \"standalone\",\n distDir: userConfig.distDir || \".farm\",\n generateBuildId,\n compress: userConfig.compress ?? true,\n devIndicators: {\n buildActivity: true,\n buildActivityPosition: \"bottom-right\",\n ...userConfig.devIndicators,\n },\n serverRuntimeConfig: userConfig.serverRuntimeConfig || {},\n publicRuntimeConfig: userConfig.publicRuntimeConfig || {},\n env,\n typescript: {\n tsconfigPath: \"tsconfig.json\",\n ignoreBuildErrors: false,\n ...userConfig.typescript,\n },\n vite: typeof userConfig.vite === \"function\" ? userConfig.vite({}) : userConfig.vite || {},\n };\n\n return resolved;\n}\n\nexport async function loadConfig(\n rootDir?: string,\n configPath?: string,\n mode = process.env.NODE_ENV === \"production\" ? \"production\" : \"development\",\n loadEnvironment?: (typeof import(\"vite\"))[\"loadEnv\"],\n): Promise<FarmUserConfig | undefined> {\n const { existsSync } = await import(\"fs\");\n const loadEnv = loadEnvironment || (await import(\"vite\")).loadEnv;\n\n const root = rootDir || process.cwd();\n const loadedEnv = loadEnv(mode, root, \"\");\n for (const [key, value] of Object.entries(loadedEnv)) {\n if (process.env[key] === undefined) {\n process.env[key] = value;\n }\n }\n const searchPaths = [\n configPath,\n \"farm.config.ts\",\n \"farm.config.mts\",\n \"farm.config.js\",\n \"farm.config.mjs\",\n \"config.ts\",\n \"config.mts\",\n \"config.js\",\n \"config.mjs\",\n ].filter(Boolean) as string[];\n\n for (const relativePath of searchPaths) {\n try {\n // Use path.join for proper path construction\n const absolutePath = relativePath.startsWith(\"/\")\n ? relativePath\n : path.join(root, relativePath);\n\n // Normalize the path to handle any issues\n const normalizedPath = path.resolve(absolutePath);\n\n // Check if file exists before trying to import\n if (!existsSync(normalizedPath)) {\n continue;\n }\n\n const loadedConfig = await loadFarmConfigFile<FarmUserConfig>(normalizedPath, { root });\n return loadedConfig.root === undefined ? { ...loadedConfig, root } : loadedConfig;\n } catch (error: any) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load config from ${relativePath}: ${message}`);\n }\n }\n return undefined;\n}\n"],"mappings":"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","names":[]}
@@ -1,42 +1,74 @@
1
1
  import {
2
2
  MiddlewareManager
3
3
  } from "./chunk-MIUW47JX.mjs";
4
- import {
5
- getStorage
6
- } from "./chunk-T4QJQK76.mjs";
7
4
  import {
8
5
  __name
9
6
  } from "./chunk-CGILA3WO.mjs";
10
7
 
11
8
  // src/middleware/chain.ts
12
- function getRateLimitStorage() {
13
- return getStorage("ratelimit");
14
- }
15
- __name(getRateLimitStorage, "getRateLimitStorage");
16
- var defaultRateLimitStorage = {
17
- async get(key) {
18
- const storage = getRateLimitStorage();
19
- const value = await storage.getItem(key);
20
- return value ?? null;
21
- },
22
- async set(key, value, ttl) {
23
- const storage = getRateLimitStorage();
24
- await storage.setItem(key, value, ttl ? { ttl } : void 0);
25
- },
26
- async delete(key) {
27
- const storage = getRateLimitStorage();
28
- await storage.removeItem(key);
29
- },
30
- async ttl(key) {
31
- const storage = getRateLimitStorage();
32
- const record = await storage.getItem(key);
33
- if (!record || !record.resetAt) {
9
+ var DEFAULT_MEMORY_RATE_LIMIT_ENTRIES = 1e5;
10
+ var _UnsupportedRateLimitStorageError = class _UnsupportedRateLimitStorageError extends TypeError {
11
+ constructor() {
12
+ super(
13
+ "RateLimitStorage must implement atomic increment(key, windowMs). Legacy get/set adapters can lose increments under concurrency. Use memoryRateLimitStorage() for one process or redisRateLimitStorage() from @farm.js/cache-redis for production."
14
+ );
15
+ this.name = "UnsupportedRateLimitStorageError";
16
+ }
17
+ };
18
+ __name(_UnsupportedRateLimitStorageError, "UnsupportedRateLimitStorageError");
19
+ var UnsupportedRateLimitStorageError = _UnsupportedRateLimitStorageError;
20
+ function memoryRateLimitStorage(options = {}) {
21
+ const maxEntries = options.maxEntries ?? DEFAULT_MEMORY_RATE_LIMIT_ENTRIES;
22
+ if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {
23
+ throw new TypeError("memoryRateLimitStorage maxEntries must be a positive safe integer.");
24
+ }
25
+ const records = /* @__PURE__ */ new Map();
26
+ function read(key, now) {
27
+ const record = records.get(key);
28
+ if (!record) return null;
29
+ if (record.resetAt <= now) {
30
+ records.delete(key);
34
31
  return null;
35
32
  }
36
- const remainingMs = record.resetAt - Date.now();
37
- return remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
33
+ return record;
38
34
  }
39
- };
35
+ __name(read, "read");
36
+ function pruneExpired(now) {
37
+ for (const [key, record] of records) {
38
+ if (record.resetAt <= now) records.delete(key);
39
+ }
40
+ }
41
+ __name(pruneExpired, "pruneExpired");
42
+ return {
43
+ increment(key, windowMs) {
44
+ if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
45
+ throw new TypeError("Rate-limit windowMs must be a positive safe integer.");
46
+ }
47
+ const now = Date.now();
48
+ const current = read(key, now);
49
+ if (current) {
50
+ const next2 = { count: current.count + 1, resetAt: current.resetAt };
51
+ records.set(key, next2);
52
+ return next2;
53
+ }
54
+ if (records.size >= maxEntries) pruneExpired(now);
55
+ if (records.size >= maxEntries) {
56
+ throw new Error(
57
+ `Process-local rate-limit storage reached its ${maxEntries} active-key capacity. Configure a shared production adapter or increase maxEntries.`
58
+ );
59
+ }
60
+ const next = { count: 1, resetAt: now + windowMs };
61
+ records.set(key, next);
62
+ return next;
63
+ },
64
+ get(key) {
65
+ const record = read(key, Date.now());
66
+ return record ? { ...record } : null;
67
+ }
68
+ };
69
+ }
70
+ __name(memoryRateLimitStorage, "memoryRateLimitStorage");
71
+ var defaultRateLimitStorage = memoryRateLimitStorage();
40
72
  function parseTimeWindow(window) {
41
73
  const match = window.match(/^(\d+)(ms|s|m|h|d)$/);
42
74
  if (!match) throw new Error(`Invalid time window: ${window}`);
@@ -49,52 +81,73 @@ function parseTimeWindow(window) {
49
81
  h: 60 * 60 * 1e3,
50
82
  d: 24 * 60 * 60 * 1e3
51
83
  };
52
- return value * multipliers[unit];
84
+ const windowMs = value * multipliers[unit];
85
+ if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
86
+ throw new Error(`Invalid time window: ${window}`);
87
+ }
88
+ return windowMs;
53
89
  }
54
90
  __name(parseTimeWindow, "parseTimeWindow");
55
91
  function createRateLimitMiddleware(config) {
92
+ if (!Number.isSafeInteger(config.requests) || config.requests <= 0) {
93
+ throw new TypeError("Rate limit requests must be a positive safe integer.");
94
+ }
56
95
  const windowMs = parseTimeWindow(config.window);
57
96
  const storage = config.storage || defaultRateLimitStorage;
97
+ assertAtomicRateLimitStorage(storage);
58
98
  return async (ctx, next) => {
59
99
  const key = config.keyGenerator ? config.keyGenerator(ctx) : `${ctx.request.socket.remoteAddress}:${ctx.pathname}`;
100
+ const current = await storage.increment(key, windowMs);
101
+ assertRateLimitIncrementResult(current);
60
102
  const now = Date.now();
61
- const ttlSeconds = Math.ceil(windowMs / 1e3);
62
- const record = await storage.get(key);
63
- if (record && now > record.resetAt) {
64
- await storage.delete(key);
65
- }
66
- const current = await storage.get(key);
67
- if (!current) {
68
- await storage.set(
69
- key,
70
- {
71
- count: 1,
72
- resetAt: now + windowMs
73
- },
74
- ttlSeconds
75
- );
76
- return next();
77
- }
78
- if (current.count >= config.requests) {
103
+ const resetIn = Math.max(1, Math.ceil((current.resetAt - now) / 1e3));
104
+ const remaining = Math.max(0, config.requests - current.count);
105
+ setRateLimitHeaders(ctx, config.requests, remaining, resetIn, Math.ceil(windowMs / 1e3));
106
+ if (current.count > config.requests) {
107
+ setMiddlewareResponseHeader(ctx, "Retry-After", String(resetIn));
79
108
  if (config.onLimit) {
80
109
  const result = await config.onLimit(ctx);
81
- if (result) return;
110
+ if (result) return result;
82
111
  }
83
112
  ctx.json(
84
113
  {
85
114
  error: "Rate limit exceeded",
86
- retryAfter: Math.ceil((current.resetAt - now) / 1e3)
115
+ retryAfter: resetIn
87
116
  },
88
117
  429
89
118
  );
90
119
  return;
91
120
  }
92
- current.count++;
93
- await storage.set(key, current, ttlSeconds);
94
121
  return next();
95
122
  };
96
123
  }
97
124
  __name(createRateLimitMiddleware, "createRateLimitMiddleware");
125
+ function assertAtomicRateLimitStorage(storage) {
126
+ if (!storage || typeof storage.increment !== "function") {
127
+ throw new UnsupportedRateLimitStorageError();
128
+ }
129
+ }
130
+ __name(assertAtomicRateLimitStorage, "assertAtomicRateLimitStorage");
131
+ function assertRateLimitIncrementResult(result) {
132
+ if (!result || !Number.isSafeInteger(result.count) || result.count <= 0 || !Number.isFinite(result.resetAt) || result.resetAt <= 0) {
133
+ throw new TypeError(
134
+ "RateLimitStorage.increment() must return a positive integer count and a resetAt timestamp."
135
+ );
136
+ }
137
+ }
138
+ __name(assertRateLimitIncrementResult, "assertRateLimitIncrementResult");
139
+ function setRateLimitHeaders(ctx, limit, remaining, resetIn, windowSeconds) {
140
+ setMiddlewareResponseHeader(ctx, "RateLimit-Policy", `"farm";q=${limit};w=${windowSeconds}`);
141
+ setMiddlewareResponseHeader(ctx, "RateLimit", `"farm";r=${remaining};t=${resetIn}`);
142
+ }
143
+ __name(setRateLimitHeaders, "setRateLimitHeaders");
144
+ function setMiddlewareResponseHeader(ctx, name, value) {
145
+ ctx.headers.set(name, value);
146
+ if (!ctx.response.headersSent && !ctx.response.writableEnded) {
147
+ ctx.response.setHeader(name, value);
148
+ }
149
+ }
150
+ __name(setMiddlewareResponseHeader, "setMiddlewareResponseHeader");
98
151
  function matchPattern(pattern, pathname) {
99
152
  if (pattern instanceof RegExp) {
100
153
  return pattern.test(pathname);
@@ -244,6 +297,15 @@ var _MiddlewareChainImpl = class _MiddlewareChainImpl {
244
297
  __name(_MiddlewareChainImpl, "MiddlewareChainImpl");
245
298
  var MiddlewareChainImpl = _MiddlewareChainImpl;
246
299
  async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage) {
300
+ if (!Number.isSafeInteger(limit) || limit <= 0) {
301
+ throw new TypeError("Rate limit must be a positive safe integer.");
302
+ }
303
+ assertAtomicRateLimitStorage(storage);
304
+ if (typeof storage.get !== "function") {
305
+ throw new TypeError(
306
+ "getRateLimitStatus() requires a RateLimitStorage adapter that implements get(key)."
307
+ );
308
+ }
247
309
  const record = await storage.get(key);
248
310
  if (!record) {
249
311
  return {
@@ -255,6 +317,7 @@ async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage)
255
317
  isLimited: false
256
318
  };
257
319
  }
320
+ assertRateLimitIncrementResult(record);
258
321
  const now = Date.now();
259
322
  if (record.resetAt && now > record.resetAt) {
260
323
  return {
@@ -275,9 +338,6 @@ async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage)
275
338
  const remainingMs = record.resetAt - now;
276
339
  resetIn = remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
277
340
  resetAt = new Date(record.resetAt);
278
- } else if (storage.ttl) {
279
- resetIn = await storage.ttl(key);
280
- resetAt = resetIn ? new Date(now + resetIn * 1e3) : null;
281
341
  }
282
342
  return {
283
343
  requests,
@@ -386,6 +446,8 @@ function farmMiddlewarePlugin(options = {}) {
386
446
  __name(farmMiddlewarePlugin, "farmMiddlewarePlugin");
387
447
 
388
448
  export {
449
+ UnsupportedRateLimitStorageError,
450
+ memoryRateLimitStorage,
389
451
  getRateLimitStatus,
390
452
  middleware,
391
453
  unwrapMiddleware,
@@ -393,4 +455,4 @@ export {
393
455
  hasMiddlewareData,
394
456
  farmMiddlewarePlugin
395
457
  };
396
- //# sourceMappingURL=chunk-UXUAWNO5.mjs.map
458
+ //# sourceMappingURL=chunk-RIXKJPGI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware/chain.ts","../src/middleware/helpers.ts","../src/middleware/vite-plugin.ts"],"sourcesContent":["/**\n * Middleware Chain Builder\n */\n\nimport type {\n MiddlewareChain,\n MiddlewareFunction,\n MiddlewareContext,\n MiddlewareConfig,\n RateLimitConfig,\n RateLimitStorage,\n RateLimitStatus,\n RateLimitIncrementResult,\n MemoryRateLimitStorageOptions,\n MiddlewareResult,\n} from \"./types\";\n\nconst DEFAULT_MEMORY_RATE_LIMIT_ENTRIES = 100_000;\n\nexport class UnsupportedRateLimitStorageError extends TypeError {\n constructor() {\n super(\n \"RateLimitStorage must implement atomic increment(key, windowMs). Legacy get/set adapters can lose increments under concurrency. Use memoryRateLimitStorage() for one process or redisRateLimitStorage() from @farm.js/cache-redis for production.\",\n );\n this.name = \"UnsupportedRateLimitStorageError\";\n }\n}\n\n/** Create an atomic, process-local fixed-window rate-limit store. */\nexport function memoryRateLimitStorage(\n options: MemoryRateLimitStorageOptions = {},\n): RateLimitStorage {\n const maxEntries = options.maxEntries ?? DEFAULT_MEMORY_RATE_LIMIT_ENTRIES;\n if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {\n throw new TypeError(\"memoryRateLimitStorage maxEntries must be a positive safe integer.\");\n }\n\n const records = new Map<string, RateLimitIncrementResult>();\n\n function read(key: string, now: number): RateLimitIncrementResult | null {\n const record = records.get(key);\n if (!record) return null;\n if (record.resetAt <= now) {\n records.delete(key);\n return null;\n }\n return record;\n }\n\n function pruneExpired(now: number): void {\n for (const [key, record] of records) {\n if (record.resetAt <= now) records.delete(key);\n }\n }\n\n return {\n increment(key, windowMs) {\n if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {\n throw new TypeError(\"Rate-limit windowMs must be a positive safe integer.\");\n }\n const now = Date.now();\n const current = read(key, now);\n if (current) {\n const next = { count: current.count + 1, resetAt: current.resetAt };\n records.set(key, next);\n return next;\n }\n\n if (records.size >= maxEntries) pruneExpired(now);\n if (records.size >= maxEntries) {\n throw new Error(\n `Process-local rate-limit storage reached its ${maxEntries} active-key capacity. Configure a shared production adapter or increase maxEntries.`,\n );\n }\n\n const next = { count: 1, resetAt: now + windowMs };\n records.set(key, next);\n return next;\n },\n get(key) {\n const record = read(key, Date.now());\n return record ? { ...record } : null;\n },\n };\n}\n\nconst defaultRateLimitStorage = memoryRateLimitStorage();\n\nfunction parseTimeWindow(window: string): number {\n const match = window.match(/^(\\d+)(ms|s|m|h|d)$/);\n if (!match) throw new Error(`Invalid time window: ${window}`);\n\n const [, amount, unit] = match;\n const value = Number.parseInt(amount, 10);\n\n const multipliers: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n };\n\n const windowMs = value * multipliers[unit];\n if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {\n throw new Error(`Invalid time window: ${window}`);\n }\n return windowMs;\n}\n\nfunction createRateLimitMiddleware(config: RateLimitConfig): MiddlewareFunction {\n if (!Number.isSafeInteger(config.requests) || config.requests <= 0) {\n throw new TypeError(\"Rate limit requests must be a positive safe integer.\");\n }\n const windowMs = parseTimeWindow(config.window);\n const storage = config.storage || defaultRateLimitStorage;\n assertAtomicRateLimitStorage(storage);\n\n return async (ctx: MiddlewareContext, next) => {\n const key = config.keyGenerator\n ? config.keyGenerator(ctx)\n : `${ctx.request.socket.remoteAddress}:${ctx.pathname}`;\n\n const current = await storage.increment(key, windowMs);\n assertRateLimitIncrementResult(current);\n const now = Date.now();\n const resetIn = Math.max(1, Math.ceil((current.resetAt - now) / 1000));\n const remaining = Math.max(0, config.requests - current.count);\n setRateLimitHeaders(ctx, config.requests, remaining, resetIn, Math.ceil(windowMs / 1000));\n\n if (current.count > config.requests) {\n setMiddlewareResponseHeader(ctx, \"Retry-After\", String(resetIn));\n if (config.onLimit) {\n const result = await config.onLimit(ctx);\n if (result) return result;\n }\n\n ctx.json(\n {\n error: \"Rate limit exceeded\",\n retryAfter: resetIn,\n },\n 429,\n );\n return;\n }\n\n return next();\n };\n}\n\nfunction assertAtomicRateLimitStorage(storage: RateLimitStorage): void {\n if (!storage || typeof storage.increment !== \"function\") {\n throw new UnsupportedRateLimitStorageError();\n }\n}\n\nfunction assertRateLimitIncrementResult(\n result: RateLimitIncrementResult,\n): asserts result is RateLimitIncrementResult {\n if (\n !result ||\n !Number.isSafeInteger(result.count) ||\n result.count <= 0 ||\n !Number.isFinite(result.resetAt) ||\n result.resetAt <= 0\n ) {\n throw new TypeError(\n \"RateLimitStorage.increment() must return a positive integer count and a resetAt timestamp.\",\n );\n }\n}\n\nfunction setRateLimitHeaders(\n ctx: MiddlewareContext,\n limit: number,\n remaining: number,\n resetIn: number,\n windowSeconds: number,\n): void {\n setMiddlewareResponseHeader(ctx, \"RateLimit-Policy\", `\"farm\";q=${limit};w=${windowSeconds}`);\n setMiddlewareResponseHeader(ctx, \"RateLimit\", `\"farm\";r=${remaining};t=${resetIn}`);\n}\n\nfunction setMiddlewareResponseHeader(ctx: MiddlewareContext, name: string, value: string): void {\n ctx.headers.set(name, value);\n if (!ctx.response.headersSent && !ctx.response.writableEnded) {\n ctx.response.setHeader(name, value);\n }\n}\n\nfunction matchPattern(pattern: string | RegExp, pathname: string): boolean {\n if (pattern instanceof RegExp) {\n return pattern.test(pathname);\n }\n\n const regexPattern = pattern\n .replace(/\\*\\*/g, \"__DOUBLE_STAR__\")\n .replace(/\\*/g, \"[^/]+\")\n .replace(/__DOUBLE_STAR__/g, \".*\")\n .replace(/\\//g, \"\\\\/\");\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(pathname);\n}\n\nclass MiddlewareChainImpl implements MiddlewareChain {\n private handlers: MiddlewareFunction[] = [];\n public config?: MiddlewareConfig;\n private basePath: string;\n\n constructor(basePath = \"/\") {\n this.basePath =\n basePath === \"/\" ? \"/\" : basePath.endsWith(\"/\") ? basePath.slice(0, -1) : basePath;\n }\n\n /**\n * Set the base path for this middleware chain (called by manager when loading)\n */\n setBasePath(path: string): void {\n this.basePath = path === \"/\" ? \"/\" : path.endsWith(\"/\") ? path.slice(0, -1) : path;\n }\n\n use(fn: MiddlewareFunction): MiddlewareChain {\n this.handlers.push(fn);\n return this;\n }\n\n /**\n * Normalize a path pattern - auto-scope to middleware route\n * If middleware is in /contact, then \"/api\" becomes \"/contact/api\"\n */\n private normalizePattern(pattern: string): string {\n // If we're at root middleware, use pattern as-is\n if (this.basePath === \"/\") {\n // Ensure it starts with /\n return pattern.startsWith(\"/\") ? pattern : `/${pattern}`;\n }\n\n // For route-specific middleware, always scope the pattern\n // Remove leading / from pattern if present, then join with basePath\n const cleanPattern = pattern.startsWith(\"/\") ? pattern.slice(1) : pattern;\n return `${this.basePath}/${cleanPattern}`;\n }\n\n /**\n * Conditionally run middleware based on a condition.\n * Only supports boolean values or functions that evaluate to boolean.\n * Route-based string matching has been removed - use function conditions instead.\n *\n * @example\n * .when(true, (ctx, next) => { ... }) // Always run\n * .when((ctx) => ctx.data.get('flag'), (ctx, next) => { ... }) // Conditional\n * .when((ctx) => ctx.pathname === '/contact', (ctx, next) => { ... }) // Path-based condition\n */\n when(\n condition: boolean | ((ctx: MiddlewareContext) => boolean),\n fn: MiddlewareFunction | ((chain: MiddlewareChain) => void),\n ): MiddlewareChain {\n const conditionalMiddleware: MiddlewareFunction = async (ctx, next) => {\n // Evaluate condition - boolean or function\n const shouldRun = typeof condition === \"function\" ? condition(ctx) : condition;\n\n if (!shouldRun) {\n return next();\n }\n\n if (typeof fn === \"function\" && fn.length === 2) {\n return (fn as MiddlewareFunction)(ctx, next);\n } else {\n const subChain = middleware(this.basePath);\n (fn as (chain: MiddlewareChain) => void)(subChain);\n const { handlers } = subChain.build();\n\n let index = 0;\n let returnedResponse: Response | undefined;\n const executeNext = async (): Promise<MiddlewareResult> => {\n if (index < handlers.length) {\n const handler = handlers[index++];\n const result = await handler(ctx, executeNext);\n if (result instanceof Response) {\n returnedResponse = result;\n return result;\n }\n } else {\n const result = await next();\n if (result instanceof Response) {\n returnedResponse = result;\n return result;\n }\n }\n return returnedResponse;\n };\n\n return executeNext();\n }\n };\n this.handlers.push(conditionalMiddleware);\n return this;\n }\n\n rateLimit(config: RateLimitConfig): MiddlewareChain {\n this.handlers.push(createRateLimitMiddleware(config));\n return this;\n }\n\n redirect(source: string, destination: string, permanent = false): MiddlewareChain {\n const redirectMiddleware: MiddlewareFunction = async (ctx, next) => {\n // Auto-scope source pattern to the middleware route\n const normalizedSource = this.normalizePattern(source);\n if (matchPattern(normalizedSource, ctx.pathname)) {\n ctx.redirect(destination, permanent ? 308 : 307);\n return;\n }\n return next();\n };\n\n this.handlers.push(redirectMiddleware);\n return this;\n }\n\n /**\n * Rewrite the current middleware route to a new destination.\n * Since each middleware file is route-specific, the source is automatically\n * the middleware's route, so you only need to specify the destination.\n *\n * @param destination - The destination path to rewrite to\n * @param condition - Optional boolean or function that evaluates to boolean.\n * If provided and evaluates to false, rewrite is skipped.\n * If not provided, rewrite always happens.\n *\n * @example\n * // In /contact/middleware.ts\n * .rewrite('/about') // Always rewrites /contact to /about\n * .rewrite('/about', true) // Always rewrites\n * .rewrite('/about', false) // Never rewrites\n * .rewrite('/about', (ctx) => ctx.data.get('shouldRewrite')) // Conditional rewrite\n */\n rewrite(\n destination: string,\n condition?: boolean | ((ctx: MiddlewareContext) => boolean),\n ): MiddlewareChain {\n const rewriteMiddleware: MiddlewareFunction = async (ctx, next) => {\n // Check condition if provided\n if (condition !== undefined) {\n const shouldRewrite = typeof condition === \"function\" ? condition(ctx) : condition;\n if (!shouldRewrite) {\n return next();\n }\n }\n\n // If this middleware is route-specific (not root)\n if (this.basePath !== \"/\") {\n // Rewrite when the pathname exactly matches this middleware's route\n // This rewrites the entire route (e.g., /contact -> /about)\n if (ctx.pathname === this.basePath) {\n ctx.rewrite(destination);\n }\n // Also handle sub-routes: rewrite /contact/something to /destination/something\n else if (ctx.pathname.startsWith(this.basePath + \"/\")) {\n const subPath = ctx.pathname.slice(this.basePath.length);\n const newPath = destination + subPath;\n ctx.rewrite(newPath);\n }\n } else {\n // For root middleware, this is less common\n // Only rewrite if pathname matches exactly (edge case)\n ctx.rewrite(destination);\n }\n return next();\n };\n\n this.handlers.push(rewriteMiddleware);\n return this;\n }\n\n build() {\n return {\n handlers: this.handlers,\n config: this.config,\n };\n }\n}\n\n/**\n * Get rate limit status for a key\n * @example\n * const status = await getRateLimitStatus('user:123', 100, storage);\n */\nexport async function getRateLimitStatus(\n key: string,\n limit: number,\n storage: RateLimitStorage = defaultRateLimitStorage,\n): Promise<RateLimitStatus> {\n if (!Number.isSafeInteger(limit) || limit <= 0) {\n throw new TypeError(\"Rate limit must be a positive safe integer.\");\n }\n assertAtomicRateLimitStorage(storage);\n if (typeof storage.get !== \"function\") {\n throw new TypeError(\n \"getRateLimitStatus() requires a RateLimitStorage adapter that implements get(key).\",\n );\n }\n const record = await storage.get(key);\n\n if (!record) {\n return {\n requests: 0,\n limit,\n remaining: limit,\n resetIn: null,\n resetAt: null,\n isLimited: false,\n };\n }\n assertRateLimitIncrementResult(record);\n\n const now = Date.now();\n\n if (record.resetAt && now > record.resetAt) {\n return {\n requests: 0,\n limit,\n remaining: limit,\n resetIn: null,\n resetAt: null,\n isLimited: false,\n };\n }\n\n const requests = record.count || 0;\n const remaining = Math.max(0, limit - requests);\n const isLimited = requests >= limit;\n\n let resetIn: number | null = null;\n let resetAt: Date | null = null;\n\n if (record.resetAt) {\n const remainingMs = record.resetAt - now;\n resetIn = remainingMs > 0 ? Math.ceil(remainingMs / 1000) : null;\n resetAt = new Date(record.resetAt);\n }\n\n return {\n requests,\n limit,\n remaining,\n resetIn,\n resetAt,\n isLimited,\n };\n}\n\nexport function middleware(basePath = \"/\"): MiddlewareChain {\n return new MiddlewareChainImpl(basePath);\n}\n","/**\n * Middleware helper utilities for pages\n */\n\nimport type { MiddlewareProps } from \"../types\";\n\n/**\n * Unwrap middleware data from PageProps\n *\n * @example\n * ```tsx\n * export default async function Page(props: PageProps) {\n * const { user, stats } = await unwrapMiddleware(props.middleware, {\n * user: null,\n * stats: { views: 0, clicks: 0 }\n * });\n *\n * return <div>Welcome {user?.name}</div>;\n * }\n * ```\n */\nexport function unwrapMiddleware<T extends Record<string, any>>(\n middleware: MiddlewareProps | undefined,\n defaults?: Partial<T>,\n): Partial<T> {\n if (!middleware) {\n return (defaults || {}) as Partial<T>;\n }\n\n const result: any = { ...defaults };\n\n for (const [key, value] of middleware.data) {\n result[key] = value;\n }\n\n return result as Partial<T>;\n}\n\n/**\n * Get a single value from middleware with a default\n *\n * @example\n * ```tsx\n * export default async function Page(props: PageProps) {\n * const user = await getMiddlewareValue(props.middleware, 'user', null);\n * return <div>Welcome {user?.name || 'Guest'}</div>;\n * }\n * ```\n */\nexport function getFromMiddleware<T = any>(\n middleware: MiddlewareProps | undefined,\n key: string,\n defaultValue?: T,\n): T | undefined {\n if (!middleware) {\n return defaultValue;\n }\n\n const value = middleware.data.get(key);\n return value !== undefined ? value : defaultValue;\n}\n\n/**\n * Check if middleware data exists\n */\nexport function hasMiddlewareData(middleware: MiddlewareProps | undefined): boolean {\n if (!middleware) return false;\n return middleware.data.size > 0;\n}\n","/**\n * Standalone Vite middleware support used by Farm's RSC and API plugins.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { Plugin, ViteDevServer } from \"vite\";\nimport { MiddlewareManager } from \"./manager\";\n\nexport interface FarmMiddlewarePluginOptions {\n /** Source directory (default: `src`). */\n srcDir?: string;\n /** Enable debug logging. */\n debug?: boolean;\n}\n\nfunction getMiddlewareAppDirectory(root: string, srcDir: string): string {\n const sourceDirectory = path.join(root, srcDir);\n const appDirectory = path.join(sourceDirectory, \"app\");\n return fs.existsSync(appDirectory) ? appDirectory : sourceDirectory;\n}\n\nexport function farmMiddlewarePlugin(options: FarmMiddlewarePluginOptions = {}): Plugin {\n const srcDir = options.srcDir ?? \"src\";\n let manager: MiddlewareManager | null = null;\n let discoveryComplete = false;\n let discoveryPromise: Promise<void> | null = null;\n\n const discover = async (server: ViteDevServer): Promise<void> => {\n manager = new MiddlewareManager(getMiddlewareAppDirectory(server.config.root, srcDir), server);\n await manager.discover();\n discoveryComplete = true;\n };\n\n return {\n name: \"@farm.js/core:middleware\",\n enforce: \"pre\",\n\n configureServer(server) {\n discoveryPromise = discover(server).catch((error) => {\n discoveryComplete = true;\n console.error(\"[FARM] Middleware discovery error:\", error);\n });\n\n const execute = async (\n req: IncomingMessage,\n res: ServerResponse,\n _pathname?: string,\n sharedData?: Map<string, any>,\n ): Promise<boolean> => {\n if (discoveryPromise && !discoveryComplete) {\n await discoveryPromise;\n }\n\n if (!manager) {\n return false;\n }\n\n const handled = await manager.execute(req, res);\n const middlewareData = (req as any).__FARM_MIDDLEWARE_DATA__;\n if (sharedData && middlewareData instanceof Map) {\n for (const [key, value] of middlewareData) {\n sharedData.set(key, value);\n }\n }\n return handled;\n };\n\n (server as any).__farmMiddleware__ = {\n execute,\n getMiddlewares: () => manager?.getMiddlewares() ?? [],\n isReady: () => discoveryComplete,\n waitForDiscovery: () => discoveryPromise,\n };\n },\n\n async handleHotUpdate({ file, server, modules }) {\n if (!/^middleware\\.[tj]sx?$/.test(path.basename(file))) {\n return;\n }\n\n for (const module of modules) {\n server.moduleGraph.invalidateModule(module);\n }\n\n await manager?.reload();\n server.ws.send({ type: \"full-reload\", path: \"*\" });\n return [];\n },\n };\n}\n"],"mappings":"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","names":["next","path","middleware"]}