@farm.js/core 0.1.0-beta.1 → 0.1.0-beta.4

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 (254) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-runtime.d.mts +2 -1
  3. package/dist/agent-runtime.d.ts +2 -1
  4. package/dist/api/route-manager.cjs +410 -15
  5. package/dist/api/route-manager.cjs.map +1 -1
  6. package/dist/api/route-manager.d.mts +4 -2
  7. package/dist/api/route-manager.d.ts +4 -2
  8. package/dist/api/route-manager.mjs +9 -8
  9. package/dist/api/runtime.cjs +748 -9
  10. package/dist/api/runtime.cjs.map +1 -1
  11. package/dist/api/runtime.d.mts +3 -16
  12. package/dist/api/runtime.d.ts +3 -16
  13. package/dist/api/runtime.mjs +8 -1
  14. package/dist/api.cjs +1243 -342
  15. package/dist/api.cjs.map +1 -1
  16. package/dist/api.d.mts +5 -147
  17. package/dist/api.d.ts +5 -147
  18. package/dist/api.mjs +51 -21
  19. package/dist/{app-CFRNJXP1.d.ts → app-BjN-da13.d.ts} +38 -3
  20. package/dist/{app-BiX4qb-d.d.mts → app-CakAr8Be.d.mts} +38 -3
  21. package/dist/app-markdown.cjs +1 -1
  22. package/dist/app-markdown.cjs.map +1 -1
  23. package/dist/app-markdown.d.mts +2 -1
  24. package/dist/app-markdown.d.ts +2 -1
  25. package/dist/app-markdown.mjs +1 -1
  26. package/dist/cache.cjs +414 -12
  27. package/dist/cache.cjs.map +1 -1
  28. package/dist/cache.d.mts +120 -6
  29. package/dist/cache.d.ts +120 -6
  30. package/dist/cache.mjs +11 -3
  31. package/dist/{chunk-Y7A27276.mjs → chunk-2CUKEMVR.mjs} +349 -15
  32. package/dist/chunk-2CUKEMVR.mjs.map +1 -0
  33. package/dist/{chunk-QF4PHCMA.mjs → chunk-2ED5Q2GH.mjs} +3 -3
  34. package/dist/chunk-2ED5Q2GH.mjs.map +1 -0
  35. package/dist/{chunk-GZP5W4K3.mjs → chunk-32W4QEJP.mjs} +1 -1
  36. package/dist/chunk-32W4QEJP.mjs.map +1 -0
  37. package/dist/{chunk-TRORP7E4.mjs → chunk-3U3ZUQAQ.mjs} +2 -2
  38. package/dist/{chunk-25D7G34K.mjs → chunk-65A7QIKI.mjs} +5 -5
  39. package/dist/{chunk-25D7G34K.mjs.map → chunk-65A7QIKI.mjs.map} +1 -1
  40. package/dist/{chunk-G3B5BRDY.mjs → chunk-AJWRO5WE.mjs} +539 -61
  41. package/dist/chunk-AJWRO5WE.mjs.map +1 -0
  42. package/dist/chunk-ALCLXXTY.mjs +187 -0
  43. package/dist/chunk-ALCLXXTY.mjs.map +1 -0
  44. package/dist/{chunk-CHFHNEMO.mjs → chunk-AOBXKNS5.mjs} +627 -84
  45. package/dist/chunk-AOBXKNS5.mjs.map +1 -0
  46. package/dist/{chunk-B6N4ZB2H.mjs → chunk-C2ROET2V.mjs} +3 -3
  47. package/dist/{chunk-JN3UU635.mjs → chunk-EJ7T4TPB.mjs} +2 -2
  48. package/dist/chunk-EJ7T4TPB.mjs.map +1 -0
  49. package/dist/{chunk-ZJQNATYV.mjs → chunk-FRPWCMMG.mjs} +3 -3
  50. package/dist/chunk-FRPWCMMG.mjs.map +1 -0
  51. package/dist/{chunk-QM6VV26B.mjs → chunk-GQVGIUSN.mjs} +3 -3
  52. package/dist/{chunk-QM6VV26B.mjs.map → chunk-GQVGIUSN.mjs.map} +1 -1
  53. package/dist/{chunk-UREJA4GZ.mjs → chunk-GXASWWJU.mjs} +1 -1
  54. package/dist/{chunk-UREJA4GZ.mjs.map → chunk-GXASWWJU.mjs.map} +1 -1
  55. package/dist/{chunk-3QJO55ZF.mjs → chunk-HNIQFZKB.mjs} +5 -3
  56. package/dist/{chunk-3QJO55ZF.mjs.map → chunk-HNIQFZKB.mjs.map} +1 -1
  57. package/dist/{chunk-PRNYWD7K.mjs → chunk-JDEOUK5V.mjs} +67 -239
  58. package/dist/chunk-JDEOUK5V.mjs.map +1 -0
  59. package/dist/{chunk-O3HADRW6.mjs → chunk-MIUW47JX.mjs} +2 -2
  60. package/dist/{chunk-O3HADRW6.mjs.map → chunk-MIUW47JX.mjs.map} +1 -1
  61. package/dist/{chunk-UHE2TTLK.mjs → chunk-NM3CRAAL.mjs} +9 -8
  62. package/dist/chunk-NM3CRAAL.mjs.map +1 -0
  63. package/dist/chunk-PFE6GMNE.mjs +603 -0
  64. package/dist/chunk-PFE6GMNE.mjs.map +1 -0
  65. package/dist/{chunk-S2XHZS7W.mjs → chunk-QGQX7SFC.mjs} +2 -2
  66. package/dist/chunk-QGQX7SFC.mjs.map +1 -0
  67. package/dist/{chunk-RKI6TN3A.mjs → chunk-QM746KUO.mjs} +9 -2
  68. package/dist/chunk-QM746KUO.mjs.map +1 -0
  69. package/dist/chunk-RBRLLZL5.mjs +81 -0
  70. package/dist/chunk-RBRLLZL5.mjs.map +1 -0
  71. package/dist/{chunk-HXP3ZSPC.mjs → chunk-SADGIRS2.mjs} +3 -3
  72. package/dist/{chunk-6XDUHOEM.mjs → chunk-TQAEEJB4.mjs} +3 -3
  73. package/dist/{chunk-AGS7UJ52.mjs → chunk-UB5UOSHB.mjs} +24 -12
  74. package/dist/chunk-UB5UOSHB.mjs.map +1 -0
  75. package/dist/{chunk-SXZTEK3V.mjs → chunk-UXUAWNO5.mjs} +2 -2
  76. package/dist/chunk-V3XURYJO.mjs +756 -0
  77. package/dist/chunk-V3XURYJO.mjs.map +1 -0
  78. package/dist/{chunk-TU4YJICB.mjs → chunk-VVKWFZAH.mjs} +41 -16
  79. package/dist/chunk-VVKWFZAH.mjs.map +1 -0
  80. package/dist/{chunk-JLWMCADZ.mjs → chunk-VY2UYN5R.mjs} +24 -4
  81. package/dist/chunk-VY2UYN5R.mjs.map +1 -0
  82. package/dist/{chunk-QFQRHRZS.mjs → chunk-W2CRQFF6.mjs} +151 -23
  83. package/dist/chunk-W2CRQFF6.mjs.map +1 -0
  84. package/dist/chunk-W4UIVMVI.mjs +10 -0
  85. package/dist/chunk-W4UIVMVI.mjs.map +1 -0
  86. package/dist/{chunk-Y2OJJD7R.mjs → chunk-XIVV5IWN.mjs} +7 -9
  87. package/dist/chunk-XIVV5IWN.mjs.map +1 -0
  88. package/dist/{chunk-OYXO65LI.mjs → chunk-YW7OBE6Q.mjs} +4 -4
  89. package/dist/chunk-YW7OBE6Q.mjs.map +1 -0
  90. package/dist/{chunk-YHU7SS6L.mjs → chunk-Z5CQMP54.mjs} +11 -11
  91. package/dist/{chunk-SOU3Q3ZA.mjs → chunk-ZZ57EH5Z.mjs} +1 -1
  92. package/dist/chunk-ZZ57EH5Z.mjs.map +1 -0
  93. package/dist/{client-D_yUjVhe.d.mts → client-BT1mFQas.d.mts} +55 -10
  94. package/dist/{client-Dkc03WP8.d.ts → client-Nn0q4eO4.d.ts} +55 -10
  95. package/dist/{client-plugins-BZnpeTGA.d.ts → client-plugins-Cw4qUGsw.d.ts} +7 -0
  96. package/dist/{client-plugins-g4bzuCmo.d.mts → client-plugins-DQQ1adXM.d.mts} +7 -0
  97. package/dist/client-plugins.d.mts +2 -1
  98. package/dist/client-plugins.d.ts +2 -1
  99. package/dist/client.cjs +922 -91
  100. package/dist/client.cjs.map +1 -1
  101. package/dist/client.d.mts +121 -3
  102. package/dist/client.d.ts +121 -3
  103. package/dist/client.mjs +23 -16
  104. package/dist/config.d.mts +2 -1
  105. package/dist/config.d.ts +2 -1
  106. package/dist/cron.cjs.map +1 -1
  107. package/dist/cron.mjs +1 -1
  108. package/dist/{devtools-AE4RVXCM.mjs → devtools-LVC3VB5P.mjs} +10 -10
  109. package/dist/{devtools-client-6WPY2AQU.mjs → devtools-client-3XRTBND5.mjs} +2 -11
  110. package/dist/devtools-client-3XRTBND5.mjs.map +1 -0
  111. package/dist/docs.cjs +14 -2
  112. package/dist/docs.cjs.map +1 -1
  113. package/dist/docs.mjs +10 -10
  114. package/dist/i18n/server.cjs +2 -2
  115. package/dist/i18n/server.cjs.map +1 -1
  116. package/dist/i18n/server.mjs +1 -1
  117. package/dist/index.cjs +2852 -463
  118. package/dist/index.cjs.map +1 -1
  119. package/dist/index.d.mts +13 -12
  120. package/dist/index.d.ts +13 -12
  121. package/dist/index.mjs +152 -109
  122. package/dist/index.mjs.map +1 -1
  123. package/dist/integrations.d.mts +2 -1
  124. package/dist/integrations.d.ts +2 -1
  125. package/dist/internal/build-runtime.cjs +1616 -149
  126. package/dist/internal/build-runtime.cjs.map +1 -1
  127. package/dist/internal/build-runtime.d.mts +4 -3
  128. package/dist/internal/build-runtime.d.ts +4 -3
  129. package/dist/internal/build-runtime.mjs +27 -25
  130. package/dist/internal/client-runtime.cjs.map +1 -1
  131. package/dist/internal/client-runtime.mjs +1 -1
  132. package/dist/internal/config-runtime.cjs +13 -2
  133. package/dist/internal/config-runtime.cjs.map +1 -1
  134. package/dist/internal/config-runtime.d.mts +3 -2
  135. package/dist/internal/config-runtime.d.ts +3 -2
  136. package/dist/internal/config-runtime.mjs +9 -9
  137. package/dist/internal/production-runtime.cjs +285 -9
  138. package/dist/internal/production-runtime.cjs.map +1 -1
  139. package/dist/internal/production-runtime.d.mts +4 -4
  140. package/dist/internal/production-runtime.d.ts +4 -4
  141. package/dist/internal/production-runtime.mjs +10 -8
  142. package/dist/{metadata-DAXRaOHx.d.ts → metadata-BAPg_Nmo.d.ts} +1 -1
  143. package/dist/{metadata-C9NZxMDW.d.mts → metadata-_6i9oFG3.d.mts} +1 -1
  144. package/dist/middleware.cjs +2 -2
  145. package/dist/middleware.cjs.map +1 -1
  146. package/dist/middleware.d.mts +4 -3
  147. package/dist/middleware.d.ts +4 -3
  148. package/dist/middleware.mjs +3 -3
  149. package/dist/navigation.cjs +40 -15
  150. package/dist/navigation.cjs.map +1 -1
  151. package/dist/navigation.mjs +3 -3
  152. package/dist/{nitro-KME62MWG.mjs → nitro-QO5LV6QK.mjs} +11 -13
  153. package/dist/{nitro-KME62MWG.mjs.map → nitro-QO5LV6QK.mjs.map} +1 -1
  154. package/dist/plugin.cjs +1032 -92
  155. package/dist/plugin.cjs.map +1 -1
  156. package/dist/plugin.d.mts +2 -1
  157. package/dist/plugin.d.ts +2 -1
  158. package/dist/plugin.mjs +23 -21
  159. package/dist/{production-runtime-DRkCHUvJ.d.ts → production-runtime-BoJDc5mc.d.ts} +1 -1
  160. package/dist/{production-runtime-flrjp_nC.d.mts → production-runtime-DPfgMV9Y.d.mts} +1 -1
  161. package/dist/routes.cjs +276 -6
  162. package/dist/routes.cjs.map +1 -1
  163. package/dist/routes.d.mts +1 -1
  164. package/dist/routes.d.ts +1 -1
  165. package/dist/routes.mjs +4 -4
  166. package/dist/runtime-9nQjVM7X.d.mts +206 -0
  167. package/dist/runtime-DgeS2skB.d.ts +206 -0
  168. package/dist/server-action-security.cjs +28 -10
  169. package/dist/server-action-security.cjs.map +1 -1
  170. package/dist/server-action-security.d.mts +2 -1
  171. package/dist/server-action-security.d.ts +2 -1
  172. package/dist/server-action-security.mjs +2 -2
  173. package/dist/server-fn-client.cjs.map +1 -1
  174. package/dist/server-fn-client.d.mts +1 -0
  175. package/dist/server-fn-client.d.ts +1 -0
  176. package/dist/server-fn-client.mjs +1 -1
  177. package/dist/server-fn.cjs +785 -3
  178. package/dist/server-fn.cjs.map +1 -1
  179. package/dist/server-fn.d.mts +10 -1
  180. package/dist/server-fn.d.ts +10 -1
  181. package/dist/server-fn.mjs +6 -3
  182. package/dist/server-plugins.d.mts +3 -2
  183. package/dist/server-plugins.d.ts +3 -2
  184. package/dist/server-query-client.cjs +278 -7
  185. package/dist/server-query-client.cjs.map +1 -1
  186. package/dist/server-query-client.mjs +4 -4
  187. package/dist/server-query.cjs +381 -10
  188. package/dist/server-query.cjs.map +1 -1
  189. package/dist/server-query.mjs +5 -5
  190. package/dist/server.cjs +1233 -118
  191. package/dist/server.cjs.map +1 -1
  192. package/dist/server.d.mts +8 -7
  193. package/dist/server.d.ts +8 -7
  194. package/dist/server.mjs +53 -33
  195. package/dist/server.mjs.map +1 -1
  196. package/dist/testing.cjs +436 -25
  197. package/dist/testing.cjs.map +1 -1
  198. package/dist/testing.d.mts +4 -3
  199. package/dist/testing.d.ts +4 -3
  200. package/dist/testing.mjs +19 -18
  201. package/dist/testing.mjs.map +1 -1
  202. package/dist/transport-BmbGTXA5.d.mts +49 -0
  203. package/dist/transport-BmbGTXA5.d.ts +49 -0
  204. package/dist/{utils-DOXXivjL.d.mts → utils-CHXlMDkg.d.mts} +1 -1
  205. package/dist/{utils-DA1yo54_.d.ts → utils-Drsyz1Vj.d.ts} +1 -1
  206. package/dist/version.cjs +36 -0
  207. package/dist/version.cjs.map +1 -0
  208. package/dist/version.d.mts +3 -0
  209. package/dist/version.d.ts +3 -0
  210. package/dist/version.mjs +8 -0
  211. package/dist/version.mjs.map +1 -0
  212. package/dist/vite.cjs +1039 -93
  213. package/dist/vite.cjs.map +1 -1
  214. package/dist/vite.d.mts +2 -1
  215. package/dist/vite.d.ts +2 -1
  216. package/dist/vite.mjs +23 -21
  217. package/dist/workflows.cjs +6 -8
  218. package/dist/workflows.cjs.map +1 -1
  219. package/dist/workflows.mjs +1 -1
  220. package/package.json +12 -5
  221. package/types/api.d.ts +44 -0
  222. package/types/client.d.ts +220 -16
  223. package/dist/chunk-4PTK6KT4.mjs +0 -364
  224. package/dist/chunk-4PTK6KT4.mjs.map +0 -1
  225. package/dist/chunk-AGS7UJ52.mjs.map +0 -1
  226. package/dist/chunk-CHFHNEMO.mjs.map +0 -1
  227. package/dist/chunk-EVGBEZDF.mjs +0 -215
  228. package/dist/chunk-EVGBEZDF.mjs.map +0 -1
  229. package/dist/chunk-G3B5BRDY.mjs.map +0 -1
  230. package/dist/chunk-GZP5W4K3.mjs.map +0 -1
  231. package/dist/chunk-JLWMCADZ.mjs.map +0 -1
  232. package/dist/chunk-JN3UU635.mjs.map +0 -1
  233. package/dist/chunk-OYXO65LI.mjs.map +0 -1
  234. package/dist/chunk-PRNYWD7K.mjs.map +0 -1
  235. package/dist/chunk-QF4PHCMA.mjs.map +0 -1
  236. package/dist/chunk-QFQRHRZS.mjs.map +0 -1
  237. package/dist/chunk-RKI6TN3A.mjs.map +0 -1
  238. package/dist/chunk-S2XHZS7W.mjs.map +0 -1
  239. package/dist/chunk-SOU3Q3ZA.mjs.map +0 -1
  240. package/dist/chunk-TU4YJICB.mjs.map +0 -1
  241. package/dist/chunk-TXCFGOHW.mjs +0 -42
  242. package/dist/chunk-TXCFGOHW.mjs.map +0 -1
  243. package/dist/chunk-UHE2TTLK.mjs.map +0 -1
  244. package/dist/chunk-Y2OJJD7R.mjs.map +0 -1
  245. package/dist/chunk-Y7A27276.mjs.map +0 -1
  246. package/dist/chunk-ZJQNATYV.mjs.map +0 -1
  247. package/dist/devtools-client-6WPY2AQU.mjs.map +0 -1
  248. /package/dist/{chunk-TRORP7E4.mjs.map → chunk-3U3ZUQAQ.mjs.map} +0 -0
  249. /package/dist/{chunk-B6N4ZB2H.mjs.map → chunk-C2ROET2V.mjs.map} +0 -0
  250. /package/dist/{chunk-HXP3ZSPC.mjs.map → chunk-SADGIRS2.mjs.map} +0 -0
  251. /package/dist/{chunk-6XDUHOEM.mjs.map → chunk-TQAEEJB4.mjs.map} +0 -0
  252. /package/dist/{chunk-SXZTEK3V.mjs.map → chunk-UXUAWNO5.mjs.map} +0 -0
  253. /package/dist/{chunk-YHU7SS6L.mjs.map → chunk-Z5CQMP54.mjs.map} +0 -0
  254. /package/dist/{devtools-AE4RVXCM.mjs.map → devtools-LVC3VB5P.mjs.map} +0 -0
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/api/runtime.ts
22
22
  var runtime_exports = {};
