@farm.js/core 0.1.0-beta.0 → 0.1.0-beta.3

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 (230) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-runtime.d.mts +1 -1
  3. package/dist/agent-runtime.d.ts +1 -1
  4. package/dist/api/route-manager.cjs +97 -5
  5. package/dist/api/route-manager.cjs.map +1 -1
  6. package/dist/api/route-manager.d.mts +3 -2
  7. package/dist/api/route-manager.d.ts +3 -2
  8. package/dist/api/route-manager.mjs +8 -8
  9. package/dist/api/runtime.cjs +441 -5
  10. package/dist/api/runtime.cjs.map +1 -1
  11. package/dist/api/runtime.d.mts +2 -16
  12. package/dist/api/runtime.d.ts +2 -16
  13. package/dist/api/runtime.mjs +7 -1
  14. package/dist/api.cjs +579 -263
  15. package/dist/api.cjs.map +1 -1
  16. package/dist/api.d.mts +4 -147
  17. package/dist/api.d.ts +4 -147
  18. package/dist/api.mjs +30 -20
  19. package/dist/{app-BiX4qb-d.d.mts → app-BB3Iu3xh.d.mts} +2 -2
  20. package/dist/{app-CFRNJXP1.d.ts → app-DOKxo-LH.d.ts} +2 -2
  21. package/dist/app-markdown.cjs +1 -1
  22. package/dist/app-markdown.cjs.map +1 -1
  23. package/dist/app-markdown.d.mts +1 -1
  24. package/dist/app-markdown.d.ts +1 -1
  25. package/dist/app-markdown.mjs +1 -1
  26. package/dist/cache.cjs +19 -0
  27. package/dist/cache.cjs.map +1 -1
  28. package/dist/cache.d.mts +21 -1
  29. package/dist/cache.d.ts +21 -1
  30. package/dist/cache.mjs +5 -3
  31. package/dist/{chunk-QF4PHCMA.mjs → chunk-2ED5Q2GH.mjs} +3 -3
  32. package/dist/chunk-2ED5Q2GH.mjs.map +1 -0
  33. package/dist/{chunk-GZP5W4K3.mjs → chunk-32W4QEJP.mjs} +1 -1
  34. package/dist/chunk-32W4QEJP.mjs.map +1 -0
  35. package/dist/{chunk-AGS7UJ52.mjs → chunk-45LKHSHJ.mjs} +2 -2
  36. package/dist/{chunk-TU4YJICB.mjs → chunk-5FW6PQ3J.mjs} +1 -1
  37. package/dist/{chunk-TU4YJICB.mjs.map → chunk-5FW6PQ3J.mjs.map} +1 -1
  38. package/dist/{chunk-TRORP7E4.mjs → chunk-5QH4IKY3.mjs} +2 -2
  39. package/dist/{chunk-RKI6TN3A.mjs → chunk-6VS6CKAV.mjs} +2 -2
  40. package/dist/chunk-6VS6CKAV.mjs.map +1 -0
  41. package/dist/{chunk-25D7G34K.mjs → chunk-6WXJ54TC.mjs} +4 -4
  42. package/dist/{chunk-3QJO55ZF.mjs → chunk-BIOIOWXZ.mjs} +5 -3
  43. package/dist/{chunk-3QJO55ZF.mjs.map → chunk-BIOIOWXZ.mjs.map} +1 -1
  44. package/dist/{chunk-QFQRHRZS.mjs → chunk-C33RALN7.mjs} +75 -11
  45. package/dist/chunk-C33RALN7.mjs.map +1 -0
  46. package/dist/{chunk-B6N4ZB2H.mjs → chunk-CSU4KJJF.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-PRNYWD7K.mjs → chunk-G5I34UA6.mjs} +67 -239
  52. package/dist/chunk-G5I34UA6.mjs.map +1 -0
  53. package/dist/{chunk-QM6VV26B.mjs → chunk-GQVGIUSN.mjs} +3 -3
  54. package/dist/{chunk-QM6VV26B.mjs.map → chunk-GQVGIUSN.mjs.map} +1 -1
  55. package/dist/{chunk-UREJA4GZ.mjs → chunk-GXASWWJU.mjs} +1 -1
  56. package/dist/{chunk-UREJA4GZ.mjs.map → chunk-GXASWWJU.mjs.map} +1 -1
  57. package/dist/{chunk-4PTK6KT4.mjs → chunk-GZWT6VI5.mjs} +22 -4
  58. package/dist/chunk-GZWT6VI5.mjs.map +1 -0
  59. package/dist/{chunk-JLWMCADZ.mjs → chunk-HZYXGV4K.mjs} +2 -2
  60. package/dist/chunk-JNYVN7YP.mjs +10 -0
  61. package/dist/chunk-JNYVN7YP.mjs.map +1 -0
  62. package/dist/{chunk-YHU7SS6L.mjs → chunk-LG3YINQN.mjs} +11 -11
  63. package/dist/chunk-LWMGIEJA.mjs +593 -0
  64. package/dist/chunk-LWMGIEJA.mjs.map +1 -0
  65. package/dist/{chunk-HXP3ZSPC.mjs → chunk-MH6FKW2I.mjs} +3 -3
  66. package/dist/{chunk-O3HADRW6.mjs → chunk-MIUW47JX.mjs} +2 -2
  67. package/dist/{chunk-O3HADRW6.mjs.map → chunk-MIUW47JX.mjs.map} +1 -1
  68. package/dist/{chunk-6XDUHOEM.mjs → chunk-NRRFGX45.mjs} +3 -3
  69. package/dist/{chunk-G3B5BRDY.mjs → chunk-OHC6VCDI.mjs} +24 -25
  70. package/dist/{chunk-G3B5BRDY.mjs.map → chunk-OHC6VCDI.mjs.map} +1 -1
  71. package/dist/{chunk-S2XHZS7W.mjs → chunk-QGQX7SFC.mjs} +2 -2
  72. package/dist/chunk-QGQX7SFC.mjs.map +1 -0
  73. package/dist/{chunk-TXCFGOHW.mjs → chunk-SHRJG6OG.mjs} +25 -1
  74. package/dist/chunk-SHRJG6OG.mjs.map +1 -0
  75. package/dist/{chunk-UHE2TTLK.mjs → chunk-T543TMFY.mjs} +8 -8
  76. package/dist/chunk-T543TMFY.mjs.map +1 -0
  77. package/dist/{chunk-SXZTEK3V.mjs → chunk-UXUAWNO5.mjs} +2 -2
  78. package/dist/{chunk-Y2OJJD7R.mjs → chunk-XIVV5IWN.mjs} +7 -9
  79. package/dist/chunk-XIVV5IWN.mjs.map +1 -0
  80. package/dist/{chunk-CHFHNEMO.mjs → chunk-XJSHJN4M.mjs} +41 -42
  81. package/dist/chunk-XJSHJN4M.mjs.map +1 -0
  82. package/dist/{chunk-Y7A27276.mjs → chunk-XUBZ7JI4.mjs} +178 -15
  83. package/dist/chunk-XUBZ7JI4.mjs.map +1 -0
  84. package/dist/{chunk-OYXO65LI.mjs → chunk-YW7OBE6Q.mjs} +4 -4
  85. package/dist/chunk-YW7OBE6Q.mjs.map +1 -0
  86. package/dist/{chunk-SOU3Q3ZA.mjs → chunk-ZZ57EH5Z.mjs} +1 -1
  87. package/dist/chunk-ZZ57EH5Z.mjs.map +1 -0
  88. package/dist/{client-D_yUjVhe.d.mts → client-DiViK9yK.d.mts} +33 -7
  89. package/dist/{client-Dkc03WP8.d.ts → client-DpEBJbts.d.ts} +33 -7
  90. package/dist/{client-plugins-BZnpeTGA.d.ts → client-plugins-CTnsZz_A.d.ts} +1 -0
  91. package/dist/{client-plugins-g4bzuCmo.d.mts → client-plugins-Cnr0D3kk.d.mts} +1 -0
  92. package/dist/client-plugins.d.mts +1 -1
  93. package/dist/client-plugins.d.ts +1 -1
  94. package/dist/client.cjs +302 -54
  95. package/dist/client.cjs.map +1 -1
  96. package/dist/client.d.mts +54 -2
  97. package/dist/client.d.ts +54 -2
  98. package/dist/client.mjs +20 -16
  99. package/dist/config.d.mts +1 -1
  100. package/dist/config.d.ts +1 -1
  101. package/dist/cron.cjs.map +1 -1
  102. package/dist/cron.mjs +1 -1
  103. package/dist/{devtools-AE4RVXCM.mjs → devtools-HE4FTUDN.mjs} +10 -10
  104. package/dist/{devtools-client-6WPY2AQU.mjs → devtools-client-3XRTBND5.mjs} +2 -11
  105. package/dist/devtools-client-3XRTBND5.mjs.map +1 -0
  106. package/dist/docs.cjs +3 -1
  107. package/dist/docs.cjs.map +1 -1
  108. package/dist/docs.mjs +10 -10
  109. package/dist/i18n/server.cjs +2 -2
  110. package/dist/i18n/server.cjs.map +1 -1
  111. package/dist/i18n/server.mjs +1 -1
  112. package/dist/index.cjs +791 -317
  113. package/dist/index.cjs.map +1 -1
  114. package/dist/index.d.mts +11 -11
  115. package/dist/index.d.ts +11 -11
  116. package/dist/index.mjs +125 -110
  117. package/dist/index.mjs.map +1 -1
  118. package/dist/integrations.d.mts +1 -1
  119. package/dist/integrations.d.ts +1 -1
  120. package/dist/internal/build-runtime.cjs +162 -60
  121. package/dist/internal/build-runtime.cjs.map +1 -1
  122. package/dist/internal/build-runtime.d.mts +3 -3
  123. package/dist/internal/build-runtime.d.ts +3 -3
  124. package/dist/internal/build-runtime.mjs +26 -25
  125. package/dist/internal/client-runtime.cjs.map +1 -1
  126. package/dist/internal/client-runtime.mjs +1 -1
  127. package/dist/internal/config-runtime.cjs +1 -1
  128. package/dist/internal/config-runtime.cjs.map +1 -1
  129. package/dist/internal/config-runtime.d.mts +2 -2
  130. package/dist/internal/config-runtime.d.ts +2 -2
  131. package/dist/internal/config-runtime.mjs +9 -9
  132. package/dist/internal/production-runtime.cjs +3 -3
  133. package/dist/internal/production-runtime.cjs.map +1 -1
  134. package/dist/internal/production-runtime.d.mts +3 -3
  135. package/dist/internal/production-runtime.d.ts +3 -3
  136. package/dist/internal/production-runtime.mjs +8 -8
  137. package/dist/{metadata-C9NZxMDW.d.mts → metadata-Dp8AdvsB.d.mts} +1 -1
  138. package/dist/{metadata-DAXRaOHx.d.ts → metadata-eoVmHoyv.d.ts} +1 -1
  139. package/dist/middleware.cjs +2 -2
  140. package/dist/middleware.cjs.map +1 -1
  141. package/dist/middleware.d.mts +3 -3
  142. package/dist/middleware.d.ts +3 -3
  143. package/dist/middleware.mjs +3 -3
  144. package/dist/navigation.cjs.map +1 -1
  145. package/dist/navigation.mjs +3 -3
  146. package/dist/{nitro-KME62MWG.mjs → nitro-QO5LV6QK.mjs} +11 -13
  147. package/dist/{nitro-KME62MWG.mjs.map → nitro-QO5LV6QK.mjs.map} +1 -1
  148. package/dist/plugin.cjs +119 -39
  149. package/dist/plugin.cjs.map +1 -1
  150. package/dist/plugin.d.mts +1 -1
  151. package/dist/plugin.d.ts +1 -1
  152. package/dist/plugin.mjs +22 -21
  153. package/dist/{production-runtime-DRkCHUvJ.d.ts → production-runtime-BqTnUTai.d.ts} +1 -1
  154. package/dist/{production-runtime-flrjp_nC.d.mts → production-runtime-DtDdG9fc.d.mts} +1 -1
  155. package/dist/routes.cjs.map +1 -1
  156. package/dist/routes.d.mts +1 -1
  157. package/dist/routes.d.ts +1 -1
  158. package/dist/routes.mjs +4 -4
  159. package/dist/runtime-C1B7pSGT.d.mts +207 -0
  160. package/dist/runtime-CdPHt0bv.d.ts +207 -0
  161. package/dist/server-action-security.cjs.map +1 -1
  162. package/dist/server-action-security.mjs +2 -2
  163. package/dist/server-fn-client.cjs.map +1 -1
  164. package/dist/server-fn-client.mjs +1 -1
  165. package/dist/server-fn.cjs.map +1 -1
  166. package/dist/server-fn.mjs +3 -3
  167. package/dist/server-plugins.d.mts +2 -2
  168. package/dist/server-plugins.d.ts +2 -2
  169. package/dist/server-query-client.cjs.map +1 -1
  170. package/dist/server-query-client.mjs +4 -4
  171. package/dist/server-query.cjs.map +1 -1
  172. package/dist/server-query.mjs +5 -5
  173. package/dist/server.cjs +148 -43
  174. package/dist/server.cjs.map +1 -1
  175. package/dist/server.d.mts +6 -6
  176. package/dist/server.d.ts +6 -6
  177. package/dist/server.mjs +36 -31
  178. package/dist/server.mjs.map +1 -1
  179. package/dist/testing.cjs +95 -5
  180. package/dist/testing.cjs.map +1 -1
  181. package/dist/testing.d.mts +3 -3
  182. package/dist/testing.d.ts +3 -3
  183. package/dist/testing.mjs +18 -18
  184. package/dist/{utils-DOXXivjL.d.mts → utils-8USa5BiY.d.mts} +1 -1
  185. package/dist/{utils-DA1yo54_.d.ts → utils-DKJb6K6G.d.ts} +1 -1
  186. package/dist/version.cjs +36 -0
  187. package/dist/version.cjs.map +1 -0
  188. package/dist/version.d.mts +3 -0
  189. package/dist/version.d.ts +3 -0
  190. package/dist/version.mjs +8 -0
  191. package/dist/version.mjs.map +1 -0
  192. package/dist/vite.cjs +126 -40
  193. package/dist/vite.cjs.map +1 -1
  194. package/dist/vite.d.mts +1 -1
  195. package/dist/vite.d.ts +1 -1
  196. package/dist/vite.mjs +22 -21
  197. package/dist/workflows.cjs +6 -8
  198. package/dist/workflows.cjs.map +1 -1
  199. package/dist/workflows.mjs +1 -1
  200. package/package.json +12 -5
  201. package/types/client.d.ts +136 -13
  202. package/dist/chunk-4PTK6KT4.mjs.map +0 -1
  203. package/dist/chunk-CHFHNEMO.mjs.map +0 -1
  204. package/dist/chunk-EVGBEZDF.mjs +0 -215
  205. package/dist/chunk-EVGBEZDF.mjs.map +0 -1
  206. package/dist/chunk-GZP5W4K3.mjs.map +0 -1
  207. package/dist/chunk-JN3UU635.mjs.map +0 -1
  208. package/dist/chunk-OYXO65LI.mjs.map +0 -1
  209. package/dist/chunk-PRNYWD7K.mjs.map +0 -1
  210. package/dist/chunk-QF4PHCMA.mjs.map +0 -1
  211. package/dist/chunk-QFQRHRZS.mjs.map +0 -1
  212. package/dist/chunk-RKI6TN3A.mjs.map +0 -1
  213. package/dist/chunk-S2XHZS7W.mjs.map +0 -1
  214. package/dist/chunk-SOU3Q3ZA.mjs.map +0 -1
  215. package/dist/chunk-TXCFGOHW.mjs.map +0 -1
  216. package/dist/chunk-UHE2TTLK.mjs.map +0 -1
  217. package/dist/chunk-Y2OJJD7R.mjs.map +0 -1
  218. package/dist/chunk-Y7A27276.mjs.map +0 -1
  219. package/dist/chunk-ZJQNATYV.mjs.map +0 -1
  220. package/dist/devtools-client-6WPY2AQU.mjs.map +0 -1
  221. /package/dist/{chunk-AGS7UJ52.mjs.map → chunk-45LKHSHJ.mjs.map} +0 -0
  222. /package/dist/{chunk-TRORP7E4.mjs.map → chunk-5QH4IKY3.mjs.map} +0 -0
  223. /package/dist/{chunk-25D7G34K.mjs.map → chunk-6WXJ54TC.mjs.map} +0 -0
  224. /package/dist/{chunk-B6N4ZB2H.mjs.map → chunk-CSU4KJJF.mjs.map} +0 -0
  225. /package/dist/{chunk-JLWMCADZ.mjs.map → chunk-HZYXGV4K.mjs.map} +0 -0
  226. /package/dist/{chunk-YHU7SS6L.mjs.map → chunk-LG3YINQN.mjs.map} +0 -0
  227. /package/dist/{chunk-HXP3ZSPC.mjs.map → chunk-MH6FKW2I.mjs.map} +0 -0
  228. /package/dist/{chunk-6XDUHOEM.mjs.map → chunk-NRRFGX45.mjs.map} +0 -0
  229. /package/dist/{chunk-SXZTEK3V.mjs.map → chunk-UXUAWNO5.mjs.map} +0 -0
  230. /package/dist/{devtools-AE4RVXCM.mjs.map → devtools-HE4FTUDN.mjs.map} +0 -0
