@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
package/dist/client.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- export { n as APIClient, A as APIClientOptions, a as APIClientWithoutIntegrationsOptions, N as InferIntegrationOperationBody, P as InferIntegrationOperationQuery, Q as InferIntegrationOperationResponse, J as IntegrationAPI, D as IntegrationClient, E as IntegrationClientAliases, L as IntegrationClientData, s as IntegrationClientError, G as IntegrationClientOptions, H as IntegrationClientRequestOptions, F as IntegrationClientRoot, K as IntegrationClients, M as IntegrationOperationResult, T as IntegrationServerClient, U as IntegrationServerClientAliases, V as IntegrationServerClientOptions, W as IntegrationServerClientRequestOptions, X as IntegrationServerClientRoot, Y as IntegrationServerRequestLike, m as RouteAPIClient, o as ServerAPIClient, S as ServerAPIClientOptions, b as ServerAPIClientWithoutIntegrationsOptions, p as createAPIClient, t as createIntegrationApi, r as createIntegrationClient, u as createIntegrationClients, w as createIntegrationServerClient, v as createIntegrations, q as createServerAPIClient, x as getIntegrationAPIManifest, y as integrationClients, z as integrationsClient, B as integrationsServer } from './client-D_yUjVhe.mjs';
1
+ import { n as ClientOptions, e as APIResult } from './client-DiViK9yK.mjs';
2
+ export { p as APIClient, f as APIClientError, A as APIClientOptions, g as APIClientSystemError, a as APIClientWithoutIntegrationsOptions, U as InferIntegrationOperationBody, V as InferIntegrationOperationQuery, W as InferIntegrationOperationResponse, N as IntegrationAPI, H as IntegrationClient, J as IntegrationClientAliases, Q as IntegrationClientData, v as IntegrationClientError, L as IntegrationClientOptions, M as IntegrationClientRequestOptions, K as IntegrationClientRoot, P as IntegrationClients, T as IntegrationOperationResult, X as IntegrationServerClient, Y as IntegrationServerClientAliases, Z as IntegrationServerClientOptions, _ as IntegrationServerClientRequestOptions, $ as IntegrationServerClientRoot, a0 as IntegrationServerRequestLike, o as RouteAPIClient, q as ServerAPIClient, S as ServerAPIClientOptions, b as ServerAPIClientWithoutIntegrationsOptions, r as createAPIClient, w as createIntegrationApi, u as createIntegrationClient, x as createIntegrationClients, z as createIntegrationServerClient, y as createIntegrations, t as createServerAPIClient, B as getIntegrationAPIManifest, D as integrationClients, E as integrationsClient, G as integrationsServer } from './client-DiViK9yK.mjs';
2
3
  export { ServerQueryFetchOptions, UseServerQueryOptions, UseServerQueryResult, fetchServerQuery, prefetchServerQuery, useServerQuery } from './server-query-client.mjs';
3
4
  export { F as FarmIntegrationAPI, e as FarmIntegrationAPIBodyFormat, f as FarmIntegrationAPIMethod, a as FarmIntegrationAPIOperation, g as FarmIntegrationAPIResponseFormat, b as api, d as defineIntegrationAPI, c as defineIntegrationAPIOperation, i as endpoint } from './integration-api-CHT2OKAf.mjs';
4
5
  import React__default, { AnchorHTMLAttributes, RefObject } from 'react';
@@ -12,6 +13,57 @@ import './cache.mjs';
12
13
  import './server-query.mjs';
13
14
  import './server-fn.mjs';
14
15
 
