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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/dist/after.d.mts +25 -0
  2. package/dist/after.d.ts +25 -0
  3. package/dist/agent-runtime.d.mts +96 -0
  4. package/dist/agent-runtime.d.ts +96 -0
  5. package/dist/api/route-manager.cjs.map +1 -1
  6. package/dist/api/route-manager.d.mts +66 -0
  7. package/dist/api/route-manager.d.ts +66 -0
  8. package/dist/api/route-manager.mjs +2 -2
  9. package/dist/api/runtime.cjs.map +1 -1
  10. package/dist/api/runtime.d.mts +3 -0
  11. package/dist/api/runtime.d.ts +3 -0
  12. package/dist/api/runtime.mjs +1 -1
  13. package/dist/api.cjs +18 -10
  14. package/dist/api.cjs.map +1 -1
  15. package/dist/api.d.mts +48 -0
  16. package/dist/api.d.ts +48 -0
  17. package/dist/api.mjs +3 -3
  18. package/dist/app-B0tE1I3o.d.ts +306 -0
  19. package/dist/app-Dv2JJb7X.d.mts +306 -0
  20. package/dist/app-markdown.d.mts +24 -0
  21. package/dist/app-markdown.d.ts +24 -0
  22. package/dist/cache.d.mts +192 -0
  23. package/dist/cache.d.ts +192 -0
  24. package/dist/{chunk-VUL55IAX.mjs → chunk-2FLBZFPG.mjs} +19 -19
  25. package/dist/chunk-2FLBZFPG.mjs.map +1 -0
  26. package/dist/{chunk-B232I2GP.mjs → chunk-3HIVDX7J.mjs} +12 -1
  27. package/dist/chunk-3HIVDX7J.mjs.map +1 -0
  28. package/dist/{chunk-JDEOUK5V.mjs → chunk-6YXKHAFU.mjs} +3 -3
  29. package/dist/{chunk-Z5CQMP54.mjs → chunk-ARRYKOI5.mjs} +2 -2
  30. package/dist/{chunk-KLA67WKG.mjs → chunk-B3FFOIWS.mjs} +2 -2
  31. package/dist/chunk-E257KFBU.mjs +227 -0
  32. package/dist/chunk-E257KFBU.mjs.map +1 -0
  33. package/dist/{chunk-PFE6GMNE.mjs → chunk-HMRFYJK6.mjs} +19 -11
  34. package/dist/chunk-HMRFYJK6.mjs.map +1 -0
  35. package/dist/{chunk-OPHK6OJN.mjs → chunk-JAEAE27K.mjs} +2 -2
  36. package/dist/{chunk-32W4QEJP.mjs → chunk-KFTGPFRD.mjs} +1 -1
  37. package/dist/chunk-KFTGPFRD.mjs.map +1 -0
  38. package/dist/{chunk-L2PE36GQ.mjs → chunk-PZXBQKCH.mjs} +15 -6
  39. package/dist/chunk-PZXBQKCH.mjs.map +1 -0
  40. package/dist/{chunk-UXUAWNO5.mjs → chunk-RIXKJPGI.mjs} +117 -55
  41. package/dist/chunk-RIXKJPGI.mjs.map +1 -0
  42. package/dist/{chunk-PNFQQSRA.mjs → chunk-T2M5QANG.mjs} +143 -41
  43. package/dist/chunk-T2M5QANG.mjs.map +1 -0
  44. package/dist/{chunk-WDU6QXNK.mjs → chunk-UCYWGN2P.mjs} +1 -1
  45. package/dist/chunk-UCYWGN2P.mjs.map +1 -0
  46. package/dist/{chunk-65A7QIKI.mjs → chunk-UMVLB3PN.mjs} +3 -3
  47. package/dist/chunk-UMVLB3PN.mjs.map +1 -0
  48. package/dist/{chunk-ARCGE2VT.mjs → chunk-VFDBC3W7.mjs} +2 -2
  49. package/dist/{chunk-ARCGE2VT.mjs.map → chunk-VFDBC3W7.mjs.map} +1 -1
  50. package/dist/{chunk-VY2UYN5R.mjs → chunk-VPCFICID.mjs} +82 -3
  51. package/dist/chunk-VPCFICID.mjs.map +1 -0
  52. package/dist/{chunk-H3TE3LOV.mjs → chunk-XMFTIVJH.mjs} +2 -2
  53. package/dist/{chunk-UB5UOSHB.mjs → chunk-ZVMV3THA.mjs} +71 -2
  54. package/dist/chunk-ZVMV3THA.mjs.map +1 -0
  55. package/dist/chunk-recovery-lnQFzcQP.d.mts +26 -0
  56. package/dist/chunk-recovery-lnQFzcQP.d.ts +26 -0
  57. package/dist/client-BT1mFQas.d.mts +447 -0
  58. package/dist/client-Nn0q4eO4.d.ts +447 -0
  59. package/dist/client-cache-CIlyBlmx.d.ts +6 -0
  60. package/dist/client-cache-D-EZ7XVW.d.mts +6 -0
  61. package/dist/client-plugins-278AvYHE.d.mts +2021 -0
  62. package/dist/client-plugins-CTQAkr7R.d.ts +2021 -0
  63. package/dist/client-plugins.d.mts +24 -0
  64. package/dist/client-plugins.d.ts +24 -0
  65. package/dist/client.cjs.map +1 -1
  66. package/dist/client.d.mts +452 -0
  67. package/dist/client.d.ts +452 -0
  68. package/dist/client.mjs +3 -3
  69. package/dist/config.d.mts +31 -0
  70. package/dist/config.d.ts +31 -0
  71. package/dist/cron.d.mts +78 -0
  72. package/dist/cron.d.ts +78 -0
  73. package/dist/deferred.d.mts +42 -0
  74. package/dist/deferred.d.ts +42 -0
  75. package/dist/deployment.cjs +12 -0
  76. package/dist/deployment.cjs.map +1 -1
  77. package/dist/deployment.d.mts +36 -0
  78. package/dist/deployment.d.ts +36 -0
  79. package/dist/deployment.mjs +3 -1
  80. package/dist/{devtools-GAZ7F3KL.mjs → devtools-K2ERKGNI.mjs} +5 -5
  81. package/dist/docs.cjs.map +1 -1
  82. package/dist/docs.d.mts +80 -0
  83. package/dist/docs.d.ts +80 -0
  84. package/dist/docs.mjs +5 -5
  85. package/dist/env-types.d.mts +12 -0
  86. package/dist/env-types.d.ts +12 -0
  87. package/dist/env.d.mts +45 -0
  88. package/dist/env.d.ts +45 -0
  89. package/dist/environment/vite.d.mts +22 -0
  90. package/dist/environment/vite.d.ts +22 -0
  91. package/dist/environment.d.mts +18 -0
  92. package/dist/environment.d.ts +18 -0
  93. package/dist/font.d.mts +95 -0
  94. package/dist/font.d.ts +95 -0
  95. package/dist/headers.d.mts +22 -0
  96. package/dist/headers.d.ts +22 -0
  97. package/dist/i18n/client.d.mts +32 -0
  98. package/dist/i18n/client.d.ts +32 -0
  99. package/dist/i18n/index.d.mts +20 -0
  100. package/dist/i18n/index.d.ts +20 -0
  101. package/dist/i18n/server.d.mts +30 -0
  102. package/dist/i18n/server.d.ts +30 -0
  103. package/dist/image/server.d.mts +37 -0
  104. package/dist/image/server.d.ts +37 -0
  105. package/dist/image/sharp.d.mts +7 -0
  106. package/dist/image/sharp.d.ts +7 -0
  107. package/dist/image-config-Duob7wER.d.mts +50 -0
  108. package/dist/image-config-Duob7wER.d.ts +50 -0
  109. package/dist/image.d.mts +39 -0
  110. package/dist/image.d.ts +39 -0
  111. package/dist/index.cjs +598 -109
  112. package/dist/index.cjs.map +1 -1
  113. package/dist/index.d.mts +477 -0
  114. package/dist/index.d.ts +477 -0
  115. package/dist/index.mjs +45 -29
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/integration-api-CHT2OKAf.d.mts +93 -0
  118. package/dist/integration-api-CHT2OKAf.d.ts +93 -0
  119. package/dist/integrations.d.mts +24 -0
  120. package/dist/integrations.d.ts +24 -0
  121. package/dist/internal/build-runtime.cjs +438 -176
  122. package/dist/internal/build-runtime.cjs.map +1 -1
  123. package/dist/internal/build-runtime.d.mts +41 -0
  124. package/dist/internal/build-runtime.d.ts +41 -0
  125. package/dist/internal/build-runtime.mjs +13 -13
  126. package/dist/internal/client-runtime.d.mts +17 -0
  127. package/dist/internal/client-runtime.d.ts +17 -0
  128. package/dist/internal/config-runtime.cjs +140 -1
  129. package/dist/internal/config-runtime.cjs.map +1 -1
  130. package/dist/internal/config-runtime.d.mts +41 -0
  131. package/dist/internal/config-runtime.d.ts +41 -0
  132. package/dist/internal/config-runtime.mjs +4 -4
  133. package/dist/internal/metadata-image-runtime.d.mts +25 -0
  134. package/dist/internal/metadata-image-runtime.d.ts +25 -0
  135. package/dist/internal/production-node-env.d.mts +12 -0
  136. package/dist/internal/production-node-env.d.ts +12 -0
  137. package/dist/internal/production-runtime.d.mts +44 -0
  138. package/dist/internal/production-runtime.d.ts +44 -0
  139. package/dist/island-CfGru1MO.d.mts +9 -0
  140. package/dist/island-CfGru1MO.d.ts +9 -0
  141. package/dist/markdown.d.mts +60 -0
  142. package/dist/markdown.d.ts +60 -0
  143. package/dist/metadata-DmCudMw_.d.mts +22 -0
  144. package/dist/metadata-xghtOlbR.d.ts +22 -0
  145. package/dist/middleware.cjs +116 -98
  146. package/dist/middleware.cjs.map +1 -1
  147. package/dist/middleware.d.mts +171 -0
  148. package/dist/middleware.d.ts +171 -0
  149. package/dist/middleware.mjs +5 -2
  150. package/dist/navigation-errors-Dvwpzaer.d.mts +13 -0
  151. package/dist/navigation-errors-Dvwpzaer.d.ts +13 -0
  152. package/dist/navigation.cjs.map +1 -1
  153. package/dist/navigation.d.mts +14 -0
  154. package/dist/navigation.d.ts +14 -0
  155. package/dist/navigation.mjs +3 -3
  156. package/dist/observability.d.mts +335 -0
  157. package/dist/observability.d.ts +335 -0
  158. package/dist/params-BALtrRim.d.ts +15 -0
  159. package/dist/params-ry-lxqmy.d.mts +15 -0
  160. package/dist/plugin-BJDf43dc.d.mts +165 -0
  161. package/dist/plugin-BJDf43dc.d.ts +165 -0
  162. package/dist/plugin.cjs +247 -28
  163. package/dist/plugin.cjs.map +1 -1
  164. package/dist/plugin.d.mts +24 -0
  165. package/dist/plugin.d.ts +24 -0
  166. package/dist/plugin.mjs +10 -10
  167. package/dist/production-runtime-BLxSv9cU.d.ts +79 -0
  168. package/dist/production-runtime-DFN2_RXq.d.mts +79 -0
  169. package/dist/query/client.d.mts +61 -0
  170. package/dist/query/client.d.ts +61 -0
  171. package/dist/query/index.d.mts +90 -0
  172. package/dist/query/index.d.ts +90 -0
  173. package/dist/query/parsers.d.mts +25 -0
  174. package/dist/query/parsers.d.ts +25 -0
  175. package/dist/query/server.d.mts +55 -0
  176. package/dist/query/server.d.ts +55 -0
  177. package/dist/request-Cq5d6qmE.d.mts +6 -0
  178. package/dist/request-LoxDW3lp.d.ts +6 -0
  179. package/dist/request.d.mts +25 -0
  180. package/dist/request.d.ts +25 -0
  181. package/dist/resolver-DJqjLMg_.d.mts +14 -0
  182. package/dist/resolver-IH4RmPEl.d.ts +14 -0
  183. package/dist/route-runtime-DoOHzCAD.d.mts +38 -0
  184. package/dist/route-runtime-DoOHzCAD.d.ts +38 -0
  185. package/dist/router.d.mts +36 -0
  186. package/dist/router.d.ts +36 -0
  187. package/dist/routes.d.mts +226 -0
  188. package/dist/routes.d.ts +226 -0
  189. package/dist/runtime-BA9TOSu1.d.mts +231 -0
  190. package/dist/runtime-Cxpq6xZN.d.mts +27 -0
  191. package/dist/runtime-DTAQ2HDv.d.ts +231 -0
  192. package/dist/runtime-bv63eUiO.d.ts +27 -0
  193. package/dist/server-action-security.cjs +23 -1
  194. package/dist/server-action-security.cjs.map +1 -1
  195. package/dist/server-action-security.d.mts +45 -0
  196. package/dist/server-action-security.d.ts +45 -0
  197. package/dist/server-action-security.mjs +1 -1
  198. package/dist/server-fn-client.cjs.map +1 -1
  199. package/dist/server-fn-client.d.mts +33 -0
  200. package/dist/server-fn-client.d.ts +33 -0
  201. package/dist/server-fn-client.mjs +1 -1
  202. package/dist/server-fn-error-DDh14a0V.d.mts +26 -0
  203. package/dist/server-fn-error-DDh14a0V.d.ts +26 -0
  204. package/dist/server-fn.cjs +140 -3
  205. package/dist/server-fn.cjs.map +1 -1
  206. package/dist/server-fn.d.mts +121 -0
  207. package/dist/server-fn.d.ts +121 -0
  208. package/dist/server-fn.mjs +14 -3
  209. package/dist/server-plugins.d.mts +57 -0
  210. package/dist/server-plugins.d.ts +57 -0
  211. package/dist/server-query-client.d.mts +51 -0
  212. package/dist/server-query-client.d.ts +51 -0
  213. package/dist/server-query.cjs +99 -1
  214. package/dist/server-query.cjs.map +1 -1
  215. package/dist/server-query.d.mts +37 -0
  216. package/dist/server-query.d.ts +37 -0
  217. package/dist/server-query.mjs +3 -3
  218. package/dist/server.cjs +403 -33
  219. package/dist/server.cjs.map +1 -1
  220. package/dist/server.d.mts +51 -0
  221. package/dist/server.d.ts +51 -0
  222. package/dist/server.mjs +14 -14
  223. package/dist/storage.d.mts +52 -0
  224. package/dist/storage.d.ts +52 -0
  225. package/dist/testing.cjs.map +1 -1
  226. package/dist/testing.d.mts +103 -0
  227. package/dist/testing.d.ts +103 -0
  228. package/dist/testing.mjs +3 -3
  229. package/dist/transport-BmbGTXA5.d.mts +49 -0
  230. package/dist/transport-BmbGTXA5.d.ts +49 -0
  231. package/dist/types-BMxWr97v.d.mts +81 -0
  232. package/dist/types-BMxWr97v.d.ts +81 -0
  233. package/dist/types-D1A6-XvH.d.mts +73 -0
  234. package/dist/types-D1A6-XvH.d.ts +73 -0
  235. package/dist/types-DTzm4TCl.d.mts +78 -0
  236. package/dist/types-DTzm4TCl.d.ts +78 -0
  237. package/dist/utils-B6GaYNJL.d.ts +23 -0
  238. package/dist/utils-CKSHiip6.d.mts +23 -0
  239. package/dist/version.cjs +1 -1
  240. package/dist/version.cjs.map +1 -1
  241. package/dist/version.d.mts +3 -0
  242. package/dist/version.d.ts +3 -0
  243. package/dist/version.mjs +1 -1
  244. package/dist/vite.cjs +255 -30
  245. package/dist/vite.cjs.map +1 -1
  246. package/dist/vite.d.mts +24 -0
  247. package/dist/vite.d.ts +24 -0
  248. package/dist/vite.mjs +10 -10
  249. package/dist/workflows.d.mts +110 -0
  250. package/dist/workflows.d.ts +110 -0
  251. package/package.json +1 -1
  252. package/types/middleware.d.ts +36 -11
  253. package/dist/chunk-32W4QEJP.mjs.map +0 -1
  254. package/dist/chunk-65A7QIKI.mjs.map +0 -1
  255. package/dist/chunk-B232I2GP.mjs.map +0 -1
  256. package/dist/chunk-I4CUBGVF.mjs +0 -93
  257. package/dist/chunk-I4CUBGVF.mjs.map +0 -1
  258. package/dist/chunk-L2PE36GQ.mjs.map +0 -1
  259. package/dist/chunk-PFE6GMNE.mjs.map +0 -1
  260. package/dist/chunk-PNFQQSRA.mjs.map +0 -1
  261. package/dist/chunk-UB5UOSHB.mjs.map +0 -1
  262. package/dist/chunk-UXUAWNO5.mjs.map +0 -1
  263. package/dist/chunk-VUL55IAX.mjs.map +0 -1
  264. package/dist/chunk-VY2UYN5R.mjs.map +0 -1
  265. package/dist/chunk-WDU6QXNK.mjs.map +0 -1
  266. /package/dist/{chunk-JDEOUK5V.mjs.map → chunk-6YXKHAFU.mjs.map} +0 -0
  267. /package/dist/{chunk-Z5CQMP54.mjs.map → chunk-ARRYKOI5.mjs.map} +0 -0
  268. /package/dist/{chunk-KLA67WKG.mjs.map → chunk-B3FFOIWS.mjs.map} +0 -0
  269. /package/dist/{chunk-OPHK6OJN.mjs.map → chunk-JAEAE27K.mjs.map} +0 -0
  270. /package/dist/{chunk-H3TE3LOV.mjs.map → chunk-XMFTIVJH.mjs.map} +0 -0
  271. /package/dist/{devtools-GAZ7F3KL.mjs.map → devtools-K2ERKGNI.mjs.map} +0 -0