23
23
  __export(runtime_exports, {
24
+ createEndpointFailureResponse: () => createEndpointFailureResponse,
24
25
  invokeAPIRouteEndpoint: () => invokeAPIRouteEndpoint,
25
26
  isWebResponse: () => isWebResponse,
26
27
  matchAPIRoute: () => matchAPIRoute,
@@ -62,6 +63,661 @@ async function _runWithCurrentRequest(request, fn) {
62
63
  }
63
64
  __name(_runWithCurrentRequest, "_runWithCurrentRequest");
64
65
 
66
+ // src/cache-invalidation.ts
67
+ var FARM_CACHE_INVALIDATION_HEADER = "x-farm-cache-invalidations";
68
+ function encodeFarmCacheInvalidations(keys) {
69
+ const normalized = Array.from(
70
+ new Set(keys.filter((key) => typeof key === "string" && key.length > 0))
71
+ );
72
+ if (normalized.length === 0) return null;
73
+ return encodeURIComponent(JSON.stringify(normalized));
74
+ }
75
+ __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
76
+ function decodeFarmCacheInvalidations(value) {
77
+ if (!value) return [];
78
+ try {
79
+ const parsed = JSON.parse(decodeURIComponent(value));
80
+ return Array.isArray(parsed) ? Array.from(
81
+ new Set(parsed.filter((key) => typeof key === "string" && key.length > 0))
82
+ ) : [];
83
+ } catch {
84
+ return [];
85
+ }
86
+ }
87
+ __name(decodeFarmCacheInvalidations, "decodeFarmCacheInvalidations");
88
+
89
+ // src/api/endpoint.ts
90
+ var import_better_call = require("better-call");
91
+
92
+ // src/observability.ts
93
+ var runtimeHandlers = /* @__PURE__ */ new Set();
94
+ var observabilityState = {
95
+ logs: false,
96
+ handlers: []
97
+ };
98
+ function emitFarmEvent(input) {
99
+ const event = {
100
+ timestamp: Date.now(),
101
+ level: inferFarmEventLevel(input.type),
102
+ ...input
103
+ };
104
+ if (!shouldEmitFarmEvent(event)) {
105
+ return event;
106
+ }
107
+ if (observabilityState.logs) {
108
+ logFarmEvent(event);
109
+ }
110
+ for (const handler of [...observabilityState.handlers, ...runtimeHandlers]) {
111
+ try {
112
+ Promise.resolve(handler(event)).catch((error) => {
113
+ console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);
114
+ });
115
+ } catch (error) {
116
+ console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);
117
+ }
118
+ }
119
+ return event;
120
+ }
121
+ __name(emitFarmEvent, "emitFarmEvent");
122
+ function shouldEmitFarmEvent(event) {
123
+ if (!observabilityState.logs && observabilityState.handlers.length === 0 && runtimeHandlers.size === 0) {
124
+ return false;
125
+ }
126
+ if (observabilityState.events && !observabilityState.events.has(event.type)) {
127
+ return false;
128
+ }
129
+ return true;
130
+ }
131
+ __name(shouldEmitFarmEvent, "shouldEmitFarmEvent");
132
+ function inferFarmEventLevel(type) {
133
+ if (type === "error" || type.endsWith(".error") || type.endsWith(".failed")) {
134
+ return "error";
135
+ }
136
+ if (type.endsWith(".bypass") || type.endsWith(".invalidated") || type.endsWith(".stale") || type.endsWith(".notFound")) {
137
+ return "warn";
138
+ }
139
+ if (type.endsWith(".hit") || type.endsWith(".miss") || type.endsWith(".start") || type.endsWith(".shellReady")) {
140
+ return "debug";
141
+ }
142
+ return "info";
143
+ }
144
+ __name(inferFarmEventLevel, "inferFarmEventLevel");
145
+ function logFarmEvent(event) {
146
+ const message = `[farm:${event.level}] ${event.type}${formatFarmEventDetails(event)}`;
147
+ switch (event.level) {
148
+ case "error":
149
+ console.error(message);
150
+ break;
151
+ case "warn":
152
+ console.warn(message);
153
+ break;
154
+ default:
155
+ console.log(message);
156
+ break;
157
+ }
158
+ }
159
+ __name(logFarmEvent, "logFarmEvent");
160
+ function formatFarmEventDetails(event) {
161
+ const details = [];
162
+ const record = event;
163
+ for (const key of [
164
+ "route",
165
+ "pathname",
166
+ "method",
167
+ "status",
168
+ "key",
169
+ "tag",
170
+ "path",
171
+ "reason",
172
+ "durationMs",
173
+ "integration",
174
+ "operation",
175
+ "plugin",
176
+ "hook",
177
+ "target",
178
+ "count"
179
+ ]) {
180
+ const value = record[key];
181
+ if (value !== void 0) {
182
+ details.push(`${key}=${formatDetailValue(value)}`);
183
+ }
184
+ }
185
+ return details.length > 0 ? ` ${details.join(" ")}` : "";
186
+ }
187
+ __name(formatFarmEventDetails, "formatFarmEventDetails");
188
+ function formatDetailValue(value) {
189
+ if (typeof value === "string") {
190
+ return value;
191
+ }
192
+ if (typeof value === "number" || typeof value === "boolean") {
193
+ return String(value);
194
+ }
195
+ try {
196
+ return JSON.stringify(value);
197
+ } catch {
198
+ return String(value);
199
+ }
200
+ }
201
+ __name(formatDetailValue, "formatDetailValue");
202
+ function formatError(error) {
203
+ return error instanceof Error ? error.message : String(error);
204
+ }
205
+ __name(formatError, "formatError");
206
+
207
+ // src/cache.ts
208
+ var _FarmDataCache = class _FarmDataCache {
209
+ constructor(config = {}) {
210
+ this.entries = /* @__PURE__ */ new Map();
211
+ this.inflight = /* @__PURE__ */ new Map();
212
+ this.invalidatedTagVersions = /* @__PURE__ */ new Map();
213
+ this.version = 0;
214
+ this.namespace = "farm";
215
+ this.local = true;
216
+ this.lease = {
217
+ enabled: true,
218
+ ttlMs: 1e4,
219
+ waitTimeoutMs: 1e4,
220
+ pollIntervalMs: 25
221
+ };
222
+ this.configure(config);
223
+ }
224
+ configure(config = {}) {
225
+ this.adapter = config.adapter;
226
+ this.namespace = normalizeCacheNamespace(config.namespace || "farm");
227
+ this.local = !config.adapter;
228
+ this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
229
+ enabled: true,
230
+ ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
231
+ waitTimeoutMs: normalizePositiveDuration(
232
+ config.lease?.waitTimeoutMs,
233
+ 1e4,
234
+ "cache.lease.waitTimeoutMs"
235
+ ),
236
+ pollIntervalMs: normalizePositiveDuration(
237
+ config.lease?.pollIntervalMs,
238
+ 25,
239
+ "cache.lease.pollIntervalMs"
240
+ )
241
+ };
242
+ if (!this.local) {
243
+ this.entries.clear();
244
+ this.inflight.clear();
245
+ this.invalidatedTagVersions.clear();
246
+ this.version = 0;
247
+ }
248
+ }
249
+ get adapterName() {
250
+ return this.adapter?.name || (this.adapter ? "custom" : "memory");
251
+ }
252
+ get hasAdapter() {
253
+ return this.adapter !== void 0;
254
+ }
255
+ get size() {
256
+ return this.entries.size;
257
+ }
258
+ get(key, options = {}) {
259
+ return this.getEntry(key, options)?.value;
260
+ }
261
+ getEntry(key, options = {}) {
262
+ const entry = this.entries.get(key);
263
+ if (!entry) {
264
+ emitFarmEvent({ type: "cache.miss", key });
265
+ return void 0;
266
+ }
267
+ const stale = this.isStale(entry, options.now);
268
+ if (stale) {
269
+ emitFarmEvent({
270
+ type: "cache.stale",
271
+ key,
272
+ tags: Array.from(entry.tags),
273
+ revalidate: entry.revalidate
274
+ });
275
+ }
276
+ if (!options.allowStale && stale) {
277
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
278
+ return void 0;
279
+ }
280
+ emitFarmEvent({
281
+ type: "cache.hit",
282
+ key,
283
+ tags: Array.from(entry.tags),
284
+ revalidate: entry.revalidate,
285
+ stale
286
+ });
287
+ return this.toPublicEntry(entry);
288
+ }
289
+ async getEntryAsync(key, options = {}) {
290
+ if (this.local) {
291
+ const localEntry = this.getEntry(key, options);
292
+ if (localEntry) return localEntry;
293
+ }
294
+ if (!this.adapter) {
295
+ return this.local ? void 0 : this.getEntry(key, options);
296
+ }
297
+ const entry = await this.adapter.get(this.createAdapterKey(key));
298
+ if (!entry) {
299
+ emitFarmEvent({ type: "cache.miss", key });
300
+ return void 0;
301
+ }
302
+ assertFarmCacheEntry(entry, key);
303
+ const stale = await this.isAdapterEntryStale(entry, options.now);
304
+ if (stale) {
305
+ emitFarmEvent({
306
+ type: "cache.stale",
307
+ key,
308
+ tags: [...entry.tags],
309
+ revalidate: entry.revalidate
310
+ });
311
+ if (!options.allowStale) {
312
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
313
+ return void 0;
314
+ }
315
+ }
316
+ emitFarmEvent({
317
+ type: "cache.hit",
318
+ key,
319
+ tags: [...entry.tags],
320
+ revalidate: entry.revalidate,
321
+ stale
322
+ });
323
+ if (this.local && !stale) {
324
+ this.hydrateLocalEntry(entry);
325
+ }
326
+ return { ...entry, key };
327
+ }
328
+ set(key, value, options = {}) {
329
+ const tags = /* @__PURE__ */ new Set();
330
+ for (const tag of options.tags ?? []) {
331
+ tags.add(normalizeCacheTag(tag));
332
+ }
333
+ for (const routePath of options.paths ?? []) {
334
+ tags.add(createPathCacheTag(routePath));
335
+ }
336
+ const entry = {
337
+ key,
338
+ value,
339
+ tags,
340
+ tagVersions: void 0,
341
+ createdAt: options.createdAt ?? Date.now(),
342
+ createdVersion: ++this.version,
343
+ revalidate: normalizeRevalidate(options.revalidate)
344
+ };
345
+ this.entries.set(key, entry);
346
+ emitFarmEvent({
347
+ type: "cache.set",
348
+ key,
349
+ tags: Array.from(tags),
350
+ revalidate: entry.revalidate
351
+ });
352
+ return this.toPublicEntry(entry);
353
+ }
354
+ async setAsync(key, value, options = {}, tagVersions) {
355
+ const tags = normalizeCacheOptionsTags(options);
356
+ const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
357
+ const entry = {
358
+ key,
359
+ value,
360
+ tags: Array.from(tags),
361
+ tagVersions: capturedVersions,
362
+ createdAt: options.createdAt ?? Date.now(),
363
+ createdVersion: ++this.version,
364
+ revalidate: normalizeRevalidate(options.revalidate)
365
+ };
366
+ if (this.local) {
367
+ this.hydrateLocalEntry(entry);
368
+ }
369
+ if (this.adapter) {
370
+ await this.adapter.set(this.createAdapterKey(key), entry);
371
+ }
372
+ emitFarmEvent({
373
+ type: "cache.set",
374
+ key,
375
+ tags: [...entry.tags],
376
+ revalidate: entry.revalidate
377
+ });
378
+ return entry;
379
+ }
380
+ delete(key) {
381
+ const deleted = this.entries.delete(key);
382
+ emitFarmEvent({ type: "cache.delete", key, deleted });
383
+ return deleted;
384
+ }
385
+ async deleteAsync(key) {
386
+ const deleted = this.entries.delete(key);
387
+ if (this.adapter) {
388
+ await this.adapter.delete(this.createAdapterKey(key));
389
+ }
390
+ emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
391
+ return this.adapter ? true : deleted;
392
+ }
393
+ clear() {
394
+ const count = this.entries.size;
395
+ this.entries.clear();
396
+ this.inflight.clear();
397
+ this.invalidatedTagVersions.clear();
398
+ this.version = 0;
399
+ emitFarmEvent({ type: "cache.clear", count });
400
+ }
401
+ async clearAsync() {
402
+ this.clear();
403
+ await this.adapter?.clear?.();
404
+ }
405
+ isStale(entry, now = Date.now()) {
406
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
407
+ return true;
408
+ }
409
+ for (const tag of entry.tags) {
410
+ const invalidatedVersion = this.invalidatedTagVersions.get(normalizeCacheTag(tag));
411
+ if (typeof invalidatedVersion === "number" && typeof entry.createdVersion === "number" && invalidatedVersion > entry.createdVersion) {
412
+ return true;
413
+ }
414
+ }
415
+ return false;
416
+ }
417
+ async isStaleAsync(entry, now = Date.now()) {
418
+ if (this.adapter) {
419
+ return this.isAdapterEntryStale(entry, now);
420
+ }
421
+ return this.isStale(entry, now);
422
+ }
423
+ revalidateTag(tag, options = {}) {
424
+ const normalized = normalizeCacheTag(tag);
425
+ const count = this.invalidateTag(normalized);
426
+ emitFarmEvent(
427
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
428
+ );
429
+ return count;
430
+ }
431
+ async revalidateTagAsync(tag, options = {}) {
432
+ const normalized = normalizeCacheTag(tag);
433
+ const count = this.invalidateTag(normalized);
434
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
435
+ emitFarmEvent(
436
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
437
+ );
438
+ return count;
439
+ }
440
+ revalidatePath(routePath) {
441
+ const normalizedPath = normalizeRevalidatePath(routePath);
442
+ const pathTag = createPathCacheTag(normalizedPath);
443
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
444
+ const count = this.invalidateTag(pathTag);
445
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
446
+ if (pprCount > 0) {
447
+ emitFarmEvent({
448
+ type: "ppr.shell.invalidated",
449
+ route: normalizedPath,
450
+ reason: "revalidatePath",
451
+ count: pprCount
452
+ });
453
+ }
454
+ return count;
455
+ }
456
+ async revalidatePathAsync(routePath) {
457
+ const normalizedPath = normalizeRevalidatePath(routePath);
458
+ const pathTag = createPathCacheTag(normalizedPath);
459
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
460
+ const count = this.invalidateTag(pathTag);
461
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
462
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
463
+ if (pprCount > 0) {
464
+ emitFarmEvent({
465
+ type: "ppr.shell.invalidated",
466
+ route: normalizedPath,
467
+ reason: "revalidatePath",
468
+ count: pprCount
469
+ });
470
+ }
471
+ return count;
472
+ }
473
+ async getOrSet(key, producer, options = {}) {
474
+ const cached = await this.getEntryAsync(key);
475
+ if (cached) {
476
+ return cached.value;
477
+ }
478
+ const inflight = this.inflight.get(key);
479
+ if (inflight) {
480
+ emitFarmEvent({ type: "cache.dedupe", key });
481
+ return inflight;
482
+ }
483
+ const tags = Array.from(normalizeCacheOptionsTags(options));
484
+ const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
485
+ emitFarmEvent({ type: "cache.error", key, operation: "set", error });
486
+ throw error;
487
+ }).finally(() => {
488
+ this.inflight.delete(key);
489
+ });
490
+ this.inflight.set(key, promise);
491
+ return promise;
492
+ }
493
+ async fillCacheEntry(key, producer, options, tags) {
494
+ const leaseKey = `${this.namespace}:lease:${key}`;
495
+ let leaseToken;
496
+ if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
497
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
498
+ if (!leaseToken) {
499
+ const shared = await this.waitForAdapterEntry(key);
500
+ if (shared) {
501
+ emitFarmEvent({ type: "cache.dedupe", key });
502
+ return shared.value;
503
+ }
504
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
505
+ }
506
+ }
507
+ try {
508
+ const initialTagVersions = await this.getAdapterTagVersions(tags);
509
+ const value = await producer();
510
+ await this.setAsync(key, value, options, initialTagVersions);
511
+ return value;
512
+ } finally {
513
+ if (leaseToken && this.adapter?.releaseLease) {
514
+ await this.adapter.releaseLease(leaseKey, leaseToken);
515
+ }
516
+ }
517
+ }
518
+ async waitForAdapterEntry(key) {
519
+ const deadline = Date.now() + this.lease.waitTimeoutMs;
520
+ while (Date.now() < deadline) {
521
+ await delay(this.lease.pollIntervalMs);
522
+ const entry = await this.getEntryAsync(key);
523
+ if (entry) return entry;
524
+ }
525
+ return void 0;
526
+ }
527
+ countEntriesForTag(tag) {
528
+ let count = 0;
529
+ for (const entry of this.entries.values()) {
530
+ if (entry.tags.has(tag)) {
531
+ count++;
532
+ }
533
+ }
534
+ return count;
535
+ }
536
+ countEntriesForTags(tags) {
537
+ let count = 0;
538
+ for (const entry of this.entries.values()) {
539
+ if (tags.every((tag) => entry.tags.has(tag))) {
540
+ count++;
541
+ }
542
+ }
543
+ return count;
544
+ }
545
+ invalidateTag(normalizedTag) {
546
+ this.invalidatedTagVersions.set(normalizedTag, ++this.version);
547
+ return this.countEntriesForTag(normalizedTag);
548
+ }
549
+ toPublicEntry(entry) {
550
+ return {
551
+ key: entry.key,
552
+ value: entry.value,
553
+ tags: Array.from(entry.tags),
554
+ tagVersions: entry.tagVersions,
555
+ createdAt: entry.createdAt,
556
+ createdVersion: entry.createdVersion,
557
+ revalidate: entry.revalidate
558
+ };
559
+ }
560
+ hydrateLocalEntry(entry) {
561
+ this.entries.set(entry.key, {
562
+ key: entry.key,
563
+ value: entry.value,
564
+ tags: new Set(entry.tags.map(normalizeCacheTag)),
565
+ tagVersions: entry.tagVersions,
566
+ createdAt: entry.createdAt,
567
+ createdVersion: entry.createdVersion ?? ++this.version,
568
+ revalidate: normalizeRevalidate(entry.revalidate)
569
+ });
570
+ }
571
+ createAdapterKey(key) {
572
+ return `${this.namespace}:entry:${key}`;
573
+ }
574
+ createAdapterTag(tag) {
575
+ return `${this.namespace}:tag:${tag}`;
576
+ }
577
+ async getAdapterTagVersions(tags) {
578
+ if (!this.adapter?.getTagVersions || tags.length === 0) return {};
579
+ const normalized = tags.map(normalizeCacheTag);
580
+ const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
581
+ const versions = await this.adapter.getTagVersions(physicalTags);
582
+ return Object.fromEntries(
583
+ normalized.map((tag, index) => [
584
+ tag,
585
+ normalizeAdapterVersion(versions[physicalTags[index]])
586
+ ])
587
+ );
588
+ }
589
+ async isAdapterEntryStale(entry, now = Date.now()) {
590
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
591
+ return true;
592
+ }
593
+ const currentVersions = await this.getAdapterTagVersions(entry.tags);
594
+ for (const tag of entry.tags) {
595
+ if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
596
+ return true;
597
+ }
598
+ }
599
+ return false;
600
+ }
601
+ };
602
+ __name(_FarmDataCache, "FarmDataCache");
603
+ var FarmDataCache = _FarmDataCache;
604
+ var FARM_DATA_CACHE_SYMBOL = /* @__PURE__ */ Symbol.for("farm.dataCache");
605
+ var farmDataCacheGlobal = globalThis;
606
+ var sharedFarmDataCache = farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] ?? (farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] = new FarmDataCache());
607
+ function createPathCacheTag(routePath) {
608
+ return `path:${normalizeRevalidatePath(routePath)}`;
609
+ }
610
+ __name(createPathCacheTag, "createPathCacheTag");
611
+ function normalizeRevalidatePath(routePath) {
612
+ if (typeof routePath !== "string") {
613
+ throw new TypeError("revalidatePath expects a path string.");
614
+ }
615
+ let normalized = routePath.trim();
616
+ if (!normalized) {
617
+ throw new Error("revalidatePath expects a non-empty path.");
618
+ }
619
+ try {
620
+ if (/^https?:\/\//.test(normalized)) {
621
+ normalized = new URL(normalized).pathname;
622
+ }
623
+ } catch {
624
+ }
625
+ normalized = normalized.split("?")[0] ?? normalized;
626
+ normalized = normalized.startsWith("/") ? normalized : `/${normalized}`;
627
+ normalized = normalized.replace(/\/{2,}/g, "/");
628
+ if (normalized.length > 1) {
629
+ normalized = normalized.replace(/\/+$/, "");
630
+ }
631
+ return normalized || "/";
632
+ }
633
+ __name(normalizeRevalidatePath, "normalizeRevalidatePath");
634
+ function normalizeRevalidate(revalidate) {
635
+ if (revalidate === false || revalidate === void 0) {
636
+ return revalidate;
637
+ }
638
+ if (!Number.isFinite(revalidate) || revalidate <= 0) {
639
+ return void 0;
640
+ }
641
+ return revalidate;
642
+ }
643
+ __name(normalizeRevalidate, "normalizeRevalidate");
644
+ function normalizeCacheTag(tag) {
645
+ if (typeof tag !== "string") {
646
+ throw new TypeError("Cache tags must be strings.");
647
+ }
648
+ const normalized = tag.trim();
649
+ if (!normalized) {
650
+ throw new Error("Cache tags cannot be empty.");
651
+ }
652
+ return normalized;
653
+ }
654
+ __name(normalizeCacheTag, "normalizeCacheTag");
655
+ function normalizeCacheNamespace(namespace) {
656
+ if (typeof namespace !== "string") {
657
+ throw new TypeError("Cache namespace must be a string.");
658
+ }
659
+ const normalized = namespace.trim().replace(/:+$/g, "");
660
+ if (!normalized) {
661
+ throw new Error("Cache namespace cannot be empty.");
662
+ }
663
+ return normalized;
664
+ }
665
+ __name(normalizeCacheNamespace, "normalizeCacheNamespace");
666
+ function normalizeAdapterVersion(value) {
667
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
668
+ }
669
+ __name(normalizeAdapterVersion, "normalizeAdapterVersion");
670
+ function normalizePositiveDuration(value, fallback, name) {
671
+ if (value === void 0) return fallback;
672
+ if (!Number.isFinite(value) || value <= 0) {
673
+ throw new TypeError(`${name} must be a positive number of milliseconds.`);
674
+ }
675
+ return Math.floor(value);
676
+ }
677
+ __name(normalizePositiveDuration, "normalizePositiveDuration");
678
+ function delay(ms) {
679
+ return new Promise((resolve) => setTimeout(resolve, ms));
680
+ }
681
+ __name(delay, "delay");
682
+ function normalizeCacheOptionsTags(options) {
683
+ const tags = /* @__PURE__ */ new Set();
684
+ for (const tag of options.tags ?? []) {
685
+ tags.add(normalizeCacheTag(tag));
686
+ }
687
+ for (const routePath of options.paths ?? []) {
688
+ tags.add(createPathCacheTag(routePath));
689
+ }
690
+ return tags;
691
+ }
692
+ __name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
693
+ function assertFarmCacheEntry(entry, expectedKey) {
694
+ if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
695
+ throw new TypeError(
696
+ `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
697
+ );
698
+ }
699
+ }
700
+ __name(assertFarmCacheEntry, "assertFarmCacheEntry");
701
+
702
+ // src/api/endpoint.ts
703
+ var _EndpointFailure = class _EndpointFailure extends Error {
704
+ constructor(code, data, options) {
705
+ super(options.message);
706
+ this.name = "EndpointFailure";
707
+ this.code = code;
708
+ this.data = data;
709
+ this.status = options.status;
710
+ }
711
+ };
712
+ __name(_EndpointFailure, "EndpointFailure");
713
+ var EndpointFailure = _EndpointFailure;
714
+ function isEndpointFailure(value) {
715
+ return value instanceof EndpointFailure;
716
+ }
717
+ __name(isEndpointFailure, "isEndpointFailure");
718
+ var EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]);
719
+ var EMPTY_ENDPOINT_CONTEXT = Object.freeze(/* @__PURE__ */ Object.create(null));
720
+
65
721
  // src/api/runtime.ts
66
722
  function matchAPIRoute(routes, pathname) {
67
723
  const exactRoute = routes.get(pathname);
@@ -94,10 +750,10 @@ __name(invokeAPIRouteEndpoint, "invokeAPIRouteEndpoint");
94
750
  async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
95
751
  const farmHandler = endpoint.__handler || (isFarmContextHandler(endpoint) ? endpoint : null);
96
752
  if (!farmHandler) {
97
- const result2 = await endpoint(request, {
753
+ const result = await endpoint(request, {
98
754
  params: Promise.resolve(params)
99
755
  });
100
- return normalizeRouteResponse(result2);
756
+ return normalizeRouteResponse(result);
101
757
  }
102
758
  const url = new URL(request.url);
103
759
  const query = {};
@@ -106,7 +762,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
106
762
  });
107
763
  let body = void 0;
108
764
  if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
109
- body = await readJSONBody(request);
765
+ body = await readRequestBody(request);
110
766
  }
111
767
  const headers = Object.fromEntries(request.headers.entries());
112
768
  const types = endpoint.__types || {};
@@ -122,15 +778,30 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
122
778
  if (headersValidation instanceof Response) {
123
779
  return headersValidation;
124
780
  }
125
- const result = await farmHandler({
781
+ const handlerContext = {
126
782
  query: queryValidation,
127
783
  body: bodyValidation,
128
784
  headers: headersValidation,
129
785
  request,
130
786
  context: {},
131
787
  params
132
- });
133
- return normalizeRouteResponse(result);
788
+ };
789
+ let execution;
790
+ try {
791
+ execution = typeof endpoint.__farmInvoke === "function" ? await endpoint.__farmInvoke(handlerContext) : {
792
+ result: await farmHandler(handlerContext),
793
+ context: handlerContext.context,
794
+ handlerExecuted: true,
795
+ invalidations: []
796
+ };
797
+ } catch (error) {
798
+ if (isEndpointFailure(error)) {
799
+ return createEndpointFailureResponse(error);
800
+ }
801
+ throw error;
802
+ }
803
+ const response = normalizeRouteResponse(execution.result);
804
+ return attachEndpointInvalidations(response, execution.invalidations);
134
805
  }
135
806
  __name(invokeAPIRouteEndpointInContext, "invokeAPIRouteEndpointInContext");
136
807
  function normalizeRouteResponse(result) {
@@ -150,6 +821,40 @@ function isWebResponse(value) {
150
821
  return value instanceof Response || typeof value === "object" && value !== null && "headers" in value && "status" in value && typeof value.arrayBuffer === "function";
151
822
  }
152
823
  __name(isWebResponse, "isWebResponse");
824
+ function attachEndpointInvalidations(response, keys) {
825
+ const existing = decodeFarmCacheInvalidations(
826
+ response.headers.get(FARM_CACHE_INVALIDATION_HEADER)
827
+ );
828
+ const encoded = encodeFarmCacheInvalidations([...existing, ...keys]);
829
+ if (!encoded) return response;
830
+ const headers = new Headers(response.headers);
831
+ headers.set(FARM_CACHE_INVALIDATION_HEADER, encoded);
832
+ return new Response(response.body, {
833
+ status: response.status,
834
+ statusText: response.statusText,
835
+ headers
836
+ });
837
+ }
838
+ __name(attachEndpointInvalidations, "attachEndpointInvalidations");
839
+ function createEndpointFailureResponse(failure) {
840
+ return new Response(
841
+ JSON.stringify({
842
+ error: {
843
+ code: failure.code,
844
+ message: failure.message,
845
+ data: failure.data
846
+ }
847
+ }),
848
+ {
849
+ status: failure.status,
850
+ headers: {
851
+ "cache-control": "no-store",
852
+ "content-type": "application/json"
853
+ }
854
+ }
855
+ );
856
+ }
857
+ __name(createEndpointFailureResponse, "createEndpointFailureResponse");
153
858
  function isFarmContextHandler(endpoint) {
154
859
  if (typeof endpoint !== "function") {
155
860
  return false;
@@ -161,17 +866,50 @@ function isFarmContextHandler(endpoint) {
161
866
  return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
162
867
  }
163
868
  __name(isFarmContextHandler, "isFarmContextHandler");
164
- async function readJSONBody(request) {
869
+ async function readRequestBody(request) {
870
+ const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
165
871
  try {
872
+ if (contentType === "multipart/form-data") {
873
+ return formDataToObject(await request.clone().formData());
874
+ }
166
875
  const text = await request.clone().text();
167
- if (text) {
876
+ if (!text) return void 0;
877
+ if (contentType === "application/x-www-form-urlencoded") {
878
+ return searchParamsToObject(new URLSearchParams(text));
879
+ }
880
+ if (contentType === "application/json" || contentType?.endsWith("+json")) {
168
881
  return JSON.parse(text);
169
882
  }
883
+ return JSON.parse(text);
170
884
  } catch {
171
885
  }
172
886
  return void 0;
173
887
  }
174
- __name(readJSONBody, "readJSONBody");
888
+ __name(readRequestBody, "readRequestBody");
889
+ function formDataToObject(formData) {
890
+ return entriesToObject(formData.entries());
891
+ }
892
+ __name(formDataToObject, "formDataToObject");
893
+ function searchParamsToObject(searchParams) {
894
+ return entriesToObject(searchParams.entries());
895
+ }
896
+ __name(searchParamsToObject, "searchParamsToObject");
897
+ function entriesToObject(entries) {
898
+ const output = /* @__PURE__ */ Object.create(null);
899
+ for (const [key, value] of entries) {
900
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
901
+ const current = output[key];
902
+ if (current === void 0) {
903
+ output[key] = value;
904
+ } else if (Array.isArray(current)) {
905
+ current.push(value);
906
+ } else {
907
+ output[key] = [current, value];
908
+ }
909
+ }
910
+ return output;
911
+ }
912
+ __name(entriesToObject, "entriesToObject");
175
913
  function validateInput(schema, value, error) {
176
914
  if (!schema || typeof schema.parse !== "function") {
177
915
  return value;
@@ -264,6 +1002,7 @@ function decodePathSegment(segment) {
264
1002
  __name(decodePathSegment, "decodePathSegment");
265
1003
  // Annotate the CommonJS export names for ESM import in node:
266
1004
  0 && (module.exports = {
1005
+ createEndpointFailureResponse,
267
1006
  invokeAPIRouteEndpoint,
268
1007
  isWebResponse,
269
1008
  matchAPIRoute,