16
+ type MutationStatus = "idle" | "pending" | "success" | "error";
17
+ type AnyMutationTarget = (...args: any[]) => Promise<any>;
18
+ type InferMutationVariables<TTarget extends AnyMutationTarget> = Parameters<TTarget> extends [] ? undefined : Parameters<TTarget>[0];
19
+ type InferMutationData<TTarget extends AnyMutationTarget> = TTarget extends {
20
+ readonly __farmRouteData: infer TData;
21
+ } ? TData : Awaited<ReturnType<TTarget>>;
22
+ type InferMutationError<TTarget extends AnyMutationTarget> = TTarget extends (...args: any[]) => Promise<APIResult<any, infer TError>> ? TError : Error;
23
+ type MutationOptimisticContext<TVariables, TData> = {
24
+ variables: TVariables | undefined;
25
+ current: TData | null;
26
+ };
27
+ type UseMutationOptions<TVariables, TData, TError = Error> = {
28
+ initialData?: TData | null;
29
+ resetOnMutate?: boolean;
30
+ optimistic?: (context: MutationOptimisticContext<TVariables, TData>) => TData | null | undefined;
31
+ rollbackOnError?: boolean;
32
+ /**
33
+ * Options forwarded to generated `api.route.method` clients.
34
+ * Server functions ignore this field.
35
+ */
36
+ request?: ClientOptions<TData, TError>;
37
+ onSuccess?: (data: TData, variables: TVariables | undefined) => void;
38
+ onError?: (error: TError, variables: TVariables | undefined) => void;
39
+ onSettled?: (data: TData | null, error: TError | null, variables: TVariables | undefined) => void;
40
+ };
41
+ type MutationInput<TTarget extends AnyMutationTarget> = InferMutationVariables<TTarget>;
42
+ type MutationData<TTarget extends AnyMutationTarget> = InferMutationData<TTarget>;
43
+ type MutationError<TTarget extends AnyMutationTarget> = InferMutationError<TTarget>;
44
+ type MutationAsync<TTarget extends AnyMutationTarget, TData = MutationData<TTarget>> = [
45
+ ] extends Parameters<TTarget> ? (variables?: MutationInput<TTarget>) => Promise<TData> : (variables: MutationInput<TTarget>) => Promise<TData>;
46
+ type MutationTrigger<TTarget extends AnyMutationTarget> = [
47
+ ] extends Parameters<TTarget> ? (variables?: MutationInput<TTarget>) => void : (variables: MutationInput<TTarget>) => void;
48
+ type UseMutationReturn<TTarget extends AnyMutationTarget, TData = MutationData<TTarget>, TError = MutationError<TTarget>> = {
49
+ pending: boolean;
50
+ status: MutationStatus;
51
+ data: TData | null;
52
+ error: TError | null;
53
+ variables: MutationInput<TTarget> | undefined;
54
+ mutate: MutationTrigger<TTarget>;
55
+ mutateAsync: MutationAsync<TTarget, TData>;
56
+ reset: () => void;
57
+ };
58
+ /**
59
+ * Track a generated API route mutation or a Farm server function with one
60
+ * React lifecycle.
61
+ *
62
+ * API routes keep using their existing fetch transport and request options.
63
+ * Server functions keep using their configured server-function transport.
64
+ */
65
+ declare function useMutation<TTarget extends AnyMutationTarget>(target: TTarget, options?: UseMutationOptions<MutationInput<TTarget>, MutationData<TTarget>, MutationError<TTarget>>): UseMutationReturn<TTarget>;
66
+
15
67
  type StoreState = Record<string, any>;
16
68
  type StoreValueUpdater<T> = T | ((previous: T) => T);
17
69
  type StorePatch<T extends StoreState> = Partial<T> | ((state: T) => Partial<T>);
@@ -326,4 +378,4 @@ declare function useNavigation(): FarmNavigationState;
326
378
  declare function useBlocker(options: UseBlockerOptions): UseBlockerReturn;
327
379
  declare function useScrollRestoration<TElement extends HTMLElement = HTMLElement>(key: string): RefObject<TElement>;
328
380
 