@@ -7,189 +7,23 @@ import {
7
7
  import {
8
8
  API_ROUTE_METHODS,
9
9
  findProgrammaticRouteFilesInDir
10
- } from "./chunk-YHU7SS6L.mjs";
10
+ } from "./chunk-LG3YINQN.mjs";
11
+ import {
12
+ getProgrammaticRouteManifest,
13
+ isProgrammaticRoutesFileName
14
+ } from "./chunk-CSU4KJJF.mjs";
11
15
  import {
12
16
  toViteModuleId
13
17
  } from "./chunk-J4FNJ5IU.mjs";
14
18
  import {
15
19
  invokeAPIRouteEndpoint,
16
20
  matchAPIRoute
17
- } from "./chunk-EVGBEZDF.mjs";
18
- import {
19
- getProgrammaticRouteManifest,
20
- isProgrammaticRoutesFileName
21
- } from "./chunk-B6N4ZB2H.mjs";
21
+ } from "./chunk-LWMGIEJA.mjs";
22
22
  import {
23
23
  __name,
24
24
  __require
25
25
  } from "./chunk-CGILA3WO.mjs";
26
26
 
27
- // src/api/endpoint.ts
28
- import { createEndpoint as betterCallEndpoint } from "better-call";
29
- function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
30
- let path;
31
- let options;
32
- let handler;
33
- if (typeof pathOrOptions === "string") {
34
- path = pathOrOptions;
35
- options = optionsOrHandler;
36
- handler = maybeHandler;
37
- } else {
38
- path = "";
39
- options = pathOrOptions;
40
- handler = optionsOrHandler;
41
- }
42
- if (typeof handler !== "function") {
43
- throw new TypeError("createEndpoint requires a handler function");
44
- }
45
- const middleware = normalizeEndpointMiddleware(options.middleware);
46
- const wrappedHandler = /* @__PURE__ */ __name(((ctx) => runEndpointMiddleware(middleware, ctx, handler)), "wrappedHandler");
47
- const { middleware: _middleware, ...betterCallOptions } = options;
48
- const endpoint = betterCallEndpoint(
49
- path || "/__farm_auto_path__",
50
- betterCallOptions,
51
- wrappedHandler
52
- );
53
- endpoint.__path = path || void 0;
54
- endpoint.__method = options.method || "GET";
55
- endpoint.__autoPath = !path;
56
- endpoint.__handler = wrappedHandler;
57
- endpoint.__middleware = middleware;
58
- endpoint.__sourceHandler = handler;
59
- endpoint.__types = {
60
- body: options.body,
61
- query: options.query,
62
- headers: options.headers,
63
- response: null
64
- };
65
- return endpoint;
66
- }
67
- __name(createEndpoint, "createEndpoint");
68
- var EMPTY_ENDPOINT_MIDDLEWARE = Object.freeze([]);
69
- var EMPTY_ENDPOINT_CONTEXT = Object.freeze(/* @__PURE__ */ Object.create(null));
70
- var UNSAFE_ENDPOINT_CONTEXT_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
71
- function normalizeEndpointMiddleware(middleware) {
72
- if (middleware === void 0) return EMPTY_ENDPOINT_MIDDLEWARE;
73
- if (!Array.isArray(middleware)) {
74
- throw new TypeError("createEndpoint middleware must be an array of functions");
75
- }
76
- const normalized = [...middleware];
77
- for (const entry of normalized) {
78
- if (typeof entry !== "function") {
79
- throw new TypeError("createEndpoint middleware entries must be functions");
80
- }
81
- }
82
- return Object.freeze(normalized);
83
- }
84
- __name(normalizeEndpointMiddleware, "normalizeEndpointMiddleware");
85
- async function runEndpointMiddleware(middleware, handlerContext, handler) {
86
- let context = createInitialEndpointContext(handlerContext.context);
87
- for (let index = 0; index < middleware.length; index++) {
88
- const result = await middleware[index]({ ...handlerContext, context });
89
- if (isEndpointResponse(result)) return result;
90
- if (result === false) return forbiddenEndpointResponse();
91
- if (result === true) continue;
92
- if (!isPlainEndpointContext(result)) {
93
- throw new TypeError(
94
- `Endpoint middleware ${index + 1} must return an object, true, false, or a Response`
95
- );
96
- }
97
- context = mergeEndpointContext(context, result, index);
98
- }
99
- return handler({ ...handlerContext, context });
100
- }
101
- __name(runEndpointMiddleware, "runEndpointMiddleware");
102
- function createInitialEndpointContext(value) {
103
- if (value === void 0 || value === null) return EMPTY_ENDPOINT_CONTEXT;
104
- if (!isPlainEndpointContext(value)) {
105
- throw new TypeError("Endpoint context must be a plain object");
106
- }
107
- return mergeEndpointContext(EMPTY_ENDPOINT_CONTEXT, value);
108
- }
109
- __name(createInitialEndpointContext, "createInitialEndpointContext");
110
- function mergeEndpointContext(current, added, middlewareIndex) {
111
- const next = Object.assign(/* @__PURE__ */ Object.create(null), current);
112
- for (const key of Reflect.ownKeys(added)) {
113
- if (!Object.prototype.propertyIsEnumerable.call(added, key)) continue;
114
- if (typeof key === "string" && UNSAFE_ENDPOINT_CONTEXT_KEYS.has(key)) {
115
- throw new TypeError(`Endpoint middleware cannot provide the unsafe context key "${key}"`);
116
- }
117
- if (Object.prototype.hasOwnProperty.call(current, key)) {
118
- const source = middlewareIndex === void 0 ? "Endpoint context" : `Endpoint middleware ${middlewareIndex + 1}`;
119
- throw new TypeError(`${source} cannot replace the existing context key "${String(key)}"`);
120
- }
121
- next[key] = added[key];
122
- }
123
- return Object.freeze(next);
124
- }
125
- __name(mergeEndpointContext, "mergeEndpointContext");
126
- function isPlainEndpointContext(value) {
127
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
128
- const prototype = Object.getPrototypeOf(value);
129
- return prototype === Object.prototype || prototype === null;
130
- }
131
- __name(isPlainEndpointContext, "isPlainEndpointContext");
132
- function isEndpointResponse(value) {
133
- return value instanceof Response || typeof value === "object" && value !== null && "headers" in value && "status" in value && typeof value.arrayBuffer === "function";
134
- }
135
- __name(isEndpointResponse, "isEndpointResponse");
136
- function forbiddenEndpointResponse() {
137
- return new Response(JSON.stringify({ error: "Forbidden" }), {
138
- status: 403,
139
- headers: { "Content-Type": "application/json" }
140
- });
141
- }
142
- __name(forbiddenEndpointResponse, "forbiddenEndpointResponse");
143
- function GET(...args) {
144
- if (args.length === 1) {
145
- return createEndpoint("", { method: "GET" }, args[0]);
146
- }
147
- return createEndpoint("", { ...args[0], method: "GET" }, args[1]);
148
- }
149
- __name(GET, "GET");
150
- function HEAD(...args) {
151
- if (args.length === 1) {
152
- return createEndpoint("", { method: "HEAD" }, args[0]);
153
- }
154
- return createEndpoint("", { ...args[0], method: "HEAD" }, args[1]);
155
- }
156
- __name(HEAD, "HEAD");
157
- function POST(...args) {
158
- if (args.length === 1) {
159
- return createEndpoint("", { method: "POST" }, args[0]);
160
- }
161
- return createEndpoint("", { ...args[0], method: "POST" }, args[1]);
162
- }
163
- __name(POST, "POST");
164
- function PUT(...args) {
165
- if (args.length === 1) {
166
- return createEndpoint("", { method: "PUT" }, args[0]);
167
- }
168
- return createEndpoint("", { ...args[0], method: "PUT" }, args[1]);
169
- }
170
- __name(PUT, "PUT");
171
- function DELETE(...args) {
172
- if (args.length === 1) {
173
- return createEndpoint("", { method: "DELETE" }, args[0]);
174
- }
175
- return createEndpoint("", { ...args[0], method: "DELETE" }, args[1]);
176
- }
177
- __name(DELETE, "DELETE");
178
- function PATCH(...args) {
179
- if (args.length === 1) {
180
- return createEndpoint("", { method: "PATCH" }, args[0]);
181
- }
182
- return createEndpoint("", { ...args[0], method: "PATCH" }, args[1]);
183
- }
184
- __name(PATCH, "PATCH");
185
- function OPTIONS(...args) {
186
- if (args.length === 1) {
187
- return createEndpoint("", { method: "OPTIONS" }, args[0]);
188
- }
189
- return createEndpoint("", { ...args[0], method: "OPTIONS" }, args[1]);
190
- }
191
- __name(OPTIONS, "OPTIONS");
192
-
193
27
  // src/api/vite-plugin.ts
