@farm.js/core 0.1.17 → 0.1.19

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 (269) hide show
  1. package/dist/after.cjs +12 -225
  2. package/dist/agent-runtime.cjs +83 -2800
  3. package/dist/api/client.cjs +17 -4060
  4. package/dist/api/route-manager.cjs +34 -4354
  5. package/dist/api/runtime.cjs +29 -2696
  6. package/dist/api.cjs +88 -8434
  7. package/dist/app-markdown.cjs +39 -280
  8. package/dist/app-markdown.mjs +3 -3
  9. package/dist/cache.cjs +38 -1560
  10. package/dist/chunk-22GUSVNJ.cjs +351 -0
  11. package/dist/{chunk-EN7WTEAY.mjs → chunk-2ANEVVF7.mjs} +1 -1
  12. package/dist/chunk-2CQ74SP6.cjs +13 -0
  13. package/dist/{chunk-YD4J4XCI.mjs → chunk-2GNATDDE.mjs} +1 -1
  14. package/dist/chunk-2SJ4RQ6P.cjs +57 -0
  15. package/dist/chunk-3376ZTRC.cjs +1 -0
  16. package/dist/chunk-4PNUXIVU.cjs +472 -0
  17. package/dist/chunk-4PPEPOZZ.cjs +21 -0
  18. package/dist/chunk-4ZFL5GFN.cjs +520 -0
  19. package/dist/chunk-5OVTOKGH.cjs +65 -0
  20. package/dist/chunk-5QIKR7RR.cjs +224 -0
  21. package/dist/chunk-5ZSWG4UX.cjs +127 -0
  22. package/dist/chunk-62YJ2IEB.cjs +238 -0
  23. package/dist/chunk-6EODJYCX.cjs +183 -0
  24. package/dist/chunk-6EXBPJ24.cjs +434 -0
  25. package/dist/chunk-6QQDAAAZ.cjs +38 -0
  26. package/dist/chunk-6V4TDWEC.cjs +455 -0
  27. package/dist/chunk-72ADZ6GQ.cjs +19 -0
  28. package/dist/chunk-75BRBIFP.cjs +172 -0
  29. package/dist/{chunk-ZCNJKLA2.mjs → chunk-7BC6GAL7.mjs} +1 -1
  30. package/dist/chunk-7W3CPVXS.cjs +24 -0
  31. package/dist/chunk-A6WIQH5Z.cjs +31 -0
  32. package/dist/chunk-A777V5WU.cjs +725 -0
  33. package/dist/chunk-AFOD3LYZ.cjs +377 -0
  34. package/dist/chunk-AH7HOAQ3.cjs +151 -0
  35. package/dist/chunk-AMDMVWMI.cjs +39 -0
  36. package/dist/chunk-AORPIPNB.cjs +552 -0
  37. package/dist/chunk-ARJWXNQL.cjs +256 -0
  38. package/dist/chunk-AYJR42WX.cjs +711 -0
  39. package/dist/chunk-BBVSJVBZ.cjs +600 -0
  40. package/dist/chunk-BIDYX3SL.cjs +91 -0
  41. package/dist/chunk-BYODCJD6.cjs +663 -0
  42. package/dist/chunk-C3VRMB6H.cjs +85 -0
  43. package/dist/chunk-C5GUTBZK.cjs +173 -0
  44. package/dist/chunk-CIAGU2X4.cjs +337 -0
  45. package/dist/chunk-CMGMGHUZ.cjs +27 -0
  46. package/dist/chunk-CXP5U3RW.cjs +54 -0
  47. package/dist/chunk-D2ULAULS.cjs +166 -0
  48. package/dist/chunk-D7JTOLFK.cjs +285 -0
  49. package/dist/chunk-DVM4FKZL.cjs +169 -0
  50. package/dist/chunk-DYEJQTDN.cjs +49 -0
  51. package/dist/chunk-E2ROOWQC.cjs +2225 -0
  52. package/dist/chunk-E3UK5IIB.cjs +593 -0
  53. package/dist/chunk-EM6SBQKM.cjs +470 -0
  54. package/dist/chunk-FJSWYIR7.cjs +482 -0
  55. package/dist/chunk-FK6GO24V.cjs +54 -0
  56. package/dist/{chunk-MVIWBEJF.mjs → chunk-FVZGEVTO.mjs} +7 -7
  57. package/dist/chunk-FXUUWYAX.cjs +654 -0
  58. package/dist/chunk-G3HRIVEY.cjs +395 -0
  59. package/dist/chunk-G643DQCH.cjs +13 -0
  60. package/dist/chunk-G7HXGLEC.cjs +175 -0
  61. package/dist/chunk-GDSHDTJ4.cjs +152 -0
  62. package/dist/chunk-GPVTX3HT.cjs +1415 -0
  63. package/dist/chunk-H6G5INWM.cjs +1094 -0
  64. package/dist/{chunk-DHDVMXYK.mjs → chunk-HALDNTIV.mjs} +30 -4
  65. package/dist/chunk-HBTUGXHS.cjs +180 -0
  66. package/dist/chunk-HREOKQWT.cjs +45 -0
  67. package/dist/{chunk-5QOEPUYE.mjs → chunk-HSDL2AUR.mjs} +1 -1
  68. package/dist/chunk-I4J452B7.cjs +435 -0
  69. package/dist/chunk-I57LW5VZ.cjs +94 -0
  70. package/dist/chunk-I5YBCWQ6.cjs +40 -0
  71. package/dist/chunk-I7PUUDGY.cjs +389 -0
  72. package/dist/chunk-IAMRBF3Z.cjs +86 -0
  73. package/dist/chunk-IQXFRNY2.cjs +169 -0
  74. package/dist/chunk-ISTFC3MZ.cjs +1357 -0
  75. package/dist/chunk-IXTFU4PL.cjs +2355 -0
  76. package/dist/chunk-J3LOGE4T.cjs +42 -0
  77. package/dist/chunk-J7FSKED3.cjs +93 -0
  78. package/dist/chunk-JDNHKPTD.cjs +22 -0
  79. package/dist/chunk-JSROZYYO.cjs +164 -0
  80. package/dist/chunk-K6FNHVDR.cjs +696 -0
  81. package/dist/chunk-KGZIORNL.cjs +43 -0
  82. package/dist/chunk-KR6CKSXT.cjs +15 -0
  83. package/dist/chunk-KROWKCUH.cjs +185 -0
  84. package/dist/chunk-KVFPGF2M.cjs +46 -0
  85. package/dist/{chunk-TNBAYAWO.mjs → chunk-L4DVIHOC.mjs} +1 -1
  86. package/dist/chunk-LCCBO7PJ.cjs +46 -0
  87. package/dist/chunk-LIUGYUX3.cjs +22 -0
  88. package/dist/chunk-LTNGXMQ6.cjs +55 -0
  89. package/dist/chunk-M2L4MYDQ.cjs +14 -0
  90. package/dist/chunk-MCJLA63J.cjs +1 -0
  91. package/dist/chunk-MKB2EGIR.cjs +148 -0
  92. package/dist/chunk-MQ3H6LT5.cjs +202 -0
  93. package/dist/chunk-MT763TDW.cjs +43 -0
  94. package/dist/{chunk-XWAYMDLB.mjs → chunk-MVUREHPN.mjs} +1 -1
  95. package/dist/chunk-MWSK6C4J.cjs +18 -0
  96. package/dist/chunk-MWWVKDW3.cjs +169 -0
  97. package/dist/{chunk-6VQIKZZO.mjs → chunk-N255VYFP.mjs} +1 -1
  98. package/dist/chunk-NBAHDVOJ.cjs +2040 -0
  99. package/dist/chunk-NO3WWW3N.cjs +192 -0
  100. package/dist/chunk-NSFC3LHB.cjs +10244 -0
  101. package/dist/chunk-NZKJGRB3.cjs +230 -0
  102. package/dist/chunk-OAVTUMJP.cjs +1496 -0
  103. package/dist/{chunk-SXHV42UQ.mjs → chunk-OFEY6KHO.mjs} +88 -13
  104. package/dist/chunk-OHY2ZWUG.cjs +25 -0
  105. package/dist/chunk-OI6CMLWX.cjs +47 -0
  106. package/dist/chunk-OWOUTKIJ.cjs +558 -0
  107. package/dist/chunk-OX6O6WVA.cjs +74 -0
  108. package/dist/chunk-OXSIH4D6.cjs +476 -0
  109. package/dist/chunk-OYDRPBBV.cjs +453 -0
  110. package/dist/chunk-OYEUREB6.cjs +35 -0
  111. package/dist/chunk-PCOTGFSM.cjs +139 -0
  112. package/dist/{chunk-76DG3LF3.mjs → chunk-PGQBL5DN.mjs} +1 -1
  113. package/dist/chunk-PZYCPSCC.cjs +35 -0
  114. package/dist/chunk-QBK2AA4U.cjs +445 -0
  115. package/dist/{chunk-UTBVHYS3.mjs → chunk-QBPKKQTD.mjs} +2 -2
  116. package/dist/chunk-QBPXNZGV.cjs +487 -0
  117. package/dist/chunk-QNPEUFHQ.cjs +27 -0
  118. package/dist/chunk-QZRVZSPN.cjs +236 -0
  119. package/dist/chunk-R5A5KNVX.cjs +20 -0
  120. package/dist/chunk-R5JIFR6B.cjs +42 -0
  121. package/dist/chunk-R6AIILII.cjs +193 -0
  122. package/dist/chunk-RFYO7QUD.cjs +9 -0
  123. package/dist/chunk-RG3ZOTG5.cjs +34 -0
  124. package/dist/chunk-ROUTX2E5.cjs +390 -0
  125. package/dist/chunk-RTHIVJ2G.cjs +54 -0
  126. package/dist/chunk-S27FMYAM.cjs +644 -0
  127. package/dist/chunk-S3A45T7F.cjs +166 -0
  128. package/dist/chunk-S3JO3N4H.cjs +17 -0
  129. package/dist/chunk-SK35NQKK.cjs +27 -0
  130. package/dist/chunk-SU7MH53P.cjs +180 -0
  131. package/dist/chunk-SVRTJOUF.cjs +113 -0
  132. package/dist/chunk-SWN467MP.cjs +18 -0
  133. package/dist/chunk-SYQ3MOWW.cjs +73 -0
  134. package/dist/chunk-T5CERMEH.cjs +417 -0
  135. package/dist/chunk-TFAXUHWX.cjs +206 -0
  136. package/dist/chunk-TIWHTW3Q.cjs +24 -0
  137. package/dist/chunk-TKJZFIML.cjs +20 -0
  138. package/dist/chunk-TKNSDBBN.cjs +193 -0
  139. package/dist/chunk-U4KT7QP3.cjs +23 -0
  140. package/dist/chunk-U5BMPGS3.cjs +862 -0
  141. package/dist/chunk-UJ2C4ICS.cjs +277 -0
  142. package/dist/chunk-UQZ4AYTH.cjs +168 -0
  143. package/dist/chunk-US2QVW3E.cjs +36 -0
  144. package/dist/{chunk-QGVJVSNX.mjs → chunk-V4AICMQA.mjs} +2 -2
  145. package/dist/chunk-VB6UCX3V.cjs +421 -0
  146. package/dist/chunk-VEKFLAQM.cjs +300 -0
  147. package/dist/chunk-VQDBNVOO.cjs +14 -0
  148. package/dist/chunk-W4E7WMXE.cjs +71 -0
  149. package/dist/chunk-WJ3HK3LJ.cjs +1102 -0
  150. package/dist/chunk-WMAPPDMM.cjs +28 -0
  151. package/dist/chunk-WMOGFOUJ.cjs +223 -0
  152. package/dist/chunk-WPYFSQKK.cjs +37 -0
  153. package/dist/{chunk-56DAX2BE.mjs → chunk-WZXN4R5Y.mjs} +24 -13
  154. package/dist/chunk-XDGMADQM.cjs +14225 -0
  155. package/dist/chunk-XGC343EY.cjs +443 -0
  156. package/dist/chunk-XSKZORAS.cjs +727 -0
  157. package/dist/chunk-XWAWFQFS.cjs +82 -0
  158. package/dist/chunk-Y4YMF2NQ.cjs +460 -0
  159. package/dist/chunk-Y4YWHNKU.cjs +250 -0
  160. package/dist/chunk-Y53ZSFN6.cjs +504 -0
  161. package/dist/chunk-YA6LLTIJ.cjs +411 -0
  162. package/dist/chunk-YFPGHF5F.cjs +202 -0
  163. package/dist/chunk-YJRZR7VU.cjs +28 -0
  164. package/dist/chunk-YTAABQEV.cjs +1 -0
  165. package/dist/chunk-YX3DBN4M.cjs +18 -0
  166. package/dist/chunk-YZTASLPQ.cjs +64 -0
  167. package/dist/chunk-Z5HIWVDP.cjs +2173 -0
  168. package/dist/chunk-ZEG3OPIB.cjs +93 -0
  169. package/dist/chunk-ZMN3H73H.cjs +155 -0
  170. package/dist/client/lifecycle.cjs +6 -35
  171. package/dist/client-plugins.cjs +7 -448
  172. package/dist/client.cjs +171 -9808
  173. package/dist/config.cjs +8 -36
  174. package/dist/cron.cjs +24 -491
  175. package/dist/deferred.cjs +26 -475
  176. package/dist/deployment.cjs +39 -210
  177. package/dist/devtools-5KGPDVKL.cjs +388 -0
  178. package/dist/{devtools-UFVTMQX5.mjs → devtools-FY5R7TQ4.mjs} +3 -3
  179. package/dist/devtools-client-4WAPJY5L.cjs +254 -0
  180. package/dist/devtools-ui-5GBDIGMK.cjs +1296 -0
  181. package/dist/docs.cjs +46 -5657
  182. package/dist/docs.mjs +5 -5
  183. package/dist/env-types.cjs +5 -226
  184. package/dist/env.cjs +21 -338
  185. package/dist/environment/vite.cjs +8 -372
  186. package/dist/environment.cjs +12 -94
  187. package/dist/font.cjs +13 -63
  188. package/dist/headers.cjs +7 -123
  189. package/dist/i18n/client.cjs +55 -294
  190. package/dist/i18n/index.cjs +22 -209
  191. package/dist/i18n/server.cjs +22 -745
  192. package/dist/image/server.cjs +13 -729
  193. package/dist/image/sharp.cjs +33 -171
  194. package/dist/image.cjs +41 -85
  195. package/dist/index.cjs +1151 -68080
  196. package/dist/index.mjs +14 -14
  197. package/dist/instrumentation.cjs +12 -138
  198. package/dist/integration-orm-55F7CII5.cjs +13 -0
  199. package/dist/integrations.cjs +55 -4090
  200. package/dist/internal/app-markdown-runtime.cjs +27 -224
  201. package/dist/internal/app-markdown-runtime.mjs +2 -2
  202. package/dist/internal/build-runtime.cjs +120 -52259
  203. package/dist/internal/build-runtime.mjs +13 -13
  204. package/dist/internal/cli-runtime.cjs +67 -13811
  205. package/dist/internal/cli-runtime.mjs +7 -7
  206. package/dist/internal/client-error-overlay.cjs +80 -733
  207. package/dist/internal/client-error-overlay.mjs +1 -1
  208. package/dist/internal/client-runtime.cjs +81 -913
  209. package/dist/internal/compression-runtime.cjs +8 -214
  210. package/dist/internal/config-runtime.cjs +42 -6547
  211. package/dist/internal/config-runtime.mjs +3 -3
  212. package/dist/internal/docs-precompiled-runtime.cjs +26 -46
  213. package/dist/internal/infra-analytics-runtime.cjs +10 -536
  214. package/dist/internal/isolated-boundary.cjs +14 -414
  215. package/dist/internal/metadata-image-runtime.cjs +7 -285
  216. package/dist/internal/product-telemetry-runtime.cjs +42 -97
  217. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  218. package/dist/internal/production-node-env.cjs +6 -63
  219. package/dist/internal/production-runtime.cjs +418 -7133
  220. package/dist/internal/production-runtime.mjs +3 -3
  221. package/dist/internal/request-cookies.cjs +6 -54
  222. package/dist/json-ld.cjs +24 -50
  223. package/dist/layers-E4WPJNY5.cjs +17 -0
  224. package/dist/manager-G4B2IPYE.cjs +14 -0
  225. package/dist/markdown.cjs +21 -547
  226. package/dist/markdown.mjs +1 -1
  227. package/dist/middleware.cjs +36 -2995
  228. package/dist/navigation.cjs +22 -2588
  229. package/dist/nitro-4I2MYLY2.cjs +652 -0
  230. package/dist/observability.cjs +22 -614
  231. package/dist/og.cjs +5 -28
  232. package/dist/plugin.cjs +106 -37442
  233. package/dist/plugin.mjs +9 -9
  234. package/dist/query/client.cjs +113 -449
  235. package/dist/query/index.cjs +26 -288
  236. package/dist/query/parsers.cjs +23 -247
  237. package/dist/query/server.cjs +36 -298
  238. package/dist/renderer/react/client.cjs +9 -43
  239. package/dist/renderer/react/server.cjs +40 -103
  240. package/dist/renderer/react/vite.cjs +7 -29
  241. package/dist/renderer-client.cjs +126 -4295
  242. package/dist/renderer.cjs +31 -249
  243. package/dist/request.cjs +5 -68
  244. package/dist/router.cjs +11 -474
  245. package/dist/routes.cjs +42 -2461
  246. package/dist/{schema-dev-notice-2IE2F2XI.mjs → schema-dev-notice-O67CPXJ6.mjs} +1 -1
  247. package/dist/schema-dev-notice-Y7MQEFGN.cjs +56 -0
  248. package/dist/schema.cjs +6 -33
  249. package/dist/search-client-G3RICOFU.cjs +13 -0
  250. package/dist/server-action-security.cjs +25 -541
  251. package/dist/server-fn-client.cjs +6 -337
  252. package/dist/server-fn.cjs +32 -1841
  253. package/dist/server-plugins.cjs +15 -884
  254. package/dist/server-query-client.cjs +15 -1883
  255. package/dist/server-query.cjs +16 -1838
  256. package/dist/server.cjs +296 -44681
  257. package/dist/server.mjs +11 -11
  258. package/dist/storage.cjs +57 -576
  259. package/dist/testing.cjs +89 -3186
  260. package/dist/theme/client.cjs +13 -108
  261. package/dist/theme/index.cjs +6 -68
  262. package/dist/theme/runtime.cjs +13 -78
  263. package/dist/theme/server.cjs +10 -179
  264. package/dist/version.cjs +4 -32
  265. package/dist/version.mjs +1 -1
  266. package/dist/vite.cjs +119 -37773
  267. package/dist/vite.mjs +9 -9
  268. package/dist/workflows.cjs +19 -1040
  269. package/package.json +1 -1