329
- export { type DefaultRouteHref, type DefaultRoutePath, type DefaultRoutePattern, type ExternalHref, FarmClientPluginManager, type FarmNavigateOptions, type FarmNavigationBlocker, type FarmNavigationBlockerContext, type FarmNavigationListener, type FarmNavigationLocation, type FarmNavigationState, type FarmViewTransitionMode, Link, type LinkDefaultRoute, type LinkProps, type PrefetchBehavior, type RouteHref, type RouteOptionalParamValue, type RouteParamValue, type RouteParams, SPARouter, type Store, type StoreApi, type StoreFields, type StoreKeyListener, type StoreKeysListener, type StoreListener, type StorePatch, type StoreState, type StoreValueUpdater, type UseBlockerOptions, type UseBlockerReturn, type UseRouterOptions, createStore, getRouter, navigateTo, prefetch, pushState, readPageState, replaceState, useBlocker, useNavigation, usePageState, useRouter, useScrollRestoration };
381
+ export { type DefaultRouteHref, type DefaultRoutePath, type DefaultRoutePattern, type ExternalHref, FarmClientPluginManager, type FarmNavigateOptions, type FarmNavigationBlocker, type FarmNavigationBlockerContext, type FarmNavigationListener, type FarmNavigationLocation, type FarmNavigationState, type FarmViewTransitionMode, type InferMutationData, type InferMutationError, type InferMutationVariables, Link, type LinkDefaultRoute, type LinkProps, type MutationAsync, type MutationOptimisticContext, type MutationStatus, type MutationTrigger, type PrefetchBehavior, type RouteHref, type RouteOptionalParamValue, type RouteParamValue, type RouteParams, SPARouter, type Store, type StoreApi, type StoreFields, type StoreKeyListener, type StoreKeysListener, type StoreListener, type StorePatch, type StoreState, type StoreValueUpdater, type UseBlockerOptions, type UseBlockerReturn, type UseMutationOptions, type UseMutationReturn, type UseRouterOptions, createStore, getRouter, navigateTo, prefetch, pushState, readPageState, replaceState, useBlocker, useMutation, useNavigation, usePageState, useRouter, useScrollRestoration };
package/dist/client.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { n as APIClient, A as APIClientOptions, a as APIClientWithoutIntegrationsOptions, N as InferIntegrationOperationBody, P as InferIntegrationOperationQuery, Q as InferIntegrationOperationResponse, J as IntegrationAPI, D as IntegrationClient, E as IntegrationClientAliases, L as IntegrationClientData, s as IntegrationClientError, G as IntegrationClientOptions, H as IntegrationClientRequestOptions, F as IntegrationClientRoot, K as IntegrationClients, M as IntegrationOperationResult, T as IntegrationServerClient, U as IntegrationServerClientAliases, V as IntegrationServerClientOptions, W as IntegrationServerClientRequestOptions, X as IntegrationServerClientRoot, Y as IntegrationServerRequestLike, m as RouteAPIClient, o as ServerAPIClient, S as ServerAPIClientOptions, b as ServerAPIClientWithoutIntegrationsOptions, p as createAPIClient, t as createIntegrationApi, r as createIntegrationClient, u as createIntegrationClients, w as createIntegrationServerClient, v as createIntegrations, q as createServerAPIClient, x as getIntegrationAPIManifest, y as integrationClients, z as integrationsClient, B as integrationsServer } from './client-Dkc03WP8.js';
1
+ import { n as ClientOptions, e as APIResult } from './client-DpEBJbts.js';
2
+ export { p as APIClient, f as APIClientError, A as APIClientOptions, g as APIClientSystemError, a as APIClientWithoutIntegrationsOptions, U as InferIntegrationOperationBody, V as InferIntegrationOperationQuery, W as InferIntegrationOperationResponse, N as IntegrationAPI, H as IntegrationClient, J as IntegrationClientAliases, Q as IntegrationClientData, v as IntegrationClientError, L as IntegrationClientOptions, M as IntegrationClientRequestOptions, K as IntegrationClientRoot, P as IntegrationClients, T as IntegrationOperationResult, X as IntegrationServerClient, Y as IntegrationServerClientAliases, Z as IntegrationServerClientOptions, _ as IntegrationServerClientRequestOptions, $ as IntegrationServerClientRoot, a0 as IntegrationServerRequestLike, o as RouteAPIClient, q as ServerAPIClient, S as ServerAPIClientOptions, b as ServerAPIClientWithoutIntegrationsOptions, r as createAPIClient, w as createIntegrationApi, u as createIntegrationClient, x as createIntegrationClients, z as createIntegrationServerClient, y as createIntegrations, t as createServerAPIClient, B as getIntegrationAPIManifest, D as integrationClients, E as integrationsClient, G as integrationsServer } from './client-DpEBJbts.js';
2
3
  export { ServerQueryFetchOptions, UseServerQueryOptions, UseServerQueryResult, fetchServerQuery, prefetchServerQuery, useServerQuery } from './server-query-client.js';
3
4
  export { F as FarmIntegrationAPI, e as FarmIntegrationAPIBodyFormat, f as FarmIntegrationAPIMethod, a as FarmIntegrationAPIOperation, g as FarmIntegrationAPIResponseFormat, b as api, d as defineIntegrationAPI, c as defineIntegrationAPIOperation, i as endpoint } from './integration-api-CHT2OKAf.js';
4
5
  import React__default, { AnchorHTMLAttributes, RefObject } from 'react';
@@ -12,6 +13,57 @@ import './cache.js';
12
13
  import './server-query.js';
13
14
  import './server-fn.js';
14
15
 