194
28
  function farmApiPlugin(options = {}) {
195
29
  const srcDir = options.srcDir ?? "src";
@@ -404,69 +238,71 @@ function farmApiPlugin(options = {}) {
404
238
  waitForDiscovery: /* @__PURE__ */ __name(() => discoveryPromise, "waitForDiscovery")
405
239
  };
406
240
  return () => {
407
- server.middlewares.use(_withAfterNodeMiddleware(async (req, res, next) => {
408
- const url = req.url || "/";
409
- const pathname = url.split("?")[0];
410
- const method = req.method || "GET";
411
- if (discoveryPromise && !discoveryComplete) {
412
- await discoveryPromise;
413
- }
414
- if (!matchAPIRoute(apiRoutesCache, pathname)) {
415
- return next();
416
- }
417
- if (!apiRouterHandler) {
418
- return next();
419
- }
420
- const startTime = Date.now();
421
- try {
422
- const farmMiddleware = server.__farmMiddleware__;
423
- if (farmMiddleware) {
424
- await farmMiddleware.waitForDiscovery?.();
425
- const middlewareData = /* @__PURE__ */ new Map();
426
- const handled = await farmMiddleware.execute(req, res, pathname, middlewareData);
427
- if (handled) {
428
- const duration2 = Date.now() - startTime;
429
- logResponse(method, pathname, res.statusCode || 200, duration2);
430
- return;
431
- }
241
+ server.middlewares.use(
242
+ _withAfterNodeMiddleware(async (req, res, next) => {
243
+ const url = req.url || "/";
244
+ const pathname = url.split("?")[0];
245
+ const method = req.method || "GET";
246
+ if (discoveryPromise && !discoveryComplete) {
247
+ await discoveryPromise;
432
248
  }
433
- const fullUrl = `http://${req.headers.host || "localhost:3000"}${url}`;
434
- const headers = new Headers();
435
- for (const [key, value] of Object.entries(req.headers)) {
436
- if (value) {
437
- headers.set(key, Array.isArray(value) ? value.join(", ") : value);
438
- }
249
+ if (!matchAPIRoute(apiRoutesCache, pathname)) {
250
+ return next();
439
251
  }
440
- let body;
441
- if (method !== "GET" && method !== "HEAD") {
442
- body = await new Promise((resolve) => {
443
- let data = "";
444
- req.on("data", (chunk) => {
445
- data += chunk;
446
- });
447
- req.on("end", () => {
448
- resolve(data);
252
+ if (!apiRouterHandler) {
253
+ return next();
254
+ }
255
+ const startTime = Date.now();
256
+ try {
257
+ const farmMiddleware = server.__farmMiddleware__;
258
+ if (farmMiddleware) {
259
+ await farmMiddleware.waitForDiscovery?.();
260
+ const middlewareData = /* @__PURE__ */ new Map();
261
+ const handled = await farmMiddleware.execute(req, res, pathname, middlewareData);
262
+ if (handled) {
263
+ const duration2 = Date.now() - startTime;
264
+ logResponse(method, pathname, res.statusCode || 200, duration2);
265
+ return;
266
+ }
267
+ }
268
+ const fullUrl = `http://${req.headers.host || "localhost:3000"}${url}`;
269
+ const headers = new Headers();
270
+ for (const [key, value] of Object.entries(req.headers)) {
271
+ if (value) {
272
+ headers.set(key, Array.isArray(value) ? value.join(", ") : value);
273
+ }
274
+ }
275
+ let body;
276
+ if (method !== "GET" && method !== "HEAD") {
277
+ body = await new Promise((resolve) => {
278
+ let data = "";
279
+ req.on("data", (chunk) => {
280
+ data += chunk;
281
+ });
282
+ req.on("end", () => {
283
+ resolve(data);
284
+ });
449
285
  });
286
+ }
287
+ const request = new Request(fullUrl, {
288
+ method,
289
+ headers,
290
+ body: body || void 0
450
291
  });
292
+ const response = await apiRouterHandler(request);
293
+ const duration = Date.now() - startTime;
294
+ logResponse(method, pathname, response.status, duration);
295
+ await sendWebResponse(res, response);
296
+ } catch (error) {
297
+ const duration = Date.now() - startTime;
298
+ logResponse(method, pathname, 500, duration);
299
+ console.error("[FARM] API error:", error);
300
+ res.statusCode = 500;
301
+ res.setHeader("Content-Type", "application/json");
302
+ res.end(JSON.stringify({ error: "Internal server error" }));
451
303
  }
452
- const request = new Request(fullUrl, {
453
- method,
454
- headers,
455
- body: body || void 0
456
- });
457
- const response = await apiRouterHandler(request);
458
- const duration = Date.now() - startTime;
459
- logResponse(method, pathname, response.status, duration);
460
- await sendWebResponse(res, response);
461
- } catch (error) {
462
- const duration = Date.now() - startTime;
463
- logResponse(method, pathname, 500, duration);
464
- console.error("[FARM] API error:", error);
465
- res.statusCode = 500;
466
- res.setHeader("Content-Type", "application/json");
467
- res.end(JSON.stringify({ error: "Internal server error" }));
468
- }
469
- }));
304
+ })
305
+ );
470
306
  };
471
307
  },
472
308
  async handleHotUpdate({ file, server, modules }) {
@@ -586,14 +422,6 @@ function farmApiPlugin(options = {}) {
586
422
  __name(farmApiPlugin, "farmApiPlugin");
587
423
 
588
424
  export {
589
- createEndpoint,
590
- GET,
591
- HEAD,
592
- POST,
593
- PUT,
594
- DELETE,
595
- PATCH,
596
- OPTIONS,
597
425
  farmApiPlugin
598
426
  };
599
- //# sourceMappingURL=chunk-PRNYWD7K.mjs.map
427
+ //# sourceMappingURL=chunk-G5I34UA6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/vite-plugin.ts"],"sourcesContent":["/**\n * Farm.js API Routes Vite Plugin\n *\n * Standalone API route support that works with any Vite setup.\n * Discovers and handles route.ts files in the api directory.\n * Also supports root routes.ts for custom route definitions.\n *\n * @example\n * ```ts\n * import { farmApiPlugin } from '@farm.js/core'\n *\n * export default defineConfig({\n * plugins: [farmApiPlugin({ srcDir: 'src' })],\n * })\n * ```\n */\n\nimport type { Plugin, ViteDevServer } from \"vite\";\nimport { API_ROUTE_METHODS, invokeAPIRouteEndpoint, matchAPIRoute } from \"./route-manager\";\nimport { sendWebResponse } from \"../server/response\";\nimport { _withAfterNodeMiddleware } from \"../after\";\nimport { getProgrammaticRouteManifest, isProgrammaticRoutesFileName } from \"../routes\";\nimport { findProgrammaticRouteFilesInDir } from \"../routes.server\";\nimport { toViteModuleId } from \"../utils\";\n\nexport interface FarmApiPluginOptions {\n /** Source directory containing the api folder (default: 'src') */\n srcDir?: string;\n /** Enable debug logging */\n debug?: boolean;\n}\n\nexport interface ApiRoute {\n path: string;\n filePath: string;\n methods: string[];\n endpoints: Record<string, any>;\n}\n\n/**\n * Farm.js API Routes Vite Plugin\n */\nexport function farmApiPlugin(options: FarmApiPluginOptions = {}): Plugin {\n const srcDir = options.srcDir ?? \"src\";\n const debug = options.debug ?? false;\n\n // API routes cache\n let apiRoutesCache: Map<string, ApiRoute> = new Map();\n let apiRouterHandler: ((req: Request) => Promise<Response>) | null = null;\n let discoveryComplete = false;\n let discoveryPromise: Promise<void> | null = null;\n\n const log = (_message: string) => {};\n const logResponse = (method: string, urlPath: string, status: number, duration: number) => {\n try {\n const pc = require(\"picocolors\");\n let statusColor = pc.green;\n if (status >= 500) statusColor = pc.red;\n else if (status >= 400) statusColor = pc.yellow;\n else if (status >= 300) statusColor = pc.cyan;\n\n const logMsg = [\n pc.dim(\"[\") + pc.bold(pc.blue(\"FARM\")) + pc.dim(\"]\"),\n pc.dim(\"[\") + pc.bold(pc.cyan(\"API\")) + pc.dim(\"]\"),\n pc.dim(\"[\") + pc.bold(pc.white(method.padEnd(3))) + pc.dim(\"]\"),\n pc.gray(urlPath),\n pc.dim(\"-\"),\n statusColor(status.toString()),\n pc.dim(`(${duration}ms)`),\n ].join(\" \");\n console.log(logMsg);\n } catch {\n console.log(`[FARM] [API] [${method}] ${urlPath} - ${status} (${duration}ms)`);\n }\n };\n\n const addEndpoint = (\n routePath: string,\n filePath: string,\n method: string,\n endpoint: any,\n ): void => {\n const normalizedMethod = method.toUpperCase();\n const existing = apiRoutesCache.get(routePath);\n\n if (existing) {\n if (!existing.methods.includes(normalizedMethod)) {\n existing.methods.push(normalizedMethod);\n }\n existing.endpoints[normalizedMethod] = endpoint;\n return;\n }\n\n apiRoutesCache.set(routePath, {\n path: routePath,\n filePath,\n methods: [normalizedMethod],\n endpoints: { [normalizedMethod]: endpoint },\n });\n };\n\n // Create API router handler\n const createRouter = async (): Promise<void> => {\n const totalEndpoints = Array.from(apiRoutesCache.values()).reduce(\n (sum, route) => sum + route.methods.length,\n 0,\n );\n\n apiRouterHandler = null;\n\n if (totalEndpoints > 0) {\n apiRouterHandler = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n const method = request.method.toUpperCase();\n const pathname = url.pathname;\n\n const match = matchAPIRoute(apiRoutesCache, pathname);\n if (!match) {\n return new Response(JSON.stringify({ error: \"Not Found\" }), {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n const { route, params } = match;\n const endpoint = route.endpoints[method];\n if (!endpoint) {\n return new Response(JSON.stringify({ error: \"Method Not Allowed\" }), {\n status: 405,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n try {\n return await invokeAPIRouteEndpoint(endpoint, request, params);\n } catch (error: any) {\n return new Response(JSON.stringify({ error: error.message || \"Internal Server Error\" }), {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n };\n\n log(`API router created with ${totalEndpoints} endpoints`);\n }\n };\n\n return {\n name: \"@farm.js/core:api\",\n enforce: \"pre\",\n\n configureServer(server: ViteDevServer) {\n // Discover API routes in /api directory\n const discoverFileRoutes = async (apiDir: string): Promise<void> => {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n\n if (!fs.existsSync(apiDir)) {\n log(\"No api directory found\");\n return;\n }\n\n const findRouteFiles = (dir: string): string[] => {\n const files: string[] = [];\n if (!fs.existsSync(dir)) return files;\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...findRouteFiles(fullPath));\n } else if (\n entry.name === \"route.ts\" ||\n entry.name === \"route.tsx\" ||\n entry.name === \"route.js\"\n ) {\n files.push(fullPath);\n }\n }\n return files;\n };\n\n const routeFiles = findRouteFiles(apiDir);\n apiRoutesCache.clear();\n\n for (const filePath of routeFiles) {\n try {\n const relativePath = path.relative(apiDir, path.dirname(filePath));\n const routePath =\n \"/api/\" + (relativePath === \".\" ? \"\" : relativePath.replace(/\\\\/g, \"/\"));\n\n const routeModule = await server.ssrLoadModule(filePath);\n const endpoints: Record<string, any> = {};\n const availableMethods: string[] = [];\n\n for (const method of API_ROUTE_METHODS) {\n if (routeModule[method]) {\n availableMethods.push(method);\n endpoints[method] = routeModule[method];\n }\n }\n\n if (availableMethods.length > 0) {\n apiRoutesCache.set(routePath, {\n path: routePath,\n filePath,\n methods: availableMethods,\n endpoints,\n });\n log(`API route discovered: ${availableMethods.join(\", \")} ${routePath}`);\n }\n } catch (e: any) {\n log(`API route load failed at ${filePath}: ${e.message}`);\n }\n }\n };\n\n // Discover routes from root routes.ts file\n const discoverRootRoutes = async (): Promise<void> => {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n\n const routesFiles = [\n path.join(server.config.root, srcDir, \"routes.ts\"),\n path.join(server.config.root, srcDir, \"routes.tsx\"),\n path.join(server.config.root, srcDir, \"routes.js\"),\n ];\n\n for (const routesFile of routesFiles) {\n if (fs.existsSync(routesFile)) {\n try {\n const routesModule = await server.ssrLoadModule(routesFile);\n\n for (const [exportName, exportValue] of Object.entries(routesModule)) {\n const endpoint = exportValue as any;\n\n if (endpoint && endpoint.__path) {\n const routePath = endpoint.__path;\n const method = String(endpoint.__method || \"GET\").toUpperCase();\n\n addEndpoint(routePath, routesFile, method, endpoint);\n log(`Root route discovered: ${method} ${routePath}`);\n }\n }\n } catch (e: any) {\n log(`Root routes.ts load failed: ${e.message}`);\n }\n break;\n }\n }\n };\n\n const discoverProgrammaticRoutes = async (): Promise<void> => {\n const path = await import(\"path\");\n const srcRoot = path.join(server.config.root, srcDir);\n const routeFiles = findProgrammaticRouteFilesInDir(srcRoot);\n\n for (const routeFile of routeFiles) {\n try {\n const routesModule = await server.ssrLoadModule(\n toViteModuleId(routeFile, server.config.root),\n );\n const manifest = getProgrammaticRouteManifest(routesModule);\n if (!manifest) continue;\n\n for (const definition of manifest.routes) {\n if (definition.kind !== \"api\") continue;\n\n for (const [method, endpoint] of Object.entries(definition.methods)) {\n if (endpoint) {\n addEndpoint(definition.path, routeFile, method, endpoint);\n log(`Programmatic route discovered: ${method} ${definition.path}`);\n }\n }\n }\n } catch (e: any) {\n log(`Programmatic routes file load failed at ${routeFile}: ${e.message}`);\n }\n }\n };\n\n // Initialize discovery\n const initializeDiscovery = async () => {\n const path = await import(\"path\");\n const apiDir = path.join(server.config.root, srcDir, \"api\");\n log(`Discovering API routes in: ${apiDir}`);\n\n await discoverFileRoutes(apiDir);\n await discoverRootRoutes();\n await discoverProgrammaticRoutes();\n await createRouter();\n\n discoveryComplete = true;\n log(`API discovery complete: ${apiRoutesCache.size} routes found`);\n };\n\n discoveryPromise = initializeDiscovery().catch((e) => {\n console.error(\"[FARM] API discovery error:\", e);\n });\n\n // Expose API router for other plugins\n (server as any).__farmApi__ = {\n getHandler: () => apiRouterHandler,\n getRoutes: () => apiRoutesCache,\n isReady: () => discoveryComplete,\n waitForDiscovery: () => discoveryPromise,\n };\n\n // Add middleware to handle API requests\n return () => {\n server.middlewares.use(\n _withAfterNodeMiddleware(async (req, res, next) => {\n const url = req.url || \"/\";\n const pathname = url.split(\"?\")[0];\n const method = req.method || \"GET\";\n\n if (discoveryPromise && !discoveryComplete) {\n await discoveryPromise;\n }\n\n if (!matchAPIRoute(apiRoutesCache, pathname)) {\n return next();\n }\n\n if (!apiRouterHandler) {\n return next();\n }\n\n const startTime = Date.now();\n\n try {\n // Execute middleware if available\n const farmMiddleware = (server as any).__farmMiddleware__;\n if (farmMiddleware) {\n await farmMiddleware.waitForDiscovery?.();\n const middlewareData = new Map<string, any>();\n const handled = await farmMiddleware.execute(req, res, pathname, middlewareData);\n if (handled) {\n const duration = Date.now() - startTime;\n logResponse(method, pathname, res.statusCode || 200, duration);\n return;\n }\n }\n\n // Convert Node request to Web Request\n const fullUrl = `http://${req.headers.host || \"localhost:3000\"}${url}`;\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value.join(\", \") : value);\n }\n }\n\n let body: string | undefined;\n if (method !== \"GET\" && method !== \"HEAD\") {\n body = await new Promise<string>((resolve) => {\n let data = \"\";\n req.on(\"data\", (chunk: any) => {\n data += chunk;\n });\n req.on(\"end\", () => {\n resolve(data);\n });\n });\n }\n\n const request = new Request(fullUrl, {\n method,\n headers,\n body: body || undefined,\n });\n\n const response = await apiRouterHandler(request);\n\n const duration = Date.now() - startTime;\n logResponse(method, pathname, response.status, duration);\n\n await sendWebResponse(res, response);\n } catch (error: any) {\n const duration = Date.now() - startTime;\n logResponse(method, pathname, 500, duration);\n console.error(\"[FARM] API error:\", error);\n res.statusCode = 500;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({ error: \"Internal server error\" }));\n }\n }),\n );\n };\n },\n\n async handleHotUpdate({ file, server, modules }) {\n const fileName = file.split(\"/\").pop() || \"\";\n\n // Handle root routes.ts updates\n if (\n fileName === \"routes.ts\" ||\n fileName === \"routes.tsx\" ||\n fileName === \"routes.js\" ||\n isProgrammaticRoutesFileName(fileName)\n ) {\n log(`Root routes file updated: ${fileName}`);\n\n for (const mod of modules) {\n server.moduleGraph.invalidateModule(mod);\n }\n\n // Clear routes from this file\n for (const [routePath, route] of apiRoutesCache) {\n if (route.filePath === file) {\n apiRoutesCache.delete(routePath);\n }\n }\n\n try {\n const routesModule = await server.ssrLoadModule(file);\n\n for (const [exportName, exportValue] of Object.entries(routesModule)) {\n const endpoint = exportValue as any;\n\n if (endpoint && endpoint.__path) {\n const routePath = endpoint.__path;\n const method = String(endpoint.__method || \"GET\").toUpperCase();\n\n addEndpoint(routePath, file, method, endpoint);\n log(`Root route reloaded: ${method} ${routePath}`);\n }\n }\n\n const manifest = getProgrammaticRouteManifest(routesModule);\n if (manifest) {\n for (const definition of manifest.routes) {\n if (definition.kind !== \"api\") continue;\n\n for (const [method, endpoint] of Object.entries(definition.methods)) {\n if (endpoint) {\n addEndpoint(definition.path, file, method, endpoint);\n log(`Programmatic route reloaded: ${method} ${definition.path}`);\n }\n }\n }\n }\n\n await createRouter();\n log(`API router recreated`);\n } catch (e: any) {\n log(`Root routes.ts HMR failed: ${e.message}`);\n }\n\n return [];\n }\n\n // Handle file-based route updates\n if (file.includes(\"/api/\") && fileName.startsWith(\"route.\")) {\n const shortPath = file.split(\"/api/\")[1] || file;\n log(`API route updated: ${shortPath}`);\n\n for (const mod of modules) {\n server.moduleGraph.invalidateModule(mod);\n }\n\n let routePathToUpdate: string | null = null;\n for (const [routePath, route] of apiRoutesCache) {\n if (route.filePath === file) {\n routePathToUpdate = routePath;\n break;\n }\n }\n\n if (routePathToUpdate) {\n try {\n const routeModule = await server.ssrLoadModule(file);\n const endpoints: Record<string, any> = {};\n const availableMethods: string[] = [];\n\n for (const method of API_ROUTE_METHODS) {\n if (routeModule[method]) {\n availableMethods.push(method);\n endpoints[method] = routeModule[method];\n }\n }\n\n if (availableMethods.length > 0) {\n apiRoutesCache.set(routePathToUpdate, {\n path: routePathToUpdate,\n filePath: file,\n methods: availableMethods,\n endpoints,\n });\n log(`API route reloaded: ${routePathToUpdate}`);\n await createRouter();\n log(`API router recreated`);\n }\n } catch (e: any) {\n log(`API route HMR failed: ${e.message}`);\n }\n } else {\n // New route file\n try {\n const path = await import(\"path\");\n const apiDir = path.join(server.config.root, srcDir, \"api\");\n const relativePath = path.relative(apiDir, path.dirname(file));\n const routePath =\n \"/api/\" + (relativePath === \".\" ? \"\" : relativePath.replace(/\\\\/g, \"/\"));\n\n const routeModule = await server.ssrLoadModule(file);\n const endpoints: Record<string, any> = {};\n const availableMethods: string[] = [];\n\n for (const method of API_ROUTE_METHODS) {\n if (routeModule[method]) {\n availableMethods.push(method);\n endpoints[method] = routeModule[method];\n }\n }\n\n if (availableMethods.length > 0) {\n apiRoutesCache.set(routePath, {\n path: routePath,\n filePath: file,\n methods: availableMethods,\n endpoints,\n });\n log(`New API route discovered: ${routePath}`);\n await createRouter();\n }\n } catch (e: any) {\n log(`New API route load failed: ${e.message}`);\n }\n }\n\n return [];\n }\n },\n };\n}\n"],"mappings":"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","names":["duration"]}
@@ -119,8 +119,8 @@ function compareFarmRouteRuleSpecificity(left, right) {
119
119
  __name(compareFarmRouteRuleSpecificity, "compareFarmRouteRuleSpecificity");
120
120
  function getFarmRouteRuleSpecificity(pattern) {
121
121
  return normalizeRoutePattern(pattern).split("/").filter(Boolean).reduce((score, segment) => {
122
- if (segment === "**" || /^\[\[\.\.\./.test(segment)) return score + 1;
123
- if (segment === "*" || /^\[\.\.\./.test(segment)) return score + 10;
122
+ if (segment === "**" || segment.startsWith("[[...")) return score + 1;
123
+ if (segment === "*" || segment.startsWith("[...")) return score + 10;
124
124
  if (/^\[.+\]$/.test(segment) || /^:.+$/.test(segment)) return score + 50;
125
125
  return score + 100;
126
126
  }, 0);
@@ -146,4 +146,4 @@ export {
146
146
  resolveFarmRouteRuleRuntimeConfig,
147
147
  farmRouteRuleMatches
148
148
  };
149
- //# sourceMappingURL=chunk-QM6VV26B.mjs.map
149
+ //# sourceMappingURL=chunk-GQVGIUSN.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/route-runtime.ts"],"sourcesContent":["export type FarmRouteRuntime = \"auto\" | \"node\" | \"edge\";\nexport type FarmRouteRegions = \"auto\" | readonly string[];\nexport type FarmRouteMaxDuration = \"auto\" | number;\n\n/** Portable execution controls shared by file, programmatic, and config routes. */\nexport interface FarmRouteRuntimeConfig {\n runtime?: FarmRouteRuntime;\n regions?: FarmRouteRegions;\n maxDuration?: FarmRouteMaxDuration;\n}\n\nexport interface ResolvedFarmRouteRuntimeConfig {\n runtime: FarmRouteRuntime;\n regions?: string[];\n maxDuration?: number;\n}\n\nexport type FarmRouteRuntimeEntryKind = \"page\" | \"api\" | \"rule\";\nexport type FarmRouteRenderingMode = \"static\" | \"dynamic\";\n\nexport interface FarmRouteRuntimeManifestEntry extends ResolvedFarmRouteRuntimeConfig {\n kind: FarmRouteRuntimeEntryKind;\n pattern: string;\n rendering: FarmRouteRenderingMode;\n source?: string;\n}\n\nexport interface FarmRouteRuntimeManifest {\n version: 1;\n routes: FarmRouteRuntimeManifestEntry[];\n}\n\nexport function normalizeFarmRouteRuntimeConfig(\n value: FarmRouteRuntimeConfig | null | undefined,\n source = \"Route configuration\",\n): FarmRouteRuntimeConfig {\n if (!value) return {};\n\n const normalized: FarmRouteRuntimeConfig = {};\n\n if (value.runtime !== undefined) {\n if (value.runtime !== \"auto\" && value.runtime !== \"node\" && value.runtime !== \"edge\") {\n throw new TypeError(`${source} runtime must be \"auto\", \"node\", or \"edge\"`);\n }\n normalized.runtime = value.runtime;\n }\n\n if (value.regions !== undefined) {\n if (value.regions === \"auto\") {\n normalized.regions = \"auto\";\n } else {\n if (!Array.isArray(value.regions) || value.regions.length === 0) {\n throw new TypeError(`${source} regions must be \"auto\" or a non-empty string array`);\n }\n\n const regions = Array.from(\n new Set(\n value.regions.map((region) => {\n if (\n typeof region !== \"string\" ||\n !region.trim() ||\n /[\\u0000-\\u001f\\u007f]/.test(region)\n ) {\n throw new TypeError(`${source} regions must contain non-empty region identifiers`);\n }\n return region.trim();\n }),\n ),\n );\n\n normalized.regions = regions;\n }\n }\n\n if (value.maxDuration !== undefined) {\n if (value.maxDuration === \"auto\") {\n normalized.maxDuration = \"auto\";\n } else if (\n typeof value.maxDuration !== \"number\" ||\n !Number.isInteger(value.maxDuration) ||\n value.maxDuration <= 0\n ) {\n throw new TypeError(`${source} maxDuration must be \"auto\" or a positive integer in seconds`);\n } else {\n normalized.maxDuration = value.maxDuration;\n }\n }\n\n return normalized;\n}\n\n/** Merge from lowest to highest precedence. Explicit \"auto\" values reset inherited hints. */\nexport function mergeFarmRouteRuntimeConfigs(\n ...configs: Array<FarmRouteRuntimeConfig | null | undefined>\n): FarmRouteRuntimeConfig {\n const merged: FarmRouteRuntimeConfig = {};\n\n for (const config of configs) {\n if (!config) continue;\n if (config.runtime !== undefined) merged.runtime = config.runtime;\n if (config.regions !== undefined) merged.regions = config.regions;\n if (config.maxDuration !== undefined) merged.maxDuration = config.maxDuration;\n }\n\n return merged;\n}\n\nexport function resolveFarmRouteRuntimeConfig(\n config: FarmRouteRuntimeConfig | null | undefined,\n source?: string,\n): ResolvedFarmRouteRuntimeConfig {\n const normalized = normalizeFarmRouteRuntimeConfig(config, source);\n\n return {\n runtime: normalized.runtime ?? \"auto\",\n ...(normalized.regions && normalized.regions !== \"auto\"\n ? { regions: [...normalized.regions] }\n : {}),\n ...(typeof normalized.maxDuration === \"number\" ? { maxDuration: normalized.maxDuration } : {}),\n };\n}\n\nexport function hasFarmRouteRuntimeControls(\n config: FarmRouteRuntimeConfig | null | undefined,\n): boolean {\n return Boolean(\n config &&\n (config.runtime !== undefined ||\n config.regions !== undefined ||\n config.maxDuration !== undefined),\n );\n}\n\nexport function getFarmRouteRuntimeConfig(value: unknown): FarmRouteRuntimeConfig {\n if (!value || typeof value !== \"object\") return {};\n const route = value as FarmRouteRuntimeConfig;\n return {\n ...(route.runtime !== undefined ? { runtime: route.runtime } : {}),\n ...(route.regions !== undefined ? { regions: route.regions } : {}),\n ...(route.maxDuration !== undefined ? { maxDuration: route.maxDuration } : {}),\n };\n}\n\nexport function createFarmRouteRuntimeKey(config: ResolvedFarmRouteRuntimeConfig): string {\n return JSON.stringify({\n runtime: config.runtime,\n regions: config.regions || null,\n maxDuration: config.maxDuration || null,\n });\n}\n\n/** Resolve matching route rules from broadest to most specific. */\nexport function resolveFarmRouteRuleRuntimeConfig(\n pathname: string,\n routeRules: Record<string, FarmRouteRuntimeConfig> | null | undefined,\n): FarmRouteRuntimeConfig {\n if (!routeRules) return {};\n\n const matches = Object.entries(routeRules)\n .filter(\n ([pattern, rule]) =>\n hasFarmRouteRuntimeControls(rule) && farmRouteRuleMatches(pattern, pathname),\n )\n .sort(([left], [right]) => compareFarmRouteRuleSpecificity(left, right));\n\n return mergeFarmRouteRuntimeConfigs(...matches.map(([, rule]) => rule));\n}\n\nexport function farmRouteRuleMatches(pattern: string, pathname: string): boolean {\n const normalizedPattern = normalizeRoutePattern(pattern);\n const normalizedPathname = normalizeRoutePattern(pathname);\n if (normalizedPattern === normalizedPathname) return true;\n\n const expression = normalizedPattern\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (segment === \"**\") return \".*\";\n if (segment === \"*\") return \"[^/]+\";\n if (/^\\[\\[\\.\\.\\..+\\]\\]$/.test(segment)) return \".*\";\n if (/^\\[\\.\\.\\..+\\]$/.test(segment)) return \".+\";\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return \"[^/]+\";\n return escapeRegExp(segment);\n })\n .join(\"/\");\n\n return new RegExp(`^/${expression}/?$`).test(normalizedPathname);\n}\n\nfunction compareFarmRouteRuleSpecificity(left: string, right: string): number {\n const leftScore = getFarmRouteRuleSpecificity(left);\n const rightScore = getFarmRouteRuleSpecificity(right);\n return leftScore - rightScore || left.localeCompare(right);\n}\n\nfunction getFarmRouteRuleSpecificity(pattern: string): number {\n return normalizeRoutePattern(pattern)\n .split(\"/\")\n .filter(Boolean)\n .reduce((score, segment) => {\n if (segment === \"**\" || /^\\[\\[\\.\\.\\./.test(segment)) return score + 1;\n if (segment === \"*\" || /^\\[\\.\\.\\./.test(segment)) return score + 10;\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return score + 50;\n return score + 100;\n }, 0);\n}\n\nfunction normalizeRoutePattern(value: string): string {\n const withSlash = value.trim().startsWith(\"/\") ? value.trim() : `/${value.trim()}`;\n return withSlash.length > 1 ? withSlash.replace(/\\/+$/, \"\") : withSlash;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/route-runtime.ts"],"sourcesContent":["export type FarmRouteRuntime = \"auto\" | \"node\" | \"edge\";\nexport type FarmRouteRegions = \"auto\" | readonly string[];\nexport type FarmRouteMaxDuration = \"auto\" | number;\n\n/** Portable execution controls shared by file, programmatic, and config routes. */\nexport interface FarmRouteRuntimeConfig {\n runtime?: FarmRouteRuntime;\n regions?: FarmRouteRegions;\n maxDuration?: FarmRouteMaxDuration;\n}\n\nexport interface ResolvedFarmRouteRuntimeConfig {\n runtime: FarmRouteRuntime;\n regions?: string[];\n maxDuration?: number;\n}\n\nexport type FarmRouteRuntimeEntryKind = \"page\" | \"api\" | \"rule\";\nexport type FarmRouteRenderingMode = \"static\" | \"dynamic\";\n\nexport interface FarmRouteRuntimeManifestEntry extends ResolvedFarmRouteRuntimeConfig {\n kind: FarmRouteRuntimeEntryKind;\n pattern: string;\n rendering: FarmRouteRenderingMode;\n source?: string;\n}\n\nexport interface FarmRouteRuntimeManifest {\n version: 1;\n routes: FarmRouteRuntimeManifestEntry[];\n}\n\nexport function normalizeFarmRouteRuntimeConfig(\n value: FarmRouteRuntimeConfig | null | undefined,\n source = \"Route configuration\",\n): FarmRouteRuntimeConfig {\n if (!value) return {};\n\n const normalized: FarmRouteRuntimeConfig = {};\n\n if (value.runtime !== undefined) {\n if (value.runtime !== \"auto\" && value.runtime !== \"node\" && value.runtime !== \"edge\") {\n throw new TypeError(`${source} runtime must be \"auto\", \"node\", or \"edge\"`);\n }\n normalized.runtime = value.runtime;\n }\n\n if (value.regions !== undefined) {\n if (value.regions === \"auto\") {\n normalized.regions = \"auto\";\n } else {\n if (!Array.isArray(value.regions) || value.regions.length === 0) {\n throw new TypeError(`${source} regions must be \"auto\" or a non-empty string array`);\n }\n\n const regions = Array.from(\n new Set(\n value.regions.map((region) => {\n if (\n typeof region !== \"string\" ||\n !region.trim() ||\n /[\\u0000-\\u001f\\u007f]/.test(region)\n ) {\n throw new TypeError(`${source} regions must contain non-empty region identifiers`);\n }\n return region.trim();\n }),\n ),\n );\n\n normalized.regions = regions;\n }\n }\n\n if (value.maxDuration !== undefined) {\n if (value.maxDuration === \"auto\") {\n normalized.maxDuration = \"auto\";\n } else if (\n typeof value.maxDuration !== \"number\" ||\n !Number.isInteger(value.maxDuration) ||\n value.maxDuration <= 0\n ) {\n throw new TypeError(`${source} maxDuration must be \"auto\" or a positive integer in seconds`);\n } else {\n normalized.maxDuration = value.maxDuration;\n }\n }\n\n return normalized;\n}\n\n/** Merge from lowest to highest precedence. Explicit \"auto\" values reset inherited hints. */\nexport function mergeFarmRouteRuntimeConfigs(\n ...configs: Array<FarmRouteRuntimeConfig | null | undefined>\n): FarmRouteRuntimeConfig {\n const merged: FarmRouteRuntimeConfig = {};\n\n for (const config of configs) {\n if (!config) continue;\n if (config.runtime !== undefined) merged.runtime = config.runtime;\n if (config.regions !== undefined) merged.regions = config.regions;\n if (config.maxDuration !== undefined) merged.maxDuration = config.maxDuration;\n }\n\n return merged;\n}\n\nexport function resolveFarmRouteRuntimeConfig(\n config: FarmRouteRuntimeConfig | null | undefined,\n source?: string,\n): ResolvedFarmRouteRuntimeConfig {\n const normalized = normalizeFarmRouteRuntimeConfig(config, source);\n\n return {\n runtime: normalized.runtime ?? \"auto\",\n ...(normalized.regions && normalized.regions !== \"auto\"\n ? { regions: [...normalized.regions] }\n : {}),\n ...(typeof normalized.maxDuration === \"number\" ? { maxDuration: normalized.maxDuration } : {}),\n };\n}\n\nexport function hasFarmRouteRuntimeControls(\n config: FarmRouteRuntimeConfig | null | undefined,\n): boolean {\n return Boolean(\n config &&\n (config.runtime !== undefined ||\n config.regions !== undefined ||\n config.maxDuration !== undefined),\n );\n}\n\nexport function getFarmRouteRuntimeConfig(value: unknown): FarmRouteRuntimeConfig {\n if (!value || typeof value !== \"object\") return {};\n const route = value as FarmRouteRuntimeConfig;\n return {\n ...(route.runtime !== undefined ? { runtime: route.runtime } : {}),\n ...(route.regions !== undefined ? { regions: route.regions } : {}),\n ...(route.maxDuration !== undefined ? { maxDuration: route.maxDuration } : {}),\n };\n}\n\nexport function createFarmRouteRuntimeKey(config: ResolvedFarmRouteRuntimeConfig): string {\n return JSON.stringify({\n runtime: config.runtime,\n regions: config.regions || null,\n maxDuration: config.maxDuration || null,\n });\n}\n\n/** Resolve matching route rules from broadest to most specific. */\nexport function resolveFarmRouteRuleRuntimeConfig(\n pathname: string,\n routeRules: Record<string, FarmRouteRuntimeConfig> | null | undefined,\n): FarmRouteRuntimeConfig {\n if (!routeRules) return {};\n\n const matches = Object.entries(routeRules)\n .filter(\n ([pattern, rule]) =>\n hasFarmRouteRuntimeControls(rule) && farmRouteRuleMatches(pattern, pathname),\n )\n .sort(([left], [right]) => compareFarmRouteRuleSpecificity(left, right));\n\n return mergeFarmRouteRuntimeConfigs(...matches.map(([, rule]) => rule));\n}\n\nexport function farmRouteRuleMatches(pattern: string, pathname: string): boolean {\n const normalizedPattern = normalizeRoutePattern(pattern);\n const normalizedPathname = normalizeRoutePattern(pathname);\n if (normalizedPattern === normalizedPathname) return true;\n\n const expression = normalizedPattern\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => {\n if (segment === \"**\") return \".*\";\n if (segment === \"*\") return \"[^/]+\";\n if (/^\\[\\[\\.\\.\\..+\\]\\]$/.test(segment)) return \".*\";\n if (/^\\[\\.\\.\\..+\\]$/.test(segment)) return \".+\";\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return \"[^/]+\";\n return escapeRegExp(segment);\n })\n .join(\"/\");\n\n return new RegExp(`^/${expression}/?$`).test(normalizedPathname);\n}\n\nfunction compareFarmRouteRuleSpecificity(left: string, right: string): number {\n const leftScore = getFarmRouteRuleSpecificity(left);\n const rightScore = getFarmRouteRuleSpecificity(right);\n return leftScore - rightScore || left.localeCompare(right);\n}\n\nfunction getFarmRouteRuleSpecificity(pattern: string): number {\n return normalizeRoutePattern(pattern)\n .split(\"/\")\n .filter(Boolean)\n .reduce((score, segment) => {\n if (segment === \"**\" || segment.startsWith(\"[[...\")) return score + 1;\n if (segment === \"*\" || segment.startsWith(\"[...\")) return score + 10;\n if (/^\\[.+\\]$/.test(segment) || /^:.+$/.test(segment)) return score + 50;\n return score + 100;\n }, 0);\n}\n\nfunction normalizeRoutePattern(value: string): string {\n const withSlash = value.trim().startsWith(\"/\") ? value.trim() : `/${value.trim()}`;\n return withSlash.length > 1 ? withSlash.replace(/\\/+$/, \"\") : withSlash;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":[]}
@@ -361,4 +361,4 @@ export {
361
361
  isCronRequestAuthorized,
362
362
  cronRoute
363
363
  };
364
- //# sourceMappingURL=chunk-UREJA4GZ.mjs.map
364
+ //# sourceMappingURL=chunk-GXASWWJU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cron.ts"],"sourcesContent":["export type FarmCronSchedule = string | string[];\n\nexport interface FarmCronJobConfig {\n /** Portable five-field cron expression, or a list of expressions. */\n schedule: FarmCronSchedule;\n /** Farm API route invoked with GET when the schedule fires. */\n path: string;\n /** Human-readable purpose shown by local tooling and deployment manifests. */\n description?: string;\n /** Disable this schedule without removing its configuration. */\n enabled?: boolean;\n}\n\nexport type FarmCronUserConfig = Record<string, FarmCronJobConfig>;\n\nexport interface FarmCronJob {\n name: string;\n schedule: string[];\n path: string;\n description?: string;\n}\n\nexport interface FarmCronResolvedConfig {\n enabled: boolean;\n secretEnv: typeof DEFAULT_FARM_CRON_SECRET_ENV;\n jobs: FarmCronJob[];\n}\n\nexport interface PreparedFarmCron {\n jobs: FarmCronJob[];\n tasks: Record<string, { handler: string; description: string }>;\n scheduledTasks: Record<string, string | string[]>;\n manifestPath?: string;\n}\n\nexport interface FarmCronRouteOptions {\n /** Environment variable containing the bearer token. */\n secretEnv?: string;\n /** Inline token, primarily useful in tests. Environment variables are preferred. */\n secret?: string;\n /** Allow a production route without a secret. Defaults to false. */\n allowUnsecured?: boolean;\n}\n\nexport interface FarmCronCloudflareConfig {\n deployConfig: true;\n wrangler: {\n triggers: {\n crons: string[];\n };\n };\n}\n\nexport const DEFAULT_FARM_CRON_SECRET_ENV = \"CRON_SECRET\";\nexport const FARM_CRON_MANIFEST = \"cron-manifest.json\";\n\nconst CRON_FIELD_RANGES = [\n [0, 59, \"minute\"],\n [0, 23, \"hour\"],\n [1, 31, \"day of month\"],\n [1, 12, \"month\"],\n [0, 6, \"day of week\"],\n] as const;\n\nexport function resolveCronConfig(\n cron: FarmCronResolvedConfig | FarmCronUserConfig | false | undefined,\n): FarmCronResolvedConfig {\n if (isResolvedCronConfig(cron)) return cron;\n if (!cron) {\n return {\n enabled: false,\n secretEnv: DEFAULT_FARM_CRON_SECRET_ENV,\n jobs: [],\n };\n }\n\n const jobs: FarmCronJob[] = [];\n for (const [name, job] of Object.entries(cron)) {\n if (!job || typeof job !== \"object\" || Array.isArray(job)) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);\n }\n if (job.enabled === false) continue;\n jobs.push(normalizeCronJob(name, job));\n }\n\n return {\n enabled: jobs.length > 0,\n secretEnv: DEFAULT_FARM_CRON_SECRET_ENV,\n jobs,\n };\n}\n\nexport async function prepareFarmCronForNitro(config: {\n root?: string;\n distDir?: string;\n cron?: FarmCronResolvedConfig | FarmCronUserConfig | false;\n}): Promise<PreparedFarmCron> {\n const cron = isResolvedCronConfig(config.cron) ? config.cron : resolveCronConfig(config.cron);\n const root = config.root || process.cwd();\n const distDir = config.distDir || \".farm\";\n const fs = await import(\"node:fs/promises\");\n const path = await import(\"node:path\");\n const manifestPath = path.join(root, distDir, FARM_CRON_MANIFEST);\n const generatedDir = path.join(root, distDir, \".nitro\", \"farm-cron\");\n\n if (!cron.enabled) {\n await Promise.all([\n fs.rm(manifestPath, { force: true }),\n fs.rm(generatedDir, { recursive: true, force: true }),\n ]);\n return {\n jobs: [],\n tasks: {},\n scheduledTasks: {},\n };\n }\n\n await fs.rm(generatedDir, { recursive: true, force: true });\n await fs.mkdir(generatedDir, { recursive: true });\n\n const tasks: PreparedFarmCron[\"tasks\"] = {};\n for (const job of cron.jobs) {\n const taskName = getFarmCronTaskName(job.name);\n const wrapperPath = path.join(generatedDir, `${safeFileName(job.name)}.mjs`);\n await fs.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), \"utf8\");\n tasks[taskName] = {\n handler: wrapperPath,\n description: job.description || `Farm cron ${job.name}`,\n };\n }\n\n const manifest = createFarmCronManifest(cron);\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n\n return {\n jobs: cron.jobs,\n tasks,\n scheduledTasks: createCronScheduledTasks(cron.jobs),\n manifestPath,\n };\n}\n\nexport function createFarmCronManifest(cron: FarmCronResolvedConfig) {\n return {\n schemaVersion: 1,\n secretEnv: cron.secretEnv,\n jobs: cron.jobs.map((job) => ({\n name: job.name,\n schedule: job.schedule,\n path: job.path,\n description: job.description || null,\n })),\n };\n}\n\nexport function createFarmCronVercelCrons(\n jobs: FarmCronJob[],\n): Array<{ path: string; schedule: string }> {\n return jobs.flatMap((job) =>\n job.schedule.map((schedule) => ({\n path: job.path,\n schedule,\n })),\n );\n}\n\nexport function applyFarmCronVercelCrons(\n vercelConfig: Record<string, any>,\n jobs: FarmCronJob[],\n): Record<string, any> {\n const existingCrons = Array.isArray(vercelConfig.crons) ? vercelConfig.crons : [];\n const seen = new Set(existingCrons.map((cron) => `${cron.path}:${cron.schedule}`));\n const crons = [...existingCrons];\n\n for (const cron of createFarmCronVercelCrons(jobs)) {\n const key = `${cron.path}:${cron.schedule}`;\n if (seen.has(key)) continue;\n seen.add(key);\n crons.push(cron);\n }\n\n return crons.length > 0 ? { ...vercelConfig, crons } : vercelConfig;\n}\n\nexport function createFarmCronCloudflareTriggers(jobs: FarmCronJob[]): string[] {\n return [...new Set(jobs.flatMap((job) => job.schedule))];\n}\n\nexport function createFarmCronCloudflareConfig(\n jobs: FarmCronJob[],\n): FarmCronCloudflareConfig | undefined {\n const crons = createFarmCronCloudflareTriggers(jobs);\n if (crons.length === 0) return undefined;\n\n return {\n deployConfig: true,\n wrangler: {\n triggers: { crons },\n },\n };\n}\n\nexport function mergeScheduledTasks(\n ...maps: Array<Record<string, string | string[]> | undefined>\n): Record<string, string | string[]> {\n const merged = new Map<string, string[]>();\n\n for (const map of maps) {\n for (const [schedule, taskNames] of Object.entries(map || {})) {\n const current = merged.get(schedule) || [];\n for (const taskName of Array.isArray(taskNames) ? taskNames : [taskNames]) {\n if (!current.includes(taskName)) current.push(taskName);\n }\n merged.set(schedule, current);\n }\n }\n\n return Object.fromEntries(\n [...merged].map(([schedule, taskNames]) => [\n schedule,\n taskNames.length === 1 ? taskNames[0] : taskNames,\n ]),\n );\n}\n\nexport function isCronRequestAuthorized(\n request: Request,\n options: FarmCronRouteOptions = {},\n): boolean {\n const secretEnv = options.secretEnv || DEFAULT_FARM_CRON_SECRET_ENV;\n const secret = options.secret || readEnvironmentValue(secretEnv);\n if (!secret) {\n return (\n options.allowUnsecured === true ||\n (!getFarmRuntimeBindings() && readEnvironmentValue(\"NODE_ENV\") !== \"production\")\n );\n }\n\n const authorization = request.headers.get(\"authorization\") || \"\";\n const bearer = authorization.startsWith(\"Bearer \") ? authorization.slice(7) : \"\";\n return bearer === secret || request.headers.get(\"x-farm-cron-secret\") === secret;\n}\n\nexport function cronRoute<TArgs extends unknown[], TResult>(\n handler: (request: Request, ...args: TArgs) => TResult,\n options: FarmCronRouteOptions = {},\n): (request: Request, ...args: TArgs) => TResult | Promise<Response> {\n return (request, ...args) => {\n if (!isCronRequestAuthorized(request, options)) {\n return Promise.resolve(\n Response.json({ error: \"Unauthorized cron request.\" }, { status: 401 }),\n );\n }\n return handler(request, ...args);\n };\n}\n\nfunction normalizeCronJob(name: string, job: FarmCronJobConfig): FarmCronJob {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(name)) {\n throw new TypeError(\n `Farm cron name ${JSON.stringify(name)} must start with a letter or number and contain only letters, numbers, dots, underscores, or hyphens.`,\n );\n }\n if (!job || typeof job !== \"object\" || Array.isArray(job)) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);\n }\n\n const path = normalizeCronPath(name, job.path);\n const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];\n const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name, value)))];\n if (schedule.length === 0) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} must define at least one schedule.`);\n }\n\n return {\n name,\n schedule,\n path,\n description: job.description?.trim() || undefined,\n };\n}\n\nfunction normalizeCronPath(name: string, value: unknown): string {\n if (typeof value !== \"string\" || !value.trim().startsWith(\"/\")) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} path must start with \"/\".`);\n }\n\n const path = value.trim();\n if (path.startsWith(\"//\") || path.includes(\"?\") || path.includes(\"#\")) {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} path must be an application pathname without a host, query, or hash.`,\n );\n }\n return path.length > 1 ? path.replace(/\\/+$/, \"\") : path;\n}\n\nfunction normalizeCronExpression(name: string, value: unknown): string {\n if (typeof value !== \"string\") {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} schedule must be a string.`);\n }\n\n const expression = value.trim().replace(/\\s+/g, \" \");\n const fields = expression.split(\" \");\n if (fields.length !== CRON_FIELD_RANGES.length) {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} schedule ${JSON.stringify(expression)} must use five fields: minute hour day-of-month month day-of-week.`,\n );\n }\n\n fields.forEach((field, index) => {\n const [minimum, maximum, label] = CRON_FIELD_RANGES[index];\n validateCronField(name, expression, field, minimum, maximum, label);\n });\n if (fields[2] !== \"*\" && fields[4] !== \"*\") {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} schedule ${JSON.stringify(expression)} cannot constrain both day-of-month and day-of-week.`,\n );\n }\n return expression;\n}\n\nfunction validateCronField(\n name: string,\n expression: string,\n field: string,\n minimum: number,\n maximum: number,\n label: string,\n): void {\n for (const segment of field.split(\",\")) {\n const [range, stepText, ...extra] = segment.split(\"/\");\n if (!range || extra.length > 0 || (stepText !== undefined && !isIntegerInRange(stepText, 1))) {\n throwInvalidCronField(name, expression, label);\n }\n\n if (range === \"*\") continue;\n const bounds = range.split(\"-\");\n if (bounds.length > 2 || !bounds.every((value) => isIntegerInRange(value, minimum, maximum))) {\n throwInvalidCronField(name, expression, label);\n }\n if (bounds.length === 2 && Number(bounds[0]) > Number(bounds[1])) {\n throwInvalidCronField(name, expression, label);\n }\n }\n}\n\nfunction isIntegerInRange(value: string, minimum: number, maximum = Number.MAX_SAFE_INTEGER) {\n if (!/^\\d+$/.test(value)) return false;\n const parsed = Number(value);\n return parsed >= minimum && parsed <= maximum;\n}\n\nfunction throwInvalidCronField(name: string, expression: string, label: string): never {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} schedule ${JSON.stringify(expression)} has an invalid ${label} field.`,\n );\n}\n\nfunction isResolvedCronConfig(value: unknown): value is FarmCronResolvedConfig {\n return (\n !!value &&\n typeof value === \"object\" &&\n \"enabled\" in value &&\n typeof (value as FarmCronResolvedConfig).enabled === \"boolean\" &&\n \"jobs\" in value &&\n Array.isArray((value as FarmCronResolvedConfig).jobs) &&\n \"secretEnv\" in value\n );\n}\n\nfunction createCronScheduledTasks(jobs: FarmCronJob[]): Record<string, string | string[]> {\n const scheduledTasks: Record<string, string | string[]> = {};\n for (const job of jobs) {\n const taskName = getFarmCronTaskName(job.name);\n for (const schedule of job.schedule) {\n scheduledTasks[schedule] = mergeTaskNames(scheduledTasks[schedule], taskName);\n }\n }\n return scheduledTasks;\n}\n\nfunction mergeTaskNames(\n current: string | string[] | undefined,\n taskName: string,\n): string | string[] {\n if (!current) return taskName;\n const names = Array.isArray(current) ? current : [current];\n return names.includes(taskName) ? names : [...names, taskName];\n}\n\nfunction getFarmCronTaskName(name: string): string {\n return `farm:cron:${name}`;\n}\n\nfunction createNitroCronTaskWrapper(job: FarmCronJob, secretEnv: string): string {\n return `\nimport { defineTask, useNitroApp } from \"nitro/runtime\";\n\nconst name = ${JSON.stringify(job.name)};\nconst path = ${JSON.stringify(job.path)};\nconst secretEnv = ${JSON.stringify(secretEnv)};\n\nfunction readSecret(event) {\n const runtimeEnv = event?.context?.cloudflare?.env || event?.context?.env || {};\n return runtimeEnv[secretEnv] || (typeof process !== \"undefined\" ? process.env?.[secretEnv] : \"\") || \"\";\n}\n\nexport default defineTask({\n meta: {\n name: ${JSON.stringify(getFarmCronTaskName(job.name))},\n description: ${JSON.stringify(job.description || `Farm cron ${job.name}`)}\n },\n async run(event) {\n const headers = new Headers({\n \"x-farm-cron-name\": name,\n \"x-farm-cron-scheduled-at\": String(event?.payload?.scheduledTime || Date.now())\n });\n const secret = readSecret(event);\n if (secret) headers.set(\"authorization\", \"Bearer \" + secret);\n\n const response = await useNitroApp().fetch(path, { method: \"GET\", headers });\n const contentType = response.headers.get(\"content-type\") || \"\";\n const body = response.status === 204\n ? null\n : contentType.includes(\"application/json\")\n ? await response.json().catch(() => null)\n : await response.text();\n\n if (!response.ok) {\n const detail = typeof body === \"string\" ? body : JSON.stringify(body);\n throw new Error(\n \"Farm cron \" + JSON.stringify(name) + \" received \" + response.status +\n \" from \" + path + (detail ? \": \" + detail : \"\")\n );\n }\n\n return { result: body };\n }\n});\n`.trim();\n}\n\nfunction readEnvironmentValue(name: string): string | undefined {\n const runtimeValue = getFarmRuntimeBindings()?.[name];\n if (typeof runtimeValue === \"string\") return runtimeValue;\n return typeof process !== \"undefined\" ? process.env?.[name] : undefined;\n}\n\nfunction getFarmRuntimeBindings(): Record<string, unknown> | undefined {\n const runtimeBindings = (globalThis as typeof globalThis & {\n __env__?: Record<string, unknown>;\n }).__env__;\n return runtimeBindings && typeof runtimeBindings === \"object\" ? runtimeBindings : undefined;\n}\n\nfunction safeFileName(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, \"-\") || \"cron\";\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cron.ts"],"sourcesContent":["export type FarmCronSchedule = string | string[];\n\nexport interface FarmCronJobConfig {\n /** Portable five-field cron expression, or a list of expressions. */\n schedule: FarmCronSchedule;\n /** Farm API route invoked with GET when the schedule fires. */\n path: string;\n /** Human-readable purpose shown by local tooling and deployment manifests. */\n description?: string;\n /** Disable this schedule without removing its configuration. */\n enabled?: boolean;\n}\n\nexport type FarmCronUserConfig = Record<string, FarmCronJobConfig>;\n\nexport interface FarmCronJob {\n name: string;\n schedule: string[];\n path: string;\n description?: string;\n}\n\nexport interface FarmCronResolvedConfig {\n enabled: boolean;\n secretEnv: typeof DEFAULT_FARM_CRON_SECRET_ENV;\n jobs: FarmCronJob[];\n}\n\nexport interface PreparedFarmCron {\n jobs: FarmCronJob[];\n tasks: Record<string, { handler: string; description: string }>;\n scheduledTasks: Record<string, string | string[]>;\n manifestPath?: string;\n}\n\nexport interface FarmCronRouteOptions {\n /** Environment variable containing the bearer token. */\n secretEnv?: string;\n /** Inline token, primarily useful in tests. Environment variables are preferred. */\n secret?: string;\n /** Allow a production route without a secret. Defaults to false. */\n allowUnsecured?: boolean;\n}\n\nexport interface FarmCronCloudflareConfig {\n deployConfig: true;\n wrangler: {\n triggers: {\n crons: string[];\n };\n };\n}\n\nexport const DEFAULT_FARM_CRON_SECRET_ENV = \"CRON_SECRET\";\nexport const FARM_CRON_MANIFEST = \"cron-manifest.json\";\n\nconst CRON_FIELD_RANGES = [\n [0, 59, \"minute\"],\n [0, 23, \"hour\"],\n [1, 31, \"day of month\"],\n [1, 12, \"month\"],\n [0, 6, \"day of week\"],\n] as const;\n\nexport function resolveCronConfig(\n cron: FarmCronResolvedConfig | FarmCronUserConfig | false | undefined,\n): FarmCronResolvedConfig {\n if (isResolvedCronConfig(cron)) return cron;\n if (!cron) {\n return {\n enabled: false,\n secretEnv: DEFAULT_FARM_CRON_SECRET_ENV,\n jobs: [],\n };\n }\n\n const jobs: FarmCronJob[] = [];\n for (const [name, job] of Object.entries(cron)) {\n if (!job || typeof job !== \"object\" || Array.isArray(job)) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);\n }\n if (job.enabled === false) continue;\n jobs.push(normalizeCronJob(name, job));\n }\n\n return {\n enabled: jobs.length > 0,\n secretEnv: DEFAULT_FARM_CRON_SECRET_ENV,\n jobs,\n };\n}\n\nexport async function prepareFarmCronForNitro(config: {\n root?: string;\n distDir?: string;\n cron?: FarmCronResolvedConfig | FarmCronUserConfig | false;\n}): Promise<PreparedFarmCron> {\n const cron = isResolvedCronConfig(config.cron) ? config.cron : resolveCronConfig(config.cron);\n const root = config.root || process.cwd();\n const distDir = config.distDir || \".farm\";\n const fs = await import(\"node:fs/promises\");\n const path = await import(\"node:path\");\n const manifestPath = path.join(root, distDir, FARM_CRON_MANIFEST);\n const generatedDir = path.join(root, distDir, \".nitro\", \"farm-cron\");\n\n if (!cron.enabled) {\n await Promise.all([\n fs.rm(manifestPath, { force: true }),\n fs.rm(generatedDir, { recursive: true, force: true }),\n ]);\n return {\n jobs: [],\n tasks: {},\n scheduledTasks: {},\n };\n }\n\n await fs.rm(generatedDir, { recursive: true, force: true });\n await fs.mkdir(generatedDir, { recursive: true });\n\n const tasks: PreparedFarmCron[\"tasks\"] = {};\n for (const job of cron.jobs) {\n const taskName = getFarmCronTaskName(job.name);\n const wrapperPath = path.join(generatedDir, `${safeFileName(job.name)}.mjs`);\n await fs.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), \"utf8\");\n tasks[taskName] = {\n handler: wrapperPath,\n description: job.description || `Farm cron ${job.name}`,\n };\n }\n\n const manifest = createFarmCronManifest(cron);\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n\n return {\n jobs: cron.jobs,\n tasks,\n scheduledTasks: createCronScheduledTasks(cron.jobs),\n manifestPath,\n };\n}\n\nexport function createFarmCronManifest(cron: FarmCronResolvedConfig) {\n return {\n schemaVersion: 1,\n secretEnv: cron.secretEnv,\n jobs: cron.jobs.map((job) => ({\n name: job.name,\n schedule: job.schedule,\n path: job.path,\n description: job.description || null,\n })),\n };\n}\n\nexport function createFarmCronVercelCrons(\n jobs: FarmCronJob[],\n): Array<{ path: string; schedule: string }> {\n return jobs.flatMap((job) =>\n job.schedule.map((schedule) => ({\n path: job.path,\n schedule,\n })),\n );\n}\n\nexport function applyFarmCronVercelCrons(\n vercelConfig: Record<string, any>,\n jobs: FarmCronJob[],\n): Record<string, any> {\n const existingCrons = Array.isArray(vercelConfig.crons) ? vercelConfig.crons : [];\n const seen = new Set(existingCrons.map((cron) => `${cron.path}:${cron.schedule}`));\n const crons = [...existingCrons];\n\n for (const cron of createFarmCronVercelCrons(jobs)) {\n const key = `${cron.path}:${cron.schedule}`;\n if (seen.has(key)) continue;\n seen.add(key);\n crons.push(cron);\n }\n\n return crons.length > 0 ? { ...vercelConfig, crons } : vercelConfig;\n}\n\nexport function createFarmCronCloudflareTriggers(jobs: FarmCronJob[]): string[] {\n return [...new Set(jobs.flatMap((job) => job.schedule))];\n}\n\nexport function createFarmCronCloudflareConfig(\n jobs: FarmCronJob[],\n): FarmCronCloudflareConfig | undefined {\n const crons = createFarmCronCloudflareTriggers(jobs);\n if (crons.length === 0) return undefined;\n\n return {\n deployConfig: true,\n wrangler: {\n triggers: { crons },\n },\n };\n}\n\nexport function mergeScheduledTasks(\n ...maps: Array<Record<string, string | string[]> | undefined>\n): Record<string, string | string[]> {\n const merged = new Map<string, string[]>();\n\n for (const map of maps) {\n for (const [schedule, taskNames] of Object.entries(map || {})) {\n const current = merged.get(schedule) || [];\n for (const taskName of Array.isArray(taskNames) ? taskNames : [taskNames]) {\n if (!current.includes(taskName)) current.push(taskName);\n }\n merged.set(schedule, current);\n }\n }\n\n return Object.fromEntries(\n [...merged].map(([schedule, taskNames]) => [\n schedule,\n taskNames.length === 1 ? taskNames[0] : taskNames,\n ]),\n );\n}\n\nexport function isCronRequestAuthorized(\n request: Request,\n options: FarmCronRouteOptions = {},\n): boolean {\n const secretEnv = options.secretEnv || DEFAULT_FARM_CRON_SECRET_ENV;\n const secret = options.secret || readEnvironmentValue(secretEnv);\n if (!secret) {\n return (\n options.allowUnsecured === true ||\n (!getFarmRuntimeBindings() && readEnvironmentValue(\"NODE_ENV\") !== \"production\")\n );\n }\n\n const authorization = request.headers.get(\"authorization\") || \"\";\n const bearer = authorization.startsWith(\"Bearer \") ? authorization.slice(7) : \"\";\n return bearer === secret || request.headers.get(\"x-farm-cron-secret\") === secret;\n}\n\nexport function cronRoute<TArgs extends unknown[], TResult>(\n handler: (request: Request, ...args: TArgs) => TResult,\n options: FarmCronRouteOptions = {},\n): (request: Request, ...args: TArgs) => TResult | Promise<Response> {\n return (request, ...args) => {\n if (!isCronRequestAuthorized(request, options)) {\n return Promise.resolve(\n Response.json({ error: \"Unauthorized cron request.\" }, { status: 401 }),\n );\n }\n return handler(request, ...args);\n };\n}\n\nfunction normalizeCronJob(name: string, job: FarmCronJobConfig): FarmCronJob {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(name)) {\n throw new TypeError(\n `Farm cron name ${JSON.stringify(name)} must start with a letter or number and contain only letters, numbers, dots, underscores, or hyphens.`,\n );\n }\n if (!job || typeof job !== \"object\" || Array.isArray(job)) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);\n }\n\n const path = normalizeCronPath(name, job.path);\n const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];\n const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name, value)))];\n if (schedule.length === 0) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} must define at least one schedule.`);\n }\n\n return {\n name,\n schedule,\n path,\n description: job.description?.trim() || undefined,\n };\n}\n\nfunction normalizeCronPath(name: string, value: unknown): string {\n if (typeof value !== \"string\" || !value.trim().startsWith(\"/\")) {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} path must start with \"/\".`);\n }\n\n const path = value.trim();\n if (path.startsWith(\"//\") || path.includes(\"?\") || path.includes(\"#\")) {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} path must be an application pathname without a host, query, or hash.`,\n );\n }\n return path.length > 1 ? path.replace(/\\/+$/, \"\") : path;\n}\n\nfunction normalizeCronExpression(name: string, value: unknown): string {\n if (typeof value !== \"string\") {\n throw new TypeError(`Farm cron ${JSON.stringify(name)} schedule must be a string.`);\n }\n\n const expression = value.trim().replace(/\\s+/g, \" \");\n const fields = expression.split(\" \");\n if (fields.length !== CRON_FIELD_RANGES.length) {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} schedule ${JSON.stringify(expression)} must use five fields: minute hour day-of-month month day-of-week.`,\n );\n }\n\n fields.forEach((field, index) => {\n const [minimum, maximum, label] = CRON_FIELD_RANGES[index];\n validateCronField(name, expression, field, minimum, maximum, label);\n });\n if (fields[2] !== \"*\" && fields[4] !== \"*\") {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} schedule ${JSON.stringify(expression)} cannot constrain both day-of-month and day-of-week.`,\n );\n }\n return expression;\n}\n\nfunction validateCronField(\n name: string,\n expression: string,\n field: string,\n minimum: number,\n maximum: number,\n label: string,\n): void {\n for (const segment of field.split(\",\")) {\n const [range, stepText, ...extra] = segment.split(\"/\");\n if (!range || extra.length > 0 || (stepText !== undefined && !isIntegerInRange(stepText, 1))) {\n throwInvalidCronField(name, expression, label);\n }\n\n if (range === \"*\") continue;\n const bounds = range.split(\"-\");\n if (bounds.length > 2 || !bounds.every((value) => isIntegerInRange(value, minimum, maximum))) {\n throwInvalidCronField(name, expression, label);\n }\n if (bounds.length === 2 && Number(bounds[0]) > Number(bounds[1])) {\n throwInvalidCronField(name, expression, label);\n }\n }\n}\n\nfunction isIntegerInRange(value: string, minimum: number, maximum = Number.MAX_SAFE_INTEGER) {\n if (!/^\\d+$/.test(value)) return false;\n const parsed = Number(value);\n return parsed >= minimum && parsed <= maximum;\n}\n\nfunction throwInvalidCronField(name: string, expression: string, label: string): never {\n throw new TypeError(\n `Farm cron ${JSON.stringify(name)} schedule ${JSON.stringify(expression)} has an invalid ${label} field.`,\n );\n}\n\nfunction isResolvedCronConfig(value: unknown): value is FarmCronResolvedConfig {\n return (\n !!value &&\n typeof value === \"object\" &&\n \"enabled\" in value &&\n typeof (value as FarmCronResolvedConfig).enabled === \"boolean\" &&\n \"jobs\" in value &&\n Array.isArray((value as FarmCronResolvedConfig).jobs) &&\n \"secretEnv\" in value\n );\n}\n\nfunction createCronScheduledTasks(jobs: FarmCronJob[]): Record<string, string | string[]> {\n const scheduledTasks: Record<string, string | string[]> = {};\n for (const job of jobs) {\n const taskName = getFarmCronTaskName(job.name);\n for (const schedule of job.schedule) {\n scheduledTasks[schedule] = mergeTaskNames(scheduledTasks[schedule], taskName);\n }\n }\n return scheduledTasks;\n}\n\nfunction mergeTaskNames(\n current: string | string[] | undefined,\n taskName: string,\n): string | string[] {\n if (!current) return taskName;\n const names = Array.isArray(current) ? current : [current];\n return names.includes(taskName) ? names : [...names, taskName];\n}\n\nfunction getFarmCronTaskName(name: string): string {\n return `farm:cron:${name}`;\n}\n\nfunction createNitroCronTaskWrapper(job: FarmCronJob, secretEnv: string): string {\n return `\nimport { defineTask, useNitroApp } from \"nitro/runtime\";\n\nconst name = ${JSON.stringify(job.name)};\nconst path = ${JSON.stringify(job.path)};\nconst secretEnv = ${JSON.stringify(secretEnv)};\n\nfunction readSecret(event) {\n const runtimeEnv = event?.context?.cloudflare?.env || event?.context?.env || {};\n return runtimeEnv[secretEnv] || (typeof process !== \"undefined\" ? process.env?.[secretEnv] : \"\") || \"\";\n}\n\nexport default defineTask({\n meta: {\n name: ${JSON.stringify(getFarmCronTaskName(job.name))},\n description: ${JSON.stringify(job.description || `Farm cron ${job.name}`)}\n },\n async run(event) {\n const headers = new Headers({\n \"x-farm-cron-name\": name,\n \"x-farm-cron-scheduled-at\": String(event?.payload?.scheduledTime || Date.now())\n });\n const secret = readSecret(event);\n if (secret) headers.set(\"authorization\", \"Bearer \" + secret);\n\n const response = await useNitroApp().fetch(path, { method: \"GET\", headers });\n const contentType = response.headers.get(\"content-type\") || \"\";\n const body = response.status === 204\n ? null\n : contentType.includes(\"application/json\")\n ? await response.json().catch(() => null)\n : await response.text();\n\n if (!response.ok) {\n const detail = typeof body === \"string\" ? body : JSON.stringify(body);\n throw new Error(\n \"Farm cron \" + JSON.stringify(name) + \" received \" + response.status +\n \" from \" + path + (detail ? \": \" + detail : \"\")\n );\n }\n\n return { result: body };\n }\n});\n`.trim();\n}\n\nfunction readEnvironmentValue(name: string): string | undefined {\n const runtimeValue = getFarmRuntimeBindings()?.[name];\n if (typeof runtimeValue === \"string\") return runtimeValue;\n return typeof process !== \"undefined\" ? process.env?.[name] : undefined;\n}\n\nfunction getFarmRuntimeBindings(): Record<string, unknown> | undefined {\n const runtimeBindings = (\n globalThis as typeof globalThis & {\n __env__?: Record<string, unknown>;\n }\n ).__env__;\n return runtimeBindings && typeof runtimeBindings === \"object\" ? runtimeBindings : undefined;\n}\n\nfunction safeFileName(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, \"-\") || \"cron\";\n}\n"],"mappings":"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","names":[]}