@farm.js/core 0.1.0-beta.97 → 0.1.0-beta.98

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 (248) hide show
  1. package/dist/after.cjs.map +1 -0
  2. package/dist/agent-runtime.cjs +7 -3
  3. package/dist/agent-runtime.cjs.map +1 -0
  4. package/dist/agent-runtime.d.mts +2 -2
  5. package/dist/agent-runtime.d.ts +2 -2
  6. package/dist/agent-runtime.mjs +2 -1
  7. package/dist/agent-runtime.mjs.map +1 -1
  8. package/dist/api/route-manager.cjs.map +1 -0
  9. package/dist/api/route-manager.d.mts +2 -2
  10. package/dist/api/route-manager.d.ts +2 -2
  11. package/dist/api/runtime.cjs.map +1 -0
  12. package/dist/api.cjs +26 -1
  13. package/dist/api.cjs.map +1 -0
  14. package/dist/api.d.mts +3 -3
  15. package/dist/api.d.ts +3 -3
  16. package/dist/api.mjs +2 -2
  17. package/dist/{app-CIOx3LvY.d.ts → app-CJKz2mbi.d.ts} +4 -4
  18. package/dist/{app-DBd6437H.d.mts → app-DMEGFLR2.d.mts} +4 -4
  19. package/dist/app-markdown.cjs.map +1 -0
  20. package/dist/app-markdown.d.mts +3 -3
  21. package/dist/app-markdown.d.ts +3 -3
  22. package/dist/cache.cjs.map +1 -0
  23. package/dist/{chunk-WD2EBM3I.mjs → chunk-3CQJV3NC.mjs} +2 -2
  24. package/dist/{chunk-I3OOUWO5.mjs → chunk-3GDRV7SG.mjs} +2 -2
  25. package/dist/{chunk-X4SFHKFH.mjs → chunk-6KJY25DQ.mjs} +5 -5
  26. package/dist/{chunk-FP5Q67FO.mjs → chunk-AAEZP2EY.mjs} +9 -9
  27. package/dist/{chunk-WMJGA32P.mjs → chunk-BXVOHG6B.mjs} +27 -2
  28. package/dist/{chunk-WMJGA32P.mjs.map → chunk-BXVOHG6B.mjs.map} +1 -1
  29. package/dist/{chunk-BZAIS65C.mjs → chunk-DIHNOVZZ.mjs} +40 -13
  30. package/dist/chunk-DIHNOVZZ.mjs.map +1 -0
  31. package/dist/{chunk-ISSFLGJ5.mjs → chunk-FDWECN3W.mjs} +8 -4
  32. package/dist/chunk-FDWECN3W.mjs.map +1 -0
  33. package/dist/chunk-FDWXXTWR.mjs +114 -0
  34. package/dist/chunk-FDWXXTWR.mjs.map +1 -0
  35. package/dist/{chunk-J3MPQ4MQ.mjs → chunk-IHADQ6J7.mjs} +2 -2
  36. package/dist/{chunk-J3MPQ4MQ.mjs.map → chunk-IHADQ6J7.mjs.map} +1 -1
  37. package/dist/{chunk-FSIXEIOB.mjs → chunk-L7FSTPGS.mjs} +2 -2
  38. package/dist/{chunk-AAC66ILR.mjs → chunk-LXXG3K2Y.mjs} +61 -2
  39. package/dist/chunk-LXXG3K2Y.mjs.map +1 -0
  40. package/dist/{chunk-GJ7W6LNK.mjs → chunk-N5RK4LK6.mjs} +3 -3
  41. package/dist/{chunk-WKDAA6V2.mjs → chunk-NBF56FXB.mjs} +20 -5
  42. package/dist/chunk-NBF56FXB.mjs.map +1 -0
  43. package/dist/chunk-RKUPOYQV.mjs +28 -0
  44. package/dist/chunk-RKUPOYQV.mjs.map +1 -0
  45. package/dist/{chunk-2SKCXYLB.mjs → chunk-RL3THP3L.mjs} +54 -5
  46. package/dist/chunk-RL3THP3L.mjs.map +1 -0
  47. package/dist/{chunk-52BR7LTX.mjs → chunk-STSPSJUI.mjs} +3 -3
  48. package/dist/{chunk-EPDIF432.mjs → chunk-UOGX6UNO.mjs} +37 -17
  49. package/dist/chunk-UOGX6UNO.mjs.map +1 -0
  50. package/dist/{chunk-YIBV77KZ.mjs → chunk-URQELPSH.mjs} +2 -2
  51. package/dist/{chunk-UMUWR5XA.mjs → chunk-UWQ4EEW7.mjs} +2 -2
  52. package/dist/{chunk-IZBX2TEU.mjs → chunk-VQG3QWWK.mjs} +2 -2
  53. package/dist/{chunk-D7F7YZ7L.mjs → chunk-WA77FWAO.mjs} +8 -8
  54. package/dist/{chunk-35NPLKQJ.mjs → chunk-XWM2C267.mjs} +21 -105
  55. package/dist/chunk-XWM2C267.mjs.map +1 -0
  56. package/dist/client/lifecycle.cjs.map +1 -0
  57. package/dist/client/lifecycle.mjs +2 -2
  58. package/dist/{client-plugins-B6-07YmP.d.mts → client-plugins-CyTLPqjP.d.mts} +38 -2
  59. package/dist/{client-plugins-By6MVUX-.d.ts → client-plugins-D-UgzngJ.d.ts} +38 -2
  60. package/dist/client-plugins.cjs +1 -1
  61. package/dist/client-plugins.cjs.map +1 -0
  62. package/dist/client-plugins.d.mts +2 -2
  63. package/dist/client-plugins.d.ts +2 -2
  64. package/dist/client-plugins.mjs +2 -2
  65. package/dist/client.cjs +61 -16
  66. package/dist/client.cjs.map +1 -0
  67. package/dist/client.d.mts +5 -5
  68. package/dist/client.d.ts +5 -5
  69. package/dist/client.mjs +7 -7
  70. package/dist/config.cjs.map +1 -0
  71. package/dist/config.d.mts +2 -2
  72. package/dist/config.d.ts +2 -2
  73. package/dist/cron.cjs +48 -12
  74. package/dist/cron.cjs.map +1 -0
  75. package/dist/cron.mjs +2 -1
  76. package/dist/deferred.cjs.map +1 -0
  77. package/dist/deployment.cjs.map +1 -0
  78. package/dist/{devtools-XWZX6CCL.mjs → devtools-KQ2PXSIC.mjs} +8 -6
  79. package/dist/{devtools-XWZX6CCL.mjs.map → devtools-KQ2PXSIC.mjs.map} +1 -1
  80. package/dist/docs.cjs +7 -3
  81. package/dist/docs.cjs.map +1 -0
  82. package/dist/docs.mjs +8 -6
  83. package/dist/env-types.cjs.map +1 -0
  84. package/dist/env.cjs.map +1 -0
  85. package/dist/environment/vite.cjs.map +1 -0
  86. package/dist/environment.cjs.map +1 -0
  87. package/dist/font.cjs.map +1 -0
  88. package/dist/headers.cjs.map +1 -0
  89. package/dist/i18n/client.cjs.map +1 -0
  90. package/dist/i18n/index.cjs.map +1 -0
  91. package/dist/i18n/server.cjs.map +1 -0
  92. package/dist/image/server.cjs +19 -4
  93. package/dist/image/server.cjs.map +1 -0
  94. package/dist/image/server.d.mts +6 -0
  95. package/dist/image/server.d.ts +6 -0
  96. package/dist/image/server.mjs +1 -1
  97. package/dist/image/sharp.cjs +1 -0
  98. package/dist/image/sharp.cjs.map +1 -0
  99. package/dist/image/sharp.mjs +1 -1
  100. package/dist/image.cjs.map +1 -0
  101. package/dist/index.cjs +370 -143
  102. package/dist/index.cjs.map +1 -0
  103. package/dist/index.d.mts +10 -10
  104. package/dist/index.d.ts +10 -10
  105. package/dist/index.mjs +29 -21
  106. package/dist/index.mjs.map +1 -1
  107. package/dist/instrumentation.cjs.map +1 -0
  108. package/dist/{integration-orm-LLW6WZNK.mjs → integration-orm-G5BPBT5X.mjs} +3 -3
  109. package/dist/integrations.cjs +168 -5
  110. package/dist/integrations.cjs.map +1 -0
  111. package/dist/integrations.d.mts +2 -2
  112. package/dist/integrations.d.ts +2 -2
  113. package/dist/integrations.mjs +10 -3
  114. package/dist/internal/build-runtime.cjs +178 -51
  115. package/dist/internal/build-runtime.cjs.map +1 -0
  116. package/dist/internal/build-runtime.d.mts +4 -4
  117. package/dist/internal/build-runtime.d.ts +4 -4
  118. package/dist/internal/build-runtime.mjs +13 -11
  119. package/dist/internal/client-runtime.cjs +1 -1
  120. package/dist/internal/client-runtime.cjs.map +1 -0
  121. package/dist/internal/client-runtime.mjs +2 -2
  122. package/dist/internal/config-runtime.cjs +48 -42
  123. package/dist/internal/config-runtime.cjs.map +1 -0
  124. package/dist/internal/config-runtime.d.mts +3 -3
  125. package/dist/internal/config-runtime.d.ts +3 -3
  126. package/dist/internal/config-runtime.mjs +7 -5
  127. package/dist/internal/isolated-boundary.cjs.map +1 -0
  128. package/dist/internal/metadata-image-runtime.cjs.map +1 -0
  129. package/dist/internal/product-telemetry-runtime.cjs +6 -2
  130. package/dist/internal/product-telemetry-runtime.cjs.map +1 -0
  131. package/dist/internal/product-telemetry-runtime.mjs +6 -2
  132. package/dist/internal/product-telemetry-runtime.mjs.map +1 -1
  133. package/dist/internal/production-node-env.cjs.map +1 -0
  134. package/dist/internal/production-runtime.cjs.map +1 -0
  135. package/dist/internal/production-runtime.d.mts +8 -8
  136. package/dist/internal/production-runtime.d.ts +8 -8
  137. package/dist/markdown.cjs.map +1 -0
  138. package/dist/{metadata-route-8_V3UonT.d.ts → metadata-route-BpU8K9RI.d.ts} +1 -1
  139. package/dist/{metadata-route-CWP_HjGU.d.mts → metadata-route-D1AYgWni.d.mts} +1 -1
  140. package/dist/middleware.cjs.map +1 -0
  141. package/dist/middleware.d.mts +4 -4
  142. package/dist/middleware.d.ts +4 -4
  143. package/dist/navigation.cjs.map +1 -0
  144. package/dist/{nitro-EGRNOB5P.mjs → nitro-IITKBMUI.mjs} +4 -3
  145. package/dist/{nitro-EGRNOB5P.mjs.map → nitro-IITKBMUI.mjs.map} +1 -1
  146. package/dist/observability.cjs.map +1 -0
  147. package/dist/plugin.cjs +143 -50
  148. package/dist/plugin.cjs.map +1 -0
  149. package/dist/plugin.d.mts +2 -2
  150. package/dist/plugin.d.ts +2 -2
  151. package/dist/plugin.mjs +10 -8
  152. package/dist/{production-runtime-BGRH1dKG.d.mts → production-runtime-BIKA-BVT.d.mts} +2 -2
  153. package/dist/{production-runtime-CdmzsDax.d.ts → production-runtime-DtCUEELY.d.ts} +2 -2
  154. package/dist/query/client.cjs.map +1 -0
  155. package/dist/query/index.cjs.map +1 -0
  156. package/dist/query/parsers.cjs.map +1 -0
  157. package/dist/query/server.cjs.map +1 -0
  158. package/dist/{render-plan-DLxJYAA5.d.mts → render-plan-Dimb23ux.d.mts} +1 -1
  159. package/dist/{render-plan-0GeHiGVZ.d.ts → render-plan-rg3uiSo3.d.ts} +1 -1
  160. package/dist/renderer/react/client.cjs.map +1 -0
  161. package/dist/renderer/react/server.cjs.map +1 -0
  162. package/dist/renderer/react/vite.cjs.map +1 -0
  163. package/dist/renderer-client.cjs +26 -1
  164. package/dist/renderer-client.cjs.map +1 -0
  165. package/dist/renderer-client.d.mts +4 -4
  166. package/dist/renderer-client.d.ts +4 -4
  167. package/dist/renderer-client.mjs +2 -2
  168. package/dist/renderer.cjs.map +1 -0
  169. package/dist/{request-BstWbZ6O.d.ts → request-ColD-ChW.d.ts} +1 -1
  170. package/dist/{request-BCNXSXLh.d.mts → request-D5zvbU2Z.d.mts} +1 -1
  171. package/dist/request.cjs.map +1 -0
  172. package/dist/request.d.mts +3 -3
  173. package/dist/request.d.ts +3 -3
  174. package/dist/router.cjs.map +1 -0
  175. package/dist/routes.cjs.map +1 -0
  176. package/dist/routes.d.mts +2 -2
  177. package/dist/routes.d.ts +2 -2
  178. package/dist/server-action-security.cjs +117 -104
  179. package/dist/server-action-security.cjs.map +1 -0
  180. package/dist/server-action-security.mjs +2 -1
  181. package/dist/server-fn-client.cjs.map +1 -0
  182. package/dist/server-fn.cjs.map +1 -0
  183. package/dist/server-fn.mjs +3 -2
  184. package/dist/server-plugins.cjs.map +1 -0
  185. package/dist/server-plugins.d.mts +3 -3
  186. package/dist/server-plugins.d.ts +3 -3
  187. package/dist/server-query-client.cjs +26 -1
  188. package/dist/server-query-client.cjs.map +1 -0
  189. package/dist/server-query-client.mjs +3 -3
  190. package/dist/server-query.cjs.map +1 -0
  191. package/dist/server-query.mjs +4 -3
  192. package/dist/server.cjs +221 -116
  193. package/dist/server.cjs.map +1 -0
  194. package/dist/server.d.mts +8 -8
  195. package/dist/server.d.ts +8 -8
  196. package/dist/server.mjs +13 -11
  197. package/dist/server.mjs.map +1 -1
  198. package/dist/{spa-router-BeyAVSc6.d.mts → spa-router-BlilYGAN.d.mts} +1 -1
  199. package/dist/{spa-router-COgu4txb.d.ts → spa-router-kXORcsT_.d.ts} +1 -1
  200. package/dist/storage.cjs +7 -3
  201. package/dist/storage.cjs.map +1 -0
  202. package/dist/storage.mjs +1 -1
  203. package/dist/testing.cjs.map +1 -0
  204. package/dist/testing.d.mts +2 -2
  205. package/dist/testing.d.ts +2 -2
  206. package/dist/testing.mjs +2 -1
  207. package/dist/testing.mjs.map +1 -1
  208. package/dist/theme/client.cjs.map +1 -0
  209. package/dist/theme/index.cjs.map +1 -0
  210. package/dist/theme/runtime.cjs.map +1 -0
  211. package/dist/theme/server.cjs.map +1 -0
  212. package/dist/{utils-DkU2c_1B.d.ts → utils-BhvF7Hhl.d.ts} +1 -1
  213. package/dist/{utils-DL2VwDQl.d.mts → utils-uF32evNX.d.mts} +1 -1
  214. package/dist/version.cjs +1 -1
  215. package/dist/version.cjs.map +1 -0
  216. package/dist/version.mjs +1 -1
  217. package/dist/vite.cjs +143 -50
  218. package/dist/vite.cjs.map +1 -0
  219. package/dist/vite.d.mts +2 -2
  220. package/dist/vite.d.ts +2 -2
  221. package/dist/vite.mjs +10 -8
  222. package/dist/{workflows-ChyK_oTu.d.mts → workflows-BantWytQ.d.mts} +7 -0
  223. package/dist/{workflows-ChyK_oTu.d.ts → workflows-BantWytQ.d.ts} +7 -0
  224. package/dist/workflows.cjs +67 -4
  225. package/dist/workflows.cjs.map +1 -0
  226. package/dist/workflows.d.mts +1 -1
  227. package/dist/workflows.d.ts +1 -1
  228. package/dist/workflows.mjs +2 -1
  229. package/package.json +17 -17
  230. package/dist/chunk-2SKCXYLB.mjs.map +0 -1
  231. package/dist/chunk-35NPLKQJ.mjs.map +0 -1
  232. package/dist/chunk-AAC66ILR.mjs.map +0 -1
  233. package/dist/chunk-BZAIS65C.mjs.map +0 -1
  234. package/dist/chunk-EPDIF432.mjs.map +0 -1
  235. package/dist/chunk-ISSFLGJ5.mjs.map +0 -1
  236. package/dist/chunk-WKDAA6V2.mjs.map +0 -1
  237. /package/dist/{chunk-WD2EBM3I.mjs.map → chunk-3CQJV3NC.mjs.map} +0 -0
  238. /package/dist/{chunk-I3OOUWO5.mjs.map → chunk-3GDRV7SG.mjs.map} +0 -0
  239. /package/dist/{chunk-X4SFHKFH.mjs.map → chunk-6KJY25DQ.mjs.map} +0 -0
  240. /package/dist/{chunk-FP5Q67FO.mjs.map → chunk-AAEZP2EY.mjs.map} +0 -0
  241. /package/dist/{chunk-FSIXEIOB.mjs.map → chunk-L7FSTPGS.mjs.map} +0 -0
  242. /package/dist/{chunk-GJ7W6LNK.mjs.map → chunk-N5RK4LK6.mjs.map} +0 -0
  243. /package/dist/{chunk-52BR7LTX.mjs.map → chunk-STSPSJUI.mjs.map} +0 -0
  244. /package/dist/{chunk-YIBV77KZ.mjs.map → chunk-URQELPSH.mjs.map} +0 -0
  245. /package/dist/{chunk-UMUWR5XA.mjs.map → chunk-UWQ4EEW7.mjs.map} +0 -0
  246. /package/dist/{chunk-IZBX2TEU.mjs.map → chunk-VQG3QWWK.mjs.map} +0 -0
  247. /package/dist/{chunk-D7F7YZ7L.mjs.map → chunk-WA77FWAO.mjs.map} +0 -0
  248. /package/dist/{integration-orm-LLW6WZNK.mjs.map → integration-orm-G5BPBT5X.mjs.map} +0 -0