package/dist/server.cjs CHANGED
@@ -1919,6 +1919,47 @@ var init_cache_invalidation = __esm({
1919
1919
  }
1920
1920
  });
1921
1921
 
1922
+ // src/server-fn-error.ts
1923
+ function isServerFnFailure(value) {
1924
+ if (!value || typeof value !== "object") return false;
1925
+ const candidate = value;
1926
+ return candidate[FARM_SERVER_FN_FAILURE_SYMBOL] === true && candidate.name === "ServerFnFailure" && typeof candidate.code === "string" && Number.isInteger(candidate.status) && (candidate.status ?? 0) >= 400 && (candidate.status ?? 0) <= 599;
1927
+ }
1928
+ function serializeServerFnFailure(value) {
1929
+ if (!isServerFnFailure(value)) return null;
1930
+ return {
1931
+ name: "ServerFnFailure",
1932
+ message: value.message,
1933
+ code: value.code,
1934
+ status: value.status,
1935
+ data: value.data
1936
+ };
1937
+ }
1938
+ var FARM_SERVER_FN_FAILURE_SYMBOL, _ServerFnFailure, ServerFnFailure;
1939
+ var init_server_fn_error = __esm({
1940
+ "src/server-fn-error.ts"() {
1941
+ "use strict";
1942
+ FARM_SERVER_FN_FAILURE_SYMBOL = /* @__PURE__ */ Symbol.for("farm.server-fn.failure");
1943
+ _ServerFnFailure = class _ServerFnFailure extends Error {
1944
+ constructor(code, data, options) {
1945
+ super(options.message);
1946
+ this.name = "ServerFnFailure";
1947
+ this.code = code;
1948
+ this.data = data;
1949
+ this.status = options.status;
1950
+ Object.defineProperty(this, FARM_SERVER_FN_FAILURE_SYMBOL, {
1951
+ value: true,
1952
+ enumerable: false
1953
+ });
1954
+ }
1955
+ };
1956
+ __name(_ServerFnFailure, "ServerFnFailure");
1957
+ ServerFnFailure = _ServerFnFailure;
1958
+ __name(isServerFnFailure, "isServerFnFailure");
1959
+ __name(serializeServerFnFailure, "serializeServerFnFailure");
1960
+ }
1961
+ });
1962
+
1922
1963
  // src/server-action-security.ts
