@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
package/dist/api.cjs CHANGED
@@ -31,9 +31,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/api/index.ts
32
32
  var api_exports = {};
33
33
  __export(api_exports, {
34
+ APIClientError: () => APIClientError,
34
35
  APIRouteManager: () => APIRouteManager,
35
36
  API_ROUTE_METHODS: () => API_ROUTE_METHODS,
36
37
  DELETE: () => DELETE,
38
+ EndpointFailure: () => EndpointFailure,
39
+ FARM_API_ROUTE_META_SYMBOL: () => FARM_API_ROUTE_META_SYMBOL,
40
+ FARM_API_ROUTE_REF_SYMBOL: () => FARM_API_ROUTE_REF_SYMBOL,
37
41
  GET: () => GET,
38
42
  HEAD: () => HEAD,
39
43
  OPTIONS: () => OPTIONS,
@@ -44,206 +48,25 @@ __export(api_exports, {
44
48
  createEndpoint: () => createEndpoint,
45
49
  createServerAPIClient: () => createServerAPIClient,
46
50
  farmApiPlugin: () => farmApiPlugin,
51
+ getAPIRouteRefMetadata: () => getAPIRouteRefMetadata,
47
52
  invokeAPIRouteEndpoint: () => invokeAPIRouteEndpoint,
53
+ isAPIRouteRef: () => isAPIRouteRef,
54
+ isEndpointFailure: () => isEndpointFailure,
55
+ isFarmAPIStream: () => isFarmAPIStream,
56
+ isJSONStreamResponse: () => isJSONStreamResponse,
57
+ isMultipartSchema: () => isMultipartSchema,
48
58
  isWebResponse: () => isWebResponse,
59
+ jsonStream: () => jsonStream,
49
60
  matchAPIRoute: () => matchAPIRoute,
50
- normalizeRouteResponse: () => normalizeRouteResponse
61
+ multipart: () => multipart,
62
+ normalizeRouteResponse: () => normalizeRouteResponse,
63
+ readJSONStream: () => readJSONStream,
64
+ toFormData: () => toFormData
51
65
  });
52
66
  module.exports = __toCommonJS(api_exports);
53
67
 
54
68
  // src/api/endpoint.ts
55
69
  var import_better_call = require("better-call");
56
- function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
57
- let path4;
58
- let options;
59
- let handler;
60
- if (typeof pathOrOptions === "string") {
61
- path4 = pathOrOptions;
62
- options = optionsOrHandler;
63
- handler = maybeHandler;
64
- } else {
65
- path4 = "";
66
- options = pathOrOptions;
67
- handler = optionsOrHandler;
68
- }
69
- if (typeof handler !== "function") {
70
- throw new TypeError("createEndpoint requires a handler function");
71
- }
72
- const middleware = normalizeEndpointMiddleware(options.middleware);
73
- const wrappedHandler = /* @__PURE__ */ __name(((ctx) => runEndpointMiddleware(middleware, ctx, handler)), "wrappedHandler");
74
- const { middleware: _middleware, ...betterCallOptions } = options;
75
- const endpoint = (0, import_better_call.createEndpoint)(
76
- path4 || "/__farm_auto_path__",
77
- betterCallOptions,
78
- wrappedHandler
79
- );
80
- endpoint.__path = path4 || void 0;
81
- endpoint.__method = options.method || "GET";
82
- endpoint.__autoPath = !path4;
83
- endpoint.__handler = wrappedHandler;
84
- endpoint.__middleware = middleware;
85
- endpoint.__sourceHandler = handler;
86
- endpoint.__types = {
87
- body: options.body,
88
- query: options.query,
89
- headers: options.headers,
90
- response: null
91
- };
92
- return endpoint;
93
- }
94
- __name(createEndpoint, "createEndpoint");
95
- var EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]);
96
- var EMPTY_ENDPOINT_CONTEXT = Object.freeze(/* @__PURE__ */ Object.create(null));
97
- var UNSAFE_ENDPOINT_CONTEXT_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
98
- function normalizeEndpointMiddleware(middleware) {
99
- if (middleware === void 0) return EMPTY_ENDPOINT_MIDDLEWARE;
100
- if (!Array.isArray(middleware)) {
101
- throw new TypeError("createEndpoint middleware must be an array of functions");
102
- }
103
- const normalized = [...middleware];
104
- for (const entry of normalized) {
105
- if (typeof entry !== "function") {
106
- throw new TypeError("createEndpoint middleware entries must be functions");
107
- }
108
- }
109
- return Object.freeze(normalized);
110
- }
111
- __name(normalizeEndpointMiddleware, "normalizeEndpointMiddleware");
112
- async function runEndpointMiddleware(middleware, handlerContext, handler) {
113
- let context = createInitialEndpointContext(handlerContext.context);
114
- for (let index = 0; index < middleware.length; index++) {
115
- const result = await middleware[index]({ ...handlerContext, context });
116
- if (isEndpointResponse(result)) return result;
117
- if (result === false) return forbiddenEndpointResponse();
118
- if (result === true) continue;
119
- if (!isPlainEndpointContext(result)) {
120
- throw new TypeError(
121
- `Endpoint middleware ${index + 1} must return an object, true, false, or a Response`
122
- );
123
- }
124
- context = mergeEndpointContext(context, result, index);
125
- }
126
- return handler({ ...handlerContext, context });
127
- }
128
- __name(runEndpointMiddleware, "runEndpointMiddleware");
129
- function createInitialEndpointContext(value) {
130
- if (value === void 0 || value === null) return EMPTY_ENDPOINT_CONTEXT;
131
- if (!isPlainEndpointContext(value)) {
132
- throw new TypeError("Endpoint context must be a plain object");
133
- }
134
- return mergeEndpointContext(EMPTY_ENDPOINT_CONTEXT, value);
135
- }
136
- __name(createInitialEndpointContext, "createInitialEndpointContext");
137
- function mergeEndpointContext(current, added, middlewareIndex) {
138
- const next = Object.assign(/* @__PURE__ */ Object.create(null), current);
139
- for (const key of Reflect.ownKeys(added)) {
140
- if (!Object.prototype.propertyIsEnumerable.call(added, key)) continue;
141
- if (typeof key === "string" && UNSAFE_ENDPOINT_CONTEXT_KEYS.has(key)) {
142
- throw new TypeError(`Endpoint middleware cannot provide the unsafe context key "${key}"`);
143
- }
144
- if (Object.prototype.hasOwnProperty.call(current, key)) {
145
- const source = middlewareIndex === void 0 ? "Endpoint context" : `Endpoint middleware ${middlewareIndex + 1}`;
146
- throw new TypeError(`${source} cannot replace the existing context key "${String(key)}"`);
147
- }
148
- next[key] = added[key];
149
- }
150
- return Object.freeze(next);
151
- }
152
- __name(mergeEndpointContext, "mergeEndpointContext");
153
- function isPlainEndpointContext(value) {
154
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
155
- const prototype = Object.getPrototypeOf(value);
156
- return prototype === Object.prototype || prototype === null;
157
- }
158
- __name(isPlainEndpointContext, "isPlainEndpointContext");
159
- function isEndpointResponse(value) {
160
- return value instanceof Response || typeof value === "object" && value !== null && "headers" in value && "status" in value && typeof value.arrayBuffer === "function";
161
- }
162
- __name(isEndpointResponse, "isEndpointResponse");
163
- function forbiddenEndpointResponse() {
164
- return new Response(JSON.stringify({ error: "Forbidden" }), {
165
- status: 403,
166
- headers: { "Content-Type": "application/json" }
167
- });
168
- }
169
- __name(forbiddenEndpointResponse, "forbiddenEndpointResponse");
170
- function GET(...args) {
171
- if (args.length === 1) {
172
- return createEndpoint("", { method: "GET" }, args[0]);
173
- }
174
- return createEndpoint("", { ...args[0], method: "GET" }, args[1]);
175
- }
176
- __name(GET, "GET");
177
- function HEAD(...args) {
178
- if (args.length === 1) {
179
- return createEndpoint("", { method: "HEAD" }, args[0]);
180
- }
181
- return createEndpoint("", { ...args[0], method: "HEAD" }, args[1]);
182
- }
183
- __name(HEAD, "HEAD");
184
- function POST(...args) {
185
- if (args.length === 1) {
186
- return createEndpoint("", { method: "POST" }, args[0]);
187
- }
188
- return createEndpoint("", { ...args[0], method: "POST" }, args[1]);
189
- }
190
- __name(POST, "POST");
191
- function PUT(...args) {
192
- if (args.length === 1) {
193
- return createEndpoint("", { method: "PUT" }, args[0]);
194
- }
195
- return createEndpoint("", { ...args[0], method: "PUT" }, args[1]);
196
- }
197
- __name(PUT, "PUT");
198
- function DELETE(...args) {
199
- if (args.length === 1) {
200
- return createEndpoint("", { method: "DELETE" }, args[0]);
201
- }
202
- return createEndpoint("", { ...args[0], method: "DELETE" }, args[1]);
203
- }
204
- __name(DELETE, "DELETE");
205
- function PATCH(...args) {
206
- if (args.length === 1) {
207
- return createEndpoint("", { method: "PATCH" }, args[0]);
208
- }
209
- return createEndpoint("", { ...args[0], method: "PATCH" }, args[1]);
210
- }
211
- __name(PATCH, "PATCH");
212
- function OPTIONS(...args) {
213
- if (args.length === 1) {
214
- return createEndpoint("", { method: "OPTIONS" }, args[0]);
215
- }
216
- return createEndpoint("", { ...args[0], method: "OPTIONS" }, args[1]);
217
- }
218
- __name(OPTIONS, "OPTIONS");
219
-
220
- // src/api/route-manager.ts
221
- var fs = __toESM(require("fs"));
222
- var path3 = __toESM(require("path"));
223
-
224
- // src/utils.ts
225
- var import_path = __toESM(require("path"));
226
- function toViteModuleId(filePath, root) {
227
- if (!import_path.default.isAbsolute(filePath)) return filePath;
228
- const relativePath = import_path.default.relative(root, filePath);
229
- if (relativePath && !relativePath.startsWith("..") && !import_path.default.isAbsolute(relativePath)) {
230
- return `/${relativePath.split(import_path.default.sep).join("/")}`;
231
- }
232
- const normalizedPath = filePath.replace(/\\/g, "/");
233
- return normalizedPath.startsWith("/") ? `/@fs${normalizedPath}` : `/@fs/${normalizedPath}`;
234
- }
235
- __name(toViteModuleId, "toViteModuleId");
236
- var logger = {
237
- info: /* @__PURE__ */ __name((message) => console.log(`[info] ${message}`), "info"),
238
- success: /* @__PURE__ */ __name((message) => console.log(`[success] ${message}`), "success"),
239
- warn: /* @__PURE__ */ __name((message) => console.warn(`\u26A0\uFE0F ${message}`), "warn"),
240
- error: /* @__PURE__ */ __name((message) => console.error(`\u274C ${message}`), "error"),
241
- ready: /* @__PURE__ */ __name((message) => console.log(`${message}`), "ready"),
242
- event: /* @__PURE__ */ __name((message) => console.log(` ${message}`), "event")
243
- };
244
-
245
- // src/routes.ts
246
- var import_react = require("react");
247
70
 