package/dist/index.cjs CHANGED
@@ -917,9 +917,13 @@ function getStorage(namespace) {
917
917
  const namespaced = (0, import_unstorage.prefixStorage)(globalStorage, base);
918
918
  return {
919
919
  ...namespaced,
920
- async clear() {
921
- const keys = await namespaced.getKeys();
922
- await Promise.all(keys.map((key) => namespaced.removeItem(key)));
920
+ // Scope the wipe to the namespace instead of the whole storage, and keep
921
+ // the caller's base so `clear("sessions")` cannot take unrelated keys with
922
+ // it. Dropping the argument silently widens a targeted clear into a
923
+ // namespace-wide delete.
924
+ async clear(base2, opts) {
925
+ const keys = await namespaced.getKeys(base2);
926
+ await Promise.all(keys.map((key) => namespaced.removeItem(key, opts)));
923
927
  }
924
928
  };
925
929
  }
@@ -1359,6 +1363,170 @@ var init_route_pattern = __esm({
1359
1363
  }
1360
1364
  });
1361
1365
 
1366
+ // src/request-origin.ts
1367
+ function getRequestSourceOrigin(request) {
1368
+ const origin = request.headers.get("origin")?.trim();
1369
+ if (origin) {
1370
+ return parseSourceOrigin(origin);
1371
+ }
1372
+ const referer = request.headers.get("referer")?.trim();
1373
+ if (referer) {
1374
+ return parseSourceOrigin(referer);
1375
+ }
1376
+ return { ok: true, origin: null };
1377
+ }
1378
+ function parseSourceOrigin(value) {
1379
+ if (value === "null") {
1380
+ return { ok: false, reason: "opaque-origin" };
1381
+ }
1382
+ try {
1383
+ const parsed = new URL(value);
1384
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
1385
+ return { ok: false, reason: "invalid-origin" };
1386
+ }
1387
+ return { ok: true, origin: parsed.origin };
1388
+ } catch {
1389
+ return { ok: false, reason: "invalid-origin" };
1390
+ }
1391
+ }
1392
+ function matchesHostHeader(sourceOrigin, request) {
1393
+ const host = request.headers.get("host")?.trim().toLowerCase();
1394
+ if (!host) return false;
1395
+ try {
1396
+ const source = new URL(sourceOrigin);
1397
+ const target = new URL(request.url);
1398
+ return source.protocol === target.protocol && source.host.toLowerCase() === host;
1399
+ } catch {
1400
+ return false;
1401
+ }
1402
+ }
1403
+ function matchesAllowedOrigin(sourceOrigin, pattern) {
1404
+ const source = new URL(sourceOrigin);
1405
+ if (!pattern.includes("*")) {
1406
+ return pattern.includes("://") ? source.origin === pattern : source.host === pattern;
1407
+ }
1408
+ const schemeEnd = pattern.indexOf("://");
1409
+ const scheme = schemeEnd === -1 ? null : pattern.slice(0, schemeEnd + 1);
1410
+ const hostPattern = pattern.slice(schemeEnd === -1 ? 0 : schemeEnd + 3);
1411
+ const [wildcardHost, port] = splitHostAndPort(hostPattern);
1412
+ const baseHost = wildcardHost.slice(2);
1413
+ if (scheme && source.protocol !== scheme) return false;
1414
+ if (port && getEffectivePort(source) !== port) return false;
1415
+ if (!port && source.port) return false;
1416
+ return source.hostname.endsWith(`.${baseHost}`) && source.hostname !== baseHost;
1417
+ }
1418
+ function normalizeAllowedOriginPattern(value, label) {
1419
+ const pattern = value.trim().toLowerCase();
1420
+ if (!pattern) {
1421
+ throw new TypeError(`${label} cannot contain empty values`);
1422
+ }
1423
+ if (pattern.includes("*")) {
1424
+ if (!/^(?:https?:\/\/)?\*\.[a-z0-9.-]+(?::\d+)?$/.test(pattern)) {
1425
+ throw new TypeError(`Invalid ${label} pattern: ${JSON.stringify(value)}`);
1426
+ }
1427
+ return pattern;
1428
+ }
1429
+ if (pattern.includes("://")) {
1430
+ let parsed;
1431
+ try {
1432
+ parsed = new URL(pattern);
1433
+ } catch {
1434
+ throw new TypeError(`Invalid ${label} value: ${JSON.stringify(value)}`);
1435
+ }
1436
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
1437
+ throw new TypeError(`${label} must contain origins without paths: ${JSON.stringify(value)}`);
1438
+ }
1439
+ return parsed.origin;
1440
+ }
1441
+ if (/[/@?#]/.test(pattern)) {
1442
+ throw new TypeError(`${label} must contain origins or hosts: ${JSON.stringify(value)}`);
1443
+ }
1444
+ try {
1445
+ return new URL(`http://${pattern}`).host;
1446
+ } catch {
1447
+ throw new TypeError(`Invalid ${label} value: ${JSON.stringify(value)}`);
1448
+ }
1449
+ }
1450
+ function splitHostAndPort(value) {
1451
+ const separator = value.lastIndexOf(":");
1452
+ if (separator === -1) return [value, null];
1453
+ return [value.slice(0, separator), value.slice(separator + 1)];
1454
+ }
1455
+ function getEffectivePort(url) {
1456
+ if (url.port) return url.port;
1457
+ if (url.protocol === "https:") return "443";
1458
+ if (url.protocol === "http:") return "80";
1459
+ return "";
1460
+ }
1461
+ var init_request_origin = __esm({
1462
+ "src/request-origin.ts"() {
1463
+ "use strict";
1464
+ __name(getRequestSourceOrigin, "getRequestSourceOrigin");
1465
+ __name(parseSourceOrigin, "parseSourceOrigin");
1466
+ __name(matchesHostHeader, "matchesHostHeader");
1467
+ __name(matchesAllowedOrigin, "matchesAllowedOrigin");
1468
+ __name(normalizeAllowedOriginPattern, "normalizeAllowedOriginPattern");
1469
+ __name(splitHostAndPort, "splitHostAndPort");
1470
+ __name(getEffectivePort, "getEffectivePort");
1471
+ }
1472
+ });
1473
+
1474
+ // src/integration-request-security.ts
1475
+ function resolveIntegrationAllowedOrigins(values, label) {
1476
+ return Object.freeze((values ?? []).map((value) => normalizeAllowedOriginPattern(value, label)));
1477
+ }
1478
+ function validateIntegrationRequestOrigin(request, policy = {}) {
1479
+ const allowedOrigins = policy.allowedOrigins ?? [];
1480
+ const requireOriginMetadata = policy.requireOriginMetadata ?? true;
1481
+ const fetchSite = request.headers.get("sec-fetch-site")?.trim().toLowerCase();
1482
+ const source = getRequestSourceOrigin(request);
1483
+ if (!source.ok) {
1484
+ return { ok: false, reason: source.reason };
1485
+ }
1486
+ if (source.origin === null) {
1487
+ if (fetchSite === "same-origin") {
1488
+ return { ok: true };
1489
+ }
1490
+ if (requireOriginMetadata) {
1491
+ return { ok: false, reason: fetchSite === "cross-site" ? "cross-site" : "missing-origin" };
1492
+ }
1493
+ return fetchSite === "cross-site" ? { ok: false, reason: "cross-site" } : { ok: true };
1494
+ }
1495
+ const requestUrl = new URL(request.url);
1496
+ const matchesConfiguredOrigin = allowedOrigins.some(
1497
+ (pattern) => matchesAllowedOrigin(source.origin, pattern)
1498
+ );
1499
+ const matchesRequest = source.origin === requestUrl.origin || matchesHostHeader(source.origin, request);
1500
+ if (!matchesRequest && !matchesConfiguredOrigin) {
1501
+ return { ok: false, reason: "cross-site" };
1502
+ }
1503
+ if (fetchSite === "cross-site" && !matchesConfiguredOrigin) {
1504
+ return { ok: false, reason: "cross-site" };
1505
+ }
1506
+ return { ok: true };
1507
+ }
1508
+ function describeIntegrationOriginRejection(reason) {
1509
+ switch (reason) {
1510
+ case "missing-origin":
1511
+ return "Request is missing same-origin metadata.";
1512
+ case "opaque-origin":
1513
+ return "Opaque origins are not allowed.";
1514
+ case "invalid-origin":
1515
+ return "Invalid request origin.";
1516
+ case "cross-site":
1517
+ return "Cross-site request was rejected.";
1518
+ }
1519
+ }
1520
+ var init_integration_request_security = __esm({
1521
+ "src/integration-request-security.ts"() {
1522
+ "use strict";
1523
+ init_request_origin();
1524
+ __name(resolveIntegrationAllowedOrigins, "resolveIntegrationAllowedOrigins");
1525
+ __name(validateIntegrationRequestOrigin, "validateIntegrationRequestOrigin");
1526
+ __name(describeIntegrationOriginRejection, "describeIntegrationOriginRejection");
1527
+ }
1528
+ });
1529
+
1362
1530
  // src/integration-api.ts