16
+ type MutationStatus = "idle" | "pending" | "success" | "error";
17
+ type AnyMutationTarget = (...args: any[]) => Promise<any>;
18
+ type InferMutationVariables<TTarget extends AnyMutationTarget> = Parameters<TTarget> extends [] ? undefined : Parameters<TTarget>[0];
19
+ type InferMutationData<TTarget extends AnyMutationTarget> = TTarget extends {
20
+ readonly __farmRouteData: infer TData;
21
+ } ? TData : Awaited<ReturnType<TTarget>>;
22
+ type InferMutationError<TTarget extends AnyMutationTarget> = TTarget extends (...args: any[]) => Promise<APIResult<any, infer TError>> ? TError : Error;
23
+ type MutationOptimisticContext<TVariables, TData> = {
24
+ variables: TVariables | undefined;
25
+ current: TData | null;
26
+ };
27
+ type UseMutationOptions<TVariables, TData, TError = Error> = {
28
+ initialData?: TData | null;
29
+ resetOnMutate?: boolean;
30
+ optimistic?: (context: MutationOptimisticContext<TVariables, TData>) => TData | null | undefined;
31
+ rollbackOnError?: boolean;
32
+ /**
33
+ * Options forwarded to generated `api.route.method` clients.
34
+ * Server functions ignore this field.
35
+ */
36
+ request?: ClientOptions<TData, TError>;
37
+ onSuccess?: (data: TData, variables: TVariables | undefined) => void;
38
+ onError?: (error: TError, variables: TVariables | undefined) => void;
39
+ onSettled?: (data: TData | null, error: TError | null, variables: TVariables | undefined) => void;
40
+ };
41
+ type MutationInput<TTarget extends AnyMutationTarget> = InferMutationVariables<TTarget>;
42
+ type MutationData<TTarget extends AnyMutationTarget> = InferMutationData<TTarget>;
43
+ type MutationError<TTarget extends AnyMutationTarget> = InferMutationError<TTarget>;
44
+ type MutationAsync<TTarget extends AnyMutationTarget, TData = MutationData<TTarget>> = [
45
+ ] extends Parameters<TTarget> ? (variables?: MutationInput<TTarget>) => Promise<TData> : (variables: MutationInput<TTarget>) => Promise<TData>;
46
+ type MutationTrigger<TTarget extends AnyMutationTarget> = [
47
+ ] extends Parameters<TTarget> ? (variables?: MutationInput<TTarget>) => void : (variables: MutationInput<TTarget>) => void;
48
+ type UseMutationReturn<TTarget extends AnyMutationTarget, TData = MutationData<TTarget>, TError = MutationError<TTarget>> = {
49
+ pending: boolean;
50
+ status: MutationStatus;
51
+ data: TData | null;
52
+ error: TError | null;
53
+ variables: MutationInput<TTarget> | undefined;
54
+ mutate: MutationTrigger<TTarget>;
55
+ mutateAsync: MutationAsync<TTarget, TData>;
56
+ reset: () => void;
57
+ };
58
+ /**
59
+ * Track a generated API route mutation or a Farm server function with one
60
+ * React lifecycle.
61
+ *
62
+ * API routes keep using their existing fetch transport and request options.
63
+ * Server functions keep using their configured server-function transport.
64
+ */
65
+ declare function useMutation<TTarget extends AnyMutationTarget>(target: TTarget, options?: UseMutationOptions<MutationInput<TTarget>, MutationData<TTarget>, MutationError<TTarget>>): UseMutationReturn<TTarget>;
66
+
15
67
  type StoreState = Record<string, any>;
16
68
  type StoreValueUpdater<T> = T | ((previous: T) => T);
17
69
  type StorePatch<T extends StoreState> = Partial<T> | ((state: T) => Partial<T>);
@@ -326,4 +378,4 @@ declare function useNavigation(): FarmNavigationState;
326
378
  declare function useBlocker(options: UseBlockerOptions): UseBlockerReturn;
327
379
  declare function useScrollRestoration<TElement extends HTMLElement = HTMLElement>(key: string): RefObject<TElement>;
328
380
 
329
- export { type DefaultRouteHref, type DefaultRoutePath, type DefaultRoutePattern, type ExternalHref, FarmClientPluginManager, type FarmNavigateOptions, type FarmNavigationBlocker, type FarmNavigationBlockerContext, type FarmNavigationListener, type FarmNavigationLocation, type FarmNavigationState, type FarmViewTransitionMode, Link, type LinkDefaultRoute, type LinkProps, type PrefetchBehavior, type RouteHref, type RouteOptionalParamValue, type RouteParamValue, type RouteParams, SPARouter, type Store, type StoreApi, type StoreFields, type StoreKeyListener, type StoreKeysListener, type StoreListener, type StorePatch, type StoreState, type StoreValueUpdater, type UseBlockerOptions, type UseBlockerReturn, type UseRouterOptions, createStore, getRouter, navigateTo, prefetch, pushState, readPageState, replaceState, useBlocker, useNavigation, usePageState, useRouter, useScrollRestoration };
381
+ export { type DefaultRouteHref, type DefaultRoutePath, type DefaultRoutePattern, type ExternalHref, FarmClientPluginManager, type FarmNavigateOptions, type FarmNavigationBlocker, type FarmNavigationBlockerContext, type FarmNavigationListener, type FarmNavigationLocation, type FarmNavigationState, type FarmViewTransitionMode, type InferMutationData, type InferMutationError, type InferMutationVariables, Link, type LinkDefaultRoute, type LinkProps, type MutationAsync, type MutationOptimisticContext, type MutationStatus, type MutationTrigger, type PrefetchBehavior, type RouteHref, type RouteOptionalParamValue, type RouteParamValue, type RouteParams, SPARouter, type Store, type StoreApi, type StoreFields, type StoreKeyListener, type StoreKeysListener, type StoreListener, type StorePatch, type StoreState, type StoreValueUpdater, type UseBlockerOptions, type UseBlockerReturn, type UseMutationOptions, type UseMutationReturn, type UseRouterOptions, createStore, getRouter, navigateTo, prefetch, pushState, readPageState, replaceState, useBlocker, useMutation, useNavigation, usePageState, useRouter, useScrollRestoration };
package/dist/client.mjs CHANGED
@@ -1,17 +1,19 @@
1
1
  import {
2
2
  Link,
3
- createStore
4
- } from "./chunk-Y7A27276.mjs";
3
+ createStore,
4
+ useMutation
5
+ } from "./chunk-XUBZ7JI4.mjs";
5
6
  import {
6
7
  installChunkErrorRecovery,
7
8
  isChunkLoadError
8
- } from "./chunk-SOU3Q3ZA.mjs";
9
+ } from "./chunk-ZZ57EH5Z.mjs";
9
10
  import {
10
11
  fetchServerQuery,
11
12
  prefetchServerQuery,
12
13
  useServerQuery
13
- } from "./chunk-HXP3ZSPC.mjs";
14
+ } from "./chunk-MH6FKW2I.mjs";
14
15
  import {
16
+ APIClientError,
15
17
  IntegrationClientError,
16
18
  createAPIClient,
17
19
  createIntegrationApi,
@@ -24,15 +26,9 @@ import {
24
26
  integrationClients,
25
27
  integrationsClient,
26
28
  integrationsServer
27
- } from "./chunk-QFQRHRZS.mjs";
28
- import "./chunk-6XDUHOEM.mjs";
29
+ } from "./chunk-C33RALN7.mjs";
30
+ import "./chunk-NRRFGX45.mjs";
29
31
  import "./chunk-SCFX4UTD.mjs";