1923
1964
  function resolveServerActionsConfig(config) {
1924
1965
  const allowedOrigins = (config?.allowedOrigins ?? []).map(normalizeAllowedOriginPattern);
@@ -2005,7 +2046,9 @@ function createServerActionRequestErrorResponse(error) {
2005
2046
  headers
2006
2047
  });
2007
2048
  }
2008
- function sanitizeServerActionError(_error) {
2049
+ function sanitizeServerActionError(error) {
2050
+ const declaredFailure = serializeServerFnFailure(error);
2051
+ if (declaredFailure) return declaredFailure;
2009
2052
  return {
2010
2053
  name: "ServerActionError",
2011
2054
  message: "Server function failed"
@@ -2304,6 +2347,7 @@ var init_server_action_security = __esm({
2304
2347
  "use strict";
2305
2348
  import_node_async_hooks = require("async_hooks");
2306
2349
  init_cache_invalidation();
2350
+ init_server_fn_error();
2307
2351
  DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT = 1e6;
2308
2352
  _ServerActionRequestError = class _ServerActionRequestError extends Error {
2309
2353
  constructor(code, status, message) {
@@ -5352,6 +5396,143 @@ var init_preload = __esm({
5352
5396
  }
5353
5397
  });
5354
5398
 
5399
+ // src/security.ts
5400
+ function resolveFarmSecurityConfig(input) {
5401
+ if (input === void 0) return { csp: false };
5402
+ if (!isPlainRecord(input)) {
5403
+ throw new TypeError("security must be an object containing the csp option.");
5404
+ }
5405
+ if (Object.prototype.hasOwnProperty.call(input, "contentSecurityPolicy")) {
5406
+ throw new TypeError(
5407
+ "security.contentSecurityPolicy is not supported. Use security.csp instead."
5408
+ );
5409
+ }
5410
+ const csp = input.csp;
5411
+ if (csp === void 0 || csp === false) return { csp: false };
5412
+ if (typeof csp === "string") {
5413
+ return {
5414
+ csp: {
5415
+ value: validateSerializedCsp(csp),
5416
+ reportOnly: false
5417
+ }
5418
+ };
5419
+ }
5420
+ if (!isPlainRecord(csp)) {
5421
+ throw new TypeError("security.csp must be a policy string, false, or an options object.");
5422
+ }
5423
+ const reportOnly = validateReportOnly(csp.reportOnly);
5424
+ if (Object.prototype.hasOwnProperty.call(csp, "value")) {
5425
+ if (Object.prototype.hasOwnProperty.call(csp, "policy") || Object.prototype.hasOwnProperty.call(csp, "directives")) {
5426
+ throw new TypeError(
5427
+ "Resolved security.csp values cannot include policy or directives options."
5428
+ );
5429
+ }
5430
+ return {
5431
+ csp: {
5432
+ value: validateSerializedCsp(csp.value),
5433
+ reportOnly
5434
+ }
5435
+ };
5436
+ }
5437
+ const { policy, directives } = csp;
5438
+ if (policy !== void 0 && directives !== void 0) {
5439
+ throw new TypeError("security.csp accepts either policy or directives, not both.");
5440
+ }
5441
+ if (policy === void 0 && directives === void 0) {
5442
+ throw new TypeError("security.csp requires a policy string or directives object.");
5443
+ }
5444
+ return {
5445
+ csp: {
5446
+ value: policy !== void 0 ? validateSerializedCsp(policy) : serializeFarmCspDirectives(directives),
5447
+ reportOnly
5448
+ }
5449
+ };
5450
+ }
5451
+ function serializeFarmCspDirectives(directives) {
5452
+ if (!isPlainRecord(directives)) {
5453
+ throw new TypeError("security.csp.directives must be an object.");
5454
+ }
5455
+ const serialized = [];
5456
+ const normalizedNames = /* @__PURE__ */ new Set();
5457
+ for (const [configuredName, configuredValue] of Object.entries(directives)) {
5458
+ if (configuredValue === false || configuredValue === null || configuredValue === void 0) {
5459
+ continue;
5460
+ }
5461
+ const name = normalizeDirectiveName(configuredName);
5462
+ if (normalizedNames.has(name)) {
5463
+ throw new TypeError(`security.csp contains the duplicate directive ${JSON.stringify(name)}.`);
5464
+ }
5465
+ normalizedNames.add(name);
5466
+ const values = configuredValue === true ? [] : (Array.isArray(configuredValue) ? configuredValue : [configuredValue]).map(
5467
+ validateDirectiveValue
5468
+ );
5469
+ serialized.push(values.length > 0 ? `${name} ${values.join(" ")}` : name);
5470
+ }
5471
+ if (serialized.length === 0) {
5472
+ throw new TypeError("security.csp.directives must contain at least one enabled directive.");
5473
+ }
5474
+ return serialized.join("; ");
5475
+ }
5476
+ function getFarmSecurityHeader(security) {
5477
+ if (!security.csp) return void 0;
5478
+ return {
5479
+ key: security.csp.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy",
5480
+ value: security.csp.value
5481
+ };
5482
+ }
5483
+ function normalizeDirectiveName(value) {
5484
+ const name = value.trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
5485
+ if (!/^[a-z][a-z0-9-]*$/.test(name)) {
5486
+ throw new TypeError(`Invalid security.csp directive name: ${JSON.stringify(value)}.`);
5487
+ }
5488
+ return name;
5489
+ }
5490
+ function validateDirectiveValue(value) {
5491
+ if (typeof value !== "string") {
5492
+ throw new TypeError("security.csp directive values must be strings or booleans.");
5493
+ }
5494
+ const normalized = value.trim();
5495
+ if (!normalized || /[;\r\n]/.test(normalized) || normalized.includes("\0")) {
5496
+ throw new TypeError(`Invalid security.csp directive value: ${JSON.stringify(value)}.`);
5497
+ }
5498
+ return normalized;
5499
+ }
5500
+ function validateSerializedCsp(value) {
5501
+ if (typeof value !== "string") {
5502
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
5503
+ }
5504
+ const normalized = value.trim().replace(/;+$/g, "").trim();
5505
+ if (!normalized || /[\r\n]/.test(normalized) || normalized.includes("\0")) {
5506
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
5507
+ }
5508
+ return normalized;
5509
+ }
5510
+ function validateReportOnly(value) {
5511
+ if (value === void 0) return false;
5512
+ if (typeof value !== "boolean") {
5513
+ throw new TypeError("security.csp.reportOnly must be a boolean.");
5514
+ }
5515
+ return value;
5516
+ }
5517
+ function isPlainRecord(value) {
5518
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
5519
+ const prototype = Object.getPrototypeOf(value);
5520
+ return prototype === Object.prototype || prototype === null;
5521
+ }
5522
+ var init_security = __esm({
5523
+ "src/security.ts"() {
5524
+ "use strict";
5525
+ __name(resolveFarmSecurityConfig, "resolveFarmSecurityConfig");
5526
+ __name(serializeFarmCspDirectives, "serializeFarmCspDirectives");
5527
+ __name(getFarmSecurityHeader, "getFarmSecurityHeader");
5528
+ __name(normalizeDirectiveName, "normalizeDirectiveName");
5529
+ __name(validateDirectiveValue, "validateDirectiveValue");
5530
+ __name(validateSerializedCsp, "validateSerializedCsp");
5531
+ __name(validateReportOnly, "validateReportOnly");
5532
+ __name(isPlainRecord, "isPlainRecord");
5533
+ }
5534
+ });
5535
+
5355
5536
  // src/write-file-if-changed.ts
5356
5537
  function writeFileIfChanged(filePath, content) {
5357
5538
  try {
@@ -10110,6 +10291,8 @@ async function resolveConfig(userConfig, mode) {
10110
10291
  const routeRules = normalizeRouteRules(userConfig.routeRules);
10111
10292
  const routeRuleRedirects = routeRulesToRedirects(routeRules);
10112
10293
  const routeRuleHeaders = routeRulesToHeaders(routeRules);
10294
+ const security = resolveFarmSecurityConfig(userConfig.security);
10295
+ const securityHeader = getFarmSecurityHeader(security);
10113
10296
  const deploy = resolveDeployConfig(userConfig);
10114
10297
  const root = userConfig.root || process.cwd();
10115
10298
  const srcDir = userConfig.srcDir || "src";
@@ -10165,7 +10348,11 @@ async function resolveConfig(userConfig, mode) {
10165
10348
  trailingSlash: userConfig.trailingSlash ?? false,
10166
10349
  redirects: /* @__PURE__ */ __name(() => [...redirects, ...routeRuleRedirects], "redirects"),
10167
10350
  rewrites: /* @__PURE__ */ __name(() => rewrites, "rewrites"),
10168
- headers: /* @__PURE__ */ __name(() => [...headers, ...routeRuleHeaders], "headers"),
10351
+ headers: /* @__PURE__ */ __name(() => [
10352
+ ...headers,
10353
+ ...routeRuleHeaders,
10354
+ ...securityHeader ? [{ source: "/*", headers: [securityHeader] }] : []
10355
+ ], "headers"),
10169
10356
  routeRules,
10170
10357
  images: resolveFarmImageConfig(userConfig.images),
10171
10358
  performance: resolveFarmPerformanceConfig(userConfig.performance),
@@ -10184,6 +10371,7 @@ async function resolveConfig(userConfig, mode) {
10184
10371
  notFound: userConfig.notFound || {},
10185
10372
  context: userConfig.context || (() => void 0),
10186
10373
  serverActions: resolveServerActionsConfig(userConfig.serverActions),
10374
+ security,
10187
10375
  deploymentId,
10188
10376
  output: userConfig.output || "standalone",
10189
10377
  distDir: userConfig.distDir || ".farm",
@@ -10263,6 +10451,7 @@ var init_config2 = __esm({
10263
10451
  init_config();
10264
10452
  init_auth_config();
10265
10453
  init_preload();
10454
+ init_security();
10266
10455
  init_config_entry();
10267
10456
  FARM_RESOLVED_CUSTOM_CONTEXT = /* @__PURE__ */ Symbol.for("farm.resolvedCustomContext");
10268
10457
  __name(normalizeDeployTarget, "normalizeDeployTarget");
@@ -21146,6 +21335,7 @@ init_devtools_config();
21146
21335
  init_config();
21147
21336
  init_auth_config();
21148
21337
  init_preload();
21338
+ init_security();
21149
21339
  var defaultDocsConfig = {
21150
21340
  enabled: false,
21151
21341
  entry: "/docs",
@@ -21213,6 +21403,7 @@ var _FarmApp = class _FarmApp {
21213
21403
  routeRules: normalizeRouteRules(config.routeRules),
21214
21404
  context: config.context || (() => void 0),
21215
21405
  serverActions: resolveServerActionsConfig(config.serverActions),
21406
+ security: resolveFarmSecurityConfig(config.security),
21216
21407
  images: resolveFarmImageConfig(config.images),
21217
21408
  performance: resolveFarmPerformanceConfig(config.performance),
21218
21409
  i18n: isResolvedI18nConfig(config.i18n) ? config.i18n : resolveFarmI18nConfig(config.i18n, {
@@ -22961,6 +23152,15 @@ function routePatternToRouteLiteral(pattern) {
22961
23152
  return JSON.stringify(pattern);
22962
23153
  }
22963
23154
  __name(routePatternToRouteLiteral, "routePatternToRouteLiteral");
23155
+ function renderTypeUnion(values) {
23156
+ return values.length <= 1 ? values[0] || "never" : `
23157
+ | ${values.join("\n | ")}`;
23158
+ }
23159
+ __name(renderTypeUnion, "renderTypeUnion");
23160
+ function renderTypeAlias(name, value) {
23161
+ return `export type ${name} =${value.startsWith("\n") ? "" : " "}${value};`;
23162
+ }
23163
+ __name(renderTypeAlias, "renderTypeAlias");
22964
23164
  function createRoutePattern(route) {
22965
23165
  if (route.segments.length === 0) return "/";
22966
23166
  return "/" + route.segments.map((seg) => {
@@ -23023,9 +23223,9 @@ async function createRouteTypeDeclarations(options, outPath) {
23023
23223
  const typeLiterals = Array.from(new Set(sortedPatterns.flatMap(routePatternToTsTypeLiterals)));
23024
23224
  const patternLiterals = sortedPatterns.map(routePatternToRouteLiteral);
23025
23225
  const routeModulePatternLiterals = Array.from(routeModulePatterns).sort().map(routePatternToRouteLiteral);
23026
- const routePathType = suppressLintOnLink ? "string" : typeLiterals.length ? typeLiterals.join(" | ") : "never";
23027
- const routePatternType = suppressLintOnLink ? "string" : patternLiterals.length ? patternLiterals.join(" | ") : "never";
23028
- const routeModulePatternType = routeModulePatternLiterals.length ? routeModulePatternLiterals.join(" | ") : "never";
23226
+ const routePathType = suppressLintOnLink ? "string" : renderTypeUnion(typeLiterals);
23227
+ const routePatternType = suppressLintOnLink ? "string" : renderTypeUnion(patternLiterals);
23228
+ const routeModulePatternType = renderTypeUnion(routeModulePatternLiterals);
23029
23229
  const routeTypesImportPath = `./${path14.basename(outPath).replace(/\.d\.ts$/, "")}`;
23030
23230
  const linkAugmentationBlock = suppressLintOnLink ? "" : `
23031
23231
  declare module "@farm.js/core/client" {
@@ -23067,9 +23267,9 @@ declare global {
23067
23267
  * Regenerated on dev start and when routes change.
23068
23268
  * Set suppressLintOnLink: true in farm.config.ts to accept any string on Link href.
23069
23269
  */
23070
- export type RoutePath = ${routePathType};
23071
- export type RoutePattern = ${routePatternType};
23072
- export type RouteModulePattern = ${routeModulePatternType};${linkAugmentationBlock}${routeModuleAugmentationBlock}
23270
+ ${renderTypeAlias("RoutePath", routePathType)}
23271
+ ${renderTypeAlias("RoutePattern", routePatternType)}
23272
+ ${renderTypeAlias("RouteModulePattern", routeModulePatternType)}${linkAugmentationBlock}${routeModuleAugmentationBlock}
23073
23273
  `;
23074
23274
  return content;
23075
23275
  }
@@ -23351,7 +23551,8 @@ async function generateFarmTypeArtifacts(options) {
23351
23551
  const sourceRoots = getFarmSourceRoots({ root, srcDir, layers: options.layers });
23352
23552
  const appDirs = getFarmAppDirectories({ root, srcDir, layers: options.layers });
23353
23553
  const result = {
23354
- apiRoutes: []
23554
+ apiRoutes: [],
23555
+ stalePaths: []
23355
23556
  };
23356
23557
  const unifiedTypesPath = (0, import_path8.join)(root, srcDir, "farm.d.ts");
23357
23558
  const shouldRefreshUnifiedTypes = shouldGenerateRoutes && !options.routeTypesOutFile || shouldGenerateEnv && !options.envTypesOutFile || shouldGenerateI18n && !options.i18nTypesOutFile;
@@ -23367,22 +23568,29 @@ async function generateFarmTypeArtifacts(options) {
23367
23568
  unifiedSections.push(await createRouteTypeDeclarations(routeOptions, unifiedTypesPath));
23368
23569
  result.routeTypesPath = unifiedTypesPath;
23369
23570
  } else if (shouldGenerateRoutes) {
23370
- result.routeTypesPath = await generateRouteTypes({
23571
+ const routeOptions = {
23371
23572
  root,
23372
23573
  srcDir,
23373
23574
  outFile: options.routeTypesOutFile,
23374
23575
  extraRoutes: options.extraRoutes || [],
23375
23576
  suppressLintOnLink: options.suppressLintOnLink,
23376
23577
  sourceRoots
23377
- });
23578
+ };
23579
+ if (options.check) {
23580
+ const routeTypesPath = resolveGeneratedPath(root, srcDir, options.routeTypesOutFile);
23581
+ const content = await createRouteTypeDeclarations(routeOptions, routeTypesPath);
23582
+ checkGeneratedFile(routeTypesPath, content, result.stalePaths);
23583
+ result.routeTypesPath = routeTypesPath;
23584
+ } else {
23585
+ result.routeTypesPath = await generateRouteTypes(routeOptions);
23586
+ }
23378
23587
  }
23379
23588
  if (shouldGenerateApi) {
23380
23589
  const generator = new APITypeGenerator(appDirs);
23381
23590
  const apiRoutes = generator.scanAPIRoutes();
23382
23591
  const apiTypesPath = options.apiTypesOutFile ? (0, import_path8.resolve)(root, options.apiTypesOutFile) : (0, import_path8.join)(root, srcDir, "lib", "api.generated.ts");
23383
23592
  const content = generator.generateAPIRouter(apiRoutes, { outFile: apiTypesPath });
23384
- (0, import_fs4.mkdirSync)((0, import_path8.dirname)(apiTypesPath), { recursive: true });
23385
- writeFileIfChanged(apiTypesPath, content);
23593
+ writeOrCheckGeneratedFile(apiTypesPath, content, options.check, result.stalePaths);
23386
23594
  result.apiTypesPath = apiTypesPath;
23387
23595
  result.apiRoutes = apiRoutes;
23388
23596
  }
@@ -23400,36 +23608,63 @@ async function generateFarmTypeArtifacts(options) {
23400
23608
  );
23401
23609
  result.envTypesPath = unifiedTypesPath;
23402
23610
  } else if (shouldGenerateEnv) {
23403
- result.envTypesPath = await generateEnvTypes({
23611
+ const envOptions = {
23404
23612
  root,
23405
23613
  srcDir,
23406
23614
  outFile: options.envTypesOutFile,
23407
23615
  configPath: options.configPath,
23408
23616
  layerConfigPaths: (options.layers ?? []).map((layer) => layer.configFile).filter((configFile) => Boolean(configFile))
23409
- });
23617
+ };
23618
+ if (options.check) {
23619
+ const envTypesPath = resolveGeneratedPath(root, srcDir, options.envTypesOutFile);
23620
+ checkGeneratedFile(
23621
+ envTypesPath,
23622
+ createEnvTypeDeclarations(envOptions, envTypesPath),
23623
+ result.stalePaths
23624
+ );
23625
+ result.envTypesPath = envTypesPath;
23626
+ } else {
23627
+ result.envTypesPath = await generateEnvTypes(envOptions);
23628
+ }
23410
23629
  }
23411
23630
  if (shouldGenerateImages && options.imageTypesOutFile) {
23412
- result.imageTypesPath = generateFarmImageTypes({
23413
- root,
23414
- srcDir,
23415
- outFile: options.imageTypesOutFile
23416
- });
23631
+ const imageTypesPath = resolveGeneratedPath(root, srcDir, options.imageTypesOutFile, false);
23632
+ if (options.check) {
23633
+ checkGeneratedFile(imageTypesPath, createFarmImageTypeDeclarations(), result.stalePaths);
23634
+ result.imageTypesPath = imageTypesPath;
23635
+ } else {
23636
+ result.imageTypesPath = generateFarmImageTypes({
23637
+ root,
23638
+ srcDir,
23639
+ outFile: options.imageTypesOutFile
23640
+ });
23641
+ }
23417
23642
  }
23418
23643
  if (shouldRefreshUnifiedTypes && options.i18nConfig?.enabled && !options.i18nTypesOutFile) {
23419
23644
  const { signatures } = await readFarmI18nCatalogs(options.i18nConfig);
23420
23645
  unifiedSections.push(renderFarmI18nTypes(options.i18nConfig.locales, signatures));
23421
23646
  result.i18nTypesPath = unifiedTypesPath;
23422
23647
  } else if (shouldGenerateI18n && options.i18nConfig) {
23423
- result.i18nTypesPath = await generateFarmI18nTypes({
23424
- root,
23425
- srcDir,
23426
- config: options.i18nConfig,
23427
- outFile: options.i18nTypesOutFile
23428
- });
23648
+ if (options.check) {
23649
+ const i18nTypesPath = resolveGeneratedPath(root, srcDir, options.i18nTypesOutFile, false);
23650
+ const { signatures } = await readFarmI18nCatalogs(options.i18nConfig);
23651
+ checkGeneratedFile(
23652
+ i18nTypesPath,
23653
+ renderFarmI18nTypes(options.i18nConfig.locales, signatures),
23654
+ result.stalePaths
23655
+ );
23656
+ result.i18nTypesPath = i18nTypesPath;
23657
+ } else {
23658
+ result.i18nTypesPath = await generateFarmI18nTypes({
23659
+ root,
23660
+ srcDir,
23661
+ config: options.i18nConfig,
23662
+ outFile: options.i18nTypesOutFile
23663
+ });
23664
+ }
23429
23665
  }
23430
23666
  if (shouldRefreshUnifiedTypes) {
23431
- (0, import_fs4.mkdirSync)((0, import_path8.dirname)(unifiedTypesPath), { recursive: true });
23432
- writeFileIfChanged(
23667
+ writeOrCheckGeneratedFile(
23433
23668
  unifiedTypesPath,
23434
23669
  `/**
23435
23670
  * Generated by Farm.js. Do not edit.
@@ -23438,14 +23673,41 @@ async function generateFarmTypeArtifacts(options) {
23438
23673
 
23439
23674
  import "@farm.js/core/image";
23440
23675
 
23441
- ${unifiedSections.join("\n")}`
23676
+ ${unifiedSections.map((section) => section.trimEnd()).join("\n\n")}
23677
+ `,
23678
+ options.check,
23679
+ result.stalePaths
23442
23680
  );
23443
23681
  result.typesPath = unifiedTypesPath;
23444
- removeLegacyTypeArtifacts(root, srcDir);
23682
+ if (options.check) {
23683
+ collectLegacyTypeArtifacts(root, srcDir, result.stalePaths);
23684
+ } else {
23685
+ removeLegacyTypeArtifacts(root, srcDir);
23686
+ }
23445
23687
  }
23446
23688
  return result;
23447
23689
  }
23448
23690
  __name(generateFarmTypeArtifacts, "generateFarmTypeArtifacts");
23691
+ function resolveGeneratedPath(root, srcDir, outFile, relativeToSrc = true) {
23692
+ if ((0, import_path8.isAbsolute)(outFile)) return (0, import_path8.resolve)(outFile);
23693
+ return (0, import_path8.resolve)(root, relativeToSrc ? (0, import_path8.join)(srcDir, outFile) : outFile);
23694
+ }
23695
+ __name(resolveGeneratedPath, "resolveGeneratedPath");
23696
+ function writeOrCheckGeneratedFile(filePath, content, check, stalePaths) {
23697
+ if (check) {
23698
+ checkGeneratedFile(filePath, content, stalePaths);
23699
+ return;
23700
+ }
23701
+ (0, import_fs4.mkdirSync)((0, import_path8.dirname)(filePath), { recursive: true });
23702
+ writeFileIfChanged(filePath, content);
23703
+ }
23704
+ __name(writeOrCheckGeneratedFile, "writeOrCheckGeneratedFile");
23705
+ function checkGeneratedFile(filePath, content, stalePaths) {
23706
+ if (!(0, import_fs4.existsSync)(filePath) || (0, import_fs4.readFileSync)(filePath, "utf8") !== content) {
23707
+ stalePaths.push(filePath);
23708
+ }
23709
+ }
23710
+ __name(checkGeneratedFile, "checkGeneratedFile");
23449
23711
  var LEGACY_TYPE_ARTIFACTS = [
23450
23712
  ["farm-routes.d.ts", "Auto-generated route types"],
23451
23713
  ["farm-env.d.ts", "Auto-generated env types"],
@@ -23463,6 +23725,14 @@ function removeLegacyTypeArtifacts(root, srcDir) {
23463
23725
  }
23464
23726
  }
23465
23727
  __name(removeLegacyTypeArtifacts, "removeLegacyTypeArtifacts");
23728
+ function collectLegacyTypeArtifacts(root, srcDir, stalePaths) {
23729
+ for (const [fileName, marker] of LEGACY_TYPE_ARTIFACTS) {
23730
+ const filePath = (0, import_path8.join)(root, srcDir, fileName);
23731
+ if (!(0, import_fs4.existsSync)(filePath)) continue;
23732
+ if ((0, import_fs4.readFileSync)(filePath, "utf8").includes(marker)) stalePaths.push(filePath);
23733
+ }
23734
+ }
23735
+ __name(collectLegacyTypeArtifacts, "collectLegacyTypeArtifacts");
23466
23736
 
23467
23737
  // src/vite.ts
23468
23738
  init_markdown();
@@ -23818,7 +24088,7 @@ function transformError(id, message) {
23818
24088
  __name(transformError, "transformError");
23819
24089
 
23820
24090
  // package.json
23821
- var version = "0.1.0-beta.14";
24091
+ var version = "0.1.0-beta.17";
23822
24092
 
23823
24093
  // src/version.ts
23824
24094
  var FARM_VERSION = version;
@@ -24145,12 +24415,31 @@ function createFarmClientOptimizeDepsConfig(entries) {
24145
24415
  };
24146
24416
  }
24147
24417
  __name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
24418
+ function createFarmSourceAlias(projectRoot, srcDir = "src") {
24419
+ return {
24420
+ "@": import_node_path9.default.resolve(projectRoot, srcDir)
24421
+ };
24422
+ }
24423
+ __name(createFarmSourceAlias, "createFarmSourceAlias");
24148
24424
  function mergeNoExternal(farmValue, userValue) {
24149
24425
  if (farmValue === true || userValue === true) return true;
24150
24426
  const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
24151
24427
  return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
24152
24428
  }
24153
24429
  __name(mergeNoExternal, "mergeNoExternal");
24430
+ function mergeAlias(farmValue, userValue) {
24431
+ if (!farmValue) return userValue || {};
24432
+ if (!userValue) return farmValue;
24433
+ if (!Array.isArray(farmValue) && !Array.isArray(userValue)) {
24434
+ return {
24435
+ ...farmValue,
24436
+ ...userValue
24437
+ };
24438
+ }
24439
+ const normalize = /* @__PURE__ */ __name((value) => Array.isArray(value) ? [...value] : Object.entries(value).map(([find, replacement]) => ({ find, replacement })), "normalize");
24440
+ return [...normalize(userValue), ...normalize(farmValue)];
24441
+ }
24442
+ __name(mergeAlias, "mergeAlias");
24154
24443
  function mergeFarmViteConfig(farmConfig, userConfig = {}) {
24155
24444
  const noDiscovery = userConfig.optimizeDeps?.noDiscovery ?? farmConfig.optimizeDeps?.noDiscovery;
24156
24445
  const holdUntilCrawlEnd = userConfig.optimizeDeps?.holdUntilCrawlEnd ?? (userConfig.optimizeDeps?.noDiscovery === true ? false : farmConfig.optimizeDeps?.holdUntilCrawlEnd);
@@ -24165,6 +24454,7 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
24165
24454
  resolve: {
24166
24455
  ...farmConfig.resolve,
24167
24456
  ...userConfig.resolve,
24457
+ alias: mergeAlias(farmConfig.resolve?.alias, userConfig.resolve?.alias),
24168
24458
  dedupe: Array.from(
24169
24459
  /* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
24170
24460
  )
@@ -27953,7 +28243,7 @@ async function defineConfig2(config = {}) {
27953
28243
  // Stub out problematic server-only modules during dev mode
27954
28244
  alias: {
27955
28245
  ...getFarmLayerAliases(config.layers),
27956
- "@": path25.resolve(appRoot, "src"),
28246
+ ...createFarmSourceAlias(appRoot, config.srcDir),
27957
28247
  // Nitro internals that should not be resolved in browser
27958
28248
  "supports-color": "data:text/javascript,export default false; export const supportsColor = false; export const stdout = false; export const stderr = false;",
27959
28249
  "@poppinss/dumper": "data:text/javascript,export default {};",
@@ -27980,6 +28270,8 @@ init_server_action_security();
27980
28270
 
27981
28271
  // src/server-fn.ts
27982
28272
  init_server_action_security();
28273
+ init_server_fn_error();
28274
+ init_server_fn_error();
27983
28275
  var FARM_SERVER_FN_SYMBOL = /* @__PURE__ */ Symbol.for("farm.server-fn");
27984
28276
  var UNSAFE_FORM_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
27985
28277
  function createServerFn(options) {
@@ -27987,6 +28279,8 @@ function createServerFn(options) {
27987
28279
  throw new TypeError("createServerFn requires a handler function");
27988
28280
  }
27989
28281
  const middleware = resolveServerFnMiddleware(options.middleware);
28282
+ const errors = normalizeServerFnErrors(options.errors);
28283
+ const error = createServerFnErrorHandler(errors);
27990
28284
  const serverFn = /* @__PURE__ */ __name(async (value) => {
27991
28285
  const formData = isFormData(value) ? value : void 0;
27992
28286
  const rawInput = formData ? formDataToObject2(formData) : value;
@@ -28004,7 +28298,7 @@ function createServerFn(options) {
28004
28298
  let resolvedContext = Object.freeze(/* @__PURE__ */ Object.create(null));
28005
28299
  const result = await runServerFnMiddleware(middleware, handlerContext, async (context) => {
28006
28300
  resolvedContext = context.context;
28007
- return options.handler(context);
28301
+ return options.handler({ ...context, error });
28008
28302
  });
28009
28303
  const parsedResult = await _parseServerFnSchema(options.output, result, "output");
28010
28304
  if (options.invalidates) {
@@ -28034,6 +28328,10 @@ function createServerFn(options) {
28034
28328
  value: options.output,
28035
28329
  enumerable: false
28036
28330
  },
28331
+ __farmServerFnError: {
28332
+ value: void 0,
28333
+ enumerable: false
28334
+ },
28037
28335
  __farmServerFnMiddleware: {
28038
28336
  value: middleware,
28039
28337
  enumerable: false
@@ -28072,6 +28370,78 @@ async function runServerFnMiddleware(middleware, handlerContext, handler) {
28072
28370
  return dispatch(0, Object.freeze(/* @__PURE__ */ Object.create(null)));
28073
28371
  }
28074
28372
  __name(runServerFnMiddleware, "runServerFnMiddleware");
28373
+ function normalizeServerFnErrors(definitions) {
28374
+ if (definitions === void 0) return Object.freeze({});
28375
+ if (!isPlainServerFnObject(definitions)) {
28376
+ throw new TypeError("createServerFn errors must be an object");
28377
+ }
28378
+ const normalized = /* @__PURE__ */ Object.create(null);
28379
+ for (const [code, definition] of Object.entries(definitions)) {
28380
+ if (!code.trim()) {
28381
+ throw new TypeError("Server function error codes cannot be empty");
28382
+ }
28383
+ if (!definition || typeof definition !== "object") {
28384
+ throw new TypeError(`Server function error "${code}" must be an object`);
28385
+ }
28386
+ if (!Number.isInteger(definition.status) || definition.status < 400 || definition.status > 599) {
28387
+ throw new TypeError(
28388
+ `Server function error "${code}" status must be an integer between 400 and 599`
28389
+ );
28390
+ }
28391
+ if (!definition.data || typeof definition.data.parse !== "function" && typeof definition.data.safeParse !== "function") {
28392
+ throw new TypeError(
28393
+ `Server function error "${code}" data must provide synchronous parse() or safeParse()`
28394
+ );
28395
+ }
28396
+ if (definition.message !== void 0 && typeof definition.message !== "string") {
28397
+ throw new TypeError(`Server function error "${code}" message must be a string`);
28398
+ }
28399
+ normalized[code] = Object.freeze({ ...definition });
28400
+ }
28401
+ return Object.freeze(normalized);
28402
+ }
28403
+ __name(normalizeServerFnErrors, "normalizeServerFnErrors");
28404
+ function createServerFnErrorHandler(definitions) {
28405
+ return ((code, data) => {
28406
+ const definition = definitions[code];
28407
+ if (!definition) {
28408
+ throw new TypeError(`Server function error "${code}" is not declared`);
28409
+ }
28410
+ const parsed = parseServerFnFailureData(code, definition.data, data);
28411
+ throw new ServerFnFailure(code, parsed, {
28412
+ status: definition.status,
28413
+ message: definition.message ?? "Server function failed"
28414
+ });
28415
+ });
28416
+ }
28417
+ __name(createServerFnErrorHandler, "createServerFnErrorHandler");
28418
+ function parseServerFnFailureData(code, schema, value) {
28419
+ if (typeof schema.safeParse === "function") {
28420
+ const result2 = schema.safeParse(value);
28421
+ if (isPromiseLike2(result2)) {
28422
+ throw new TypeError(`Server function error "${code}" data schema must parse synchronously`);
28423
+ }
28424
+ return unwrapSafeParseResult(result2);
28425
+ }
28426
+ const result = schema.parse(value);
28427
+ if (isPromiseLike2(result)) {
28428
+ throw new TypeError(`Server function error "${code}" data schema must parse synchronously`);
28429
+ }
28430
+ return result;
28431
+ }
28432
+ __name(parseServerFnFailureData, "parseServerFnFailureData");
28433
+ function isPlainServerFnObject(value) {
28434
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
28435
+ const prototype = Object.getPrototypeOf(value);
28436
+ return prototype === Object.prototype || prototype === null;
28437
+ }
28438
+ __name(isPlainServerFnObject, "isPlainServerFnObject");
28439
+ function isPromiseLike2(value) {
28440
+ return Boolean(
28441
+ value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function"
28442
+ );
28443
+ }
28444
+ __name(isPromiseLike2, "isPromiseLike");
28075
28445
  function resolveServerFnMiddleware(middleware) {
28076
28446
  const resolved = [];
28077
28447
  const seen = /* @__PURE__ */ new Set();