1363
1531
  function defineIntegrationAPIOperation(operation2) {
1364
1532
  return {
@@ -4195,6 +4363,7 @@ var init_integrations = __esm({
4195
4363
  "src/integrations.ts"() {
4196
4364
  "use strict";
4197
4365
  init_route_pattern();
4366
+ init_integration_request_security();
4198
4367
  init_integration_api();
4199
4368
  init_plugin_integration_context();
4200
4369
  init_decode();
@@ -4660,6 +4829,29 @@ var init_markdown = __esm({
4660
4829
  }
4661
4830
  });
4662
4831
 
4832
+ // src/utils/runtime-env.ts
4833
+ function getFarmRuntimeBindings() {
4834
+ const runtimeBindings = globalThis.__env__;
4835
+ return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
4836
+ }
4837
+ function readFarmEnvironmentValue(name2) {
4838
+ const runtimeValue = getFarmRuntimeBindings()?.[name2];
4839
+ if (typeof runtimeValue === "string") return runtimeValue;
4840
+ return typeof process !== "undefined" ? process.env?.[name2] : void 0;
4841
+ }
4842
+ function isFarmDeployedRuntime() {
4843
+ if (getFarmRuntimeBindings()) return true;
4844
+ return readFarmEnvironmentValue("NODE_ENV") === "production";
4845
+ }
4846
+ var init_runtime_env = __esm({
4847
+ "src/utils/runtime-env.ts"() {
4848
+ "use strict";
4849
+ __name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
4850
+ __name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
4851
+ __name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
4852
+ }
4853
+ });
4854
+
4663
4855
  // src/workflows.ts
4664
4856
  var workflows_exports = {};
4665
4857
  __export(workflows_exports, {
@@ -4708,7 +4900,8 @@ function resolveWorkflowsConfig(workflows) {
4708
4900
  dirs,
4709
4901
  route: normalizeWorkflowRoute(options.route || DEFAULT_FARM_WORKFLOW_ROUTE),
4710
4902
  secretEnv: options.secretEnv || DEFAULT_FARM_WORKFLOW_SECRET_ENV,
4711
- secret: options.secret
4903
+ secret: options.secret,
4904
+ allowUnsecured: options.allowUnsecured === true
4712
4905
  };
4713
4906
  }
4714
4907
  async function discoverFarmWorkflows(config, options = {}) {
@@ -4834,8 +5027,11 @@ async function prepareFarmWorkflowsForNitro(config) {
4834
5027
  await fs16.mkdir(generatedDir, { recursive: true });
4835
5028
  const tasks = {};
4836
5029
  const scheduledTasks = createScheduledTasks(workflows);
5030
+ const wrapperNames = resolveWorkflowWrapperFileNames(workflows.map((workflow) => workflow.id));
4837
5031
  for (const workflow of workflows) {
4838
- const wrapperPath = toPosixPath(path43.join(generatedDir, `${safeFileName(workflow.id)}.mjs`));
5032
+ const wrapperPath = toPosixPath(
5033
+ path43.join(generatedDir, `${wrapperNames.get(workflow.id)}.mjs`)
5034
+ );
4839
5035
  await fs16.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
4840
5036
  tasks[workflow.id] = {
4841
5037
  handler: wrapperPath,
@@ -5196,8 +5392,16 @@ function readScheduledTime(payload) {
5196
5392
  return payload && typeof payload === "object" && "scheduledTime" in payload ? payload.scheduledTime : void 0;
5197
5393
  }
5198
5394
  function verifyWorkflowSecret(request, config) {
5199
- const secret = config.secret || process.env[config.secretEnv] || "";
5200
- if (!secret) return null;
5395
+ const secret = config.secret || readFarmEnvironmentValue(config.secretEnv) || "";
5396
+ if (!secret) {
5397
+ if (config.allowUnsecured === true || !isFarmDeployedRuntime()) return null;
5398
+ return Response.json(
5399
+ {
5400
+ error: "Workflow route requires a secret. Set the CRON_SECRET environment variable, configure workflows.secret, or set workflows.allowUnsecured to true."
5401
+ },
5402
+ { status: 401 }
5403
+ );
5404
+ }
5201
5405
  const authorization = request.headers.get("authorization") || "";
5202
5406
  const bearer = authorization.match(/^Bearer\s+(.+)$/i)?.[1] || "";
5203
5407
  const headerSecret = request.headers.get("x-farm-workflow-secret") || "";
@@ -5210,6 +5414,37 @@ function joinRoute(...parts) {
5210
5414
  function trimSlashes(value) {
5211
5415
  return value.replace(/^\/+|\/+$/g, "");
5212
5416
  }
5417
+ function resolveWorkflowWrapperFileNames(ids) {
5418
+ const groups = /* @__PURE__ */ new Map();
5419
+ for (const id of ids) {
5420
+ const key = safeFileName(id).toLowerCase();
5421
+ groups.set(key, (groups.get(key) ?? 0) + 1);
5422
+ }
5423
+ const resolved = /* @__PURE__ */ new Map();
5424
+ const claimed = /* @__PURE__ */ new Map();
5425
+ for (const id of ids) {
5426
+ const base = safeFileName(id);
5427
+ const key = base.toLowerCase();
5428
+ const fileName = (groups.get(key) ?? 0) > 1 ? `${key}-${workflowIdFingerprint(id)}` : base;
5429
+ const claimedBy = claimed.get(fileName.toLowerCase());
5430
+ if (claimedBy !== void 0) {
5431
+ throw new Error(
5432
+ `Farm workflows ${JSON.stringify(claimedBy)} and ${JSON.stringify(id)} generate the same wrapper file ${JSON.stringify(`${fileName}.mjs`)}. Rename one of them.`
5433
+ );
5434
+ }
5435
+ claimed.set(fileName.toLowerCase(), id);
5436
+ resolved.set(id, fileName);
5437
+ }
5438
+ return resolved;
5439
+ }
5440
+ function workflowIdFingerprint(value) {
5441
+ let hash = 2166136261;
5442
+ for (let index = 0; index < value.length; index += 1) {
5443
+ hash ^= value.charCodeAt(index);
5444
+ hash = Math.imul(hash, 16777619);
5445
+ }
5446
+ return (hash >>> 0).toString(16).padStart(8, "0");
5447
+ }
5213
5448
  function safeFileName(value) {
5214
5449
  return value.replace(/[^a-zA-Z0-9._-]+/g, "-") || "workflow";
5215
5450
  }
@@ -5222,6 +5457,7 @@ var init_workflows = __esm({
5222
5457
  "use strict";
5223
5458
  init_server_http();
5224
5459
  init_search_params();
5460
+ init_runtime_env();
5225
5461
  init_decode();
5226
5462
  init_utils();
5227
5463
  init_route_pattern();
@@ -5261,6 +5497,8 @@ var init_workflows = __esm({
5261
5497
  __name(verifyWorkflowSecret, "verifyWorkflowSecret");
5262
5498
  __name(joinRoute, "joinRoute");
5263
5499
  __name(trimSlashes, "trimSlashes");
5500
+ __name(resolveWorkflowWrapperFileNames, "resolveWorkflowWrapperFileNames");
5501
+ __name(workflowIdFingerprint, "workflowIdFingerprint");
5264
5502
  __name(safeFileName, "safeFileName");
5265
5503
  __name(relativePath, "relativePath");
5266
5504
  }
@@ -5312,9 +5550,10 @@ async function prepareFarmCronForNitro(config) {
5312
5550
  await fs16.rm(generatedDir, { recursive: true, force: true });
5313
5551
  await fs16.mkdir(generatedDir, { recursive: true });
5314
5552
  const tasks = {};
5553
+ const wrapperNames = resolveCronWrapperFileNames(cron.jobs.map((job) => job.name));
5315
5554
  for (const job of cron.jobs) {
5316
5555
  const taskName = getFarmCronTaskName(job.name);
5317
- const wrapperPath = toPosixPath(path43.join(generatedDir, `${safeFileName2(job.name)}.mjs`));
5556
+ const wrapperPath = toPosixPath(path43.join(generatedDir, `${wrapperNames.get(job.name)}.mjs`));
5318
5557
  await fs16.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), "utf8");
5319
5558
  tasks[taskName] = {
5320
5559
  handler: wrapperPath,
@@ -5397,9 +5636,9 @@ function mergeScheduledTasks(...maps) {
5397
5636
  }
5398
5637
  function isCronRequestAuthorized(request, options = {}) {
5399
5638
  const secretEnv = options.secretEnv || DEFAULT_FARM_CRON_SECRET_ENV;
5400
- const secret = options.secret || readEnvironmentValue(secretEnv);
5639
+ const secret = options.secret || readFarmEnvironmentValue(secretEnv);
5401
5640
  if (!secret) {
5402
- return options.allowUnsecured === true || !getFarmRuntimeBindings() && readEnvironmentValue("NODE_ENV") !== "production";
5641
+ return options.allowUnsecured === true || !getFarmRuntimeBindings() && readFarmEnvironmentValue("NODE_ENV") !== "production";
5403
5642
  }
5404
5643
  const authorization = request.headers.get("authorization") || "";
5405
5644
  const bearer = /^Bearer (.*)$/i.exec(authorization)?.[1] || "";
@@ -5596,14 +5835,36 @@ export default defineTask({
5596
5835
  });
5597
5836
  `.trim();
5598
5837
  }
5599
- function readEnvironmentValue(name2) {
5600
- const runtimeValue = getFarmRuntimeBindings()?.[name2];
5601
- if (typeof runtimeValue === "string") return runtimeValue;
5602
- return typeof process !== "undefined" ? process.env?.[name2] : void 0;
5838
+ function resolveCronWrapperFileNames(names) {
5839
+ const groups = /* @__PURE__ */ new Map();
5840
+ for (const name2 of names) {
5841
+ const key = safeFileName2(name2).toLowerCase();
5842
+ groups.set(key, (groups.get(key) ?? 0) + 1);
5843
+ }
5844
+ const resolved = /* @__PURE__ */ new Map();
5845
+ const claimed = /* @__PURE__ */ new Map();
5846
+ for (const name2 of names) {
5847
+ const base = safeFileName2(name2);
5848
+ const key = base.toLowerCase();
5849
+ const fileName = (groups.get(key) ?? 0) > 1 ? `${key}-${cronNameFingerprint(name2)}` : base;
5850
+ const claimedBy = claimed.get(fileName.toLowerCase());
5851
+ if (claimedBy !== void 0) {
5852
+ throw new Error(
5853
+ `Farm cron jobs ${JSON.stringify(claimedBy)} and ${JSON.stringify(name2)} generate the same wrapper file ${JSON.stringify(`${fileName}.mjs`)}. Rename one of them.`
5854
+ );
5855
+ }
5856
+ claimed.set(fileName.toLowerCase(), name2);
5857
+ resolved.set(name2, fileName);
5858
+ }
5859
+ return resolved;
5603
5860
  }
5604
- function getFarmRuntimeBindings() {
5605
- const runtimeBindings = globalThis.__env__;
5606
- return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
5861
+ function cronNameFingerprint(value) {
5862
+ let hash = 2166136261;
5863
+ for (let index = 0; index < value.length; index += 1) {
5864
+ hash ^= value.charCodeAt(index);
5865
+ hash = Math.imul(hash, 16777619);
5866
+ }
5867
+ return (hash >>> 0).toString(16).padStart(8, "0");
5607
5868
  }
5608
5869
  function safeFileName2(value) {
5609
5870
  return value.replace(/[^a-zA-Z0-9._-]+/g, "-") || "cron";
@@ -5613,6 +5874,7 @@ var init_cron = __esm({
5613
5874
  "src/cron.ts"() {
5614
5875
  "use strict";
5615
5876
  init_utils();
5877
+ init_runtime_env();
5616
5878
  DEFAULT_FARM_CRON_SECRET_ENV = "CRON_SECRET";
5617
5879
  FARM_CRON_MANIFEST = "cron-manifest.json";
5618
5880
  CRON_FIELD_RANGES = [
@@ -5643,8 +5905,8 @@ var init_cron = __esm({
5643
5905
  __name(mergeTaskNames, "mergeTaskNames");
5644
5906
  __name(getFarmCronTaskName, "getFarmCronTaskName");
5645
5907
  __name(createNitroCronTaskWrapper, "createNitroCronTaskWrapper");
5646
- __name(readEnvironmentValue, "readEnvironmentValue");
5647
- __name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
5908
+ __name(resolveCronWrapperFileNames, "resolveCronWrapperFileNames");
5909
+ __name(cronNameFingerprint, "cronNameFingerprint");
5648
5910
  __name(safeFileName2, "safeFileName");
5649
5911
  }
5650
5912
  });
@@ -6715,7 +6977,9 @@ var init_server_fn_error = __esm({
6715
6977
 
6716
6978
  // src/server-action-security.ts
6717
6979
  function resolveServerActionsConfig(config) {
6718
- const allowedOrigins = (config?.allowedOrigins ?? []).map(normalizeAllowedOriginPattern);
6980
+ const allowedOrigins = (config?.allowedOrigins ?? []).map(
6981
+ (value) => normalizeAllowedOriginPattern(value, SERVER_ACTION_ALLOWED_ORIGINS_LABEL)
6982
+ );
6719
6983
  const bodySizeLimit = parseBodySizeLimit(
6720
6984
  config?.bodySizeLimit ?? DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT,
6721
6985
  "serverActions.bodySizeLimit"
@@ -6734,7 +6998,7 @@ function validateServerActionRequest(request, config) {
6734
6998
  );
6735
6999
  }
6736
7000
  const requestUrl = new URL(request.url);
6737
- const sourceOrigin = getRequestSourceOrigin(request);
7001
+ const sourceOrigin = resolveSourceOrigin(request);
6738
7002
  const fetchSite = request.headers.get("sec-fetch-site")?.trim().toLowerCase();
6739
7003
  if (!sourceOrigin) {
6740
7004
  if (fetchSite !== "same-origin") {
@@ -6850,103 +7114,16 @@ function getFallbackAbortController() {
6850
7114
  }
6851
7115
  return globalState2[FALLBACK_ABORT_CONTROLLER_KEY];
6852
7116
  }
6853
- function normalizeAllowedOriginPattern(value) {
6854
- const pattern = value.trim().toLowerCase();
6855
- if (!pattern) {
6856
- throw new TypeError("serverActions.allowedOrigins cannot contain empty values");
6857
- }
6858
- if (pattern.includes("*")) {
6859
- if (!/^(?:https?:\/\/)?\*\.[a-z0-9.-]+(?::\d+)?$/.test(pattern)) {
6860
- throw new TypeError(`Invalid serverActions.allowedOrigins pattern: ${JSON.stringify(value)}`);
6861
- }
6862
- return pattern;
6863
- }
6864
- if (pattern.includes("://")) {
6865
- let parsed;
6866
- try {
6867
- parsed = new URL(pattern);
6868
- } catch {
6869
- throw new TypeError(`Invalid serverActions.allowedOrigins value: ${JSON.stringify(value)}`);
6870
- }
6871
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
6872
- throw new TypeError(
6873
- `serverActions.allowedOrigins must contain origins without paths: ${JSON.stringify(value)}`
6874
- );
6875
- }
6876
- return parsed.origin;
6877
- }
6878
- if (/[/@?#]/.test(pattern)) {
6879
- throw new TypeError(
6880
- `serverActions.allowedOrigins must contain origins or hosts: ${JSON.stringify(value)}`
7117
+ function resolveSourceOrigin(request) {
7118
+ const result = getRequestSourceOrigin(request);
7119
+ if (!result.ok) {
7120
+ throw new ServerActionRequestError(
7121
+ "INVALID_ORIGIN",
7122
+ 403,
7123
+ result.reason === "opaque-origin" ? "Opaque origins are not allowed" : "Invalid request origin"
6881
7124
  );
6882
7125
  }
6883
- try {
6884
- return new URL(`http://${pattern}`).host;
6885
- } catch {
6886
- throw new TypeError(`Invalid serverActions.allowedOrigins value: ${JSON.stringify(value)}`);
6887
- }
6888
- }
6889
- function getRequestSourceOrigin(request) {
6890
- const origin = request.headers.get("origin")?.trim();
6891
- if (origin) {
6892
- return parseSourceOrigin(origin);
6893
- }
6894
- const referer = request.headers.get("referer")?.trim();
6895
- if (referer) {
6896
- return parseSourceOrigin(referer);
6897
- }
6898
- return null;
6899
- }
6900
- function parseSourceOrigin(value) {
6901
- if (value === "null") {
6902
- throw new ServerActionRequestError("INVALID_ORIGIN", 403, "Opaque origins are not allowed");
6903
- }
6904
- try {
6905
- const parsed = new URL(value);
6906
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
6907
- throw new Error("Unsupported protocol");
6908
- }
6909
- return parsed.origin;
6910
- } catch {
6911
- throw new ServerActionRequestError("INVALID_ORIGIN", 403, "Invalid request origin");
6912
- }
6913
- }
6914
- function matchesHostHeader(sourceOrigin, request) {
6915
- const host = request.headers.get("host")?.trim().toLowerCase();
6916
- if (!host) return false;
6917
- try {
6918
- const source = new URL(sourceOrigin);
6919
- const target = new URL(request.url);
6920
- return source.protocol === target.protocol && source.host.toLowerCase() === host;
6921
- } catch {
6922
- return false;
6923
- }
6924
- }
6925
- function matchesAllowedOrigin(sourceOrigin, pattern) {
6926
- const source = new URL(sourceOrigin);
6927
- if (!pattern.includes("*")) {
6928
- return pattern.includes("://") ? source.origin === pattern : source.host === pattern;
6929
- }
6930
- const schemeEnd = pattern.indexOf("://");
6931
- const scheme = schemeEnd === -1 ? null : pattern.slice(0, schemeEnd + 1);
6932
- const hostPattern = pattern.slice(schemeEnd === -1 ? 0 : schemeEnd + 3);
6933
- const [wildcardHost, port] = splitHostAndPort(hostPattern);
6934
- const baseHost = wildcardHost.slice(2);
6935
- if (scheme && source.protocol !== scheme) return false;
6936
- if (port && getEffectivePort(source) !== port) return false;
6937
- if (!port && source.port) return false;
6938
- return source.hostname.endsWith(`.${baseHost}`) && source.hostname !== baseHost;
6939
- }
6940
- function splitHostAndPort(value) {
6941
- const separator = value.lastIndexOf(":");
6942
- if (separator === -1) return [value, null];
6943
- return [value.slice(0, separator), value.slice(separator + 1)];
6944
- }
6945
- function getEffectivePort(url) {
6946
- if (url.port) return url.port;
6947
- if (url.protocol === "https:") return "443";
6948
- if (url.protocol === "http:") return "80";
6949
- return "";
7126
+ return result.origin;
6950
7127
  }
6951
7128
  function validateActionId(actionId) {
6952
7129
  if (!actionId || actionId.length > 4096 || hasControlCharacters(actionId)) {
@@ -7067,14 +7244,16 @@ function throwIfAborted2(signal) {
7067
7244
  if (signal.reason !== void 0) throw signal.reason;
7068
7245
  throw new DOMException("The operation was aborted", "AbortError");
7069
7246
  }
7070
- var import_node_async_hooks, DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT, _ServerActionRequestError, ServerActionRequestError, SERVER_ACTION_STORAGE_KEY, FALLBACK_ABORT_CONTROLLER_KEY, FORM_ACTION_CONTENT_TYPES, JAVASCRIPT_ACTION_CONTENT_TYPES;
7247
+ var import_node_async_hooks, SERVER_ACTION_ALLOWED_ORIGINS_LABEL, DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT, _ServerActionRequestError, ServerActionRequestError, SERVER_ACTION_STORAGE_KEY, FALLBACK_ABORT_CONTROLLER_KEY, FORM_ACTION_CONTENT_TYPES, JAVASCRIPT_ACTION_CONTENT_TYPES;
7071
7248
  var init_server_action_security = __esm({
7072
7249
  "src/server-action-security.ts"() {
7073
7250
  "use strict";
7074
7251
  import_node_async_hooks = require("async_hooks");
7075
7252
  init_cache_invalidation();
7253
+ init_request_origin();
7076
7254
  init_server_fn_error();
7077
7255
  init_server_http();
7256
+ SERVER_ACTION_ALLOWED_ORIGINS_LABEL = "serverActions.allowedOrigins";
7078
7257
  DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT = 1e6;
7079
7258
  _ServerActionRequestError = class _ServerActionRequestError extends Error {
7080
7259
  constructor(code, status, message) {
@@ -7115,13 +7294,7 @@ var init_server_action_security = __esm({
7115
7294
  });
7116
7295
  __name(getServerActionStorage, "getServerActionStorage");
7117
7296
  __name(getFallbackAbortController, "getFallbackAbortController");
7118
- __name(normalizeAllowedOriginPattern, "normalizeAllowedOriginPattern");
7119
- __name(getRequestSourceOrigin, "getRequestSourceOrigin");
7120
- __name(parseSourceOrigin, "parseSourceOrigin");
7121
- __name(matchesHostHeader, "matchesHostHeader");
7122
- __name(matchesAllowedOrigin, "matchesAllowedOrigin");
7123
- __name(splitHostAndPort, "splitHostAndPort");
7124
- __name(getEffectivePort, "getEffectivePort");
7297
+ __name(resolveSourceOrigin, "resolveSourceOrigin");
7125
7298
  __name(validateActionId, "validateActionId");
7126
7299
  __name(hasControlCharacters, "hasControlCharacters");
7127
7300
  __name(getSupportedContentType, "getSupportedContentType");
@@ -17012,7 +17185,7 @@ var init_server3 = __esm({
17012
17185
  var version;
17013
17186
  var init_package = __esm({
17014
17187
  "package.json"() {
17015
- version = "0.1.0-beta.97";
17188
+ version = "0.1.0-beta.98";
17016
17189
  }
17017
17190
  });
17018
17191
 
@@ -25065,10 +25238,11 @@ function createFarmImageHandler(config, options) {
25065
25238
  "quality"
25066
25239
  );
25067
25240
  const accept = request.headers.get("accept") ?? "";
25241
+ const negotiatedFormat = selectOutputFormat(accept, config.formats) ?? "";
25068
25242
  const cacheKey = `${sourceUrl.href}
25069
25243
  ${width}
25070
25244
  ${quality}
25071
- ${accept}`;
25245
+ ${negotiatedFormat}`;
25072
25246
  let optimized = cache.get(cacheKey);
25073
25247
  if (!optimized) {
25074
25248
  const fetchedSource = await fetchImageSource(
@@ -25095,7 +25269,8 @@ ${accept}`;
25095
25269
  quality,
25096
25270
  accept,
25097
25271
  formats: config.formats,
25098
- signal: request.signal
25272
+ signal: request.signal,
25273
+ maximumResponseBody: config.maximumResponseBody
25099
25274
  });
25100
25275
  throwIfAborted3(request.signal);
25101
25276
  validateTransformedResult(result, config);
@@ -25426,7 +25601,7 @@ function throwIfAborted3(signal) {
25426
25601
  function isAbortError(error) {
25427
25602
  return error instanceof Error && error.name === "AbortError";
25428
25603
  }
25429
- var _FarmImageRequestError, FarmImageRequestError, _FarmImageMemoryCache, FarmImageMemoryCache;
25604
+ var _FarmImageRequestError, FarmImageRequestError, DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT, _FarmImageMemoryCache, FarmImageMemoryCache;
25430
25605
  var init_image_server = __esm({
25431
25606
  "src/image-server.ts"() {
25432
25607
  "use strict";
@@ -25442,6 +25617,7 @@ var init_image_server = __esm({
25442
25617
  __name(_FarmImageRequestError, "FarmImageRequestError");
25443
25618
  FarmImageRequestError = _FarmImageRequestError;
25444
25619
  __name(createFarmImageHandler, "createFarmImageHandler");
25620
+ DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT = 10 * 1024 * 1024;
25445
25621
  __name(selectOutputFormat, "selectOutputFormat");
25446
25622
  __name(isPrivateImageAddress, "isPrivateImageAddress");
25447
25623
  __name(parseAllowedInteger, "parseAllowedInteger");
@@ -38279,6 +38455,7 @@ __export(src_exports, {
38279
38455
  defineStorageClient: () => defineStorageClient,
38280
38456
  defineTask: () => defineTask,
38281
38457
  defineWorkflow: () => defineWorkflow,
38458
+ describeIntegrationOriginRejection: () => describeIntegrationOriginRejection,
38282
38459
  discoverFarmDocsPages: () => discoverFarmDocsPages,
38283
38460
  discoverFarmWorkflows: () => discoverFarmWorkflows,
38284
38461
  dispatchIntegrationRequest: () => dispatchIntegrationRequest,
@@ -38475,6 +38652,7 @@ __export(src_exports, {
38475
38652
  resolveFarmRouteRuleRuntimeConfig: () => resolveFarmRouteRuleRuntimeConfig,
38476
38653
  resolveFarmRouteRuntimeConfig: () => resolveFarmRouteRuntimeConfig,
38477
38654
  resolveFarmThemeConfig: () => resolveFarmThemeConfig,
38655
+ resolveIntegrationAllowedOrigins: () => resolveIntegrationAllowedOrigins,
38478
38656
  resolveIntegrationOrmRuntimeClient: () => resolveIntegrationOrmRuntimeClient,
38479
38657
  resolveIntegrationPlugins: () => resolveIntegrationPlugins,
38480
38658
  resolveMarkdownConfig: () => resolveMarkdownConfig,
@@ -38535,6 +38713,7 @@ __export(src_exports, {
38535
38713
  useServerFn: () => useServerFn,
38536
38714
  useServerQuery: () => useServerQuery,
38537
38715
  useTheme: () => useTheme,
38716
+ validateIntegrationRequestOrigin: () => validateIntegrationRequestOrigin,
38538
38717
  validateServerActionRequest: () => validateServerActionRequest,
38539
38718
  vercelBlobStorage: () => vercelBlobStorage,
38540
38719
  vercelKVStorage: () => vercelKVStorage,
@@ -40247,6 +40426,7 @@ var _FarmClientDataCache = class _FarmClientDataCache {
40247
40426
  const watched = /* @__PURE__ */ new Set();
40248
40427
  for (const key of this.listeners.keys()) watched.add(this.resolveKey(key));
40249
40428
  let remaining = false;
40429
+ const swept = /* @__PURE__ */ new Set();
40250
40430
  for (const [key, entry] of this.entries) {
40251
40431
  if (entry.gcAt === void 0) continue;
40252
40432
  if (now2 < entry.gcAt || entry.fetching || this.inflight.has(key) || watched.has(key)) {
@@ -40255,9 +40435,28 @@ var _FarmClientDataCache = class _FarmClientDataCache {
40255
40435
  }
40256
40436
  this.entries.delete(key);
40257
40437
  this.persistence?.onDelete(key);
40438
+ swept.add(key);
40258
40439
  }
40440
+ if (swept.size > 0) this.sweepEntryMetadata(swept);
40259
40441
  if (remaining) this.scheduleGcSweep();
40260
40442
  }
40443
+ /**
40444
+ * Entry eviction alone leaves the per-key metadata behind. `invalidatedAt`
40445
+ * marks and provisional aliases are created per query invocation, so with
40446
+ * dynamic keys they accumulate for the lifetime of the page even though the
40447
+ * entries they describe are long gone.
40448
+ */
40449
+ sweepEntryMetadata(swept) {
40450
+ for (const key of swept) this.invalidatedAt.delete(key);
40451
+ for (const [alias, target] of this.aliases) {
40452
+ if (this.entries.has(alias) || this.listeners.has(alias)) continue;
40453
+ const resolved = this.resolveKey(target);
40454
+ if (!swept.has(resolved)) continue;
40455
+ if (this.entries.has(resolved) || this.listeners.has(resolved)) continue;
40456
+ this.aliases.delete(alias);
40457
+ this.invalidatedAt.delete(alias);
40458
+ }
40459
+ }
40261
40460
  emit(key, event) {
40262
40461
  this.notifyListeners(key, event);
40263
40462
  for (const [alias, target] of this.aliases) {
@@ -40268,7 +40467,12 @@ var _FarmClientDataCache = class _FarmClientDataCache {
40268
40467
  }
40269
40468
  notifyListeners(key, event) {
40270
40469
  for (const listener of this.listeners.get(key) ?? []) {
40271
- listener(event);
40470
+ try {
40471
+ listener(event);
40472
+ } catch (error) {
40473
+ const detail = error instanceof Error ? error.stack ?? error.message : String(error);
40474
+ console.warn(`[farm:client-cache] cache listener failed: ${detail}`);
40475
+ }
40272
40476
  }
40273
40477
  }
40274
40478
  };
@@ -53922,29 +54126,36 @@ __name(isFormData4, "isFormData");
53922
54126
  // src/cache-invalidation-broadcast.ts
53923
54127
  init_cache_invalidation();
53924
54128
  var FARM_CACHE_INVALIDATION_CHANNEL = "farm:cache-invalidation";
53925
- var activeBridge;
54129
+ var FARM_CACHE_INVALIDATION_BRIDGE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationBridge");
54130
+ var bridgeGlobal = globalThis;
53926
54131
  function enableCrossTabCacheInvalidation(options = {}) {
53927
54132
  if (typeof BroadcastChannel !== "function") return () => {
53928
54133
  };
53929
54134
  const channelName = options.channelName ?? FARM_CACHE_INVALIDATION_CHANNEL;
53930
- if (activeBridge) {
53931
- if (activeBridge.channelName !== channelName) {
54135
+ const existing = bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE];
54136
+ let bridge;
54137
+ if (existing) {
54138
+ if (existing.channelName !== channelName) {
53932
54139
  throw new Error(
53933
- `Cross-tab cache invalidation is already enabled on channel "${activeBridge.channelName}".`
54140
+ `Cross-tab cache invalidation is already enabled on channel "${existing.channelName}".`
53934
54141
  );
53935
54142
  }
53936
- activeBridge.refCount += 1;
54143
+ existing.refCount += 1;
54144
+ bridge = existing;
53937
54145
  } else {
53938
- activeBridge = createBridge(channelName);
54146
+ bridge = createBridge(channelName);
54147
+ bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE] = bridge;
53939
54148
  }
53940
54149
  let disposed = false;
53941
54150
  return () => {
53942
- if (disposed || !activeBridge) return;
54151
+ if (disposed) return;
53943
54152
  disposed = true;
53944
- activeBridge.refCount -= 1;
53945
- if (activeBridge.refCount === 0) {
53946
- activeBridge.teardown();
53947
- activeBridge = void 0;
54153
+ bridge.refCount -= 1;
54154
+ if (bridge.refCount === 0) {
54155
+ bridge.teardown();
54156
+ if (bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE] === bridge) {
54157
+ bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE] = void 0;
54158
+ }
53948
54159
  }
53949
54160
  };
53950
54161
  }
@@ -54152,7 +54363,7 @@ function createSink(engine) {
54152
54363
  scheduleFlush(engine);
54153
54364
  },
54154
54365
  onClear() {
54155
- if (engine.disabled) return;
54366
+ if (engine.disabled || engine.clearing) return;
54156
54367
  engine.pendingSets.clear();
54157
54368
  engine.pendingDeletes.clear();
54158
54369
  void engine.adapter.clear().catch((error) => disableEngine(engine, error));
@@ -54173,7 +54384,8 @@ function initPersistedClientCache(adapter, options = {}) {
54173
54384
  pendingDeletes: /* @__PURE__ */ new Set(),
54174
54385
  flushTimer: void 0,
54175
54386
  hydrating: false,
54176
- disabled: false
54387
+ disabled: false,
54388
+ clearing: false
54177
54389
  };
54178
54390
  activeEngine = engine;
54179
54391
  engine.cache.attachPersistence(createSink(engine));
@@ -54188,6 +54400,7 @@ function disposePersistedClientCache() {
54188
54400
  const engine = activeEngine;
54189
54401
  if (!engine) return;
54190
54402
  activeEngine = void 0;
54403
+ engine.disabled = true;
54191
54404
  engine.cache.attachPersistence(void 0);
54192
54405
  if (engine.flushTimer !== void 0) {
54193
54406
  clearTimeout(engine.flushTimer);
@@ -54199,7 +54412,18 @@ function disposePersistedClientCache() {
54199
54412
  __name(disposePersistedClientCache, "disposePersistedClientCache");
54200
54413
  async function clearPersistedCache() {
54201
54414
  const engine = activeEngine;
54202
- if (!engine) return;
54415
+ if (!engine) {
54416
+ getFarmClientDataCache().clear();
54417
+ return;
54418
+ }
54419
+ engine.pendingSets.clear();
54420
+ engine.pendingDeletes.clear();
54421
+ engine.clearing = true;
54422
+ try {
54423
+ engine.cache.clear();
54424
+ } finally {
54425
+ engine.clearing = false;
54426
+ }
54203
54427
  engine.pendingSets.clear();
54204
54428
  engine.pendingDeletes.clear();
54205
54429
  try {
@@ -57672,6 +57896,7 @@ __name(decodeCookiePart, "decodeCookiePart");
57672
57896
  defineStorageClient,
57673
57897
  defineTask,
57674
57898
  defineWorkflow,
57899
+ describeIntegrationOriginRejection,
57675
57900
  discoverFarmDocsPages,
57676
57901
  discoverFarmWorkflows,
57677
57902
  dispatchIntegrationRequest,
@@ -57868,6 +58093,7 @@ __name(decodeCookiePart, "decodeCookiePart");
57868
58093
  resolveFarmRouteRuleRuntimeConfig,
57869
58094
  resolveFarmRouteRuntimeConfig,
57870
58095
  resolveFarmThemeConfig,
58096
+ resolveIntegrationAllowedOrigins,
57871
58097
  resolveIntegrationOrmRuntimeClient,
57872
58098
  resolveIntegrationPlugins,
57873
58099
  resolveMarkdownConfig,
@@ -57928,6 +58154,7 @@ __name(decodeCookiePart, "decodeCookiePart");
57928
58154
  useServerFn,
57929
58155
  useServerQuery,
57930
58156
  useTheme,
58157
+ validateIntegrationRequestOrigin,
57931
58158
  validateServerActionRequest,
57932
58159
  vercelBlobStorage,
57933
58160
  vercelKVStorage,