30
- import {
31
- api,
32
- defineIntegrationAPI,
33
- defineIntegrationAPIOperation,
34
- endpoint
35
- } from "./chunk-JK25YEN6.mjs";
36
32
  import {
37
33
  SPARouter,
38
34
  getRouter,
@@ -46,22 +42,29 @@ import {
46
42
  usePageState,
47
43
  useRouter,
48
44
  useScrollRestoration
49
- } from "./chunk-TU4YJICB.mjs";
45
+ } from "./chunk-5FW6PQ3J.mjs";
50
46
  import "./chunk-ITN462YM.mjs";
51
47
  import "./chunk-B232I2GP.mjs";
48
+ import {
49
+ api,
50
+ defineIntegrationAPI,
51
+ defineIntegrationAPIOperation,
52
+ endpoint
53
+ } from "./chunk-JK25YEN6.mjs";
52
54
  import "./chunk-GS6K5OCM.mjs";
53
55
  import "./chunk-44ZCFSKE.mjs";
54
- import "./chunk-ZBE6MLHL.mjs";
55
- import "./chunk-4PTK6KT4.mjs";
56
- import "./chunk-TXCFGOHW.mjs";
56
+ import "./chunk-GZWT6VI5.mjs";
57
57
  import "./chunk-WZ5QFROO.mjs";
58
+ import "./chunk-SHRJG6OG.mjs";
58
59
  import "./chunk-7ZY5AIJO.mjs";
60
+ import "./chunk-ZBE6MLHL.mjs";
59
61
  import {
60
62
  FarmClientPluginManager,
61
63
  createClientPluginManager
62
64
  } from "./chunk-NNLCAVB6.mjs";
63
65
  import "./chunk-CGILA3WO.mjs";
64
66
  export {
67
+ APIClientError,
65
68
  FarmClientPluginManager,
66
69
  IntegrationClientError,
67
70
  Link,
@@ -94,6 +97,7 @@ export {
94
97
  readPageState,
95
98
  replaceState,
96
99
  useBlocker,
100
+ useMutation,
97
101
  useNavigation,
98
102
  usePageState,
99
103
  useRouter,
package/dist/config.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { T as FarmUserConfig } from './client-plugins-g4bzuCmo.mjs';
1
+ import { T as FarmUserConfig } from './client-plugins-Cnr0D3kk.mjs';
2
2
  import './plugin-BJDf43dc.mjs';
3
3
  import 'react';
4
4
  import 'http';
package/dist/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { T as FarmUserConfig } from './client-plugins-BZnpeTGA.js';
1
+ import { T as FarmUserConfig } from './client-plugins-CTnsZz_A.js';
2
2
  import './plugin-BJDf43dc.js';
3
3
  import 'react';
4
4
  import 'http';
package/dist/cron.cjs.map CHANGED
@@ -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":[]}
package/dist/cron.mjs CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  mergeScheduledTasks,
12
12
  prepareFarmCronForNitro,
13
13
  resolveCronConfig
14
- } from "./chunk-UREJA4GZ.mjs";
14
+ } from "./chunk-GXASWWJU.mjs";
15
15
  import "./chunk-CGILA3WO.mjs";