@@ -0,0 +1,1357 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+ var _chunkBBVSJVBZcjs = require('./chunk-BBVSJVBZ.cjs');
6
+
7
+
8
+ var _chunkI57LW5VZcjs = require('./chunk-I57LW5VZ.cjs');
9
+
10
+
11
+ var _chunkS3JO3N4Hcjs = require('./chunk-S3JO3N4H.cjs');
12
+
13
+ // src/llms-txt.ts
14
+ function resolveFarmLlmsTxtConfig(input) {
15
+ if (!input) return { enabled: false, include: [], exclude: [], full: false };
16
+ if (input === true) return { enabled: true, include: [], exclude: [], full: true };
17
+ if (typeof input !== "object") {
18
+ throw new TypeError("agent.llmsTxt must be true, false, or an options object.");
19
+ }
20
+ if (input.enabled === false) return { enabled: false, include: [], exclude: [], full: false };
21
+ for (const key of ["title", "summary", "details"]) {
22
+ if (input[key] !== void 0 && typeof input[key] !== "string") {
23
+ throw new TypeError(`agent.llmsTxt.${key} must be a string.`);
24
+ }
25
+ }
26
+ if (input.full !== void 0 && typeof input.full !== "boolean") {
27
+ throw new TypeError("agent.llmsTxt.full must be a boolean.");
28
+ }
29
+ if (input.revalidate !== void 0 && (typeof input.revalidate !== "number" || !Number.isFinite(input.revalidate) || input.revalidate < 0)) {
30
+ throw new TypeError("agent.llmsTxt.revalidate must be a number of seconds.");
31
+ }
32
+ return {
33
+ enabled: true,
34
+ ...input.title ? { title: input.title } : {},
35
+ ...input.summary ? { summary: input.summary } : {},
36
+ ...input.details ? { details: input.details } : {},
37
+ include: resolveRoutePatterns(input.include, "include"),
38
+ exclude: resolveRoutePatterns(input.exclude, "exclude"),
39
+ full: input.full !== false,
40
+ ...input.revalidate !== void 0 ? { revalidate: input.revalidate } : {}
41
+ };
42
+ }
43
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveFarmLlmsTxtConfig, "resolveFarmLlmsTxtConfig");
44
+ function resolveRoutePatterns(value, key) {
45
+ if (value === void 0) return [];
46
+ if (!Array.isArray(value)) {
47
+ throw new TypeError(`agent.llmsTxt.${key} must be an array of route patterns.`);
48
+ }
49
+ return value.map((pattern, index) => {
50
+ if (typeof pattern !== "string" || !pattern.startsWith("/")) {
51
+ throw new TypeError(
52
+ `agent.llmsTxt.${key}[${index}] must be a route pattern starting with "/", such as "/docs/[...slug]".`
53
+ );
54
+ }
55
+ return pattern;
56
+ });
57
+ }
58
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveRoutePatterns, "resolveRoutePatterns");
59
+ function collectFarmLlmsTxtPages(sources, options) {
60
+ const include = _nullishCoalesce(options.include, () => ( []));
61
+ const exclude = _nullishCoalesce(options.exclude, () => ( []));
62
+ const pages = /* @__PURE__ */ new Map();
63
+ for (const source of sources) {
64
+ const path = source.pattern;
65
+ if (path.includes("[") || pages.has(path)) continue;
66
+ if (include.length && !include.some((pattern) => _chunkBBVSJVBZcjs.matchesFarmMarkdownRoutePattern.call(void 0, pattern, path))) {
67
+ continue;
68
+ }
69
+ if (exclude.some((pattern) => _chunkBBVSJVBZcjs.matchesFarmMarkdownRoutePattern.call(void 0, pattern, path))) continue;
70
+ const target = _chunkBBVSJVBZcjs.isFarmMarkdownMirrorExposed.call(void 0, options.markdown, path) ? _chunkBBVSJVBZcjs.getFarmMarkdownMirrorPath.call(void 0, path) : path;
71
+ const description = readMetadataString(source.metadata, "description");
72
+ pages.set(path, {
73
+ path,
74
+ title: _nullishCoalesce(readMetadataTitle(source.metadata), () => ( fallbackPageTitle(path))),
75
+ url: `${options.origin}${_chunkI57LW5VZcjs.applyFarmBasePath.call(void 0, target, options.basePath)}`,
76
+ ...description ? { description } : {}
77
+ });
78
+ }
79
+ return [...pages.values()].sort((left, right) => left.path.localeCompare(right.path));
80
+ }
81
+ _chunkS3JO3N4Hcjs.__name.call(void 0, collectFarmLlmsTxtPages, "collectFarmLlmsTxtPages");
82
+ function createFarmDefaultLlmsTxt(options) {
83
+ const { config, pages } = options;
84
+ const summary = _nullishCoalesce(config.summary, () => ( readMetadataString(options.rootMetadata, "description")));
85
+ return {
86
+ title: _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(config.title, () => ( readMetadataTitle(options.rootMetadata))), () => ( _optionalChain([pages, 'access', _2 => _2.find, 'call', _3 => _3((page) => page.path === "/"), 'optionalAccess', _4 => _4.title]))), () => ( new URL(options.origin).host)),
87
+ ...summary ? { summary } : {},
88
+ ...config.details ? { details: config.details } : {},
89
+ sections: pages.length ? [
90
+ {
91
+ title: "Pages",
92
+ links: pages.map(({ title, url, description }) => ({
93
+ title,
94
+ url,
95
+ ...description ? { description } : {}
96
+ }))
97
+ }
98
+ ] : []
99
+ };
100
+ }
101
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmDefaultLlmsTxt, "createFarmDefaultLlmsTxt");
102
+ function serializeFarmLlmsTxt(value) {
103
+ if (typeof value === "string") {
104
+ if (!value.trim()) throw new TypeError("llms.ts returned an empty llms.txt");
105
+ return value.endsWith("\n") ? value : `${value}
106
+ `;
107
+ }
108
+ if (!isRecord(value)) {
109
+ throw new TypeError("llms.ts must return llms.txt text, an llms.txt object, or a Response");
110
+ }
111
+ const title = requireText(value.title, "llms.ts must return a non-empty title");
112
+ const summary = optionalText(value.summary, "llms.ts summary must be a string");
113
+ const details = optionalText(value.details, "llms.ts details must be a string");
114
+ if (value.sections !== void 0 && !Array.isArray(value.sections)) {
115
+ throw new TypeError("llms.ts sections must be an array");
116
+ }
117
+ const blocks = [`# ${toSingleLine(title)}`];
118
+ if (_optionalChain([summary, 'optionalAccess', _5 => _5.trim, 'call', _6 => _6()])) blocks.push(`> ${toSingleLine(summary)}`);
119
+ if (_optionalChain([details, 'optionalAccess', _7 => _7.trim, 'call', _8 => _8()])) blocks.push(details.trim());
120
+ for (const [sectionIndex, section] of (_nullishCoalesce(value.sections, () => ( []))).entries()) {
121
+ if (!isRecord(section)) {
122
+ throw new TypeError(`llms.ts section ${sectionIndex} must be an object`);
123
+ }
124
+ const sectionTitle = requireText(
125
+ section.title,
126
+ `llms.ts section ${sectionIndex} must include a non-empty title`
127
+ );
128
+ if (!Array.isArray(section.links)) {
129
+ throw new TypeError(`llms.ts section "${sectionTitle}" must include a links array`);
130
+ }
131
+ const links = section.links.map((link, linkIndex) => {
132
+ const where = `llms.ts section "${sectionTitle}" link ${linkIndex}`;
133
+ if (!isRecord(link)) throw new TypeError(`${where} must be an object`);
134
+ const linkTitle = requireText(link.title, `${where} must include a non-empty title`);
135
+ const url = requireText(link.url, `${where} must include a non-empty url`);
136
+ const description = optionalText(link.description, `${where} description must be a string`);
137
+ return `- [${escapeLinkText(linkTitle)}](${escapeLinkUrl(url)})${_optionalChain([description, 'optionalAccess', _9 => _9.trim, 'call', _10 => _10()]) ? `: ${toSingleLine(description)}` : ""}`;
138
+ });
139
+ blocks.push(`## ${toSingleLine(sectionTitle)}`, links.join("\n"));
140
+ }
141
+ return `${blocks.filter(Boolean).join("\n\n")}
142
+ `;
143
+ }
144
+ _chunkS3JO3N4Hcjs.__name.call(void 0, serializeFarmLlmsTxt, "serializeFarmLlmsTxt");
145
+ function createFarmLlmsMarkdownReader(fetchMarkdown) {
146
+ return async (url) => {
147
+ try {
148
+ const response = await fetchMarkdown(
149
+ new Request(url, { headers: { accept: "text/markdown" } })
150
+ );
151
+ const type = _nullishCoalesce(response.headers.get("content-type"), () => ( ""));
152
+ if (!response.ok || !type.toLowerCase().startsWith("text/markdown")) {
153
+ await _optionalChain([response, 'access', _11 => _11.body, 'optionalAccess', _12 => _12.cancel, 'call', _13 => _13()]);
154
+ return null;
155
+ }
156
+ return await response.text();
157
+ } catch (e) {
158
+ return null;
159
+ }
160
+ };
161
+ }
162
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmLlmsMarkdownReader, "createFarmLlmsMarkdownReader");
163
+ async function renderFarmLlmsFullTxt(value, options) {
164
+ const index = serializeFarmLlmsTxt(value);
165
+ if (typeof value === "string") return index;
166
+ const llms = value;
167
+ const links = [];
168
+ const seen = /* @__PURE__ */ new Set();
169
+ for (const section of _nullishCoalesce(llms.sections, () => ( []))) {
170
+ for (const link of section.links) {
171
+ if (seen.has(link.url)) continue;
172
+ seen.add(link.url);
173
+ links.push(link);
174
+ }
175
+ }
176
+ const contents = await mapWithConcurrency(
177
+ links,
178
+ _nullishCoalesce(options.concurrency, () => ( 4)),
179
+ (link) => shouldInlineLlmsLink(link.url, options.origin) ? options.readMarkdown(link.url) : null
180
+ );
181
+ const blocks = [`# ${toSingleLine(llms.title)}`];
182
+ if (_optionalChain([llms, 'access', _14 => _14.summary, 'optionalAccess', _15 => _15.trim, 'call', _16 => _16()])) blocks.push(`> ${toSingleLine(llms.summary)}`);
183
+ if (_optionalChain([llms, 'access', _17 => _17.details, 'optionalAccess', _18 => _18.trim, 'call', _19 => _19()])) blocks.push(llms.details.trim());
184
+ const pages = links.map((link, index2) => {
185
+ const parts = [`## ${toSingleLine(link.title)}`, `URL: ${escapeLinkUrl(link.url)}`];
186
+ if (_optionalChain([link, 'access', _20 => _20.description, 'optionalAccess', _21 => _21.trim, 'call', _22 => _22()])) parts.push(toSingleLine(link.description));
187
+ const content = stripFrontmatter(_nullishCoalesce(contents[index2], () => ( ""))).trim();
188
+ if (content) parts.push(content);
189
+ return parts.join("\n\n");
190
+ });
191
+ if (pages.length) blocks.push(pages.join("\n\n---\n\n"));
192
+ return `${blocks.join("\n\n")}
193
+ `;
194
+ }
195
+ _chunkS3JO3N4Hcjs.__name.call(void 0, renderFarmLlmsFullTxt, "renderFarmLlmsFullTxt");
196
+ function stripFrontmatter(markdown) {
197
+ const match = /^\uFEFF?---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/.exec(markdown);
198
+ return match ? markdown.slice(match[0].length) : markdown;
199
+ }
200
+ _chunkS3JO3N4Hcjs.__name.call(void 0, stripFrontmatter, "stripFrontmatter");
201
+ function shouldInlineLlmsLink(url, origin) {
202
+ let target;
203
+ try {
204
+ target = new URL(url, origin);
205
+ } catch (e2) {
206
+ return false;
207
+ }
208
+ return target.origin === origin && !/\/llms(-full)?\.txt$/.test(target.pathname);
209
+ }
210
+ _chunkS3JO3N4Hcjs.__name.call(void 0, shouldInlineLlmsLink, "shouldInlineLlmsLink");
211
+ async function mapWithConcurrency(items, limit, run) {
212
+ const results = [];
213
+ let next = 0;
214
+ const worker = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, async () => {
215
+ while (next < items.length) {
216
+ const index = next++;
217
+ results[index] = await run(items[index]);
218
+ }
219
+ }, "worker");
220
+ await Promise.all(Array.from({ length: Math.min(Math.max(limit, 1), items.length) }, worker));
221
+ return results;
222
+ }
223
+ _chunkS3JO3N4Hcjs.__name.call(void 0, mapWithConcurrency, "mapWithConcurrency");
224
+ function readMetadataTitle(metadata) {
225
+ if (!isRecord(metadata)) return void 0;
226
+ const { title } = metadata;
227
+ if (typeof title === "string") return title.trim() || void 0;
228
+ if (isRecord(title)) {
229
+ for (const key of ["absolute", "default"]) {
230
+ const value = title[key];
231
+ if (typeof value === "string" && value.trim()) return value.trim();
232
+ }
233
+ }
234
+ return void 0;
235
+ }
236
+ _chunkS3JO3N4Hcjs.__name.call(void 0, readMetadataTitle, "readMetadataTitle");
237
+ function readMetadataString(metadata, key) {
238
+ if (!isRecord(metadata)) return void 0;
239
+ const value = metadata[key];
240
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
241
+ }
242
+ _chunkS3JO3N4Hcjs.__name.call(void 0, readMetadataString, "readMetadataString");
243
+ function fallbackPageTitle(path) {
244
+ if (path === "/") return "Home";
245
+ const segments = path.split("/").filter(Boolean);
246
+ const segment = _nullishCoalesce(segments[segments.length - 1], () => ( path));
247
+ const words = segment.replace(/[-_]+/g, " ").trim();
248
+ return words ? words[0].toUpperCase() + words.slice(1) : path;
249
+ }
250
+ _chunkS3JO3N4Hcjs.__name.call(void 0, fallbackPageTitle, "fallbackPageTitle");
251
+ function toSingleLine(value) {
252
+ return value.replace(/\s+/g, " ").trim();
253
+ }
254
+ _chunkS3JO3N4Hcjs.__name.call(void 0, toSingleLine, "toSingleLine");
255
+ function escapeLinkText(value) {
256
+ return toSingleLine(value).replace(/[\\[\]]/g, "\\$&");
257
+ }
258
+ _chunkS3JO3N4Hcjs.__name.call(void 0, escapeLinkText, "escapeLinkText");
259
+ function escapeLinkUrl(value) {
260
+ return value.trim().replace(
261
+ /[\s()<>]/g,
262
+ (character) => character === "(" ? "%28" : character === ")" ? "%29" : encodeURIComponent(character)
263
+ );
264
+ }
265
+ _chunkS3JO3N4Hcjs.__name.call(void 0, escapeLinkUrl, "escapeLinkUrl");
266
+ function requireText(value, message) {
267
+ if (typeof value !== "string" || !value.trim()) throw new TypeError(message);
268
+ return value;
269
+ }
270
+ _chunkS3JO3N4Hcjs.__name.call(void 0, requireText, "requireText");
271
+ function optionalText(value, message) {
272
+ if (value === void 0) return void 0;
273
+ if (typeof value !== "string") throw new TypeError(message);
274
+ return value;
275
+ }
276
+ _chunkS3JO3N4Hcjs.__name.call(void 0, optionalText, "optionalText");
277
+ function isRecord(value) {
278
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
279
+ }
280
+ _chunkS3JO3N4Hcjs.__name.call(void 0, isRecord, "isRecord");
281
+
282
+ // src/agent-crawlers.ts
283
+ var FARM_AI_CRAWLERS = {
284
+ search: [
285
+ "OAI-SearchBot",
286
+ "ChatGPT-User",
287
+ "Claude-SearchBot",
288
+ "Claude-User",
289
+ "PerplexityBot",
290
+ "Perplexity-User"
291
+ ],
292
+ training: [
293
+ "GPTBot",
294
+ "ClaudeBot",
295
+ "Google-Extended",
296
+ "CCBot",
297
+ "Applebot-Extended",
298
+ "Meta-ExternalAgent",
299
+ "Bytespider"
300
+ ]
301
+ };
302
+ var LINE_BREAK = /[\r\n]/;
303
+ function resolveFarmAgentCrawlers(input) {
304
+ if (!input) return { enabled: false, rules: [] };
305
+ if (input === true) return { enabled: true, rules: [] };
306
+ if (typeof input !== "object" || Array.isArray(input)) {
307
+ throw new TypeError("agent.crawlers must be true, false, or an options object.");
308
+ }
309
+ if (input.enabled === false) return { enabled: false, rules: [] };
310
+ for (const key of ["search", "training"]) {
311
+ const policy = input[key];
312
+ if (policy !== void 0 && policy !== "allow" && policy !== "block") {
313
+ throw new TypeError(`agent.crawlers.${key} must be "allow" or "block".`);
314
+ }
315
+ }
316
+ return {
317
+ enabled: true,
318
+ ...input.search ? { search: input.search } : {},
319
+ ...input.training ? { training: input.training } : {},
320
+ rules: resolveRobotsRules(input.rules),
321
+ ...input.sitemap !== void 0 ? { sitemap: resolveSitemapUrls(input.sitemap) } : {}
322
+ };
323
+ }
324
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveFarmAgentCrawlers, "resolveFarmAgentCrawlers");
325
+ function resolveRobotsRules(value) {
326
+ if (value === void 0) return [];
327
+ if (!Array.isArray(value)) {
328
+ throw new TypeError("agent.crawlers.rules must be an array of robots.txt rules.");
329
+ }
330
+ return value.map((rule, index) => {
331
+ const name = `agent.crawlers.rules[${index}]`;
332
+ if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
333
+ throw new TypeError(`${name} must be an object.`);
334
+ }
335
+ const userAgent = readDirectiveValues(rule.userAgent, `${name}.userAgent`);
336
+ if (userAgent.length === 0) {
337
+ throw new TypeError(`${name}.userAgent must name at least one user agent.`);
338
+ }
339
+ const allow = readDirectiveValues(rule.allow, `${name}.allow`);
340
+ const disallow = readDirectiveValues(rule.disallow, `${name}.disallow`);
341
+ if (rule.crawlDelay !== void 0 && (typeof rule.crawlDelay !== "number" || !Number.isFinite(rule.crawlDelay) || rule.crawlDelay < 0)) {
342
+ throw new TypeError(`${name}.crawlDelay must be a number of seconds.`);
343
+ }
344
+ return {
345
+ userAgent,
346
+ ...allow.length ? { allow } : {},
347
+ ...disallow.length ? { disallow } : {},
348
+ ...rule.crawlDelay !== void 0 ? { crawlDelay: rule.crawlDelay } : {}
349
+ };
350
+ });
351
+ }
352
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveRobotsRules, "resolveRobotsRules");
353
+ function readDirectiveValues(value, name) {
354
+ if (value === void 0) return [];
355
+ const values = Array.isArray(value) ? value : [value];
356
+ for (const item of values) {
357
+ if (typeof item !== "string" || !item || LINE_BREAK.test(item)) {
358
+ throw new TypeError(`${name} must be a non-empty string or an array of them.`);
359
+ }
360
+ }
361
+ return values;
362
+ }
363
+ _chunkS3JO3N4Hcjs.__name.call(void 0, readDirectiveValues, "readDirectiveValues");
364
+ function resolveSitemapUrls(value) {
365
+ const values = Array.isArray(value) ? value : [value];
366
+ for (const item of values) {
367
+ if (typeof item !== "string" || !toAbsoluteHttpUrl(item) || LINE_BREAK.test(item)) {
368
+ throw new TypeError("agent.crawlers.sitemap must be an absolute URL or an array of them.");
369
+ }
370
+ }
371
+ return values;
372
+ }
373
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveSitemapUrls, "resolveSitemapUrls");
374
+ function toAbsoluteHttpUrl(value) {
375
+ if (typeof value !== "string" && !(value instanceof URL)) return null;
376
+ try {
377
+ const url = new URL(String(value));
378
+ return url.protocol === "https:" || url.protocol === "http:" ? url : null;
379
+ } catch (e3) {
380
+ return null;
381
+ }
382
+ }
383
+ _chunkS3JO3N4Hcjs.__name.call(void 0, toAbsoluteHttpUrl, "toAbsoluteHttpUrl");
384
+ function createFarmAgentRobots(options) {
385
+ const { crawlers } = options;
386
+ const rules = [];
387
+ for (const group of ["search", "training"]) {
388
+ const policy = crawlers[group];
389
+ if (!policy) continue;
390
+ rules.push({
391
+ userAgent: [...FARM_AI_CRAWLERS[group]],
392
+ ...policy === "allow" ? { allow: "/" } : { disallow: "/" }
393
+ });
394
+ }
395
+ rules.push(...crawlers.rules);
396
+ const namesEveryAgent = crawlers.rules.some(
397
+ (rule) => (Array.isArray(rule.userAgent) ? rule.userAgent : [rule.userAgent]).includes("*")
398
+ );
399
+ if (!namesEveryAgent) rules.push({ userAgent: "*", allow: "/" });
400
+ const sitemap = _nullishCoalesce(crawlers.sitemap, () => ( resolveDefaultSitemap(options)));
401
+ return { rules, ...sitemap.length > 0 ? { sitemap } : {} };
402
+ }
403
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmAgentRobots, "createFarmAgentRobots");
404
+ function resolveDefaultSitemap(options) {
405
+ if (!options.sitemapPath) return [];
406
+ const base = toAbsoluteHttpUrl(options.metadataBase);
407
+ if (!base) return [];
408
+ return [new URL(_chunkI57LW5VZcjs.applyFarmBasePath.call(void 0, options.sitemapPath, options.basePath), base).href];
409
+ }
410
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveDefaultSitemap, "resolveDefaultSitemap");
411
+
412
+ // src/security.ts
413
+ function resolveFarmSecurityConfig(input) {
414
+ if (input === void 0) return { csp: false };
415
+ if (!isPlainRecord(input)) {
416
+ throw new TypeError("security must be an object containing the csp option.");
417
+ }
418
+ if (Object.prototype.hasOwnProperty.call(input, "contentSecurityPolicy")) {
419
+ throw new TypeError(
420
+ "security.contentSecurityPolicy is not supported. Use security.csp instead."
421
+ );
422
+ }
423
+ const csp = input.csp;
424
+ if (csp === void 0 || csp === false) return { csp: false };
425
+ if (typeof csp === "string") {
426
+ return {
427
+ csp: {
428
+ value: validateSerializedCsp(csp),
429
+ reportOnly: false,
430
+ nonce: false
431
+ }
432
+ };
433
+ }
434
+ if (!isPlainRecord(csp)) {
435
+ throw new TypeError("security.csp must be a policy string, false, or an options object.");
436
+ }
437
+ const reportOnly = validateReportOnly(csp.reportOnly);
438
+ const nonce = validateNonce(csp.nonce);
439
+ if (Object.prototype.hasOwnProperty.call(csp, "value")) {
440
+ if (Object.prototype.hasOwnProperty.call(csp, "policy") || Object.prototype.hasOwnProperty.call(csp, "directives")) {
441
+ throw new TypeError(
442
+ "Resolved security.csp values cannot include policy or directives options."
443
+ );
444
+ }
445
+ return {
446
+ csp: {
447
+ value: validateSerializedCsp(csp.value),
448
+ reportOnly,
449
+ nonce
450
+ }
451
+ };
452
+ }
453
+ const { policy, directives } = csp;
454
+ if (policy !== void 0 && directives !== void 0) {
455
+ throw new TypeError("security.csp accepts either policy or directives, not both.");
456
+ }
457
+ if (policy === void 0 && directives === void 0) {
458
+ throw new TypeError("security.csp requires a policy string or directives object.");
459
+ }
460
+ return {
461
+ csp: {
462
+ value: policy !== void 0 ? validateSerializedCsp(policy) : serializeFarmCspDirectives(directives),
463
+ reportOnly,
464
+ nonce
465
+ }
466
+ };
467
+ }
468
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveFarmSecurityConfig, "resolveFarmSecurityConfig");
469
+ function serializeFarmCspDirectives(directives) {
470
+ if (!isPlainRecord(directives)) {
471
+ throw new TypeError("security.csp.directives must be an object.");
472
+ }
473
+ const serialized = [];
474
+ const normalizedNames = /* @__PURE__ */ new Set();
475
+ for (const [configuredName, configuredValue] of Object.entries(directives)) {
476
+ if (configuredValue === false || configuredValue === null || configuredValue === void 0) {
477
+ continue;
478
+ }
479
+ const name = normalizeDirectiveName(configuredName);
480
+ if (normalizedNames.has(name)) {
481
+ throw new TypeError(`security.csp contains the duplicate directive ${JSON.stringify(name)}.`);
482
+ }
483
+ normalizedNames.add(name);
484
+ const values = configuredValue === true ? [] : (Array.isArray(configuredValue) ? configuredValue : [configuredValue]).map(
485
+ validateDirectiveValue
486
+ );
487
+ serialized.push(values.length > 0 ? `${name} ${values.join(" ")}` : name);
488
+ }
489
+ if (serialized.length === 0) {
490
+ throw new TypeError("security.csp.directives must contain at least one enabled directive.");
491
+ }
492
+ return serialized.join("; ");
493
+ }
494
+ _chunkS3JO3N4Hcjs.__name.call(void 0, serializeFarmCspDirectives, "serializeFarmCspDirectives");
495
+ function getFarmSecurityHeader(security, nonce) {
496
+ if (!security.csp) return void 0;
497
+ if (security.csp.nonce && !nonce) return void 0;
498
+ return {
499
+ key: security.csp.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy",
500
+ value: nonce ? applyFarmCspNonceToPolicy(security.csp.value, nonce) : security.csp.value
501
+ };
502
+ }
503
+ _chunkS3JO3N4Hcjs.__name.call(void 0, getFarmSecurityHeader, "getFarmSecurityHeader");
504
+ function createFarmCspNonce(security) {
505
+ if (!security.csp || !security.csp.nonce) return void 0;
506
+ const bytes = new Uint8Array(16);
507
+ globalThis.crypto.getRandomValues(bytes);
508
+ return Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("");
509
+ }
510
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmCspNonce, "createFarmCspNonce");
511
+ function applyFarmCspNonceToPolicy(policy, nonce) {
512
+ validateCspNonce(nonce);
513
+ return applyFarmCspScriptSourcesToPolicy(policy, [`'nonce-${nonce}'`]);
514
+ }
515
+ _chunkS3JO3N4Hcjs.__name.call(void 0, applyFarmCspNonceToPolicy, "applyFarmCspNonceToPolicy");
516
+ function applyFarmCspHashesToPolicy(policy, hashes) {
517
+ const sources = hashes.map((hash) => {
518
+ if (!/^sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2}$/.test(hash)) {
519
+ throw new TypeError(`Invalid CSP script hash: ${JSON.stringify(hash)}.`);
520
+ }
521
+ return `'${hash}'`;
522
+ });
523
+ return applyFarmCspScriptSourcesToPolicy(policy, sources);
524
+ }
525
+ _chunkS3JO3N4Hcjs.__name.call(void 0, applyFarmCspHashesToPolicy, "applyFarmCspHashesToPolicy");
526
+ function applyFarmCspScriptSourcesToPolicy(policy, sources) {
527
+ const uniqueSources = [...new Set(sources)];
528
+ if (uniqueSources.length === 0) return policy;
529
+ const segments = policy.split(";").map((segment) => segment.trim()).filter(Boolean);
530
+ const names = segments.map((segment) => segment.split(/\s+/, 1)[0].toLowerCase());
531
+ const governingName = names.includes("script-src-elem") ? "script-src-elem" : names.includes("script-src") ? "script-src" : names.includes("default-src") ? "default-src" : void 0;
532
+ if (!governingName) return `${policy}; script-src ${uniqueSources.join(" ")}`;
533
+ return segments.map((segment, index) => {
534
+ if (names[index] !== governingName) return segment;
535
+ const existing = new Set(segment.split(/\s+/));
536
+ const missing = uniqueSources.filter((source) => !existing.has(source));
537
+ return missing.length > 0 ? `${segment} ${missing.join(" ")}` : segment;
538
+ }).join("; ");
539
+ }
540
+ _chunkS3JO3N4Hcjs.__name.call(void 0, applyFarmCspScriptSourcesToPolicy, "applyFarmCspScriptSourcesToPolicy");
541
+ function addFarmCspNonceToScriptTags(html, nonce) {
542
+ validateCspNonce(nonce);
543
+ return createFarmCspNonceRewriter(nonce).write(html, true);
544
+ }
545
+ _chunkS3JO3N4Hcjs.__name.call(void 0, addFarmCspNonceToScriptTags, "addFarmCspNonceToScriptTags");
546
+ function removeFarmCspNoncesFromScriptTags(html) {
547
+ return createFarmScriptTagRewriter(stripScriptNonceAttribute).write(html, true);
548
+ }
549
+ _chunkS3JO3N4Hcjs.__name.call(void 0, removeFarmCspNoncesFromScriptTags, "removeFarmCspNoncesFromScriptTags");
550
+ async function createFarmCspScriptHashes(html) {
551
+ const hashes = [];
552
+ const seen = /* @__PURE__ */ new Set();
553
+ for (const content of collectFarmInlineScriptContents(html)) {
554
+ const digest = await globalThis.crypto.subtle.digest(
555
+ "SHA-256",
556
+ new TextEncoder().encode(content)
557
+ );
558
+ let binary = "";
559
+ for (const byte of new Uint8Array(digest)) binary += String.fromCharCode(byte);
560
+ const hash = `sha256-${globalThis.btoa(binary)}`;
561
+ if (!seen.has(hash)) {
562
+ seen.add(hash);
563
+ hashes.push(hash);
564
+ }
565
+ }
566
+ return hashes;
567
+ }
568
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmCspScriptHashes, "createFarmCspScriptHashes");
569
+ async function applyFarmCspHashesToHtml(html, security) {
570
+ if (!security.csp || !security.csp.nonce) return void 0;
571
+ const staticHtml = removeFarmCspNoncesFromScriptTags(html);
572
+ const hashes = await createFarmCspScriptHashes(staticHtml);
573
+ return {
574
+ html: staticHtml,
575
+ header: {
576
+ key: security.csp.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy",
577
+ value: applyFarmCspHashesToPolicy(security.csp.value, hashes)
578
+ }
579
+ };
580
+ }
581
+ _chunkS3JO3N4Hcjs.__name.call(void 0, applyFarmCspHashesToHtml, "applyFarmCspHashesToHtml");
582
+ function applyFarmCspNonceToResponse(response, security) {
583
+ if (!security.csp || !security.csp.nonce) return response;
584
+ if (!_optionalChain([response, 'access', _23 => _23.headers, 'access', _24 => _24.get, 'call', _25 => _25("content-type"), 'optionalAccess', _26 => _26.toLowerCase, 'call', _27 => _27(), 'access', _28 => _28.includes, 'call', _29 => _29("text/html")])) return response;
585
+ const nonce = createFarmCspNonce(security);
586
+ const securityHeader = getFarmSecurityHeader(security, nonce);
587
+ const headers = new Headers(response.headers);
588
+ headers.set(securityHeader.key, securityHeader.value);
589
+ headers.delete("content-length");
590
+ if (!response.body) {
591
+ return new Response(null, {
592
+ status: response.status,
593
+ statusText: response.statusText,
594
+ headers
595
+ });
596
+ }
597
+ const decoder = new TextDecoder();
598
+ const encoder = new TextEncoder();
599
+ const rewriter = createFarmCspNonceRewriter(nonce);
600
+ const body = response.body.pipeThrough(
601
+ new TransformStream({
602
+ transform(chunk, controller) {
603
+ const output = rewriter.write(decoder.decode(chunk, { stream: true }));
604
+ if (output) controller.enqueue(encoder.encode(output));
605
+ },
606
+ flush(controller) {
607
+ const output = rewriter.write(decoder.decode(), true);
608
+ if (output) controller.enqueue(encoder.encode(output));
609
+ }
610
+ })
611
+ );
612
+ return new Response(body, {
613
+ status: response.status,
614
+ statusText: response.statusText,
615
+ headers
616
+ });
617
+ }
618
+ _chunkS3JO3N4Hcjs.__name.call(void 0, applyFarmCspNonceToResponse, "applyFarmCspNonceToResponse");
619
+ function farmCspBlocksFrameworkInlineScripts(security) {
620
+ if (!security.csp) return false;
621
+ if (security.csp.nonce) return false;
622
+ const directives = parseCspDirectives(security.csp.value);
623
+ const governing = _nullishCoalesce(_nullishCoalesce(directives.get("script-src-elem"), () => ( directives.get("script-src"))), () => ( directives.get("default-src")));
624
+ if (!governing) return false;
625
+ const sources = governing.map((source) => source.toLowerCase());
626
+ const disablesUnsafeInline = sources.some(
627
+ (value) => value === "'strict-dynamic'" || value.startsWith("'nonce-") || value.startsWith("'sha256-") || value.startsWith("'sha384-") || value.startsWith("'sha512-")
628
+ );
629
+ return !sources.includes("'unsafe-inline'") || disablesUnsafeInline;
630
+ }
631
+ _chunkS3JO3N4Hcjs.__name.call(void 0, farmCspBlocksFrameworkInlineScripts, "farmCspBlocksFrameworkInlineScripts");
632
+ function parseCspDirectives(value) {
633
+ const directives = /* @__PURE__ */ new Map();
634
+ for (const segment of value.split(";")) {
635
+ const parts = segment.trim().split(/\s+/).filter(Boolean);
636
+ if (parts.length === 0) continue;
637
+ const name = parts[0].toLowerCase();
638
+ if (!directives.has(name)) directives.set(name, parts.slice(1));
639
+ }
640
+ return directives;
641
+ }
642
+ _chunkS3JO3N4Hcjs.__name.call(void 0, parseCspDirectives, "parseCspDirectives");
643
+ function normalizeDirectiveName(value) {
644
+ const name = value.trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
645
+ if (!/^[a-z][a-z0-9-]*$/.test(name)) {
646
+ throw new TypeError(`Invalid security.csp directive name: ${JSON.stringify(value)}.`);
647
+ }
648
+ return name;
649
+ }
650
+ _chunkS3JO3N4Hcjs.__name.call(void 0, normalizeDirectiveName, "normalizeDirectiveName");
651
+ function validateDirectiveValue(value) {
652
+ if (typeof value !== "string") {
653
+ throw new TypeError("security.csp directive values must be strings or booleans.");
654
+ }
655
+ const normalized = value.trim();
656
+ if (!normalized || /[;\r\n]/.test(normalized) || normalized.includes("\0")) {
657
+ throw new TypeError(`Invalid security.csp directive value: ${JSON.stringify(value)}.`);
658
+ }
659
+ return normalized;
660
+ }
661
+ _chunkS3JO3N4Hcjs.__name.call(void 0, validateDirectiveValue, "validateDirectiveValue");
662
+ function validateSerializedCsp(value) {
663
+ if (typeof value !== "string") {
664
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
665
+ }
666
+ const normalized = value.trim().replace(/;+$/g, "").trim();
667
+ if (!normalized || /[\r\n]/.test(normalized) || normalized.includes("\0")) {
668
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
669
+ }
670
+ return normalized;
671
+ }
672
+ _chunkS3JO3N4Hcjs.__name.call(void 0, validateSerializedCsp, "validateSerializedCsp");
673
+ function validateReportOnly(value) {
674
+ if (value === void 0) return false;
675
+ if (typeof value !== "boolean") {
676
+ throw new TypeError("security.csp.reportOnly must be a boolean.");
677
+ }
678
+ return value;
679
+ }
680
+ _chunkS3JO3N4Hcjs.__name.call(void 0, validateReportOnly, "validateReportOnly");
681
+ function validateNonce(value) {
682
+ if (value === void 0) return false;
683
+ if (typeof value !== "boolean") {
684
+ throw new TypeError("security.csp.nonce must be a boolean.");
685
+ }
686
+ return value;
687
+ }
688
+ _chunkS3JO3N4Hcjs.__name.call(void 0, validateNonce, "validateNonce");
689
+ function validateCspNonce(value) {
690
+ if (!/^[A-Za-z0-9+/_-]+={0,2}$/.test(value)) {
691
+ throw new TypeError("A CSP nonce must be a base64 or base64url value.");
692
+ }
693
+ }
694
+ _chunkS3JO3N4Hcjs.__name.call(void 0, validateCspNonce, "validateCspNonce");
695
+ function createFarmCspNonceRewriter(nonce) {
696
+ validateCspNonce(nonce);
697
+ return createFarmScriptTagRewriter((tag) => stampScriptTag(tag, nonce));
698
+ }
699
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmCspNonceRewriter, "createFarmCspNonceRewriter");
700
+ function createFarmScriptTagRewriter(transformScriptTag) {
701
+ let pending = "";
702
+ let rawTextElement;
703
+ return {
704
+ write(chunk, final = false) {
705
+ pending += chunk;
706
+ let output = "";
707
+ while (pending) {
708
+ if (rawTextElement) {
709
+ if (rawTextElement === "plaintext") {
710
+ output += pending;
711
+ pending = "";
712
+ break;
713
+ }
714
+ const closing = `</${rawTextElement}`;
715
+ const start2 = findRawTextEnd(pending, rawTextElement);
716
+ if (start2 === -1) {
717
+ if (final) {
718
+ output += pending;
719
+ pending = "";
720
+ } else {
721
+ const keep = matchingSuffixLength(pending, closing);
722
+ output += pending.slice(0, pending.length - keep);
723
+ pending = pending.slice(pending.length - keep);
724
+ }
725
+ break;
726
+ }
727
+ output += pending.slice(0, start2);
728
+ pending = pending.slice(start2);
729
+ const end2 = findHtmlTagEnd(pending);
730
+ if (end2 === -1) {
731
+ if (final) {
732
+ output += pending;
733
+ pending = "";
734
+ }
735
+ break;
736
+ }
737
+ output += pending.slice(0, end2 + 1);
738
+ pending = pending.slice(end2 + 1);
739
+ rawTextElement = void 0;
740
+ continue;
741
+ }
742
+ const start = pending.indexOf("<");
743
+ if (start === -1) {
744
+ output += pending;
745
+ pending = "";
746
+ break;
747
+ }
748
+ output += pending.slice(0, start);
749
+ pending = pending.slice(start);
750
+ if (pending.startsWith("<!--")) {
751
+ const end2 = pending.indexOf("-->", 4);
752
+ if (end2 === -1) {
753
+ if (final) {
754
+ output += pending;
755
+ pending = "";
756
+ }
757
+ break;
758
+ }
759
+ output += pending.slice(0, end2 + 3);
760
+ pending = pending.slice(end2 + 3);
761
+ continue;
762
+ }
763
+ if (!final && "<!--".startsWith(pending)) break;
764
+ const tagNameMatch = pending.match(/^<\/?([a-z][a-z0-9:-]*)\b/i);
765
+ if (!tagNameMatch) {
766
+ if (!final && /^<\/?[a-z][a-z0-9:-]*$/i.test(pending)) break;
767
+ output += pending[0];
768
+ pending = pending.slice(1);
769
+ continue;
770
+ }
771
+ const end = findHtmlTagEnd(pending);
772
+ if (end === -1) {
773
+ if (!final) break;
774
+ output += pending;
775
+ pending = "";
776
+ break;
777
+ }
778
+ const tag = pending.slice(0, end + 1);
779
+ const tagName = tagNameMatch[1].toLowerCase();
780
+ const isClosing = pending.startsWith("</");
781
+ const isSelfClosing = /\/\s*>$/.test(tag);
782
+ output += !isClosing && tagName === "script" ? transformScriptTag(tag) : tag;
783
+ pending = pending.slice(end + 1);
784
+ if (!isClosing && !isSelfClosing && rawTextElements.has(tagName)) {
785
+ rawTextElement = tagName;
786
+ }
787
+ }
788
+ return output;
789
+ }
790
+ };
791
+ }
792
+ _chunkS3JO3N4Hcjs.__name.call(void 0, createFarmScriptTagRewriter, "createFarmScriptTagRewriter");
793
+ var rawTextElements = /* @__PURE__ */ new Map([
794
+ ["iframe", /<\/iframe(?=[\s/>]|$)/gi],
795
+ ["noembed", /<\/noembed(?=[\s/>]|$)/gi],
796
+ ["noframes", /<\/noframes(?=[\s/>]|$)/gi],
797
+ ["plaintext", null],
798
+ ["script", /<\/script(?=[\s/>]|$)/gi],
799
+ ["style", /<\/style(?=[\s/>]|$)/gi],
800
+ ["textarea", /<\/textarea(?=[\s/>]|$)/gi],
801
+ ["title", /<\/title(?=[\s/>]|$)/gi],
802
+ ["xmp", /<\/xmp(?=[\s/>]|$)/gi]
803
+ ]);
804
+ function stampScriptTag(tag, nonce) {
805
+ const opening = _optionalChain([tag, 'access', _30 => _30.match, 'call', _31 => _31(/^<script\b/i), 'optionalAccess', _32 => _32[0]]);
806
+ if (!opening) return tag;
807
+ const attributes = stripScriptNonceAttribute(tag).slice(opening.length, -1);
808
+ return `<script nonce="${nonce}"${attributes}>`;
809
+ }
810
+ _chunkS3JO3N4Hcjs.__name.call(void 0, stampScriptTag, "stampScriptTag");
811
+ function stripScriptNonceAttribute(tag) {
812
+ let normalized = tag;
813
+ let range = findScriptTagAttributeRange(normalized, "nonce");
814
+ while (range) {
815
+ normalized = normalized.slice(0, range.start) + normalized.slice(range.end);
816
+ range = findScriptTagAttributeRange(normalized, "nonce");
817
+ }
818
+ return normalized;
819
+ }
820
+ _chunkS3JO3N4Hcjs.__name.call(void 0, stripScriptNonceAttribute, "stripScriptNonceAttribute");
821
+ function collectFarmInlineScriptContents(html) {
822
+ const contents = [];
823
+ let offset = 0;
824
+ while (offset < html.length) {
825
+ const start = html.indexOf("<", offset);
826
+ if (start === -1) break;
827
+ if (html.startsWith("<!--", start)) {
828
+ const commentEnd = html.indexOf("-->", start + 4);
829
+ offset = commentEnd === -1 ? html.length : commentEnd + 3;
830
+ continue;
831
+ }
832
+ const remaining = html.slice(start);
833
+ const tagNameMatch = remaining.match(/^<\/?([a-z][a-z0-9:-]*)\b/i);
834
+ if (!tagNameMatch) {
835
+ offset = start + 1;
836
+ continue;
837
+ }
838
+ const tagEnd = findHtmlTagEnd(remaining);
839
+ if (tagEnd === -1) break;
840
+ const tag = remaining.slice(0, tagEnd + 1);
841
+ const tagName = tagNameMatch[1].toLowerCase();
842
+ const isClosing = remaining.startsWith("</");
843
+ const isSelfClosing = /\/\s*>$/.test(tag);
844
+ offset = start + tagEnd + 1;
845
+ if (isClosing || isSelfClosing || !rawTextElements.has(tagName)) continue;
846
+ if (tagName === "plaintext") break;
847
+ const closingStart = findRawTextEnd(html, tagName, offset);
848
+ const contentEnd = closingStart === -1 ? html.length : closingStart;
849
+ if (tagName === "script" && !findScriptTagAttributeRange(tag, "src")) {
850
+ contents.push(html.slice(offset, contentEnd));
851
+ }
852
+ if (closingStart === -1) break;
853
+ const closingEnd = findHtmlTagEnd(html.slice(contentEnd));
854
+ if (closingEnd === -1) break;
855
+ offset = contentEnd + closingEnd + 1;
856
+ }
857
+ return contents;
858
+ }
859
+ _chunkS3JO3N4Hcjs.__name.call(void 0, collectFarmInlineScriptContents, "collectFarmInlineScriptContents");
860
+ function findScriptTagAttributeRange(tag, expectedName) {
861
+ const opening = _optionalChain([tag, 'access', _33 => _33.match, 'call', _34 => _34(/^<script\b/i), 'optionalAccess', _35 => _35[0]]);
862
+ if (!opening) return void 0;
863
+ let offset = opening.length;
864
+ while (offset < tag.length - 1) {
865
+ const whitespaceStart = offset;
866
+ while (/\s/.test(tag[offset] || "")) offset++;
867
+ if (tag[offset] === "/" || tag[offset] === ">" || offset >= tag.length - 1) break;
868
+ const nameStart = offset;
869
+ while (offset < tag.length && !/[\s=/>]/.test(tag[offset])) offset++;
870
+ const name = tag.slice(nameStart, offset).toLowerCase();
871
+ while (/\s/.test(tag[offset] || "")) offset++;
872
+ if (tag[offset] === "=") {
873
+ offset++;
874
+ while (/\s/.test(tag[offset] || "")) offset++;
875
+ const quote = tag[offset] === '"' || tag[offset] === "'" ? tag[offset++] : void 0;
876
+ if (quote) {
877
+ while (offset < tag.length && tag[offset] !== quote) offset++;
878
+ if (tag[offset] === quote) offset++;
879
+ } else {
880
+ while (offset < tag.length && !/[\s>]/.test(tag[offset])) offset++;
881
+ }
882
+ }
883
+ if (name === expectedName) return { start: whitespaceStart, end: offset };
884
+ }
885
+ return void 0;
886
+ }
887
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findScriptTagAttributeRange, "findScriptTagAttributeRange");
888
+ function findRawTextEnd(input, tagName, offset = 0) {
889
+ const closing = rawTextElements.get(tagName);
890
+ closing.lastIndex = offset;
891
+ return _nullishCoalesce(_optionalChain([closing, 'access', _36 => _36.exec, 'call', _37 => _37(input), 'optionalAccess', _38 => _38.index]), () => ( -1));
892
+ }
893
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findRawTextEnd, "findRawTextEnd");
894
+ function matchingSuffixLength(input, token) {
895
+ const limit = Math.min(token.length - 1, input.length);
896
+ for (let length = limit; length > 0; length--) {
897
+ if (token.startsWith(input.slice(-length).toLowerCase())) return length;
898
+ }
899
+ return 0;
900
+ }
901
+ _chunkS3JO3N4Hcjs.__name.call(void 0, matchingSuffixLength, "matchingSuffixLength");
902
+ function findHtmlTagEnd(tag) {
903
+ let quote;
904
+ for (let index = 1; index < tag.length; index++) {
905
+ const character = tag[index];
906
+ if (quote) {
907
+ if (character === quote) quote = void 0;
908
+ } else if (character === '"' || character === "'") {
909
+ quote = character;
910
+ } else if (character === ">") {
911
+ return index;
912
+ }
913
+ }
914
+ return -1;
915
+ }
916
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findHtmlTagEnd, "findHtmlTagEnd");
917
+ function isPlainRecord(value) {
918
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
919
+ const prototype = Object.getPrototypeOf(value);
920
+ return prototype === Object.prototype || prototype === null;
921
+ }
922
+ _chunkS3JO3N4Hcjs.__name.call(void 0, isPlainRecord, "isPlainRecord");
923
+
924
+ // src/preload.ts
925
+ var DEFAULT_PRELOAD_CONFIG = {
926
+ mode: "enforce",
927
+ maxImages: 1,
928
+ maxFonts: 2
929
+ };
930
+ var reportedWarnings = /* @__PURE__ */ new Map();
931
+ var nextWarningExpiry = Infinity;
932
+ var PRELOAD_WARNING_TTL_MS = 6e4;
933
+ var MAX_REPORTED_PRELOAD_WARNINGS = 256;
934
+ function resolveFarmPerformanceConfig(config) {
935
+ return {
936
+ preload: {
937
+ mode: _optionalChain([config, 'optionalAccess', _39 => _39.preload, 'optionalAccess', _40 => _40.mode]) === "warn" ? "warn" : "enforce",
938
+ maxImages: normalizeBudget(_optionalChain([config, 'optionalAccess', _41 => _41.preload, 'optionalAccess', _42 => _42.maxImages]), DEFAULT_PRELOAD_CONFIG.maxImages),
939
+ maxFonts: normalizeBudget(_optionalChain([config, 'optionalAccess', _43 => _43.preload, 'optionalAccess', _44 => _44.maxFonts]), DEFAULT_PRELOAD_CONFIG.maxFonts)
940
+ }
941
+ };
942
+ }
943
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveFarmPerformanceConfig, "resolveFarmPerformanceConfig");
944
+ function manageFarmHtmlPreloads(html, config) {
945
+ const elements = findHtmlLinkElements(html);
946
+ const candidates = elements.flatMap((element, index) => {
947
+ const kind = getHtmlPreloadKind(element.value);
948
+ return kind ? [
949
+ {
950
+ index,
951
+ kind,
952
+ href: readHtmlAttribute(element.value, "href"),
953
+ highPriority: _optionalChain([readHtmlAttribute, 'call', _45 => _45(element.value, "fetchpriority"), 'optionalAccess', _46 => _46.toLowerCase, 'call', _47 => _47()]) === "high"
954
+ }
955
+ ] : [];
956
+ });
957
+ const budget = selectPreloadsWithinBudget(candidates, config);
958
+ if (config.mode === "warn" || budget.removed.size === 0) {
959
+ return { value: html, warnings: budget.warnings };
960
+ }
961
+ return {
962
+ value: removeHtmlLinkElements(html, elements, budget.removed),
963
+ warnings: budget.warnings
964
+ };
965
+ }
966
+ _chunkS3JO3N4Hcjs.__name.call(void 0, manageFarmHtmlPreloads, "manageFarmHtmlPreloads");
967
+ function manageFarmLinkHeaderPreloads(value, config) {
968
+ if (!value) return { value, warnings: [] };
969
+ const links = splitLinkHeader(value);
970
+ const candidates = links.flatMap((link, index) => {
971
+ const kind = getLinkHeaderPreloadKind(link);
972
+ return kind ? [
973
+ {
974
+ index,
975
+ kind,
976
+ href: getLinkHeaderTarget(link),
977
+ highPriority: _optionalChain([getLinkHeaderParameter, 'call', _48 => _48(link, "fetchpriority"), 'optionalAccess', _49 => _49.toLowerCase, 'call', _50 => _50()]) === "high"
978
+ }
979
+ ] : [];
980
+ });
981
+ const budget = selectPreloadsWithinBudget(candidates, config);
982
+ return {
983
+ value: config.mode === "enforce" ? links.filter((_, index) => !budget.removed.has(index)).join(", ") : value,
984
+ warnings: budget.warnings
985
+ };
986
+ }
987
+ _chunkS3JO3N4Hcjs.__name.call(void 0, manageFarmLinkHeaderPreloads, "manageFarmLinkHeaderPreloads");
988
+ function manageFarmDocumentPreloads(html, linkHeader, config) {
989
+ const elements = findHtmlLinkElements(html);
990
+ const links = linkHeader ? splitLinkHeader(linkHeader) : [];
991
+ const headerOffset = elements.length;
992
+ const candidates = [];
993
+ for (const [index, element] of elements.entries()) {
994
+ const kind = getHtmlPreloadKind(element.value);
995
+ if (!kind) continue;
996
+ candidates.push({
997
+ index,
998
+ kind,
999
+ href: readHtmlAttribute(element.value, "href"),
1000
+ highPriority: _optionalChain([readHtmlAttribute, 'call', _51 => _51(element.value, "fetchpriority"), 'optionalAccess', _52 => _52.toLowerCase, 'call', _53 => _53()]) === "high"
1001
+ });
1002
+ }
1003
+ for (const [index, link] of links.entries()) {
1004
+ const kind = getLinkHeaderPreloadKind(link);
1005
+ if (!kind) continue;
1006
+ candidates.push({
1007
+ index: headerOffset + index,
1008
+ kind,
1009
+ href: getLinkHeaderTarget(link),
1010
+ highPriority: _optionalChain([getLinkHeaderParameter, 'call', _54 => _54(link, "fetchpriority"), 'optionalAccess', _55 => _55.toLowerCase, 'call', _56 => _56()]) === "high"
1011
+ });
1012
+ }
1013
+ const budget = selectPreloadsWithinBudget(candidates, config);
1014
+ if (config.mode === "warn" || budget.removed.size === 0) {
1015
+ return { html, linkHeader, warnings: budget.warnings };
1016
+ }
1017
+ return {
1018
+ html: removeHtmlLinkElements(html, elements, budget.removed),
1019
+ linkHeader: links.filter((_, index) => !budget.removed.has(headerOffset + index)).join(", "),
1020
+ warnings: budget.warnings
1021
+ };
1022
+ }
1023
+ _chunkS3JO3N4Hcjs.__name.call(void 0, manageFarmDocumentPreloads, "manageFarmDocumentPreloads");
1024
+ function reportFarmPreloadWarnings(warnings, context = "the rendered document") {
1025
+ if (warnings.length === 0 && reportedWarnings.size === 0) return;
1026
+ const now = Date.now();
1027
+ if (now >= nextWarningExpiry) {
1028
+ nextWarningExpiry = Infinity;
1029
+ for (const [key, reportedAt] of reportedWarnings) {
1030
+ const expiresAt = reportedAt + PRELOAD_WARNING_TTL_MS;
1031
+ if (now >= expiresAt) reportedWarnings.delete(key);
1032
+ else nextWarningExpiry = Math.min(nextWarningExpiry, expiresAt);
1033
+ }
1034
+ }
1035
+ for (const warning of warnings) {
1036
+ const key = `${context}:${warning.kind}:${warning.count}:${warning.budget}:${warning.removed}`;
1037
+ const reportedAt = reportedWarnings.get(key);
1038
+ if (reportedAt !== void 0 && now - reportedAt < PRELOAD_WARNING_TTL_MS) continue;
1039
+ reportedWarnings.set(key, now);
1040
+ nextWarningExpiry = Math.min(nextWarningExpiry, now + PRELOAD_WARNING_TTL_MS);
1041
+ while (reportedWarnings.size > MAX_REPORTED_PRELOAD_WARNINGS) {
1042
+ const oldest = reportedWarnings.keys().next().value;
1043
+ if (oldest === void 0) break;
1044
+ reportedWarnings.delete(oldest);
1045
+ }
1046
+ const action = warning.removed > 0 ? ` Removed ${warning.removed} lower-priority hint(s).` : "";
1047
+ const recommendation = warning.kind === "image" ? ' Mark only the LCP image with `preload` or `fetchPriority="high"`.' : " Set `preload: false` on fonts that are not required above the fold.";
1048
+ console.warn(
1049
+ `[Farm.js] ${context} emitted ${warning.count} ${warning.kind} preload hints (budget: ${warning.budget}).${action}${recommendation}`
1050
+ );
1051
+ }
1052
+ }
1053
+ _chunkS3JO3N4Hcjs.__name.call(void 0, reportFarmPreloadWarnings, "reportFarmPreloadWarnings");
1054
+ function selectPreloadsWithinBudget(candidates, config) {
1055
+ const removed = /* @__PURE__ */ new Set();
1056
+ const warnings = [];
1057
+ for (const kind of ["image", "font"]) {
1058
+ const resources = /* @__PURE__ */ new Map();
1059
+ for (const candidate of candidates) {
1060
+ if (candidate.kind !== kind) continue;
1061
+ const key = _nullishCoalesce(candidate.href, () => ( `#${candidate.index}`));
1062
+ const hints = resources.get(key);
1063
+ if (hints) hints.push(candidate);
1064
+ else resources.set(key, [candidate]);
1065
+ }
1066
+ const limit = kind === "image" ? config.maxImages : config.maxFonts;
1067
+ if (resources.size <= limit) continue;
1068
+ const ranked = [...resources.values()].map((hints) => ({
1069
+ hints,
1070
+ index: hints[0].index,
1071
+ highPriority: hints.some((hint) => hint.highPriority)
1072
+ })).sort(
1073
+ (left, right) => Number(right.highPriority) - Number(left.highPriority) || left.index - right.index
1074
+ );
1075
+ if (config.mode === "enforce") {
1076
+ for (const resource of ranked.slice(limit)) {
1077
+ for (const hint of resource.hints) removed.add(hint.index);
1078
+ }
1079
+ }
1080
+ warnings.push({
1081
+ kind,
1082
+ count: resources.size,
1083
+ budget: limit,
1084
+ removed: config.mode === "enforce" ? resources.size - limit : 0
1085
+ });
1086
+ }
1087
+ return { removed, warnings };
1088
+ }
1089
+ _chunkS3JO3N4Hcjs.__name.call(void 0, selectPreloadsWithinBudget, "selectPreloadsWithinBudget");
1090
+ function getHtmlPreloadKind(link) {
1091
+ const rel = _optionalChain([readHtmlAttribute, 'call', _57 => _57(link, "rel"), 'optionalAccess', _58 => _58.toLowerCase, 'call', _59 => _59(), 'access', _60 => _60.split, 'call', _61 => _61(/\s+/)]) || [];
1092
+ if (!rel.includes("preload")) return void 0;
1093
+ return normalizePreloadKind(readHtmlAttribute(link, "as"));
1094
+ }
1095
+ _chunkS3JO3N4Hcjs.__name.call(void 0, getHtmlPreloadKind, "getHtmlPreloadKind");
1096
+ function getLinkHeaderPreloadKind(link) {
1097
+ const relations = _nullishCoalesce(_optionalChain([getLinkHeaderParameter, 'call', _62 => _62(link, "rel"), 'optionalAccess', _63 => _63.toLowerCase, 'call', _64 => _64(), 'access', _65 => _65.split, 'call', _66 => _66(/\s+/)]), () => ( []));
1098
+ if (!relations.includes("preload")) return void 0;
1099
+ return normalizePreloadKind(getLinkHeaderParameter(link, "as"));
1100
+ }
1101
+ _chunkS3JO3N4Hcjs.__name.call(void 0, getLinkHeaderPreloadKind, "getLinkHeaderPreloadKind");
1102
+ function getLinkHeaderTarget(link) {
1103
+ const start = link.indexOf("<");
1104
+ const end = link.indexOf(">", start + 1);
1105
+ return start === -1 || end === -1 ? void 0 : link.slice(start + 1, end).trim();
1106
+ }
1107
+ _chunkS3JO3N4Hcjs.__name.call(void 0, getLinkHeaderTarget, "getLinkHeaderTarget");
1108
+ function getLinkHeaderParameter(link, name) {
1109
+ const uriEnd = link.indexOf(">");
1110
+ if (uriEnd === -1) return void 0;
1111
+ for (const parameter of splitLinkParameters(link.slice(uriEnd + 1))) {
1112
+ const separator = parameter.indexOf("=");
1113
+ const parameterName = (separator === -1 ? parameter : parameter.slice(0, separator)).trim().toLowerCase();
1114
+ if (parameterName !== name.toLowerCase() || separator === -1) continue;
1115
+ const rawValue = parameter.slice(separator + 1).trim();
1116
+ if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
1117
+ return rawValue.slice(1, -1).replace(/\\([\\"])/g, "$1");
1118
+ }
1119
+ return rawValue;
1120
+ }
1121
+ return void 0;
1122
+ }
1123
+ _chunkS3JO3N4Hcjs.__name.call(void 0, getLinkHeaderParameter, "getLinkHeaderParameter");
1124
+ function splitLinkParameters(value) {
1125
+ const parameters = [];
1126
+ let start = 0;
1127
+ let quoted = false;
1128
+ for (let index = 0; index < value.length; index += 1) {
1129
+ const character = value[index];
1130
+ if (character === '"' && !isEscaped(value, index)) quoted = !quoted;
1131
+ else if (character === ";" && !quoted) {
1132
+ const parameter2 = value.slice(start, index).trim();
1133
+ if (parameter2) parameters.push(parameter2);
1134
+ start = index + 1;
1135
+ }
1136
+ }
1137
+ const parameter = value.slice(start).trim();
1138
+ if (parameter) parameters.push(parameter);
1139
+ return parameters;
1140
+ }
1141
+ _chunkS3JO3N4Hcjs.__name.call(void 0, splitLinkParameters, "splitLinkParameters");
1142
+ function normalizePreloadKind(value) {
1143
+ const normalized = _optionalChain([value, 'optionalAccess', _67 => _67.toLowerCase, 'call', _68 => _68()]);
1144
+ return normalized === "image" || normalized === "font" ? normalized : void 0;
1145
+ }
1146
+ _chunkS3JO3N4Hcjs.__name.call(void 0, normalizePreloadKind, "normalizePreloadKind");
1147
+ function readHtmlAttribute(element, name) {
1148
+ const match = element.match(
1149
+ new RegExp(`\\s${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i")
1150
+ );
1151
+ return _nullishCoalesce(_nullishCoalesce(_optionalChain([match, 'optionalAccess', _69 => _69[1]]), () => ( _optionalChain([match, 'optionalAccess', _70 => _70[2]]))), () => ( _optionalChain([match, 'optionalAccess', _71 => _71[3]])));
1152
+ }
1153
+ _chunkS3JO3N4Hcjs.__name.call(void 0, readHtmlAttribute, "readHtmlAttribute");
1154
+ function findHtmlLinkElements(html) {
1155
+ const lastToken = typeof html === "string" ? findLastPreloadToken(html) : Infinity;
1156
+ if (lastToken === -1) return [];
1157
+ const elements = [];
1158
+ let lowerHtml = foldHtmlTagCase(
1159
+ lastToken === Infinity ? html : html.slice(0, lastToken + RAW_TEXT_TAG_LOOKAHEAD)
1160
+ );
1161
+ const rawTextTag = /<(script|style|template|textarea|title|noscript|svg)(?=[\s/>])/y;
1162
+ const linkTag = /<link(?=[\s/>])/iy;
1163
+ const ordinaryTag = /<\/?[A-Za-z][\w:-]*(?=[\s/>])/y;
1164
+ let cursor = 0;
1165
+ while (cursor < html.length) {
1166
+ const start = html.indexOf("<", cursor);
1167
+ if (start === -1 || start > lastToken) break;
1168
+ if (html.startsWith("<!--", start)) {
1169
+ const commentEnd = html.indexOf("-->", start + 4);
1170
+ cursor = commentEnd === -1 ? html.length : commentEnd + 3;
1171
+ continue;
1172
+ }
1173
+ rawTextTag.lastIndex = start;
1174
+ const rawText = rawTextTag.exec(lowerHtml);
1175
+ if (_optionalChain([rawText, 'optionalAccess', _72 => _72[1]])) {
1176
+ const openingEnd = findHtmlTagEnd2(html, start);
1177
+ if (openingEnd === -1) break;
1178
+ if (rawText[1] === "svg" && html[openingEnd - 2] === "/") {
1179
+ cursor = openingEnd;
1180
+ continue;
1181
+ }
1182
+ let closingStart = findHtmlClosingTag(lowerHtml, rawText[1], openingEnd);
1183
+ if (closingStart === -1 && lowerHtml.length < html.length) {
1184
+ lowerHtml = foldHtmlTagCase(html);
1185
+ closingStart = findHtmlClosingTag(lowerHtml, rawText[1], openingEnd);
1186
+ }
1187
+ if (closingStart === -1) {
1188
+ cursor = html.length;
1189
+ continue;
1190
+ }
1191
+ const closingEnd = findHtmlTagEnd2(html, closingStart);
1192
+ cursor = closingEnd === -1 ? html.length : closingEnd;
1193
+ continue;
1194
+ }
1195
+ linkTag.lastIndex = start;
1196
+ if (linkTag.test(html)) {
1197
+ const end = findHtmlTagEnd2(html, start);
1198
+ if (end === -1) break;
1199
+ elements.push({ start, end, value: html.slice(start, end) });
1200
+ cursor = end;
1201
+ continue;
1202
+ }
1203
+ ordinaryTag.lastIndex = start;
1204
+ if (ordinaryTag.test(html)) {
1205
+ const end = findHtmlTagEnd2(html, start);
1206
+ cursor = end === -1 ? html.length : end;
1207
+ continue;
1208
+ }
1209
+ cursor = start + 1;
1210
+ }
1211
+ return elements;
1212
+ }
1213
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findHtmlLinkElements, "findHtmlLinkElements");
1214
+ var RAW_TEXT_TAG_LOOKAHEAD = 16;
1215
+ var PRELOAD_TOKEN = /\bpreload\b/gi;
1216
+ function findLastPreloadToken(html) {
1217
+ let last = -1;
1218
+ PRELOAD_TOKEN.lastIndex = 0;
1219
+ for (let match = PRELOAD_TOKEN.exec(html); match; match = PRELOAD_TOKEN.exec(html)) {
1220
+ last = match.index;
1221
+ }
1222
+ return last;
1223
+ }
1224
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findLastPreloadToken, "findLastPreloadToken");
1225
+ function foldHtmlTagCase(html) {
1226
+ const lowerHtml = html.toLowerCase();
1227
+ return lowerHtml.length === html.length ? lowerHtml : html.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
1228
+ }
1229
+ _chunkS3JO3N4Hcjs.__name.call(void 0, foldHtmlTagCase, "foldHtmlTagCase");
1230
+ function findHtmlClosingTag(html, tagName, start) {
1231
+ const prefix = `</${tagName}`;
1232
+ let candidate = html.indexOf(prefix, start);
1233
+ while (candidate !== -1) {
1234
+ const boundary = html[candidate + prefix.length];
1235
+ if (boundary === ">" || boundary === "/" || /\s/.test(_nullishCoalesce(boundary, () => ( "")))) return candidate;
1236
+ candidate = html.indexOf(prefix, candidate + prefix.length);
1237
+ }
1238
+ return -1;
1239
+ }
1240
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findHtmlClosingTag, "findHtmlClosingTag");
1241
+ function findHtmlTagEnd2(html, start) {
1242
+ let quote;
1243
+ for (let index = start + 1; index < html.length; index += 1) {
1244
+ const character = html[index];
1245
+ if (quote) {
1246
+ if (character === quote) quote = void 0;
1247
+ } else if (character === '"' || character === "'") {
1248
+ quote = character;
1249
+ } else if (character === ">") {
1250
+ return index + 1;
1251
+ }
1252
+ }
1253
+ return -1;
1254
+ }
1255
+ _chunkS3JO3N4Hcjs.__name.call(void 0, findHtmlTagEnd2, "findHtmlTagEnd");
1256
+ function removeHtmlLinkElements(html, elements, removed) {
1257
+ let cursor = 0;
1258
+ let output = "";
1259
+ for (const [index, element] of elements.entries()) {
1260
+ if (!removed.has(index)) continue;
1261
+ output += html.slice(cursor, element.start);
1262
+ cursor = element.end;
1263
+ }
1264
+ return output + html.slice(cursor);
1265
+ }
1266
+ _chunkS3JO3N4Hcjs.__name.call(void 0, removeHtmlLinkElements, "removeHtmlLinkElements");
1267
+ function splitLinkHeader(value) {
1268
+ const links = [];
1269
+ let start = 0;
1270
+ let insideAngleBrackets = false;
1271
+ let quoted = false;
1272
+ for (let index = 0; index < value.length; index += 1) {
1273
+ const character = value[index];
1274
+ if (quoted) {
1275
+ if (character === '"' && !isEscaped(value, index)) quoted = false;
1276
+ continue;
1277
+ }
1278
+ if (character === '"') {
1279
+ quoted = true;
1280
+ } else if (character === "<") {
1281
+ insideAngleBrackets = true;
1282
+ } else if (character === ">") {
1283
+ insideAngleBrackets = false;
1284
+ } else if (character === "," && !insideAngleBrackets) {
1285
+ links.push(value.slice(start, index).trim());
1286
+ start = index + 1;
1287
+ }
1288
+ }
1289
+ links.push(value.slice(start).trim());
1290
+ return links.filter(Boolean);
1291
+ }
1292
+ _chunkS3JO3N4Hcjs.__name.call(void 0, splitLinkHeader, "splitLinkHeader");
1293
+ function isEscaped(value, index) {
1294
+ let backslashes = 0;
1295
+ for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
1296
+ backslashes += 1;
1297
+ }
1298
+ return backslashes % 2 === 1;
1299
+ }
1300
+ _chunkS3JO3N4Hcjs.__name.call(void 0, isEscaped, "isEscaped");
1301
+ function normalizeBudget(value, fallback) {
1302
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
1303
+ }
1304
+ _chunkS3JO3N4Hcjs.__name.call(void 0, normalizeBudget, "normalizeBudget");
1305
+
1306
+ // src/preview-noindex.ts
1307
+ var FARM_PREVIEW_ROBOTS_TAG = "noindex, nofollow";
1308
+ function resolveFarmNoindexPreviews(input) {
1309
+ if (input === void 0) return false;
1310
+ if (typeof input !== "boolean") {
1311
+ throw new TypeError("agent.noindexPreviews must be a boolean.");
1312
+ }
1313
+ return input;
1314
+ }
1315
+ _chunkS3JO3N4Hcjs.__name.call(void 0, resolveFarmNoindexPreviews, "resolveFarmNoindexPreviews");
1316
+ function applyFarmPreviewRobotsTag(response) {
1317
+ try {
1318
+ response.headers.set("X-Robots-Tag", FARM_PREVIEW_ROBOTS_TAG);
1319
+ return response;
1320
+ } catch (e4) {
1321
+ const headers = new Headers(response.headers);
1322
+ headers.set("X-Robots-Tag", FARM_PREVIEW_ROBOTS_TAG);
1323
+ return new Response(response.body, {
1324
+ status: response.status,
1325
+ statusText: response.statusText,
1326
+ headers
1327
+ });
1328
+ }
1329
+ }
1330
+ _chunkS3JO3N4Hcjs.__name.call(void 0, applyFarmPreviewRobotsTag, "applyFarmPreviewRobotsTag");
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+ exports.resolveFarmLlmsTxtConfig = resolveFarmLlmsTxtConfig; exports.collectFarmLlmsTxtPages = collectFarmLlmsTxtPages; exports.createFarmDefaultLlmsTxt = createFarmDefaultLlmsTxt; exports.serializeFarmLlmsTxt = serializeFarmLlmsTxt; exports.createFarmLlmsMarkdownReader = createFarmLlmsMarkdownReader; exports.renderFarmLlmsFullTxt = renderFarmLlmsFullTxt; exports.resolveFarmAgentCrawlers = resolveFarmAgentCrawlers; exports.createFarmAgentRobots = createFarmAgentRobots; exports.resolveFarmSecurityConfig = resolveFarmSecurityConfig; exports.getFarmSecurityHeader = getFarmSecurityHeader; exports.createFarmCspNonce = createFarmCspNonce; exports.addFarmCspNonceToScriptTags = addFarmCspNonceToScriptTags; exports.applyFarmCspHashesToHtml = applyFarmCspHashesToHtml; exports.applyFarmCspNonceToResponse = applyFarmCspNonceToResponse; exports.farmCspBlocksFrameworkInlineScripts = farmCspBlocksFrameworkInlineScripts; exports.createFarmCspNonceRewriter = createFarmCspNonceRewriter; exports.resolveFarmPerformanceConfig = resolveFarmPerformanceConfig; exports.manageFarmHtmlPreloads = manageFarmHtmlPreloads; exports.manageFarmLinkHeaderPreloads = manageFarmLinkHeaderPreloads; exports.manageFarmDocumentPreloads = manageFarmDocumentPreloads; exports.reportFarmPreloadWarnings = reportFarmPreloadWarnings; exports.FARM_PREVIEW_ROBOTS_TAG = FARM_PREVIEW_ROBOTS_TAG; exports.resolveFarmNoindexPreviews = resolveFarmNoindexPreviews; exports.applyFarmPreviewRobotsTag = applyFarmPreviewRobotsTag;