248
71
  // src/observability.ts
249
72
  var runtimeHandlers = /* @__PURE__ */ new Set();
@@ -361,14 +184,58 @@ function formatError(error) {
361
184
  __name(formatError, "formatError");
362
185
 
363
186
  // src/cache-invalidation.ts
187
+ var FARM_CACHE_INVALIDATION_HEADER = "x-farm-cache-invalidations";
364
188
  var FARM_CACHE_INVALIDATION_STATE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationState");
365
189
  var globalState = globalThis;
366
190
  function getFarmCacheInvalidationState() {
367
191
  return globalState[FARM_CACHE_INVALIDATION_STATE] ?? (globalState[FARM_CACHE_INVALIDATION_STATE] = {
368
- listeners: /* @__PURE__ */ new Set()
192
+ listeners: /* @__PURE__ */ new Set(),
193
+ taskListeners: /* @__PURE__ */ new Set()
369
194
  });
370
195
  }
371
196
  __name(getFarmCacheInvalidationState, "getFarmCacheInvalidationState");
197
+ function notifyFarmCacheInvalidation(key) {
198
+ if (typeof key !== "string" || key.length === 0) return;
199
+ for (const listener of getFarmCacheInvalidationState().listeners) {
200
+ listener(key);
201
+ }
202
+ }
203
+ __name(notifyFarmCacheInvalidation, "notifyFarmCacheInvalidation");
204
+ function notifyFarmCacheTask(task) {
205
+ for (const listener of getFarmCacheInvalidationState().taskListeners) {
206
+ listener(task);
207
+ }
208
+ }
209
+ __name(notifyFarmCacheTask, "notifyFarmCacheTask");
210
+ function applyFarmCacheInvalidations(keys) {
211
+ if (!Array.isArray(keys)) return;
212
+ for (const key of keys) {
213
+ if (typeof key === "string") {
214
+ notifyFarmCacheInvalidation(key);
215
+ }
216
+ }
217
+ }
218
+ __name(applyFarmCacheInvalidations, "applyFarmCacheInvalidations");
219
+ function encodeFarmCacheInvalidations(keys) {
220
+ const normalized = Array.from(
221
+ new Set(keys.filter((key) => typeof key === "string" && key.length > 0))
222
+ );
223
+ if (normalized.length === 0) return null;
224
+ return encodeURIComponent(JSON.stringify(normalized));
225
+ }
226
+ __name(encodeFarmCacheInvalidations, "encodeFarmCacheInvalidations");
227
+ function decodeFarmCacheInvalidations(value) {
228
+ if (!value) return [];
229
+ try {
230
+ const parsed = JSON.parse(decodeURIComponent(value));
231
+ return Array.isArray(parsed) ? Array.from(
232
+ new Set(parsed.filter((key) => typeof key === "string" && key.length > 0))
233
+ ) : [];
234
+ } catch {
235
+ return [];
236
+ }
237
+ }
238
+ __name(decodeFarmCacheInvalidations, "decodeFarmCacheInvalidations");
372
239
  function subscribeFarmCacheInvalidation(listener) {
373
240
  const state = getFarmCacheInvalidationState();
374
241
  state.listeners.add(listener);
@@ -385,11 +252,51 @@ __name(_setFarmI18nSnapshotResolver, "_setFarmI18nSnapshotResolver");
385
252
 
386
253
  // src/cache.ts
387
254
  var _FarmDataCache = class _FarmDataCache {
388
- constructor() {
255
+ constructor(config = {}) {
389
256
  this.entries = /* @__PURE__ */ new Map();
390
257
  this.inflight = /* @__PURE__ */ new Map();
391
258
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
392
259
  this.version = 0;
260
+ this.namespace = "farm";
261
+ this.local = true;
262
+ this.lease = {
263
+ enabled: true,
264
+ ttlMs: 1e4,
265
+ waitTimeoutMs: 1e4,
266
+ pollIntervalMs: 25
267
+ };
268
+ this.configure(config);
269
+ }
270
+ configure(config = {}) {
271
+ this.adapter = config.adapter;
272
+ this.namespace = normalizeCacheNamespace(config.namespace || "farm");
273
+ this.local = !config.adapter;
274
+ this.lease = config.lease === false ? { ...this.lease, enabled: false } : {
275
+ enabled: true,
276
+ ttlMs: normalizePositiveDuration(config.lease?.ttlMs, 1e4, "cache.lease.ttlMs"),
277
+ waitTimeoutMs: normalizePositiveDuration(
278
+ config.lease?.waitTimeoutMs,
279
+ 1e4,
280
+ "cache.lease.waitTimeoutMs"
281
+ ),
282
+ pollIntervalMs: normalizePositiveDuration(
283
+ config.lease?.pollIntervalMs,
284
+ 25,
285
+ "cache.lease.pollIntervalMs"
286
+ )
287
+ };
288
+ if (!this.local) {
289
+ this.entries.clear();
290
+ this.inflight.clear();
291
+ this.invalidatedTagVersions.clear();
292
+ this.version = 0;
293
+ }
294
+ }
295
+ get adapterName() {
296
+ return this.adapter?.name || (this.adapter ? "custom" : "memory");
297
+ }
298
+ get hasAdapter() {
299
+ return this.adapter !== void 0;
393
300
  }
394
301
  get size() {
395
302
  return this.entries.size;
@@ -425,6 +332,45 @@ var _FarmDataCache = class _FarmDataCache {
425
332
  });
426
333
  return this.toPublicEntry(entry);
427
334
  }
335
+ async getEntryAsync(key, options = {}) {
336
+ if (this.local) {
337
+ const localEntry = this.getEntry(key, options);
338
+ if (localEntry) return localEntry;
339
+ }
340
+ if (!this.adapter) {
341
+ return this.local ? void 0 : this.getEntry(key, options);
342
+ }
343
+ const entry = await this.adapter.get(this.createAdapterKey(key));
344
+ if (!entry) {
345
+ emitFarmEvent({ type: "cache.miss", key });
346
+ return void 0;
347
+ }
348
+ assertFarmCacheEntry(entry, key);
349
+ const stale = await this.isAdapterEntryStale(entry, options.now);
350
+ if (stale) {
351
+ emitFarmEvent({
352
+ type: "cache.stale",
353
+ key,
354
+ tags: [...entry.tags],
355
+ revalidate: entry.revalidate
356
+ });
357
+ if (!options.allowStale) {
358
+ emitFarmEvent({ type: "cache.miss", key, reason: "stale" });
359
+ return void 0;
360
+ }
361
+ }
362
+ emitFarmEvent({
363
+ type: "cache.hit",
364
+ key,
365
+ tags: [...entry.tags],
366
+ revalidate: entry.revalidate,
367
+ stale
368
+ });
369
+ if (this.local && !stale) {
370
+ this.hydrateLocalEntry(entry);
371
+ }
372
+ return { ...entry, key };
373
+ }
428
374
  set(key, value, options = {}) {
429
375
  const tags = /* @__PURE__ */ new Set();
430
376
  for (const tag of options.tags ?? []) {
@@ -437,6 +383,7 @@ var _FarmDataCache = class _FarmDataCache {
437
383
  key,
438
384
  value,
439
385
  tags,
386
+ tagVersions: void 0,
440
387
  createdAt: options.createdAt ?? Date.now(),
441
388
  createdVersion: ++this.version,
442
389
  revalidate: normalizeRevalidate(options.revalidate)
@@ -450,11 +397,45 @@ var _FarmDataCache = class _FarmDataCache {
450
397
  });
451
398
  return this.toPublicEntry(entry);
452
399
  }
400
+ async setAsync(key, value, options = {}, tagVersions) {
401
+ const tags = normalizeCacheOptionsTags(options);
402
+ const capturedVersions = tagVersions ?? await this.getAdapterTagVersions(Array.from(tags.values()));
403
+ const entry = {
404
+ key,
405
+ value,
406
+ tags: Array.from(tags),
407
+ tagVersions: capturedVersions,
408
+ createdAt: options.createdAt ?? Date.now(),
409
+ createdVersion: ++this.version,
410
+ revalidate: normalizeRevalidate(options.revalidate)
411
+ };
412
+ if (this.local) {
413
+ this.hydrateLocalEntry(entry);
414
+ }
415
+ if (this.adapter) {
416
+ await this.adapter.set(this.createAdapterKey(key), entry);
417
+ }
418
+ emitFarmEvent({
419
+ type: "cache.set",
420
+ key,
421
+ tags: [...entry.tags],
422
+ revalidate: entry.revalidate
423
+ });
424
+ return entry;
425
+ }
453
426
  delete(key) {
454
427
  const deleted = this.entries.delete(key);
455
428
  emitFarmEvent({ type: "cache.delete", key, deleted });
456
429
  return deleted;
457
430
  }
431
+ async deleteAsync(key) {
432
+ const deleted = this.entries.delete(key);
433
+ if (this.adapter) {
434
+ await this.adapter.delete(this.createAdapterKey(key));
435
+ }
436
+ emitFarmEvent({ type: "cache.delete", key, deleted: this.adapter ? true : deleted });
437
+ return this.adapter ? true : deleted;
438
+ }
458
439
  clear() {
459
440
  const count = this.entries.size;
460
441
  this.entries.clear();
@@ -463,6 +444,10 @@ var _FarmDataCache = class _FarmDataCache {
463
444
  this.version = 0;
464
445
  emitFarmEvent({ type: "cache.clear", count });
465
446
  }
447
+ async clearAsync() {
448
+ this.clear();
449
+ await this.adapter?.clear?.();
450
+ }
466
451
  isStale(entry, now = Date.now()) {
467
452
  if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
468
453
  return true;
@@ -475,6 +460,12 @@ var _FarmDataCache = class _FarmDataCache {
475
460
  }
476
461
  return false;
477
462
  }
463
+ async isStaleAsync(entry, now = Date.now()) {
464
+ if (this.adapter) {
465
+ return this.isAdapterEntryStale(entry, now);
466
+ }
467
+ return this.isStale(entry, now);
468
+ }
478
469
  revalidateTag(tag, options = {}) {
479
470
  const normalized = normalizeCacheTag(tag);
480
471
  const count = this.invalidateTag(normalized);
@@ -483,6 +474,15 @@ var _FarmDataCache = class _FarmDataCache {
483
474
  );
484
475
  return count;
485
476
  }
477
+ async revalidateTagAsync(tag, options = {}) {
478
+ const normalized = normalizeCacheTag(tag);
479
+ const count = this.invalidateTag(normalized);
480
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(normalized)]);
481
+ emitFarmEvent(
482
+ options.source === "updateTag" ? { type: "cache.updateTag", tag: normalized, count } : { type: "cache.revalidateTag", tag: normalized, profile: options.profile, count }
483
+ );
484
+ return count;
485
+ }
486
486
  revalidatePath(routePath) {
487
487
  const normalizedPath = normalizeRevalidatePath(routePath);
488
488
  const pathTag = createPathCacheTag(normalizedPath);
@@ -499,8 +499,25 @@ var _FarmDataCache = class _FarmDataCache {
499
499
  }
500
500
  return count;
501
501
  }
502
+ async revalidatePathAsync(routePath) {
503
+ const normalizedPath = normalizeRevalidatePath(routePath);
504
+ const pathTag = createPathCacheTag(normalizedPath);
505
+ const pprCount = this.countEntriesForTags([pathTag, "ppr"]);
506
+ const count = this.invalidateTag(pathTag);
507
+ await this.adapter?.invalidateTags?.([this.createAdapterTag(pathTag)]);
508
+ emitFarmEvent({ type: "cache.revalidatePath", path: normalizedPath, count });
509
+ if (pprCount > 0) {
510
+ emitFarmEvent({
511
+ type: "ppr.shell.invalidated",
512
+ route: normalizedPath,
513
+ reason: "revalidatePath",
514
+ count: pprCount
515
+ });
516
+ }
517
+ return count;
518
+ }
502
519
  async getOrSet(key, producer, options = {}) {
503
- const cached = this.getEntry(key);
520
+ const cached = await this.getEntryAsync(key);
504
521
  if (cached) {
505
522
  return cached.value;
506
523
  }
@@ -509,10 +526,8 @@ var _FarmDataCache = class _FarmDataCache {
509
526
  emitFarmEvent({ type: "cache.dedupe", key });
510
527
  return inflight;
511
528
  }
512
- const promise = Promise.resolve().then(producer).then((value) => {
513
- this.set(key, value, options);
514
- return value;
515
- }).catch((error) => {
529
+ const tags = Array.from(normalizeCacheOptionsTags(options));
530
+ const promise = this.fillCacheEntry(key, producer, options, tags).catch((error) => {
516
531
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
517
532
  throw error;
518
533
  }).finally(() => {
@@ -521,6 +536,40 @@ var _FarmDataCache = class _FarmDataCache {
521
536
  this.inflight.set(key, promise);
522
537
  return promise;
523
538
  }
539
+ async fillCacheEntry(key, producer, options, tags) {
540
+ const leaseKey = `${this.namespace}:lease:${key}`;
541
+ let leaseToken;
542
+ if (this.adapter?.acquireLease && this.adapter.releaseLease && this.lease.enabled) {
543
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
544
+ if (!leaseToken) {
545
+ const shared = await this.waitForAdapterEntry(key);
546
+ if (shared) {
547
+ emitFarmEvent({ type: "cache.dedupe", key });
548
+ return shared.value;
549
+ }
550
+ leaseToken = await this.adapter.acquireLease(leaseKey, this.lease.ttlMs);
551
+ }
552
+ }
553
+ try {
554
+ const initialTagVersions = await this.getAdapterTagVersions(tags);
555
+ const value = await producer();
556
+ await this.setAsync(key, value, options, initialTagVersions);
557
+ return value;
558
+ } finally {
559
+ if (leaseToken && this.adapter?.releaseLease) {
560
+ await this.adapter.releaseLease(leaseKey, leaseToken);
561
+ }
562
+ }
563
+ }
564
+ async waitForAdapterEntry(key) {
565
+ const deadline = Date.now() + this.lease.waitTimeoutMs;
566
+ while (Date.now() < deadline) {
567
+ await delay(this.lease.pollIntervalMs);
568
+ const entry = await this.getEntryAsync(key);
569
+ if (entry) return entry;
570
+ }
571
+ return void 0;
572
+ }
524
573
  countEntriesForTag(tag) {
525
574
  let count = 0;
526
575
  for (const entry of this.entries.values()) {
@@ -548,11 +597,53 @@ var _FarmDataCache = class _FarmDataCache {
548
597
  key: entry.key,
549
598
  value: entry.value,
550
599
  tags: Array.from(entry.tags),
600
+ tagVersions: entry.tagVersions,
551
601
  createdAt: entry.createdAt,
552
602
  createdVersion: entry.createdVersion,
553
603
  revalidate: entry.revalidate
554
604
  };
555
605
  }
606
+ hydrateLocalEntry(entry) {
607
+ this.entries.set(entry.key, {
608
+ key: entry.key,
609
+ value: entry.value,
610
+ tags: new Set(entry.tags.map(normalizeCacheTag)),
611
+ tagVersions: entry.tagVersions,
612
+ createdAt: entry.createdAt,
613
+ createdVersion: entry.createdVersion ?? ++this.version,
614
+ revalidate: normalizeRevalidate(entry.revalidate)
615
+ });
616
+ }
617
+ createAdapterKey(key) {
618
+ return `${this.namespace}:entry:${key}`;
619
+ }
620
+ createAdapterTag(tag) {
621
+ return `${this.namespace}:tag:${tag}`;
622
+ }
623
+ async getAdapterTagVersions(tags) {
624
+ if (!this.adapter?.getTagVersions || tags.length === 0) return {};
625
+ const normalized = tags.map(normalizeCacheTag);
626
+ const physicalTags = normalized.map((tag) => this.createAdapterTag(tag));
627
+ const versions = await this.adapter.getTagVersions(physicalTags);
628
+ return Object.fromEntries(
629
+ normalized.map((tag, index) => [
630
+ tag,
631
+ normalizeAdapterVersion(versions[physicalTags[index]])
632
+ ])
633
+ );
634
+ }
635
+ async isAdapterEntryStale(entry, now = Date.now()) {
636
+ if (typeof entry.revalidate === "number" && entry.revalidate > 0 && now - entry.createdAt >= entry.revalidate * 1e3) {
637
+ return true;
638
+ }
639
+ const currentVersions = await this.getAdapterTagVersions(entry.tags);
640
+ for (const tag of entry.tags) {
641
+ if (normalizeAdapterVersion(currentVersions[tag]) > normalizeAdapterVersion(entry.tagVersions?.[tag])) {
642
+ return true;
643
+ }
644
+ }
645
+ return false;
646
+ }
556
647
  };
557
648
  __name(_FarmDataCache, "FarmDataCache");
558
649
  var FarmDataCache = _FarmDataCache;
@@ -561,10 +652,64 @@ var farmDataCacheGlobal = globalThis;
561
652
  var sharedFarmDataCache = farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] ?? (farmDataCacheGlobal[FARM_DATA_CACHE_SYMBOL] = new FarmDataCache());
562
653
  var functionIds = /* @__PURE__ */ new WeakMap();
563
654
  var nextFunctionId = 0;
655
+ function getFarmDataCache() {
656
+ return sharedFarmDataCache;
657
+ }
658
+ __name(getFarmDataCache, "getFarmDataCache");
659
+ function updateTag(tag) {
660
+ const cache = getFarmDataCache();
661
+ if (cache.hasAdapter) {
662
+ const task = cache.revalidateTagAsync(tag, { source: "updateTag" }).then(() => void 0);
663
+ notifyFarmCacheTask(task);
664
+ return task;
665
+ }
666
+ cache.revalidateTag(tag, { source: "updateTag" });
667
+ }
668
+ __name(updateTag, "updateTag");
669
+ function revalidatePath(routePath) {
670
+ const cache = getFarmDataCache();
671
+ if (cache.hasAdapter) {
672
+ const task = cache.revalidatePathAsync(routePath).then(() => void 0);
673
+ notifyFarmCacheTask(task);
674
+ return task;
675
+ }
676
+ cache.revalidatePath(routePath);
677
+ }
678
+ __name(revalidatePath, "revalidatePath");
679
+ function invalidate(key) {
680
+ const clientKey = createRouteDataCacheKey(key);
681
+ const task = updateTag(createRouteDataCacheTag(key));
682
+ notifyFarmCacheInvalidation(clientKey);
683
+ return task;
684
+ }
685
+ __name(invalidate, "invalidate");
686
+ async function applyFarmCacheInvalidationTargets(targets) {
687
+ if (!Array.isArray(targets)) {
688
+ throw new TypeError("Cache invalidations must resolve to an array of targets.");
689
+ }
690
+ const clientKeys = [];
691
+ for (const target of targets) {
692
+ assertFarmCacheInvalidationTarget(target);
693
+ if ("key" in target) {
694
+ await invalidate(target.key);
695
+ clientKeys.push(createRouteDataCacheKey(target.key));
696
+ } else if ("path" in target) {
697
+ await revalidatePath(target.path);
698
+ } else {
699
+ await updateTag(target.tag);
700
+ }
701
+ }
702
+ return Array.from(new Set(clientKeys));
703
+ }
704
+ __name(applyFarmCacheInvalidationTargets, "applyFarmCacheInvalidationTargets");
564
705
  function createPathCacheTag(routePath) {
565
706
  return `path:${normalizeRevalidatePath(routePath)}`;
566
707
  }
567
708
  __name(createPathCacheTag, "createPathCacheTag");
709
+ function createRouteDataCacheTag(key) {
710
+ return `route-data:${createRouteDataCacheKey(key)}`;
711
+ }
712
+ __name(createRouteDataCacheTag, "createRouteDataCacheTag");
568
713
  function createRouteDataCacheKey(key) {
569
714
  return createFarmCacheKey(Array.isArray(key) ? key : [key]);
570
715
  }
@@ -603,73 +748,618 @@ function normalizeRevalidate(revalidate) {
603
748
  if (!Number.isFinite(revalidate) || revalidate <= 0) {
604
749
  return void 0;
605
750
  }
606
- return revalidate;
751
+ return revalidate;
752
+ }
753
+ __name(normalizeRevalidate, "normalizeRevalidate");
754
+ function normalizeCacheTag(tag) {
755
+ if (typeof tag !== "string") {
756
+ throw new TypeError("Cache tags must be strings.");
757
+ }
758
+ const normalized = tag.trim();
759
+ if (!normalized) {
760
+ throw new Error("Cache tags cannot be empty.");
761
+ }
762
+ return normalized;
763
+ }
764
+ __name(normalizeCacheTag, "normalizeCacheTag");
765
+ function normalizeCacheNamespace(namespace) {
766
+ if (typeof namespace !== "string") {
767
+ throw new TypeError("Cache namespace must be a string.");
768
+ }
769
+ const normalized = namespace.trim().replace(/:+$/g, "");
770
+ if (!normalized) {
771
+ throw new Error("Cache namespace cannot be empty.");
772
+ }
773
+ return normalized;
774
+ }
775
+ __name(normalizeCacheNamespace, "normalizeCacheNamespace");
776
+ function normalizeAdapterVersion(value) {
777
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
778
+ }
779
+ __name(normalizeAdapterVersion, "normalizeAdapterVersion");
780
+ function normalizePositiveDuration(value, fallback, name) {
781
+ if (value === void 0) return fallback;
782
+ if (!Number.isFinite(value) || value <= 0) {
783
+ throw new TypeError(`${name} must be a positive number of milliseconds.`);
784
+ }
785
+ return Math.floor(value);
786
+ }
787
+ __name(normalizePositiveDuration, "normalizePositiveDuration");
788
+ function delay(ms) {
789
+ return new Promise((resolve) => setTimeout(resolve, ms));
790
+ }
791
+ __name(delay, "delay");
792
+ function normalizeCacheOptionsTags(options) {
793
+ const tags = /* @__PURE__ */ new Set();
794
+ for (const tag of options.tags ?? []) {
795
+ tags.add(normalizeCacheTag(tag));
796
+ }
797
+ for (const routePath of options.paths ?? []) {
798
+ tags.add(createPathCacheTag(routePath));
799
+ }
800
+ return tags;
801
+ }
802
+ __name(normalizeCacheOptionsTags, "normalizeCacheOptionsTags");
803
+ function assertFarmCacheEntry(entry, expectedKey) {
804
+ if (!entry || typeof entry !== "object" || entry.key !== expectedKey || !Array.isArray(entry.tags) || typeof entry.createdAt !== "number") {
805
+ throw new TypeError(
806
+ `Cache adapter returned an invalid entry for ${JSON.stringify(expectedKey)}.`
807
+ );
808
+ }
809
+ }
810
+ __name(assertFarmCacheEntry, "assertFarmCacheEntry");
811
+ function assertFarmCacheInvalidationTarget(target) {
812
+ if (!target || typeof target !== "object") {
813
+ throw new TypeError("Cache invalidation targets must be { key }, { path }, or { tag }.");
814
+ }
815
+ if ("key" in target) {
816
+ const key = target.key;
817
+ if (typeof key === "string" || Array.isArray(key)) return;
818
+ } else if ("path" in target && typeof target.path === "string") {
819
+ return;
820
+ } else if ("tag" in target && typeof target.tag === "string") {
821
+ return;
822
+ }
823
+ throw new TypeError("Cache invalidation targets must contain a string/array key, path, or tag.");
824
+ }
825
+ __name(assertFarmCacheInvalidationTarget, "assertFarmCacheInvalidationTarget");
826
+ function getFunctionCacheIdentity(fn) {
827
+ if (fn.name) {
828
+ return `name:${fn.name}`;
829
+ }
830
+ let id = functionIds.get(fn);
831
+ if (!id) {
832
+ id = ++nextFunctionId;
833
+ functionIds.set(fn, id);
834
+ }
835
+ return `anonymous:${id}`;
836
+ }
837
+ __name(getFunctionCacheIdentity, "getFunctionCacheIdentity");
838
+ function stableSerialize(value, seen = /* @__PURE__ */ new WeakSet()) {
839
+ if (value === null) return "null";
840
+ if (value === void 0) return "undefined";
841
+ const valueType = typeof value;
842
+ if (valueType === "string") return JSON.stringify(value);
843
+ if (valueType === "number" || valueType === "boolean" || valueType === "bigint") {
844
+ return `${valueType}:${String(value)}`;
845
+ }
846
+ if (valueType === "symbol") {
847
+ return `symbol:${String(value)}`;
848
+ }
849
+ if (valueType === "function") {
850
+ return `function:${getFunctionCacheIdentity(value)}`;
851
+ }
852
+ if (value instanceof Date) {
853
+ return `date:${value.toISOString()}`;
854
+ }
855
+ if (value instanceof URL) {
856
+ return `url:${value.toString()}`;
857
+ }
858
+ if (value instanceof RegExp) {
859
+ return `regexp:${value.toString()}`;
860
+ }
861
+ if (Array.isArray(value)) {
862
+ return `[${value.map((item) => stableSerialize(item, seen)).join(",")}]`;
863
+ }
864
+ if (value && typeof value === "object") {
865
+ if (seen.has(value)) {
866
+ return "[Circular]";
867
+ }
868
+ seen.add(value);
869
+ const entries = Object.entries(value).sort(
870
+ ([a], [b]) => a.localeCompare(b)
871
+ );
872
+ const serialized = entries.map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item, seen)}`).join(",");
873
+ seen.delete(value);
874
+ return `{${serialized}}`;
875
+ }
876
+ return String(value);
877
+ }
878
+ __name(stableSerialize, "stableSerialize");
879
+
880
+ // src/api/transport.ts
881
+ function multipart(schema) {
882
+ if (!Object.isExtensible(schema) && !isMultipartSchema(schema)) {
883
+ throw new TypeError("multipart() requires an extensible schema object");
884
+ }
885
+ if (!isMultipartSchema(schema)) {
886
+ Object.defineProperty(schema, "__farmMultipartSchema", {
887
+ value: true,
888
+ configurable: false,
889
+ enumerable: false,
890
+ writable: false
891
+ });
892
+ }
893
+ return schema;
894
+ }
895
+ __name(multipart, "multipart");
896
+ function isMultipartSchema(value) {
897
+ return typeof value === "object" && value !== null && value.__farmMultipartSchema === true && typeof value.parse === "function";
898
+ }
899
+ __name(isMultipartSchema, "isMultipartSchema");
900
+ function toFormData(values) {
901
+ const formData = new FormData();
902
+ for (const [key, value] of Object.entries(values)) {
903
+ if (isUnsafeFormKey(key)) continue;
904
+ if (Array.isArray(value)) {
905
+ for (const entry of value) appendFormValue(formData, key, entry);
906
+ continue;
907
+ }
908
+ appendFormValue(formData, key, value);
909
+ }
910
+ return formData;
911
+ }
912
+ __name(toFormData, "toFormData");
913
+ function jsonStream(source, init = {}) {
914
+ const iterator = toAsyncIterator(source);
915
+ const encoder = new TextEncoder();
916
+ let finished = false;
917
+ const body = new ReadableStream(
918
+ {
919
+ async pull(controller) {
920
+ if (finished) return;
921
+ try {
922
+ const next = await iterator.next();
923
+ if (next.done) {
924
+ finished = true;
925
+ controller.close();
926
+ return;
927
+ }
928
+ controller.enqueue(encoder.encode(`${JSON.stringify(next.value)}
929
+ `));
930
+ } catch (error) {
931
+ finished = true;
932
+ controller.error(error);
933
+ }
934
+ },
935
+ async cancel(reason) {
936
+ finished = true;
937
+ await iterator.return?.(reason);
938
+ }
939
+ },
940
+ {
941
+ // Do not read the next application event until the response consumer
942
+ // requests another chunk.
943
+ highWaterMark: 0
944
+ }
945
+ );
946
+ const headers = new Headers(init.headers);
947
+ if (!headers.has("content-type")) {
948
+ headers.set("content-type", "application/x-ndjson; charset=utf-8");
949
+ }
950
+ headers.set("cache-control", headers.get("cache-control") ?? "no-store");
951
+ return new Response(body, {
952
+ ...init,
953
+ headers
954
+ });
955
+ }
956
+ __name(jsonStream, "jsonStream");
957
+ function isJSONStreamResponse(response) {
958
+ const contentType = response.headers?.get?.("content-type")?.toLowerCase() ?? "";
959
+ return contentType.includes("application/x-ndjson") || contentType.includes("application/ndjson");
960
+ }
961
+ __name(isJSONStreamResponse, "isJSONStreamResponse");
962
+ function readJSONStream(response) {
963
+ if (!response.body) {
964
+ throw new TypeError("Cannot read a JSON stream response without a body");
965
+ }
966
+ const reader = response.body.getReader();
967
+ const decoder = new TextDecoder();
968
+ let buffer = "";
969
+ let completed = false;
970
+ let claimed = false;
971
+ const iterator = {
972
+ async next() {
973
+ while (true) {
974
+ const lineEnd = buffer.indexOf("\n");
975
+ if (lineEnd >= 0) {
976
+ const line = buffer.slice(0, lineEnd).trim();
977
+ buffer = buffer.slice(lineEnd + 1);
978
+ if (!line) continue;
979
+ return { done: false, value: JSON.parse(line) };
980
+ }
981
+ if (completed) {
982
+ const line = buffer.trim();
983
+ buffer = "";
984
+ if (!line) return { done: true, value: void 0 };
985
+ return { done: false, value: JSON.parse(line) };
986
+ }
987
+ const chunk = await reader.read();
988
+ completed = chunk.done;
989
+ buffer += decoder.decode(chunk.value, { stream: !chunk.done });
990
+ }
991
+ },
992
+ async return() {
993
+ completed = true;
994
+ buffer = "";
995
+ await reader.cancel();
996
+ return { done: true, value: void 0 };
997
+ }
998
+ };
999
+ return {
1000
+ response,
1001
+ async cancel(reason) {
1002
+ completed = true;
1003
+ buffer = "";
1004
+ await reader.cancel(reason);
1005
+ },
1006
+ [Symbol.asyncIterator]() {
1007
+ if (claimed) {
1008
+ throw new TypeError("Farm API streams can only be consumed once");
1009
+ }
1010
+ claimed = true;
1011
+ return iterator;
1012
+ }
1013
+ };
1014
+ }
1015
+ __name(readJSONStream, "readJSONStream");
1016
+ function isFarmAPIStream(value) {
1017
+ return typeof value === "object" && value !== null && "response" in value && typeof value.cancel === "function" && typeof value[Symbol.asyncIterator] === "function";
1018
+ }
1019
+ __name(isFarmAPIStream, "isFarmAPIStream");
1020
+ function appendFormValue(formData, key, value) {
1021
+ if (value === void 0) return;
1022
+ if (value === null) {
1023
+ formData.append(key, "");
1024
+ return;
1025
+ }
1026
+ if (value instanceof Blob) {
1027
+ formData.append(key, value);
1028
+ return;
1029
+ }
1030
+ if (value instanceof Date) {
1031
+ formData.append(key, value.toISOString());
1032
+ return;
1033
+ }
1034
+ formData.append(key, String(value));
1035
+ }
1036
+ __name(appendFormValue, "appendFormValue");
1037
+ function isUnsafeFormKey(key) {
1038
+ return key === "__proto__" || key === "constructor" || key === "prototype";
1039
+ }
1040
+ __name(isUnsafeFormKey, "isUnsafeFormKey");
1041
+ function toAsyncIterator(source) {
1042
+ if (Symbol.asyncIterator in Object(source)) {
1043
+ return source[Symbol.asyncIterator]();
1044
+ }
1045
+ const iterator = source[Symbol.iterator]();
1046
+ return {
1047
+ next: /* @__PURE__ */ __name(async () => iterator.next(), "next"),
1048
+ return: iterator.return ? async (value) => iterator.return(value) : void 0
1049
+ };
1050
+ }
1051
+ __name(toAsyncIterator, "toAsyncIterator");
1052
+
1053
+ // src/api/endpoint.ts
1054
+ var _EndpointFailure = class _EndpointFailure extends Error {
1055
+ constructor(code, data, options) {
1056
+ super(options.message);
1057
+ this.name = "EndpointFailure";
1058
+ this.code = code;
1059
+ this.data = data;
1060
+ this.status = options.status;
1061
+ }
1062
+ };
1063
+ __name(_EndpointFailure, "EndpointFailure");
1064
+ var EndpointFailure = _EndpointFailure;
1065
+ function isEndpointFailure(value) {
1066
+ return value instanceof EndpointFailure;
1067
+ }
1068
+ __name(isEndpointFailure, "isEndpointFailure");
1069
+ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
1070
+ let path4;
1071
+ let options;
1072
+ let handler;
1073
+ if (typeof pathOrOptions === "string") {
1074
+ path4 = pathOrOptions;
1075
+ options = optionsOrHandler;
1076
+ handler = maybeHandler;
1077
+ } else {
1078
+ path4 = "";
1079
+ options = pathOrOptions;
1080
+ handler = optionsOrHandler;
1081
+ }
1082
+ if (typeof handler !== "function") {
1083
+ throw new TypeError("createEndpoint requires a handler function");
1084
+ }
1085
+ const middleware = normalizeEndpointMiddleware(options.middleware);
1086
+ const errors = normalizeEndpointErrors(options.errors);
1087
+ const fail = createEndpointFail(errors);
1088
+ const wrappedHandler = /* @__PURE__ */ __name((async (ctx) => {
1089
+ const execution = await runEndpointMiddleware(
1090
+ middleware,
1091
+ ctx,
1092
+ handler,
1093
+ fail,
1094
+ options.invalidates
1095
+ );
1096
+ return execution.result;
1097
+ }), "wrappedHandler");
1098
+ const {
1099
+ middleware: _middleware,
1100
+ errors: _errors,
1101
+ invalidates: _invalidates,
1102
+ ...betterCallOptions
1103
+ } = options;
1104
+ const endpoint = (0, import_better_call.createEndpoint)(
1105
+ path4 || "/__farm_auto_path__",
1106
+ betterCallOptions,
1107
+ wrappedHandler
1108
+ );
1109
+ endpoint.__path = path4 || void 0;
1110
+ endpoint.__method = options.method || "GET";
1111
+ endpoint.__autoPath = !path4;
1112
+ endpoint.__handler = wrappedHandler;
1113
+ endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, fail, options.invalidates);
1114
+ endpoint.__middleware = middleware;
1115
+ endpoint.__sourceHandler = handler;
1116
+ endpoint.__invalidates = options.invalidates;
1117
+ endpoint.__errors = errors;
1118
+ endpoint.__types = {
1119
+ body: options.body,
1120
+ inputBody: isMultipartSchema(options.body) ? "form-data" : options.body,
1121
+ query: options.query,
1122
+ headers: options.headers,
1123
+ response: null,
1124
+ errors
1125
+ };
1126
+ return endpoint;
1127
+ }
1128
+ __name(createEndpoint, "createEndpoint");
1129
+ var EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]);
1130
+ var EMPTY_ENDPOINT_CONTEXT = Object.freeze(/* @__PURE__ */ Object.create(null));
1131
+ var UNSAFE_ENDPOINT_CONTEXT_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
1132
+ function normalizeEndpointErrors(definitions) {
1133
+ if (definitions === void 0) return Object.freeze({});
1134
+ if (!isPlainEndpointContext(definitions)) {
1135
+ throw new TypeError("createEndpoint errors must be an object");
1136
+ }
1137
+ const normalized = /* @__PURE__ */ Object.create(null);
1138
+ for (const [code, definition] of Object.entries(definitions)) {
1139
+ if (!code.trim()) {
1140
+ throw new TypeError("Endpoint error codes cannot be empty");
1141
+ }
1142
+ if (!definition || typeof definition !== "object") {
1143
+ throw new TypeError(`Endpoint error "${code}" must be an object`);
1144
+ }
1145
+ if (!Number.isInteger(definition.status) || definition.status < 400 || definition.status > 599) {
1146
+ throw new TypeError(`Endpoint error "${code}" status must be an integer between 400 and 599`);
1147
+ }
1148
+ if (!definition.schema || typeof definition.schema.parse !== "function") {
1149
+ throw new TypeError(`Endpoint error "${code}" requires a schema with parse()`);
1150
+ }
1151
+ if (definition.message !== void 0 && typeof definition.message !== "string") {
1152
+ throw new TypeError(`Endpoint error "${code}" message must be a string`);
1153
+ }
1154
+ normalized[code] = Object.freeze({ ...definition });
1155
+ }
1156
+ return Object.freeze(normalized);
1157
+ }
1158
+ __name(normalizeEndpointErrors, "normalizeEndpointErrors");
1159
+ function createEndpointFail(definitions) {
1160
+ return ((code, data) => {
1161
+ const definition = definitions[code];
1162
+ if (!definition) {
1163
+ throw new TypeError(`Endpoint error "${code}" is not declared`);
1164
+ }
1165
+ const parsed = definition.schema.parse(data);
1166
+ throw new EndpointFailure(code, parsed, {
1167
+ status: definition.status,
1168
+ message: definition.message ?? "Request failed"
1169
+ });
1170
+ });
1171
+ }
1172
+ __name(createEndpointFail, "createEndpointFail");
1173
+ function normalizeEndpointMiddleware(middleware) {
1174
+ if (middleware === void 0) return EMPTY_ENDPOINT_MIDDLEWARE;
1175
+ if (!Array.isArray(middleware)) {
1176
+ throw new TypeError("createEndpoint middleware must be an array of functions");
1177
+ }
1178
+ const normalized = [...middleware];
1179
+ for (const entry of normalized) {
1180
+ if (typeof entry !== "function") {
1181
+ throw new TypeError("createEndpoint middleware entries must be functions");
1182
+ }
1183
+ }
1184
+ return Object.freeze(normalized);
607
1185
  }
608
- __name(normalizeRevalidate, "normalizeRevalidate");
609
- function normalizeCacheTag(tag) {
610
- if (typeof tag !== "string") {
611
- throw new TypeError("Cache tags must be strings.");
1186
+ __name(normalizeEndpointMiddleware, "normalizeEndpointMiddleware");
1187
+ async function runEndpointMiddleware(middleware, handlerContext, handler, fail, invalidations) {
1188
+ let context = createInitialEndpointContext(handlerContext.context);
1189
+ for (let index = 0; index < middleware.length; index++) {
1190
+ const result2 = await middleware[index]({ ...handlerContext, context });
1191
+ if (isEndpointResponse(result2)) {
1192
+ return {
1193
+ result: result2,
1194
+ context,
1195
+ handlerExecuted: false,
1196
+ invalidations: []
1197
+ };
1198
+ }
1199
+ if (result2 === false) {
1200
+ return {
1201
+ result: forbiddenEndpointResponse(),
1202
+ context,
1203
+ handlerExecuted: false,
1204
+ invalidations: []
1205
+ };
1206
+ }
1207
+ if (result2 === true) continue;
1208
+ if (!isPlainEndpointContext(result2)) {
1209
+ throw new TypeError(
1210
+ `Endpoint middleware ${index + 1} must return an object, true, false, or a Response`
1211
+ );
1212
+ }
1213
+ context = mergeEndpointContext(context, result2, index);
612
1214
  }
613
- const normalized = tag.trim();
614
- if (!normalized) {
615
- throw new Error("Cache tags cannot be empty.");
1215
+ const result = await handler({ ...handlerContext, context, fail });
1216
+ return {
1217
+ result,
1218
+ context,
1219
+ handlerExecuted: true,
1220
+ invalidations: await applyEndpointInvalidations(
1221
+ invalidations,
1222
+ {
1223
+ ...handlerContext,
1224
+ context,
1225
+ result
1226
+ },
1227
+ result
1228
+ )
1229
+ };
1230
+ }
1231
+ __name(runEndpointMiddleware, "runEndpointMiddleware");
1232
+ async function applyEndpointInvalidations(declaration, context, result) {
1233
+ if (!declaration || isEndpointResponse(result) && result.status >= 400) {
1234
+ return [];
1235
+ }
1236
+ const targets = typeof declaration === "function" ? await declaration(context) : declaration;
1237
+ if (!Array.isArray(targets)) {
1238
+ throw new TypeError(
1239
+ "Endpoint invalidates must resolve to an array of { key }, { path }, or { tag } targets"
1240
+ );
616
1241
  }
617
- return normalized;
1242
+ return applyFarmCacheInvalidationTargets(targets);
618
1243
  }
619
- __name(normalizeCacheTag, "normalizeCacheTag");
620
- function getFunctionCacheIdentity(fn) {
621
- if (fn.name) {
622
- return `name:${fn.name}`;
1244
+ __name(applyEndpointInvalidations, "applyEndpointInvalidations");
1245
+ function createInitialEndpointContext(value) {
1246
+ if (value === void 0 || value === null) return EMPTY_ENDPOINT_CONTEXT;
1247
+ if (!isPlainEndpointContext(value)) {
1248
+ throw new TypeError("Endpoint context must be a plain object");
623
1249
  }
624
- let id = functionIds.get(fn);
625
- if (!id) {
626
- id = ++nextFunctionId;
627
- functionIds.set(fn, id);
1250
+ return mergeEndpointContext(EMPTY_ENDPOINT_CONTEXT, value);
1251
+ }
1252
+ __name(createInitialEndpointContext, "createInitialEndpointContext");
1253
+ function mergeEndpointContext(current, added, middlewareIndex) {
1254
+ const next = Object.assign(/* @__PURE__ */ Object.create(null), current);
1255
+ for (const key of Reflect.ownKeys(added)) {
1256
+ if (!Object.prototype.propertyIsEnumerable.call(added, key)) continue;
1257
+ if (typeof key === "string" && UNSAFE_ENDPOINT_CONTEXT_KEYS.has(key)) {
1258
+ throw new TypeError(`Endpoint middleware cannot provide the unsafe context key "${key}"`);
1259
+ }
1260
+ if (Object.prototype.hasOwnProperty.call(current, key)) {
1261
+ const source = middlewareIndex === void 0 ? "Endpoint context" : `Endpoint middleware ${middlewareIndex + 1}`;
1262
+ throw new TypeError(`${source} cannot replace the existing context key "${String(key)}"`);
1263
+ }
1264
+ next[key] = added[key];
628
1265
  }
629
- return `anonymous:${id}`;
1266
+ return Object.freeze(next);
630
1267
  }
631
- __name(getFunctionCacheIdentity, "getFunctionCacheIdentity");
632
- function stableSerialize(value, seen = /* @__PURE__ */ new WeakSet()) {
633
- if (value === null) return "null";
634
- if (value === void 0) return "undefined";
635
- const valueType = typeof value;
636
- if (valueType === "string") return JSON.stringify(value);
637
- if (valueType === "number" || valueType === "boolean" || valueType === "bigint") {
638
- return `${valueType}:${String(value)}`;
1268
+ __name(mergeEndpointContext, "mergeEndpointContext");
1269
+ function isPlainEndpointContext(value) {
1270
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1271
+ const prototype = Object.getPrototypeOf(value);
1272
+ return prototype === Object.prototype || prototype === null;
1273
+ }
1274
+ __name(isPlainEndpointContext, "isPlainEndpointContext");
1275
+ function isEndpointResponse(value) {
1276
+ return value instanceof Response || typeof value === "object" && value !== null && "headers" in value && "status" in value && typeof value.arrayBuffer === "function";
1277
+ }
1278
+ __name(isEndpointResponse, "isEndpointResponse");
1279
+ function forbiddenEndpointResponse() {
1280
+ return new Response(JSON.stringify({ error: "Forbidden" }), {
1281
+ status: 403,
1282
+ headers: { "Content-Type": "application/json" }
1283
+ });
1284
+ }
1285
+ __name(forbiddenEndpointResponse, "forbiddenEndpointResponse");
1286
+ function GET(...args) {
1287
+ if (args.length === 1) {
1288
+ return createEndpoint("", { method: "GET" }, args[0]);
639
1289
  }
640
- if (valueType === "symbol") {
641
- return `symbol:${String(value)}`;
1290
+ return createEndpoint("", { ...args[0], method: "GET" }, args[1]);
1291
+ }
1292
+ __name(GET, "GET");
1293
+ function HEAD(...args) {
1294
+ if (args.length === 1) {
1295
+ return createEndpoint("", { method: "HEAD" }, args[0]);
642
1296
  }
643
- if (valueType === "function") {
644
- return `function:${getFunctionCacheIdentity(value)}`;
1297
+ return createEndpoint("", { ...args[0], method: "HEAD" }, args[1]);
1298
+ }
1299
+ __name(HEAD, "HEAD");
1300
+ function POST(...args) {
1301
+ if (args.length === 1) {
1302
+ return createEndpoint("", { method: "POST" }, args[0]);
645
1303
  }
646
- if (value instanceof Date) {
647
- return `date:${value.toISOString()}`;
1304
+ return createEndpoint("", { ...args[0], method: "POST" }, args[1]);
1305
+ }
1306
+ __name(POST, "POST");
1307
+ function PUT(...args) {
1308
+ if (args.length === 1) {
1309
+ return createEndpoint("", { method: "PUT" }, args[0]);
648
1310
  }
649
- if (value instanceof URL) {
650
- return `url:${value.toString()}`;
1311
+ return createEndpoint("", { ...args[0], method: "PUT" }, args[1]);
1312
+ }
1313
+ __name(PUT, "PUT");
1314
+ function DELETE(...args) {
1315
+ if (args.length === 1) {
1316
+ return createEndpoint("", { method: "DELETE" }, args[0]);
651
1317
  }
652
- if (value instanceof RegExp) {
653
- return `regexp:${value.toString()}`;
1318
+ return createEndpoint("", { ...args[0], method: "DELETE" }, args[1]);
1319
+ }
1320
+ __name(DELETE, "DELETE");
1321
+ function PATCH(...args) {
1322
+ if (args.length === 1) {
1323
+ return createEndpoint("", { method: "PATCH" }, args[0]);
654
1324
  }
655
- if (Array.isArray(value)) {
656
- return `[${value.map((item) => stableSerialize(item, seen)).join(",")}]`;
1325
+ return createEndpoint("", { ...args[0], method: "PATCH" }, args[1]);
1326
+ }
1327
+ __name(PATCH, "PATCH");
1328
+ function OPTIONS(...args) {
1329
+ if (args.length === 1) {
1330
+ return createEndpoint("", { method: "OPTIONS" }, args[0]);
657
1331
  }
658
- if (value && typeof value === "object") {
659
- if (seen.has(value)) {
660
- return "[Circular]";
661
- }
662
- seen.add(value);
663
- const entries = Object.entries(value).sort(
664
- ([a], [b]) => a.localeCompare(b)
665
- );
666
- const serialized = entries.map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item, seen)}`).join(",");
667
- seen.delete(value);
668
- return `{${serialized}}`;
1332
+ return createEndpoint("", { ...args[0], method: "OPTIONS" }, args[1]);
1333
+ }
1334
+ __name(OPTIONS, "OPTIONS");
1335
+
1336
+ // src/api/route-manager.ts
1337
+ var fs = __toESM(require("fs"));
1338
+ var path3 = __toESM(require("path"));
1339
+
1340
+ // src/utils.ts
1341
+ var import_path = __toESM(require("path"));
1342
+ function toViteModuleId(filePath, root) {
1343
+ if (!import_path.default.isAbsolute(filePath)) return filePath;
1344
+ const relativePath = import_path.default.relative(root, filePath);
1345
+ if (relativePath && !relativePath.startsWith("..") && !import_path.default.isAbsolute(relativePath)) {
1346
+ return `/${relativePath.split(import_path.default.sep).join("/")}`;
669
1347
  }
670
- return String(value);
1348
+ const normalizedPath = filePath.replace(/\\/g, "/");
1349
+ return normalizedPath.startsWith("/") ? `/@fs${normalizedPath}` : `/@fs/${normalizedPath}`;
671
1350
  }
672
- __name(stableSerialize, "stableSerialize");
1351
+ __name(toViteModuleId, "toViteModuleId");
1352
+ var logger = {
1353
+ info: /* @__PURE__ */ __name((message) => console.log(`[info] ${message}`), "info"),
1354
+ success: /* @__PURE__ */ __name((message) => console.log(`[success] ${message}`), "success"),
1355
+ warn: /* @__PURE__ */ __name((message) => console.warn(`\u26A0\uFE0F ${message}`), "warn"),
1356
+ error: /* @__PURE__ */ __name((message) => console.error(`\u274C ${message}`), "error"),
1357
+ ready: /* @__PURE__ */ __name((message) => console.log(`${message}`), "ready"),
1358
+ event: /* @__PURE__ */ __name((message) => console.log(` ${message}`), "event")
1359
+ };
1360
+
1361
+ // src/routes.ts
1362
+ var import_react = require("react");
673
1363
 
674
1364
  // src/route-runtime.ts
675
1365
  function normalizeFarmRouteRuntimeConfig(value, source = "Route configuration") {
@@ -1032,10 +1722,10 @@ __name(invokeAPIRouteEndpoint, "invokeAPIRouteEndpoint");
1032
1722
  async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
1033
1723
  const farmHandler = endpoint.__handler || (isFarmContextHandler(endpoint) ? endpoint : null);
1034
1724
  if (!farmHandler) {
1035
- const result2 = await endpoint(request, {
1725
+ const result = await endpoint(request, {
1036
1726
  params: Promise.resolve(params)
1037
1727
  });
1038
- return normalizeRouteResponse(result2);
1728
+ return normalizeRouteResponse(result);
1039
1729
  }
1040
1730
  const url = new URL(request.url);
1041
1731
  const query = {};
@@ -1044,7 +1734,7 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
1044
1734
  });
1045
1735
  let body = void 0;
1046
1736
  if (request.method.toUpperCase() !== "GET" && request.method.toUpperCase() !== "HEAD") {
1047
- body = await readJSONBody(request);
1737
+ body = await readRequestBody(request);
1048
1738
  }
1049
1739
  const headers = Object.fromEntries(request.headers.entries());
1050
1740
  const types = endpoint.__types || {};
@@ -1060,15 +1750,30 @@ async function invokeAPIRouteEndpointInContext(endpoint, request, params) {
1060
1750
  if (headersValidation instanceof Response) {
1061
1751
  return headersValidation;
1062
1752
  }
1063
- const result = await farmHandler({
1753
+ const handlerContext = {
1064
1754
  query: queryValidation,
1065
1755
  body: bodyValidation,
1066
1756
  headers: headersValidation,
1067
1757
  request,
1068
1758
  context: {},
1069
1759
  params
1070
- });
1071
- return normalizeRouteResponse(result);
1760
+ };
1761
+ let execution;
1762
+ try {
1763
+ execution = typeof endpoint.__farmInvoke === "function" ? await endpoint.__farmInvoke(handlerContext) : {
1764
+ result: await farmHandler(handlerContext),
1765
+ context: handlerContext.context,
1766
+ handlerExecuted: true,
1767
+ invalidations: []
1768
+ };
1769
+ } catch (error) {
1770
+ if (isEndpointFailure(error)) {
1771
+ return createEndpointFailureResponse(error);
1772
+ }
1773
+ throw error;
1774
+ }
1775
+ const response = normalizeRouteResponse(execution.result);
1776
+ return attachEndpointInvalidations(response, execution.invalidations);
1072
1777
  }
1073
1778
  __name(invokeAPIRouteEndpointInContext, "invokeAPIRouteEndpointInContext");
1074
1779
  function normalizeRouteResponse(result) {
@@ -1088,6 +1793,40 @@ function isWebResponse(value) {
1088
1793
  return value instanceof Response || typeof value === "object" && value !== null && "headers" in value && "status" in value && typeof value.arrayBuffer === "function";
1089
1794
  }
1090
1795
  __name(isWebResponse, "isWebResponse");
1796
+ function attachEndpointInvalidations(response, keys) {
1797
+ const existing = decodeFarmCacheInvalidations(
1798
+ response.headers.get(FARM_CACHE_INVALIDATION_HEADER)
1799
+ );
1800
+ const encoded = encodeFarmCacheInvalidations([...existing, ...keys]);
1801
+ if (!encoded) return response;
1802
+ const headers = new Headers(response.headers);
1803
+ headers.set(FARM_CACHE_INVALIDATION_HEADER, encoded);
1804
+ return new Response(response.body, {
1805
+ status: response.status,
1806
+ statusText: response.statusText,
1807
+ headers
1808
+ });
1809
+ }
1810
+ __name(attachEndpointInvalidations, "attachEndpointInvalidations");
1811
+ function createEndpointFailureResponse(failure) {
1812
+ return new Response(
1813
+ JSON.stringify({
1814
+ error: {
1815
+ code: failure.code,
1816
+ message: failure.message,
1817
+ data: failure.data
1818
+ }
1819
+ }),
1820
+ {
1821
+ status: failure.status,
1822
+ headers: {
1823
+ "cache-control": "no-store",
1824
+ "content-type": "application/json"
1825
+ }
1826
+ }
1827
+ );
1828
+ }
1829
+ __name(createEndpointFailureResponse, "createEndpointFailureResponse");
1091
1830
  function isFarmContextHandler(endpoint) {
1092
1831
  if (typeof endpoint !== "function") {
1093
1832
  return false;
@@ -1099,17 +1838,50 @@ function isFarmContextHandler(endpoint) {
1099
1838
  return firstParameter === "ctx" || firstParameter === "context" || firstParameter.startsWith("{");
1100
1839
  }
1101
1840
  __name(isFarmContextHandler, "isFarmContextHandler");
1102
- async function readJSONBody(request) {
1841
+ async function readRequestBody(request) {
1842
+ const contentType = request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
1103
1843
  try {
1844
+ if (contentType === "multipart/form-data") {
1845
+ return formDataToObject(await request.clone().formData());
1846
+ }
1104
1847
  const text = await request.clone().text();
1105
- if (text) {
1848
+ if (!text) return void 0;
1849
+ if (contentType === "application/x-www-form-urlencoded") {
1850
+ return searchParamsToObject(new URLSearchParams(text));
1851
+ }
1852
+ if (contentType === "application/json" || contentType?.endsWith("+json")) {
1106
1853
  return JSON.parse(text);
1107
1854
  }
1855
+ return JSON.parse(text);
1108
1856
  } catch {
1109
1857
  }
1110
1858
  return void 0;
1111
1859
  }
1112
- __name(readJSONBody, "readJSONBody");
1860
+ __name(readRequestBody, "readRequestBody");
1861
+ function formDataToObject(formData) {
1862
+ return entriesToObject(formData.entries());
1863
+ }
1864
+ __name(formDataToObject, "formDataToObject");
1865
+ function searchParamsToObject(searchParams) {
1866
+ return entriesToObject(searchParams.entries());
1867
+ }
1868
+ __name(searchParamsToObject, "searchParamsToObject");
1869
+ function entriesToObject(entries) {
1870
+ const output = /* @__PURE__ */ Object.create(null);
1871
+ for (const [key, value] of entries) {
1872
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
1873
+ const current = output[key];
1874
+ if (current === void 0) {
1875
+ output[key] = value;
1876
+ } else if (Array.isArray(current)) {
1877
+ current.push(value);
1878
+ } else {
1879
+ output[key] = [current, value];
1880
+ }
1881
+ }
1882
+ return output;
1883
+ }
1884
+ __name(entriesToObject, "entriesToObject");
1113
1885
  function validateInput(schema, value, error) {
1114
1886
  if (!schema || typeof schema.parse !== "function") {
1115
1887
  return value;
@@ -1569,7 +2341,7 @@ function mergeIntegrationClientData(...values) {
1569
2341
  continue;
1570
2342
  }
1571
2343
  merged = {
1572
- ...merged || {},
2344
+ ...merged,
1573
2345
  ...data
1574
2346
  };
1575
2347
  }
@@ -2220,6 +2992,20 @@ function normalizeFarmClientCacheKey(key) {
2220
2992
  __name(normalizeFarmClientCacheKey, "normalizeFarmClientCacheKey");
2221
2993
 
2222
2994
  // src/api/client.ts
2995
+ var FARM_API_ROUTE_REF_SYMBOL = /* @__PURE__ */ Symbol.for("farm.api.route-ref");
2996
+ var FARM_API_ROUTE_META_SYMBOL = /* @__PURE__ */ Symbol.for("farm.api.route-meta");
2997
+ var _APIClientError = class _APIClientError extends Error {
2998
+ constructor(code, data, options) {
2999
+ super(options.message);
3000
+ this.name = "APIClientError";
3001
+ this.code = code;
3002
+ this.data = data;
3003
+ this.status = options.status;
3004
+ this.response = options.response;
3005
+ }
3006
+ };
3007
+ __name(_APIClientError, "APIClientError");
3008
+ var APIClientError = _APIClientError;
2223
3009
  function createAPIClient(options = {}) {
2224
3010
  options ?? (options = {});
2225
3011
  const baseURL = options.baseURL || (typeof window !== "undefined" ? window.location.origin : "http://localhost:3000");
@@ -2245,21 +3031,30 @@ function createAPIClient(options = {}) {
2245
3031
  }
2246
3032
  });
2247
3033
  }
3034
+ const headers = {
3035
+ "Content-Type": "application/json",
3036
+ ...options.headers,
3037
+ ...requestOptions.headers
3038
+ };
2248
3039
  const fetchOptions = {
2249
3040
  method: requestOptions.method || "GET",
2250
- headers: {
2251
- "Content-Type": "application/json",
2252
- ...options.headers,
2253
- ...requestOptions.headers
2254
- }
3041
+ headers
2255
3042
  };
2256
- if (requestOptions.body) {
2257
- fetchOptions.body = JSON.stringify(requestOptions.body);
3043
+ if (requestOptions.body !== void 0) {
3044
+ if (isFormData(requestOptions.body)) {
3045
+ deleteHeader(headers, "content-type");
3046
+ fetchOptions.body = requestOptions.body;
3047
+ } else {
3048
+ fetchOptions.body = JSON.stringify(requestOptions.body);
3049
+ }
2258
3050
  }
2259
3051
  const response = await fetch(url.toString(), fetchOptions);
3052
+ applyFarmCacheInvalidations(
3053
+ decodeFarmCacheInvalidations(response.headers?.get?.(FARM_CACHE_INVALIDATION_HEADER))
3054
+ );
2260
3055
  let data = void 0;
2261
3056
  if (response.status !== 204 && response.status !== 205) {
2262
- data = await response.json();
3057
+ data = isJSONStreamResponse(response) ? readJSONStream(response) : await response.json();
2263
3058
  }
2264
3059
  return { response, data };
2265
3060
  }, "fetchClient");
@@ -2405,16 +3200,16 @@ function createAPIClient(options = {}) {
2405
3200
  }
2406
3201
  }
2407
3202
  attempt += 1;
2408
- const delay = typeof clientOptions?.retry?.delay === "function" ? clientOptions.retry.delay(attempt) : clientOptions?.retry?.delay ?? 0;
2409
- if (delay > 0) {
2410
- await new Promise((resolve) => setTimeout(resolve, delay));
3203
+ const delay2 = typeof clientOptions?.retry?.delay === "function" ? clientOptions.retry.delay(attempt) : clientOptions?.retry?.delay ?? 0;
3204
+ if (delay2 > 0) {
3205
+ await new Promise((resolve) => setTimeout(resolve, delay2));
2411
3206
  }
2412
3207
  }
2413
3208
  })();
2414
3209
  inflightState.set(cacheKey, { promise, startedAt: now });
2415
3210
  try {
2416
3211
  const result2 = await promise;
2417
- if (!result2.error && isCacheEnabled) {
3212
+ if (!result2.error && isCacheEnabled && !isFarmAPIStream(result2.data)) {
2418
3213
  const updatedAt = Date.now();
2419
3214
  cacheState.set(cacheKey, {
2420
3215
  data: result2.data,
@@ -2487,19 +3282,48 @@ function createAPIClient(options = {}) {
2487
3282
  clientOptions?.onSettled?.(result.data, result.error);
2488
3283
  return result;
2489
3284
  }, "request");
2490
- return createNestedProxy([], request, routeMeta, baseURL, rootAliases);
3285
+ return createNestedProxy(
3286
+ [],
3287
+ request,
3288
+ routeMeta,
3289
+ baseURL,
3290
+ options.baseURL === void 0,
3291
+ rootAliases
3292
+ );
2491
3293
  }
2492
3294
  __name(createAPIClient, "createAPIClient");
2493
- function createNestedProxy(path4, client, routeMeta, baseURL, rootAliases) {
3295
+ function createNestedProxy(path4, client, routeMeta, baseURL, sameOrigin, rootAliases) {
2494
3296
  const target = /* @__PURE__ */ __name(() => {
2495
3297
  }, "target");
2496
3298
  const proxy = new Proxy(target, {
2497
3299
  // When accessing a property (api.hello)
2498
3300
  get(_target, prop) {
3301
+ if (prop === FARM_API_ROUTE_REF_SYMBOL) {
3302
+ return path4.length > 0;
3303
+ }
3304
+ if (prop === FARM_API_ROUTE_META_SYMBOL) {
3305
+ const metadata = resolveRouteMeta({ path: path4, baseURL });
3306
+ return Object.freeze({
3307
+ path: metadata.routePath,
3308
+ method: metadata.method,
3309
+ baseURL,
3310
+ sameOrigin
3311
+ });
3312
+ }
2499
3313
  if (path4.length === 0 && typeof prop === "string" && rootAliases && prop in rootAliases) {
2500
3314
  return rootAliases[prop];
2501
3315
  }
2502
- return createNestedProxy([...path4, prop], client, routeMeta, baseURL, rootAliases);
3316
+ if (typeof prop !== "string") {
3317
+ return Reflect.get(_target, prop);
3318
+ }
3319
+ return createNestedProxy(
3320
+ [...path4, prop],
3321
+ client,
3322
+ routeMeta,
3323
+ baseURL,
3324
+ sameOrigin,
3325
+ rootAliases
3326
+ );
2503
3327
  },
2504
3328
  // When calling as a function
2505
3329
  apply(_target, _thisArg, args) {
@@ -2521,6 +3345,26 @@ function createNestedProxy(path4, client, routeMeta, baseURL, rootAliases) {
2521
3345
  return proxy;
2522
3346
  }
2523
3347
  __name(createNestedProxy, "createNestedProxy");
3348
+ function isAPIRouteRef(value) {
3349
+ return typeof value === "function" && value[FARM_API_ROUTE_REF_SYMBOL] === true;
3350
+ }
3351
+ __name(isAPIRouteRef, "isAPIRouteRef");
3352
+ function getAPIRouteRefMetadata(value) {
3353
+ if (!isAPIRouteRef(value)) return null;
3354
+ const metadata = value[FARM_API_ROUTE_META_SYMBOL];
3355
+ if (!metadata || typeof metadata !== "object") return null;
3356
+ const candidate = metadata;
3357
+ if (typeof candidate.path !== "string" || typeof candidate.method !== "string" || typeof candidate.baseURL !== "string" || typeof candidate.sameOrigin !== "boolean") {
3358
+ return null;
3359
+ }
3360
+ return {
3361
+ path: candidate.path,
3362
+ method: candidate.method,
3363
+ baseURL: candidate.baseURL,
3364
+ sameOrigin: candidate.sameOrigin
3365
+ };
3366
+ }
3367
+ __name(getAPIRouteRefMetadata, "getAPIRouteRefMetadata");
2524
3368
  function createServerAPIClient(endpoints, options = {}) {
2525
3369
  if (options.integrations === false || Object.prototype.hasOwnProperty.call(endpoints, "integrations")) {
2526
3370
  return endpoints;
@@ -2587,7 +3431,10 @@ function resolveTargetKey(routeMeta, target, input, baseURL = "http://localhost:
2587
3431
  }
2588
3432
  if (Array.isArray(target)) {
2589
3433
  const [route, routeInput] = target;
2590
- return resolveTargetKey(routeMeta, route, routeInput, baseURL);
3434
+ if (typeof route === "function") {
3435
+ return resolveTargetKey(routeMeta, route, routeInput, baseURL);
3436
+ }
3437
+ return normalizeFarmClientCacheKey(target);
2591
3438
  }
2592
3439
  if ("key" in target) return normalizeFarmClientCacheKey(target.key);
2593
3440
  if ("path" in target) {
@@ -2613,18 +3460,56 @@ function resolveRouteMeta(meta) {
2613
3460
  }
2614
3461
  __name(resolveRouteMeta, "resolveRouteMeta");
2615
3462
  function normalizeError(error) {
2616
- if (error instanceof Error) return error;
2617
- return new Error(typeof error === "string" ? error : "Unknown error");
3463
+ if (error instanceof APIClientError) return error;
3464
+ const normalized = new APIClientError("network_error", void 0, {
3465
+ status: 0,
3466
+ message: error instanceof Error ? error.message : typeof error === "string" ? error : "Network request failed"
3467
+ });
3468
+ normalized.cause = error;
3469
+ return normalized;
2618
3470
  }
2619
3471
  __name(normalizeError, "normalizeError");
3472
+ function isFormData(value) {
3473
+ return typeof value === "object" && value !== null && (typeof FormData !== "undefined" && value instanceof FormData || Object.prototype.toString.call(value) === "[object FormData]" && typeof value.entries === "function");
3474
+ }
3475
+ __name(isFormData, "isFormData");
3476
+ function deleteHeader(headers, name) {
3477
+ const normalized = name.toLowerCase();
3478
+ for (const key of Object.keys(headers)) {
3479
+ if (key.toLowerCase() === normalized) delete headers[key];
3480
+ }
3481
+ }
3482
+ __name(deleteHeader, "deleteHeader");
2620
3483
  function createResponseError2(response, data) {
2621
- const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
2622
- error.status = response.status;
2623
- error.response = response;
2624
- error.data = data;
2625
- return error;
3484
+ const expected = readEndpointErrorEnvelope(data);
3485
+ if (expected) {
3486
+ return new APIClientError(expected.code, expected.data, {
3487
+ status: response.status,
3488
+ message: expected.message,
3489
+ response
3490
+ });
3491
+ }
3492
+ return new APIClientError("http_error", data, {
3493
+ status: response.status,
3494
+ message: `HTTP ${response.status}: ${response.statusText}`,
3495
+ response
3496
+ });
2626
3497
  }
2627
3498
  __name(createResponseError2, "createResponseError");
3499
+ function readEndpointErrorEnvelope(data) {
3500
+ if (!data || typeof data !== "object") return null;
3501
+ const error = data.error;
3502
+ if (!error || typeof error !== "object") return null;
3503
+ const code = error.code;
3504
+ const message = error.message;
3505
+ if (typeof code !== "string" || typeof message !== "string") return null;
3506
+ return {
3507
+ code,
3508
+ message,
3509
+ data: error.data
3510
+ };
3511
+ }
3512
+ __name(readEndpointErrorEnvelope, "readEndpointErrorEnvelope");
2628
3513
 
2629
3514
  // src/server/response.ts
2630
3515
  var import_node_events = require("events");
@@ -2996,69 +3881,71 @@ function farmApiPlugin(options = {}) {
2996
3881
  waitForDiscovery: /* @__PURE__ */ __name(() => discoveryPromise, "waitForDiscovery")
2997
3882
  };
2998
3883
  return () => {
2999
- server.middlewares.use(_withAfterNodeMiddleware(async (req, res, next) => {
3000
- const url = req.url || "/";
3001
- const pathname = url.split("?")[0];
3002
- const method = req.method || "GET";
3003
- if (discoveryPromise && !discoveryComplete) {
3004
- await discoveryPromise;
3005
- }
3006
- if (!matchAPIRoute(apiRoutesCache, pathname)) {
3007
- return next();
3008
- }
3009
- if (!apiRouterHandler) {
3010
- return next();
3011
- }
3012
- const startTime = Date.now();
3013
- try {
3014
- const farmMiddleware = server.__farmMiddleware__;
3015
- if (farmMiddleware) {
3016
- await farmMiddleware.waitForDiscovery?.();
3017
- const middlewareData = /* @__PURE__ */ new Map();
3018
- const handled = await farmMiddleware.execute(req, res, pathname, middlewareData);
3019
- if (handled) {
3020
- const duration2 = Date.now() - startTime;
3021
- logResponse(method, pathname, res.statusCode || 200, duration2);
3022
- return;
3023
- }
3884
+ server.middlewares.use(
3885
+ _withAfterNodeMiddleware(async (req, res, next) => {
3886
+ const url = req.url || "/";
3887
+ const pathname = url.split("?")[0];
3888
+ const method = req.method || "GET";
3889
+ if (discoveryPromise && !discoveryComplete) {
3890
+ await discoveryPromise;
3024
3891
  }
3025
- const fullUrl = `http://${req.headers.host || "localhost:3000"}${url}`;
3026
- const headers = new Headers();
3027
- for (const [key, value] of Object.entries(req.headers)) {
3028
- if (value) {
3029
- headers.set(key, Array.isArray(value) ? value.join(", ") : value);
3030
- }
3892
+ if (!matchAPIRoute(apiRoutesCache, pathname)) {
3893
+ return next();
3031
3894
  }
3032
- let body;
3033
- if (method !== "GET" && method !== "HEAD") {
3034
- body = await new Promise((resolve) => {
3035
- let data = "";
3036
- req.on("data", (chunk) => {
3037
- data += chunk;
3038
- });
3039
- req.on("end", () => {
3040
- resolve(data);
3895
+ if (!apiRouterHandler) {
3896
+ return next();
3897
+ }
3898
+ const startTime = Date.now();
3899
+ try {
3900
+ const farmMiddleware = server.__farmMiddleware__;
3901
+ if (farmMiddleware) {
3902
+ await farmMiddleware.waitForDiscovery?.();
3903
+ const middlewareData = /* @__PURE__ */ new Map();
3904
+ const handled = await farmMiddleware.execute(req, res, pathname, middlewareData);
3905
+ if (handled) {
3906
+ const duration2 = Date.now() - startTime;
3907
+ logResponse(method, pathname, res.statusCode || 200, duration2);
3908
+ return;
3909
+ }
3910
+ }
3911
+ const fullUrl = `http://${req.headers.host || "localhost:3000"}${url}`;
3912
+ const headers = new Headers();
3913
+ for (const [key, value] of Object.entries(req.headers)) {
3914
+ if (value) {
3915
+ headers.set(key, Array.isArray(value) ? value.join(", ") : value);
3916
+ }
3917
+ }
3918
+ let body;
3919
+ if (method !== "GET" && method !== "HEAD") {
3920
+ body = await new Promise((resolve) => {
3921
+ let data = "";
3922
+ req.on("data", (chunk) => {
3923
+ data += chunk;
3924
+ });
3925
+ req.on("end", () => {
3926
+ resolve(data);
3927
+ });
3041
3928
  });
3929
+ }
3930
+ const request = new Request(fullUrl, {
3931
+ method,
3932
+ headers,
3933
+ body: body || void 0
3042
3934
  });
3935
+ const response = await apiRouterHandler(request);
3936
+ const duration = Date.now() - startTime;
3937
+ logResponse(method, pathname, response.status, duration);
3938
+ await sendWebResponse(res, response);
3939
+ } catch (error) {
3940
+ const duration = Date.now() - startTime;
3941
+ logResponse(method, pathname, 500, duration);
3942
+ console.error("[FARM] API error:", error);
3943
+ res.statusCode = 500;
3944
+ res.setHeader("Content-Type", "application/json");
3945
+ res.end(JSON.stringify({ error: "Internal server error" }));
3043
3946
  }
3044
- const request = new Request(fullUrl, {
3045
- method,
3046
- headers,
3047
- body: body || void 0
3048
- });
3049
- const response = await apiRouterHandler(request);
3050
- const duration = Date.now() - startTime;
3051
- logResponse(method, pathname, response.status, duration);
3052
- await sendWebResponse(res, response);
3053
- } catch (error) {
3054
- const duration = Date.now() - startTime;
3055
- logResponse(method, pathname, 500, duration);
3056
- console.error("[FARM] API error:", error);
3057
- res.statusCode = 500;
3058
- res.setHeader("Content-Type", "application/json");
3059
- res.end(JSON.stringify({ error: "Internal server error" }));
3060
- }
3061
- }));
3947
+ })
3948
+ );
3062
3949
  };
3063
3950
  },
3064
3951
  async handleHotUpdate({ file, server, modules }) {
@@ -3178,9 +4065,13 @@ function farmApiPlugin(options = {}) {
3178
4065
  __name(farmApiPlugin, "farmApiPlugin");
3179
4066
  // Annotate the CommonJS export names for ESM import in node:
3180
4067
  0 && (module.exports = {
4068
+ APIClientError,
3181
4069
  APIRouteManager,
3182
4070
  API_ROUTE_METHODS,
3183
4071
  DELETE,
4072
+ EndpointFailure,
4073
+ FARM_API_ROUTE_META_SYMBOL,
4074
+ FARM_API_ROUTE_REF_SYMBOL,
3184
4075
  GET,
3185
4076
  HEAD,
3186
4077
  OPTIONS,
@@ -3191,9 +4082,19 @@ __name(farmApiPlugin, "farmApiPlugin");
3191
4082
  createEndpoint,
3192
4083
  createServerAPIClient,
3193
4084
  farmApiPlugin,
4085
+ getAPIRouteRefMetadata,
3194
4086
  invokeAPIRouteEndpoint,
4087
+ isAPIRouteRef,
4088
+ isEndpointFailure,
4089
+ isFarmAPIStream,
4090
+ isJSONStreamResponse,
4091
+ isMultipartSchema,
3195
4092
  isWebResponse,
4093
+ jsonStream,
3196
4094
  matchAPIRoute,
3197
- normalizeRouteResponse
4095
+ multipart,
4096
+ normalizeRouteResponse,
4097
+ readJSONStream,
4098
+ toFormData
3198
4099
  });
3199
4100
  //# sourceMappingURL=api.cjs.map