16
16
  export {
17
17
  DEFAULT_FARM_CRON_SECRET_ENV,
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  getDeployTargetForPreset
3
- } from "./chunk-UHE2TTLK.mjs";
3
+ } from "./chunk-T543TMFY.mjs";
4
4
  import "./chunk-UVCIEUJC.mjs";
5
5
  import "./chunk-RSKVYESE.mjs";
6
6
  import "./chunk-74YTBPTY.mjs";
7
7
  import "./chunk-7MABZJIM.mjs";
8
- import "./chunk-OYXO65LI.mjs";
8
+ import "./chunk-YW7OBE6Q.mjs";
9
9
  import "./chunk-GY2STC2S.mjs";
10
+ import "./chunk-45LKHSHJ.mjs";
10
11
  import "./chunk-LLC7BNXW.mjs";
11
- import "./chunk-S2XHZS7W.mjs";
12
- import "./chunk-Y2OJJD7R.mjs";
12
+ import "./chunk-QGQX7SFC.mjs";
13
+ import "./chunk-XIVV5IWN.mjs";
13
14
  import {
14
15
  resolveCronConfig
15
- } from "./chunk-UREJA4GZ.mjs";
16
- import "./chunk-AGS7UJ52.mjs";
16
+ } from "./chunk-GXASWWJU.mjs";
17
17
  import "./chunk-K4667E2Q.mjs";
18
18
  import "./chunk-QGOHVJ6J.mjs";
19
19
  import "./chunk-FQYDHKKU.mjs";
@@ -21,10 +21,10 @@ import {
21
21
  mergeFarmRouteRuntimeConfigs,
22
22
  resolveFarmRouteRuleRuntimeConfig,
23
23
  resolveFarmRouteRuntimeConfig
24
- } from "./chunk-QM6VV26B.mjs";
25
- import "./chunk-JK25YEN6.mjs";
24
+ } from "./chunk-GQVGIUSN.mjs";
26
25
  import "./chunk-B232I2GP.mjs";
27
- import "./chunk-TXCFGOHW.mjs";
26
+ import "./chunk-JK25YEN6.mjs";
27
+ import "./chunk-SHRJG6OG.mjs";
28
28
  import {
29
29
  __name
30
30
  } from "./chunk-CGILA3WO.mjs";
@@ -367,4 +367,4 @@ __name(createFarmDevtoolsSnapshot, "createFarmDevtoolsSnapshot");
367
367
  export {
368
368
  createFarmDevtoolsSnapshot
369
369
  };
370
- //# sourceMappingURL=devtools-AE4RVXCM.mjs.map
370
+ //# sourceMappingURL=devtools-HE4FTUDN.mjs.map
@@ -10,16 +10,7 @@ import {
10
10
  function parseShortcut(shortcut) {
11
11
  const tokens = shortcut.toLowerCase().split("+").map((token) => token.trim()).filter(Boolean);
12
12
  const key = tokens.find(
13
- (token) => ![
14
- "alt",
15
- "ctrl",
16
- "control",
17
- "meta",
18
- "cmd",
19
- "command",
20
- "mod",
21
- "shift"
22
- ].includes(token)
13
+ (token) => !["alt", "ctrl", "control", "meta", "cmd", "command", "mod", "shift"].includes(token)
23
14
  );
24
15
  if (!key) {
25
16
  return null;
@@ -222,4 +213,4 @@ __name(generateFarmDevtoolsClientRuntime, "generateFarmDevtoolsClientRuntime");
222
213
  export {
223
214
  generateFarmDevtoolsClientRuntime
224
215
  };
225
- //# sourceMappingURL=devtools-client-6WPY2AQU.mjs.map
216
+ //# sourceMappingURL=devtools-client-3XRTBND5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/devtools-client.ts"],"sourcesContent":["import {\n FARM_DEVTOOLS_LAUNCH_PARAM,\n FARM_DEVTOOLS_PATH,\n type ResolvedFarmDevtoolsConfig,\n} from \"./devtools-config\";\n\ntype ParsedShortcut = {\n key: string;\n alt: boolean;\n ctrl: boolean;\n meta: boolean;\n mod: boolean;\n shift: boolean;\n};\n\nfunction parseShortcut(shortcut: string): ParsedShortcut | null {\n const tokens = shortcut\n .toLowerCase()\n .split(\"+\")\n .map((token) => token.trim())\n .filter(Boolean);\n const key = tokens.find(\n (token) =>\n ![\"alt\", \"ctrl\", \"control\", \"meta\", \"cmd\", \"command\", \"mod\", \"shift\"].includes(token),\n );\n\n if (!key) {\n return null;\n }\n\n return {\n key,\n alt: tokens.includes(\"alt\"),\n ctrl: tokens.includes(\"ctrl\") || tokens.includes(\"control\"),\n meta: tokens.includes(\"meta\") || tokens.includes(\"cmd\") || tokens.includes(\"command\"),\n mod: tokens.includes(\"mod\"),\n shift: tokens.includes(\"shift\"),\n };\n}\n\nexport function generateFarmDevtoolsClientRuntime(config: ResolvedFarmDevtoolsConfig): string {\n if (!config.enabled) {\n return \"\";\n }\n\n const shortcut = config.shortcut ? parseShortcut(config.shortcut) : null;\n const overlayStyles = `\n #__farm_devtools_overlay__ {\n position: fixed;\n inset: 0;\n z-index: 2147483646;\n display: grid;\n place-items: center;\n padding: 20px;\n background: rgb(0 0 0 / 0);\n backdrop-filter: blur(0);\n opacity: 0;\n pointer-events: none;\n transition: background-color 150ms ease-out, backdrop-filter 150ms ease-out, opacity 150ms ease-out;\n }\n #__farm_devtools_overlay__[data-open=\"true\"] {\n background: rgb(0 0 0 / 0.12);\n backdrop-filter: blur(1px);\n opacity: 1;\n pointer-events: auto;\n }\n #__farm_devtools_overlay__ > iframe {\n display: block;\n width: min(960px, calc(100vw - 40px));\n height: min(560px, calc(100dvh - 40px));\n border: 0;\n border-radius: 12px;\n background: transparent;\n box-shadow: 0 24px 80px rgb(0 0 0 / 0.48), 0 4px 18px rgb(0 0 0 / 0.24);\n transform: scale(0.985) translateY(4px);\n transition: transform 150ms ease-out;\n }\n #__farm_devtools_overlay__[data-open=\"true\"] > iframe {\n transform: scale(1) translateY(0);\n }\n @media (max-width: 700px) {\n #__farm_devtools_overlay__ { padding: 8px; }\n #__farm_devtools_overlay__ > iframe {\n width: calc(100vw - 16px);\n height: calc(100dvh - 16px);\n border-radius: 10px;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n #__farm_devtools_overlay__, #__farm_devtools_overlay__ > iframe { transition: none; }\n }\n `;\n\n return `\n(() => {\n const overlayId = \"__farm_devtools_overlay__\";\n const styleId = \"__farm_devtools_overlay_styles__\";\n const runtimeKey = \"__FARM_DEVTOOLS_RUNTIME__\";\n const launchParam = ${JSON.stringify(FARM_DEVTOOLS_LAUNCH_PARAM)};\n const devtoolsPath = ${JSON.stringify(FARM_DEVTOOLS_PATH)};\n const validViews = new Set([\"overview\", \"routes\", \"api\", \"systems\", \"runtime\", \"raw\"]);\n const shortcut = ${JSON.stringify(shortcut)};\n const isMac = /Mac|iPhone|iPad|iPod/.test(navigator.platform);\n let returnFocus = null;\n\n const matchesShortcut = (event) => {\n if (!shortcut || event.repeat) return false;\n const expectedCtrl = shortcut.ctrl || (shortcut.mod && !isMac);\n const expectedMeta = shortcut.meta || (shortcut.mod && isMac);\n if (\n Boolean(event.altKey) !== shortcut.alt ||\n Boolean(event.ctrlKey) !== expectedCtrl ||\n Boolean(event.metaKey) !== expectedMeta ||\n Boolean(event.shiftKey) !== shortcut.shift\n ) return false;\n\n if (shortcut.key === \".\" || shortcut.key === \"period\") return event.code === \"Period\";\n if (shortcut.key === \",\" || shortcut.key === \"comma\") return event.code === \"Comma\";\n if (shortcut.key === \"/\" || shortcut.key === \"slash\") return event.code === \"Slash\";\n return String(event.key || \"\").toLowerCase() === shortcut.key;\n };\n\n const ensureStyles = () => {\n if (document.getElementById(styleId)) return;\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.textContent = ${JSON.stringify(overlayStyles)};\n document.head.appendChild(style);\n };\n\n const close = () => {\n const overlay = document.getElementById(overlayId);\n if (!overlay) return;\n const focusTarget = returnFocus;\n returnFocus = null;\n overlay.dataset.open = \"false\";\n window.setTimeout(() => {\n overlay.remove();\n focusTarget?.focus?.();\n }, 160);\n };\n\n const open = (view = \"overview\") => {\n if (document.getElementById(overlayId)) return;\n ensureStyles();\n returnFocus = document.activeElement;\n const overlay = document.createElement(\"div\");\n overlay.id = overlayId;\n overlay.setAttribute(\"aria-label\", \"Farm.js DevTools overlay\");\n const frame = document.createElement(\"iframe\");\n const resolvedView = validViews.has(view) ? view : \"overview\";\n frame.src = devtoolsPath + \"?embedded=1\" + (resolvedView === \"overview\" ? \"\" : \"#\" + resolvedView);\n frame.title = \"Farm.js DevTools\";\n frame.addEventListener(\"load\", () => frame.contentWindow?.focus(), { once: true });\n overlay.appendChild(frame);\n overlay.addEventListener(\"pointerdown\", (event) => {\n if (event.target === overlay) close();\n });\n document.body.appendChild(overlay);\n requestAnimationFrame(() => {\n overlay.dataset.open = \"true\";\n });\n };\n\n const toggle = () => {\n if (document.getElementById(overlayId)) close();\n else open();\n };\n\n const onKeydown = (event) => {\n if (event.key === \"Escape\" && document.getElementById(overlayId)) {\n event.preventDefault();\n close();\n return;\n }\n if (!matchesShortcut(event)) return;\n event.preventDefault();\n event.stopPropagation();\n toggle();\n };\n\n const onMessage = (event) => {\n if (event.origin !== location.origin) return;\n const frame = document.querySelector(\"#\" + overlayId + \" > iframe\");\n if (!frame || event.source !== frame.contentWindow) return;\n if (event.data?.type === \"farm:devtools:close\") close();\n if (event.data?.type === \"farm:devtools:keydown\" && matchesShortcut(event.data.event || {})) close();\n };\n\n window[runtimeKey]?.dispose?.();\n window.addEventListener(\"keydown\", onKeydown, true);\n window.addEventListener(\"message\", onMessage);\n window[runtimeKey] = {\n dispose() {\n window.removeEventListener(\"keydown\", onKeydown, true);\n window.removeEventListener(\"message\", onMessage);\n },\n };\n window.__FARM_DEVTOOLS__ = { open, close, toggle };\n\n const launchUrl = new URL(location.href);\n const launchRequest = launchUrl.searchParams.get(launchParam);\n if (launchRequest !== null) {\n const hashView = launchUrl.hash.slice(1);\n const launchView = validViews.has(launchRequest)\n ? launchRequest\n : validViews.has(hashView)\n ? hashView\n : \"overview\";\n launchUrl.searchParams.delete(launchParam);\n if (validViews.has(hashView)) launchUrl.hash = \"\";\n history.replaceState(\n history.state,\n \"\",\n launchUrl.pathname + launchUrl.search + launchUrl.hash,\n );\n const launch = () => requestAnimationFrame(() => open(launchView));\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", launch, { once: true });\n } else {\n launch();\n }\n }\n})();\n`;\n}\n"],"mappings":";;;;;;;;;AAeA,SAAS,cAAc,UAAyC;AAC9D,QAAM,SAAS,SACZ,YAAY,EACZ,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,OAAO;AACjB,QAAM,MAAM,OAAO;AAAA,IACjB,CAAC,UACC,CAAC,CAAC,OAAO,QAAQ,WAAW,QAAQ,OAAO,WAAW,OAAO,OAAO,EAAE,SAAS,KAAK;AAAA,EACxF;AAEA,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,KAAK,OAAO,SAAS,KAAK;AAAA,IAC1B,MAAM,OAAO,SAAS,MAAM,KAAK,OAAO,SAAS,SAAS;AAAA,IAC1D,MAAM,OAAO,SAAS,MAAM,KAAK,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,SAAS;AAAA,IACpF,KAAK,OAAO,SAAS,KAAK;AAAA,IAC1B,OAAO,OAAO,SAAS,OAAO;AAAA,EAChC;AACF;AAvBS;AAyBF,SAAS,kCAAkC,QAA4C;AAC5F,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,OAAO,WAAW,cAAc,OAAO,QAAQ,IAAI;AACpE,QAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+CtB,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKe,KAAK,UAAU,0BAA0B,CAAC;AAAA,yBACzC,KAAK,UAAU,kBAAkB,CAAC;AAAA;AAAA,qBAEtC,KAAK,UAAU,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAyBnB,KAAK,UAAU,aAAa,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmGvD;AAzLgB;","names":[]}
package/dist/docs.cjs CHANGED
@@ -747,7 +747,9 @@ function readManifest(contentDir) {
747
747
  const manifestPath = import_node_path.default.join(contentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST);
748
748
  if (!(0, import_node_fs.existsSync)(manifestPath)) return null;
749
749
  try {
750
- const parsed = JSON.parse((0, import_node_fs.readFileSync)(manifestPath, "utf8"));
750
+ const parsed = JSON.parse(
751
+ (0, import_node_fs.readFileSync)(manifestPath, "utf8")
752
+ );
751
753
  if (parsed.version !== 1 || !parsed.pages || typeof parsed.pages !== "object") return null;
752
754
  const pages = Object.fromEntries(
753
755
  Object.entries(parsed.pages).filter(