@farm.js/core 0.1.17 → 0.1.18

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 (249) 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/cache.cjs +38 -1560
  9. package/dist/chunk-22GUSVNJ.cjs +351 -0
  10. package/dist/chunk-2CQ74SP6.cjs +13 -0
  11. package/dist/chunk-2SJ4RQ6P.cjs +57 -0
  12. package/dist/chunk-3376ZTRC.cjs +1 -0
  13. package/dist/{chunk-YD4J4XCI.mjs → chunk-3XG26Z3J.mjs} +1 -1
  14. package/dist/chunk-4PNUXIVU.cjs +472 -0
  15. package/dist/chunk-4PPEPOZZ.cjs +21 -0
  16. package/dist/chunk-4ZFL5GFN.cjs +520 -0
  17. package/dist/chunk-5OVTOKGH.cjs +65 -0
  18. package/dist/chunk-5QIKR7RR.cjs +224 -0
  19. package/dist/chunk-5ZSWG4UX.cjs +127 -0
  20. package/dist/chunk-62YJ2IEB.cjs +238 -0
  21. package/dist/chunk-6EODJYCX.cjs +183 -0
  22. package/dist/chunk-6EXBPJ24.cjs +434 -0
  23. package/dist/chunk-6QQDAAAZ.cjs +38 -0
  24. package/dist/chunk-6V4TDWEC.cjs +455 -0
  25. package/dist/chunk-72ADZ6GQ.cjs +19 -0
  26. package/dist/chunk-75BRBIFP.cjs +172 -0
  27. package/dist/chunk-7W3CPVXS.cjs +24 -0
  28. package/dist/chunk-A6WIQH5Z.cjs +31 -0
  29. package/dist/chunk-AFOD3LYZ.cjs +377 -0
  30. package/dist/chunk-AMDMVWMI.cjs +39 -0
  31. package/dist/chunk-AORPIPNB.cjs +552 -0
  32. package/dist/chunk-ARJWXNQL.cjs +256 -0
  33. package/dist/chunk-AWRISO2H.cjs +2199 -0
  34. package/dist/chunk-AYJR42WX.cjs +711 -0
  35. package/dist/chunk-B4CH33IG.cjs +644 -0
  36. package/dist/chunk-BIDYX3SL.cjs +91 -0
  37. package/dist/chunk-BSTRERPP.cjs +40 -0
  38. package/dist/chunk-BYODCJD6.cjs +663 -0
  39. package/dist/chunk-C3VRMB6H.cjs +85 -0
  40. package/dist/chunk-C5GUTBZK.cjs +173 -0
  41. package/dist/chunk-CIAGU2X4.cjs +337 -0
  42. package/dist/chunk-CMGMGHUZ.cjs +27 -0
  43. package/dist/chunk-CXP5U3RW.cjs +54 -0
  44. package/dist/chunk-D2ULAULS.cjs +166 -0
  45. package/dist/chunk-D7JTOLFK.cjs +285 -0
  46. package/dist/chunk-DVM4FKZL.cjs +169 -0
  47. package/dist/chunk-DYEJQTDN.cjs +49 -0
  48. package/dist/chunk-E2BMSZ2W.cjs +151 -0
  49. package/dist/chunk-E3UK5IIB.cjs +593 -0
  50. package/dist/chunk-EM6SBQKM.cjs +470 -0
  51. package/dist/chunk-FJSWYIR7.cjs +482 -0
  52. package/dist/chunk-FK6GO24V.cjs +54 -0
  53. package/dist/chunk-FXUUWYAX.cjs +654 -0
  54. package/dist/chunk-G3HRIVEY.cjs +395 -0
  55. package/dist/chunk-G643DQCH.cjs +13 -0
  56. package/dist/chunk-G7HXGLEC.cjs +175 -0
  57. package/dist/chunk-GDSHDTJ4.cjs +152 -0
  58. package/dist/chunk-GNEO2XOF.cjs +2040 -0
  59. package/dist/{chunk-56DAX2BE.mjs → chunk-GYKJCFTS.mjs} +1 -1
  60. package/dist/chunk-H6G5INWM.cjs +1094 -0
  61. package/dist/chunk-HBTUGXHS.cjs +180 -0
  62. package/dist/chunk-HREOKQWT.cjs +45 -0
  63. package/dist/chunk-I4J452B7.cjs +435 -0
  64. package/dist/chunk-I57LW5VZ.cjs +94 -0
  65. package/dist/chunk-I7PUUDGY.cjs +389 -0
  66. package/dist/chunk-IAMRBF3Z.cjs +86 -0
  67. package/dist/chunk-IKNRN4VS.cjs +14214 -0
  68. package/dist/chunk-IQXFRNY2.cjs +169 -0
  69. package/dist/chunk-IXTFU4PL.cjs +2355 -0
  70. package/dist/chunk-J2OP5GG3.cjs +725 -0
  71. package/dist/chunk-J3LOGE4T.cjs +42 -0
  72. package/dist/chunk-J7FSKED3.cjs +93 -0
  73. package/dist/chunk-JDNHKPTD.cjs +22 -0
  74. package/dist/chunk-JSROZYYO.cjs +164 -0
  75. package/dist/chunk-K6FNHVDR.cjs +696 -0
  76. package/dist/chunk-KGZIORNL.cjs +43 -0
  77. package/dist/{chunk-MVIWBEJF.mjs → chunk-KPNVGRBL.mjs} +1 -1
  78. package/dist/chunk-KR6CKSXT.cjs +15 -0
  79. package/dist/chunk-KROWKCUH.cjs +185 -0
  80. package/dist/chunk-KVFPGF2M.cjs +46 -0
  81. package/dist/chunk-LCCBO7PJ.cjs +46 -0
  82. package/dist/chunk-LIUGYUX3.cjs +22 -0
  83. package/dist/chunk-LTNGXMQ6.cjs +55 -0
  84. package/dist/chunk-M2L4MYDQ.cjs +14 -0
  85. package/dist/chunk-MCJLA63J.cjs +1 -0
  86. package/dist/chunk-MKB2EGIR.cjs +148 -0
  87. package/dist/chunk-MQ3H6LT5.cjs +202 -0
  88. package/dist/chunk-MT763TDW.cjs +43 -0
  89. package/dist/chunk-MWSK6C4J.cjs +18 -0
  90. package/dist/chunk-MWWVKDW3.cjs +169 -0
  91. package/dist/chunk-NO3WWW3N.cjs +192 -0
  92. package/dist/chunk-NV3A5DXM.cjs +862 -0
  93. package/dist/chunk-NWOD6NIT.cjs +9 -0
  94. package/dist/chunk-NZKJGRB3.cjs +230 -0
  95. package/dist/chunk-OAVTUMJP.cjs +1496 -0
  96. package/dist/chunk-OHY2ZWUG.cjs +25 -0
  97. package/dist/chunk-OI6CMLWX.cjs +47 -0
  98. package/dist/chunk-OIEOCXKG.cjs +453 -0
  99. package/dist/chunk-OWOUTKIJ.cjs +558 -0
  100. package/dist/chunk-OX6O6WVA.cjs +74 -0
  101. package/dist/chunk-OXSIH4D6.cjs +476 -0
  102. package/dist/chunk-OYEUREB6.cjs +35 -0
  103. package/dist/chunk-PCOTGFSM.cjs +139 -0
  104. package/dist/chunk-PZYCPSCC.cjs +35 -0
  105. package/dist/chunk-QBK2AA4U.cjs +445 -0
  106. package/dist/chunk-QBPXNZGV.cjs +487 -0
  107. package/dist/chunk-QNPEUFHQ.cjs +27 -0
  108. package/dist/chunk-QZRVZSPN.cjs +236 -0
  109. package/dist/chunk-R5A5KNVX.cjs +20 -0
  110. package/dist/chunk-R5JIFR6B.cjs +42 -0
  111. package/dist/chunk-R6AIILII.cjs +193 -0
  112. package/dist/chunk-RG3ZOTG5.cjs +34 -0
  113. package/dist/chunk-ROUTX2E5.cjs +390 -0
  114. package/dist/chunk-RTHIVJ2G.cjs +54 -0
  115. package/dist/chunk-S3A45T7F.cjs +166 -0
  116. package/dist/chunk-S3JO3N4H.cjs +17 -0
  117. package/dist/chunk-SK35NQKK.cjs +27 -0
  118. package/dist/chunk-SU7MH53P.cjs +180 -0
  119. package/dist/chunk-SVRTJOUF.cjs +113 -0
  120. package/dist/chunk-SWN467MP.cjs +18 -0
  121. package/dist/chunk-SYQ3MOWW.cjs +73 -0
  122. package/dist/chunk-T5CERMEH.cjs +417 -0
  123. package/dist/chunk-TFAXUHWX.cjs +206 -0
  124. package/dist/chunk-TIWHTW3Q.cjs +24 -0
  125. package/dist/chunk-TKJZFIML.cjs +20 -0
  126. package/dist/chunk-TKNSDBBN.cjs +193 -0
  127. package/dist/chunk-TWGMSEHX.cjs +525 -0
  128. package/dist/chunk-TYQUSXUG.cjs +1357 -0
  129. package/dist/chunk-U4KT7QP3.cjs +23 -0
  130. package/dist/chunk-UJ2C4ICS.cjs +277 -0
  131. package/dist/chunk-UN5GHC5V.cjs +10244 -0
  132. package/dist/chunk-UQZ4AYTH.cjs +168 -0
  133. package/dist/chunk-US2QVW3E.cjs +36 -0
  134. package/dist/chunk-VB6UCX3V.cjs +421 -0
  135. package/dist/chunk-VEKFLAQM.cjs +300 -0
  136. package/dist/chunk-VQDBNVOO.cjs +14 -0
  137. package/dist/chunk-W4E7WMXE.cjs +71 -0
  138. package/dist/chunk-WJ3HK3LJ.cjs +1102 -0
  139. package/dist/chunk-WMAPPDMM.cjs +28 -0
  140. package/dist/chunk-WMOGFOUJ.cjs +223 -0
  141. package/dist/chunk-WPYFSQKK.cjs +37 -0
  142. package/dist/chunk-WZMNW2IW.cjs +1415 -0
  143. package/dist/chunk-XGC343EY.cjs +443 -0
  144. package/dist/chunk-XSKZORAS.cjs +727 -0
  145. package/dist/chunk-XWAWFQFS.cjs +82 -0
  146. package/dist/chunk-Y4YMF2NQ.cjs +460 -0
  147. package/dist/chunk-Y4YWHNKU.cjs +250 -0
  148. package/dist/chunk-Y53ZSFN6.cjs +504 -0
  149. package/dist/chunk-YA6LLTIJ.cjs +411 -0
  150. package/dist/chunk-YFPGHF5F.cjs +202 -0
  151. package/dist/chunk-YJRZR7VU.cjs +28 -0
  152. package/dist/chunk-YTAABQEV.cjs +1 -0
  153. package/dist/chunk-YX3DBN4M.cjs +18 -0
  154. package/dist/chunk-YZTASLPQ.cjs +64 -0
  155. package/dist/chunk-Z5HIWVDP.cjs +2173 -0
  156. package/dist/chunk-ZEG3OPIB.cjs +93 -0
  157. package/dist/chunk-ZMN3H73H.cjs +155 -0
  158. package/dist/client/lifecycle.cjs +6 -35
  159. package/dist/client-plugins.cjs +7 -448
  160. package/dist/client.cjs +171 -9808
  161. package/dist/config.cjs +8 -36
  162. package/dist/cron.cjs +24 -491
  163. package/dist/deferred.cjs +26 -475
  164. package/dist/deployment.cjs +39 -210
  165. package/dist/devtools-OUIPHVV6.cjs +388 -0
  166. package/dist/devtools-client-4WAPJY5L.cjs +254 -0
  167. package/dist/devtools-ui-5GBDIGMK.cjs +1296 -0
  168. package/dist/docs.cjs +46 -5657
  169. package/dist/env-types.cjs +5 -226
  170. package/dist/env.cjs +21 -338
  171. package/dist/environment/vite.cjs +8 -372
  172. package/dist/environment.cjs +12 -94
  173. package/dist/font.cjs +13 -63
  174. package/dist/headers.cjs +7 -123
  175. package/dist/i18n/client.cjs +55 -294
  176. package/dist/i18n/index.cjs +22 -209
  177. package/dist/i18n/server.cjs +22 -745
  178. package/dist/image/server.cjs +13 -729
  179. package/dist/image/sharp.cjs +33 -171
  180. package/dist/image.cjs +41 -85
  181. package/dist/index.cjs +1151 -68080
  182. package/dist/index.mjs +3 -3
  183. package/dist/instrumentation.cjs +12 -138
  184. package/dist/integration-orm-55F7CII5.cjs +13 -0
  185. package/dist/integrations.cjs +55 -4090
  186. package/dist/internal/app-markdown-runtime.cjs +27 -224
  187. package/dist/internal/build-runtime.cjs +120 -52259
  188. package/dist/internal/build-runtime.mjs +3 -3
  189. package/dist/internal/cli-runtime.cjs +67 -13811
  190. package/dist/internal/client-error-overlay.cjs +80 -733
  191. package/dist/internal/client-error-overlay.mjs +1 -1
  192. package/dist/internal/client-runtime.cjs +81 -913
  193. package/dist/internal/compression-runtime.cjs +8 -214
  194. package/dist/internal/config-runtime.cjs +42 -6547
  195. package/dist/internal/docs-precompiled-runtime.cjs +26 -46
  196. package/dist/internal/infra-analytics-runtime.cjs +10 -536
  197. package/dist/internal/isolated-boundary.cjs +14 -414
  198. package/dist/internal/metadata-image-runtime.cjs +7 -285
  199. package/dist/internal/product-telemetry-runtime.cjs +42 -97
  200. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  201. package/dist/internal/production-node-env.cjs +6 -63
  202. package/dist/internal/production-runtime.cjs +418 -7133
  203. package/dist/internal/request-cookies.cjs +6 -54
  204. package/dist/json-ld.cjs +24 -50
  205. package/dist/layers-E4WPJNY5.cjs +17 -0
  206. package/dist/manager-G4B2IPYE.cjs +14 -0
  207. package/dist/markdown.cjs +21 -547
  208. package/dist/middleware.cjs +36 -2995
  209. package/dist/navigation.cjs +22 -2588
  210. package/dist/nitro-4I2MYLY2.cjs +652 -0
  211. package/dist/observability.cjs +22 -614
  212. package/dist/og.cjs +5 -28
  213. package/dist/plugin.cjs +106 -37442
  214. package/dist/plugin.mjs +2 -2
  215. package/dist/query/client.cjs +113 -449
  216. package/dist/query/index.cjs +26 -288
  217. package/dist/query/parsers.cjs +23 -247
  218. package/dist/query/server.cjs +36 -298
  219. package/dist/renderer/react/client.cjs +9 -43
  220. package/dist/renderer/react/server.cjs +40 -103
  221. package/dist/renderer/react/vite.cjs +7 -29
  222. package/dist/renderer-client.cjs +126 -4295
  223. package/dist/renderer.cjs +31 -249
  224. package/dist/request.cjs +5 -68
  225. package/dist/router.cjs +11 -474
  226. package/dist/routes.cjs +42 -2461
  227. package/dist/schema-dev-notice-MXSZMVDG.cjs +56 -0
  228. package/dist/schema.cjs +6 -33
  229. package/dist/search-client-G3RICOFU.cjs +13 -0
  230. package/dist/server-action-security.cjs +25 -541
  231. package/dist/server-fn-client.cjs +6 -337
  232. package/dist/server-fn.cjs +32 -1841
  233. package/dist/server-plugins.cjs +15 -884
  234. package/dist/server-query-client.cjs +15 -1883
  235. package/dist/server-query.cjs +16 -1838
  236. package/dist/server.cjs +296 -44681
  237. package/dist/server.mjs +2 -2
  238. package/dist/storage.cjs +57 -576
  239. package/dist/testing.cjs +89 -3186
  240. package/dist/theme/client.cjs +13 -108
  241. package/dist/theme/index.cjs +6 -68
  242. package/dist/theme/runtime.cjs +13 -78
  243. package/dist/theme/server.cjs +10 -179
  244. package/dist/version.cjs +4 -32
  245. package/dist/version.mjs +1 -1
  246. package/dist/vite.cjs +119 -37773
  247. package/dist/vite.mjs +2 -2
  248. package/dist/workflows.cjs +19 -1040
  249. package/package.json +1 -1
@@ -1,3024 +1,65 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
30
2
 
31
- // src/middleware/index.ts
32
- var middleware_exports = {};
33
- __export(middleware_exports, {
34
- MiddlewareManager: () => MiddlewareManager,
35
- UnsupportedRateLimitStorageError: () => UnsupportedRateLimitStorageError,
36
- _runWithMiddlewareContext: () => _runWithMiddlewareContext,
37
- _runWithMiddlewareData: () => _runWithMiddlewareData,
38
- applyProductionMiddlewareHeaders: () => applyProductionMiddlewareHeaders,
39
- canonicalizeRequestPathSegments: () => canonicalizeRequestPathSegments,
40
- createContext: () => createContext,
41
- createProductionMiddlewareRunner: () => createProductionMiddlewareRunner,
42
- farmMiddlewarePlugin: () => farmMiddlewarePlugin,
43
- getFromMiddleware: () => getFromMiddleware,
44
- getMiddlewareContext: () => getMiddlewareContext,
45
- getMiddlewareData: () => getMiddlewareData,
46
- getMiddlewareValue: () => getMiddlewareValue,
47
- getRateLimitStatus: () => getRateLimitStatus,
48
- hasMiddlewareData: () => hasMiddlewareData,
49
- matchesMiddlewareConfig: () => matchesMiddlewareConfig2,
50
- memoryRateLimitStorage: () => memoryRateLimitStorage,
51
- middleware: () => middleware,
52
- unwrapMiddleware: () => unwrapMiddleware
53
- });
54
- module.exports = __toCommonJS(middleware_exports);
55
3
 
56
- // src/middleware/chain.ts
57
- var DEFAULT_MEMORY_RATE_LIMIT_ENTRIES = 1e5;
58
- var _UnsupportedRateLimitStorageError = class _UnsupportedRateLimitStorageError extends TypeError {
59
- constructor() {
60
- super(
61
- "RateLimitStorage must implement atomic increment(key, windowMs). Legacy get/set adapters can lose increments under concurrency. Use memoryRateLimitStorage() for one process or redisRateLimitStorage() from @farm.js/cache-redis for production."
62
- );
63
- this.name = "UnsupportedRateLimitStorageError";
64
- }
65
- };
66
- __name(_UnsupportedRateLimitStorageError, "UnsupportedRateLimitStorageError");
67
- var UnsupportedRateLimitStorageError = _UnsupportedRateLimitStorageError;
68
- function memoryRateLimitStorage(options = {}) {
69
- const maxEntries = options.maxEntries ?? DEFAULT_MEMORY_RATE_LIMIT_ENTRIES;
70
- if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {
71
- throw new TypeError("memoryRateLimitStorage maxEntries must be a positive safe integer.");
72
- }
73
- const records = /* @__PURE__ */ new Map();
74
- let earliestExpiry = Infinity;
75
- function read(key, now) {
76
- const record = records.get(key);
77
- if (!record) return null;
78
- if (record.resetAt <= now) {
79
- records.delete(key);
80
- return null;
81
- }
82
- return record;
83
- }
84
- __name(read, "read");
85
- function pruneExpired(now) {
86
- if (now < earliestExpiry) return;
87
- earliestExpiry = Infinity;
88
- for (const [key, record] of records) {
89
- if (record.resetAt <= now) records.delete(key);
90
- else earliestExpiry = Math.min(earliestExpiry, record.resetAt);
91
- }
92
- }
93
- __name(pruneExpired, "pruneExpired");
94
- return {
95
- increment(key, windowMs) {
96
- if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
97
- throw new TypeError("Rate-limit windowMs must be a positive safe integer.");
98
- }
99
- const now = Date.now();
100
- const current = read(key, now);
101
- if (current) {
102
- current.count++;
103
- return { ...current };
104
- }
105
- if (records.size >= maxEntries) pruneExpired(now);
106
- if (records.size >= maxEntries) {
107
- throw new Error(
108
- `Process-local rate-limit storage reached its ${maxEntries} active-key capacity. Configure a shared production adapter or increase maxEntries.`
109
- );
110
- }
111
- const next = { count: 1, resetAt: now + windowMs };
112
- records.set(key, next);
113
- earliestExpiry = Math.min(earliestExpiry, next.resetAt);
114
- return { ...next };
115
- },
116
- get(key) {
117
- const record = read(key, Date.now());
118
- return record ? { ...record } : null;
119
- }
120
- };
121
- }
122
- __name(memoryRateLimitStorage, "memoryRateLimitStorage");
123
- var defaultRateLimitStorage = memoryRateLimitStorage();
124
- function parseTimeWindow(window) {
125
- const match = window.match(/^(\d+)(ms|s|m|h|d)$/);
126
- if (!match) throw new Error(`Invalid time window: ${window}`);
127
- const [, amount, unit] = match;
128
- const value = Number.parseInt(amount, 10);
129
- const multipliers = {
130
- ms: 1,
131
- s: 1e3,
132
- m: 60 * 1e3,
133
- h: 60 * 60 * 1e3,
134
- d: 24 * 60 * 60 * 1e3
135
- };
136
- const windowMs = value * multipliers[unit];
137
- if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
138
- throw new Error(`Invalid time window: ${window}`);
139
- }
140
- return windowMs;
141
- }
142
- __name(parseTimeWindow, "parseTimeWindow");
143
- function createRateLimitMiddleware(config) {
144
- if (!Number.isSafeInteger(config.requests) || config.requests <= 0) {
145
- throw new TypeError("Rate limit requests must be a positive safe integer.");
146
- }
147
- const windowMs = parseTimeWindow(config.window);
148
- const storage = config.storage || defaultRateLimitStorage;
149
- assertAtomicRateLimitStorage(storage);
150
- return async (ctx, next) => {
151
- const key = config.keyGenerator ? config.keyGenerator(ctx) : `${requireRateLimitClientAddress(ctx)}:${ctx.pathname}`;
152
- const current = await storage.increment(key, windowMs);
153
- assertRateLimitIncrementResult(current);
154
- const now = Date.now();
155
- const resetIn = Math.max(1, Math.ceil((current.resetAt - now) / 1e3));
156
- const remaining = Math.max(0, config.requests - current.count);
157
- setRateLimitHeaders(ctx, config.requests, remaining, resetIn, Math.ceil(windowMs / 1e3));
158
- if (current.count > config.requests) {
159
- setMiddlewareResponseHeader(ctx, "Retry-After", String(resetIn));
160
- if (config.onLimit) {
161
- const result = await config.onLimit(ctx);
162
- if (result) return result;
163
- }
164
- ctx.json(
165
- {
166
- error: "Rate limit exceeded",
167
- retryAfter: resetIn
168
- },
169
- 429
170
- );
171
- return;
172
- }
173
- return next();
174
- };
175
- }
176
- __name(createRateLimitMiddleware, "createRateLimitMiddleware");
177
- function requireRateLimitClientAddress(ctx) {
178
- const address = ctx.request.socket?.remoteAddress;
179
- if (address) return address;
180
- throw new Error(
181
- "Rate limiting could not identify the caller: this runtime reports no client address. Set `server.trustProxy` so a proxy's x-forwarded-for is trusted, or pass a `keyGenerator` that derives the bucket from something you do have, such as a session or an API key."
182
- );
183
- }
184
- __name(requireRateLimitClientAddress, "requireRateLimitClientAddress");
185
- function assertAtomicRateLimitStorage(storage) {
186
- if (!storage || typeof storage.increment !== "function") {
187
- throw new UnsupportedRateLimitStorageError();
188
- }
189
- }
190
- __name(assertAtomicRateLimitStorage, "assertAtomicRateLimitStorage");
191
- function assertRateLimitIncrementResult(result) {
192
- if (!result || !Number.isSafeInteger(result.count) || result.count <= 0 || !Number.isFinite(result.resetAt) || result.resetAt <= 0) {
193
- throw new TypeError(
194
- "RateLimitStorage.increment() must return a positive integer count and a resetAt timestamp."
195
- );
196
- }
197
- }
198
- __name(assertRateLimitIncrementResult, "assertRateLimitIncrementResult");
199
- function setRateLimitHeaders(ctx, limit, remaining, resetIn, windowSeconds) {
200
- setMiddlewareResponseHeader(ctx, "RateLimit-Policy", `"farm";q=${limit};w=${windowSeconds}`);
201
- setMiddlewareResponseHeader(ctx, "RateLimit", `"farm";r=${remaining};t=${resetIn}`);
202
- }
203
- __name(setRateLimitHeaders, "setRateLimitHeaders");
204
- function setMiddlewareResponseHeader(ctx, name, value) {
205
- ctx.headers.set(name, value);
206
- if (!ctx.response.headersSent && !ctx.response.writableEnded) {
207
- ctx.response.setHeader(name, value);
208
- }
209
- }
210
- __name(setMiddlewareResponseHeader, "setMiddlewareResponseHeader");
211
- function matchPattern(pattern, pathname) {
212
- if (pattern instanceof RegExp) {
213
- return pattern.test(pathname);
214
- }
215
- const regexPattern = pattern.replace(/\*\*/g, "__DOUBLE_STAR__").replace(/\*/g, "__SINGLE_STAR__").replace(/[.+?^${}()|[\]\\/]/g, "\\$&").replace(/__DOUBLE_STAR__/g, ".*").replace(/__SINGLE_STAR__/g, "[^/]+");
216
- const regex = new RegExp(`^${regexPattern}$`);
217
- return regex.test(pathname);
218
- }
219
- __name(matchPattern, "matchPattern");
220
- var _MiddlewareChainImpl = class _MiddlewareChainImpl {
221
- constructor(basePath = "/") {
222
- this.handlers = [];
223
- this.basePath = basePath === "/" ? "/" : basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
224
- }
225
- /**
226
- * Set the base path for this middleware chain (called by manager when loading)
227
- */
228
- setBasePath(path4) {
229
- this.basePath = path4 === "/" ? "/" : path4.endsWith("/") ? path4.slice(0, -1) : path4;
230
- }
231
- use(fn) {
232
- this.handlers.push(fn);
233
- return this;
234
- }
235
- /**
236
- * Normalize a path pattern - auto-scope to middleware route
237
- * If middleware is in /contact, then "/api" becomes "/contact/api"
238
- */
239
- normalizePattern(pattern) {
240
- if (this.basePath === "/") {
241
- return pattern.startsWith("/") ? pattern : `/${pattern}`;
242
- }
243
- const cleanPattern = pattern.startsWith("/") ? pattern.slice(1) : pattern;
244
- return `${this.basePath}/${cleanPattern}`;
245
- }
246
- /**
247
- * Conditionally run middleware based on a condition.
248
- * Only supports boolean values or functions that evaluate to boolean.
249
- * Route-based string matching has been removed - use function conditions instead.
250
- *
251
- * @example
252
- * .when(true, (ctx, next) => { ... }) // Always run
253
- * .when((ctx) => ctx.data.get('flag'), (ctx, next) => { ... }) // Conditional
254
- * .when((ctx) => ctx.pathname === '/contact', (ctx, next) => { ... }) // Path-based condition
255
- */
256
- when(condition, fn) {
257
- const conditionalMiddleware = /* @__PURE__ */ __name(async (ctx, next) => {
258
- const shouldRun = typeof condition === "function" ? condition(ctx) : condition;
259
- if (!shouldRun) {
260
- return next();
261
- }
262
- if (typeof fn === "function" && fn.length === 2) {
263
- return fn(ctx, next);
264
- } else {
265
- const subChain = middleware(this.basePath);
266
- fn(subChain);
267
- const { handlers } = subChain.build();
268
- let index = 0;
269
- let returnedResponse;
270
- const executeNext = /* @__PURE__ */ __name(async () => {
271
- if (index < handlers.length) {
272
- const handler = handlers[index++];
273
- const result = await handler(ctx, executeNext);
274
- if (result instanceof Response) {
275
- returnedResponse = result;
276
- return result;
277
- }
278
- } else {
279
- const result = await next();
280
- if (result instanceof Response) {
281
- returnedResponse = result;
282
- return result;
283
- }
284
- }
285
- return returnedResponse;
286
- }, "executeNext");
287
- return executeNext();
288
- }
289
- }, "conditionalMiddleware");
290
- this.handlers.push(conditionalMiddleware);
291
- return this;
292
- }
293
- rateLimit(config) {
294
- this.handlers.push(createRateLimitMiddleware(config));
295
- return this;
296
- }
297
- redirect(source, destination, permanent = false) {
298
- const redirectMiddleware = /* @__PURE__ */ __name(async (ctx, next) => {
299
- const normalizedSource = this.normalizePattern(source);
300
- if (matchPattern(normalizedSource, ctx.pathname)) {
301
- ctx.redirect(destination, permanent ? 308 : 307);
302
- return;
303
- }
304
- return next();
305
- }, "redirectMiddleware");
306
- this.handlers.push(redirectMiddleware);
307
- return this;
308
- }
309
- /**
310
- * Rewrite the current middleware route to a new destination.
311
- * Since each middleware file is route-specific, the source is automatically
312
- * the middleware's route, so you only need to specify the destination.
313
- *
314
- * @param destination - The destination path to rewrite to
315
- * @param condition - Optional boolean or function that evaluates to boolean.
316
- * If provided and evaluates to false, rewrite is skipped.
317
- * If not provided, rewrite always happens.
318
- *
319
- * @example
320
- * // In /contact/middleware.ts
321
- * .rewrite('/about') // Always rewrites /contact to /about
322
- * .rewrite('/about', true) // Always rewrites
323
- * .rewrite('/about', false) // Never rewrites
324
- * .rewrite('/about', (ctx) => ctx.data.get('shouldRewrite')) // Conditional rewrite
325
- */
326
- rewrite(destination, condition) {
327
- const rewriteMiddleware = /* @__PURE__ */ __name(async (ctx, next) => {
328
- if (condition !== void 0) {
329
- const shouldRewrite = typeof condition === "function" ? condition(ctx) : condition;
330
- if (!shouldRewrite) {
331
- return next();
332
- }
333
- }
334
- if (this.basePath !== "/") {
335
- if (ctx.pathname === this.basePath) {
336
- ctx.rewrite(destination);
337
- } else if (ctx.pathname.startsWith(this.basePath + "/")) {
338
- const subPath = ctx.pathname.slice(this.basePath.length);
339
- const newPath = destination + subPath;
340
- ctx.rewrite(newPath);
341
- }
342
- } else {
343
- ctx.rewrite(destination);
344
- }
345
- return next();
346
- }, "rewriteMiddleware");
347
- this.handlers.push(rewriteMiddleware);
348
- return this;
349
- }
350
- build() {
351
- return {
352
- handlers: this.handlers,
353
- config: this.config
354
- };
355
- }
356
- };
357
- __name(_MiddlewareChainImpl, "MiddlewareChainImpl");
358
- var MiddlewareChainImpl = _MiddlewareChainImpl;
359
- async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage) {
360
- if (!Number.isSafeInteger(limit) || limit <= 0) {
361
- throw new TypeError("Rate limit must be a positive safe integer.");
362
- }
363
- assertAtomicRateLimitStorage(storage);
364
- if (typeof storage.get !== "function") {
365
- throw new TypeError(
366
- "getRateLimitStatus() requires a RateLimitStorage adapter that implements get(key)."
367
- );
368
- }
369
- const record = await storage.get(key);
370
- if (!record) {
371
- return {
372
- requests: 0,
373
- limit,
374
- remaining: limit,
375
- resetIn: null,
376
- resetAt: null,
377
- isLimited: false
378
- };
379
- }
380
- assertRateLimitIncrementResult(record);
381
- const now = Date.now();
382
- if (record.resetAt && now > record.resetAt) {
383
- return {
384
- requests: 0,
385
- limit,
386
- remaining: limit,
387
- resetIn: null,
388
- resetAt: null,
389
- isLimited: false
390
- };
391
- }
392
- const requests = record.count || 0;
393
- const remaining = Math.max(0, limit - requests);
394
- const isLimited = requests >= limit;
395
- let resetIn = null;
396
- let resetAt = null;
397
- if (record.resetAt) {
398
- const remainingMs = record.resetAt - now;
399
- resetIn = remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
400
- resetAt = new Date(record.resetAt);
401
- }
402
- return {
403
- requests,
404
- limit,
405
- remaining,
406
- resetIn,
407
- resetAt,
408
- isLimited
409
- };
410
- }
411
- __name(getRateLimitStatus, "getRateLimitStatus");
412
- function middleware(basePath = "/") {
413
- return new MiddlewareChainImpl(basePath);
414
- }
415
- __name(middleware, "middleware");
416
4
 
417
- // src/server/request.ts
418
- var import_node_async_hooks = require("async_hooks");
419
- var import_node_stream = require("stream");
420
5
 
421
- // src/server/request-bridge.ts
422
- var CURRENT_REQUEST_RESOLVER_KEY = /* @__PURE__ */ Symbol.for("farm.currentRequestResolver");
423
- function getGlobalState() {
424
- return globalThis;
425
- }
426
- __name(getGlobalState, "getGlobalState");
427
- function _setCurrentRequestResolver(resolver) {
428
- getGlobalState()[CURRENT_REQUEST_RESOLVER_KEY] = resolver;
429
- }
430
- __name(_setCurrentRequestResolver, "_setCurrentRequestResolver");
431
6
 
432
- // src/server/request.ts
433
- var REQUEST_STORAGE_KEY = /* @__PURE__ */ Symbol.for("@farm.js/core/request-storage");
434
- function getRequestStore() {
435
- const runtime3 = globalThis;
436
- const existing = runtime3[REQUEST_STORAGE_KEY];
437
- if (existing instanceof import_node_async_hooks.AsyncLocalStorage) {
438
- return existing;
439
- }
440
- const storage = new import_node_async_hooks.AsyncLocalStorage();
441
- runtime3[REQUEST_STORAGE_KEY] = storage;
442
- return storage;
443
- }
444
- __name(getRequestStore, "getRequestStore");
445
- var requestStore = getRequestStore();
446
- _setCurrentRequestResolver(() => requestStore.getStore());
447
- function resolveFarmRequestURL(req, options = {}) {
448
- if (options.origin) {
449
- return new URL(req.url || "/", options.origin);
450
- }
451
- const forwardedHost = options.trustProxy ? firstForwardedHeaderValue(req.headers["x-forwarded-host"]) : void 0;
452
- const fallbackHost = firstForwardedHeaderValue(req.headers.host) || "localhost";
453
- const forwardedProto = options.trustProxy ? firstForwardedHeaderValue(req.headers["x-forwarded-proto"]) : void 0;
454
- const normalizedProto = forwardedProto?.toLowerCase();
455
- const proto = normalizedProto === "https" || normalizedProto === "http" ? normalizedProto : isEncryptedFarmRequest(req) ? "https" : "http";
456
- return new URL(req.url || "/", resolveRequestOrigin(proto, forwardedHost, fallbackHost));
457
- }
458
- __name(resolveFarmRequestURL, "resolveFarmRequestURL");
459
- function createWebRequestFromFarmRequest(req, options = {}) {
460
- const fullUrl = resolveFarmRequestURL(req, options).toString();
461
- const headers = new Headers();
462
- for (const [key, value] of Object.entries(req.headers)) {
463
- if (value == null) {
464
- continue;
465
- }
466
- if (Array.isArray(value)) {
467
- for (const item of value) {
468
- headers.append(key, item);
469
- }
470
- continue;
471
- }
472
- headers.set(key, value);
473
- }
474
- const method = (req.method || "GET").toUpperCase();
475
- const init = {
476
- method: req.method,
477
- headers
478
- };
479
- if (method !== "GET" && method !== "HEAD") {
480
- init.body = import_node_stream.Readable.toWeb(req);
481
- init.duplex = "half";
482
- }
483
- return new Request(fullUrl, init);
484
- }
485
- __name(createWebRequestFromFarmRequest, "createWebRequestFromFarmRequest");
486
- function isEncryptedFarmRequest(req) {
487
- return Boolean(req.socket?.encrypted);
488
- }
489
- __name(isEncryptedFarmRequest, "isEncryptedFarmRequest");
490
- function firstForwardedHeaderValue(value) {
491
- const first = Array.isArray(value) ? value[0] : value;
492
- const token = first?.split(",", 1)[0]?.trim();
493
- return token || void 0;
494
- }
495
- __name(firstForwardedHeaderValue, "firstForwardedHeaderValue");
496
- function resolveRequestOrigin(proto, host, fallback) {
497
- for (const candidate of [host, fallback, "localhost"]) {
498
- if (!candidate) continue;
499
- if (/[\s/?#@\\]/u.test(candidate)) continue;
500
- try {
501
- const url = new URL(`${proto}://${candidate}`);
502
- if (url.username || url.password || url.pathname !== "/" || url.search || url.hash) continue;
503
- return url.origin;
504
- } catch {
505
- }
506
- }
507
- return `${proto}://localhost`;
508
- }
509
- __name(resolveRequestOrigin, "resolveRequestOrigin");
510
7
 
511
- // src/request-cookies.ts
512
- function parseRequestCookieHeader(header) {
513
- if (!header?.trim()) return [];
514
- return header.split(";").map((part) => part.trim()).filter(Boolean).map((part) => {
515
- const separatorIndex = part.indexOf("=");
516
- if (separatorIndex === -1) {
517
- return {
518
- name: decodeCookiePart(part),
519
- value: ""
520
- };
521
- }
522
- return {
523
- name: decodeCookiePart(part.slice(0, separatorIndex).trim()),
524
- value: decodeCookiePart(part.slice(separatorIndex + 1).trim())
525
- };
526
- }).filter((cookie) => cookie.name.length > 0);
527
- }
528
- __name(parseRequestCookieHeader, "parseRequestCookieHeader");
529
- function decodeCookiePart(value) {
530
- try {
531
- return decodeURIComponent(value);
532
- } catch {
533
- return value;
534
- }
535
- }
536
- __name(decodeCookiePart, "decodeCookiePart");
537
8
 
538
- // src/middleware/cookie-header.ts
539
- function parseMiddlewareCookieHeader(cookieHeader) {
540
- const cookies = /* @__PURE__ */ Object.create(null);
541
- for (const cookie of parseRequestCookieHeader(cookieHeader)) {
542
- if (!Object.prototype.hasOwnProperty.call(cookies, cookie.name)) {
543
- cookies[cookie.name] = cookie.value;
544
- }
545
- }
546
- return cookies;
547
- }
548
- __name(parseMiddlewareCookieHeader, "parseMiddlewareCookieHeader");
549
- function applyCookieNamePrefixRequirements(name, options) {
550
- if (name.startsWith("__Host-")) {
551
- return { ...options, secure: true, path: "/", domain: void 0 };
552
- }
553
- if (name.startsWith("__Secure-")) {
554
- return { ...options, secure: true };
555
- }
556
- return options;
557
- }
558
- __name(applyCookieNamePrefixRequirements, "applyCookieNamePrefixRequirements");
559
- function serializeMiddlewareCookie(name, value, options = {}) {
560
- const resolved = applyCookieNamePrefixRequirements(name, options);
561
- let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
562
- if (resolved.maxAge != null) cookie += `; Max-Age=${resolved.maxAge}`;
563
- if (resolved.expires) cookie += `; Expires=${resolved.expires.toUTCString()}`;
564
- cookie += `; Path=${resolved.path || "/"}`;
565
- if (resolved.domain) cookie += `; Domain=${resolved.domain}`;
566
- if (resolved.secure) cookie += "; Secure";
567
- if (resolved.httpOnly) cookie += "; HttpOnly";
568
- if (resolved.sameSite) {
569
- cookie += `; SameSite=${resolved.sameSite.charAt(0).toUpperCase()}${resolved.sameSite.slice(1)}`;
570
- }
571
- return cookie;
572
- }
573
- __name(serializeMiddlewareCookie, "serializeMiddlewareCookie");
574
- function serializeMiddlewareCookieDeletion(name, options = {}) {
575
- return serializeMiddlewareCookie(name, "", { ...options, maxAge: 0, expires: /* @__PURE__ */ new Date(0) });
576
- }
577
- __name(serializeMiddlewareCookieDeletion, "serializeMiddlewareCookieDeletion");
578
9
 
579
- // src/middleware/context.ts
580
- var _CookieJarImpl = class _CookieJarImpl {
581
- constructor(req, res) {
582
- this.req = req;
583
- this.res = res;
584
- this.cookies = parseMiddlewareCookieHeader(req.headers.cookie);
585
- const existing = res.getHeader("Set-Cookie");
586
- this.setCookies = Array.isArray(existing) ? existing.map(String) : existing === void 0 ? [] : [String(existing)];
587
- }
588
- get(name) {
589
- return this.cookies[name];
590
- }
591
- set(name, value, options = {}) {
592
- this.cookies[name] = value;
593
- const cookieString = serializeMiddlewareCookie(name, value, options);
594
- this.setCookies.push(cookieString);
595
- this.res.setHeader("Set-Cookie", this.setCookies);
596
- }
597
- delete(name, options = {}) {
598
- delete this.cookies[name];
599
- this.setCookies.push(serializeMiddlewareCookieDeletion(name, options));
600
- this.res.setHeader("Set-Cookie", this.setCookies);
601
- }
602
- getAll() {
603
- return { ...this.cookies };
604
- }
605
- };
606
- __name(_CookieJarImpl, "CookieJarImpl");
607
- var CookieJarImpl = _CookieJarImpl;
608
- function createContext(req, res, viteServer, parent, server) {
609
- const url = resolveFarmRequestURL(req, { trustProxy: server?.trustProxy });
610
- const headers = /* @__PURE__ */ new Map();
611
- const data = parent?.data ? new Map(parent.data) : /* @__PURE__ */ new Map();
612
- const locals = parent?.locals ? new Map(parent.locals) : /* @__PURE__ */ new Map();
613
- const cookies = new CookieJarImpl(req, res);
614
- if (parent?.headers) {
615
- for (const [key, value] of Object.entries(parent.headers)) {
616
- headers.set(key, value);
617
- }
618
- }
619
- let handled = false;
620
- const applyResponseHeaders = /* @__PURE__ */ __name(() => {
621
- for (const [key, value] of headers) {
622
- try {
623
- res.setHeader(key, value);
624
- } catch {
625
- }
626
- }
627
- }, "applyResponseHeaders");
628
- const ctx = {
629
- request: req,
630
- response: res,
631
- url,
632
- pathname: url.pathname,
633
- searchParams: url.searchParams,
634
- method: req.method || "GET",
635
- params: {},
636
- route: url.pathname,
637
- parent,
638
- vite: {
639
- isDev: process.env.NODE_ENV !== "production",
640
- hmr: !!viteServer?.hot,
641
- server: viteServer
642
- },
643
- data,
644
- locals,
645
- headers,
646
- cookies,
647
- _handled: false,
648
- redirect(redirectUrl, status = 307) {
649
- if (handled) {
650
- console.warn("Response already sent, cannot redirect");
651
- return;
652
- }
653
- ctx._redirectUrl = redirectUrl;
654
- ctx._handled = true;
655
- handled = true;
656
- applyResponseHeaders();
657
- res.writeHead(status, {
658
- Location: redirectUrl,
659
- "Content-Type": "text/plain"
660
- });
661
- res.end(`Redirecting to ${redirectUrl}`);
662
- },
663
- rewrite(rewriteUrl) {
664
- ctx._rewriteUrl = rewriteUrl;
665
- const newUrl = new URL(rewriteUrl, ctx.url);
666
- ctx.url = newUrl;
667
- ctx.pathname = newUrl.pathname;
668
- ctx.searchParams = newUrl.searchParams;
669
- ctx.route = newUrl.pathname;
670
- req.url = rewriteUrl;
671
- },
672
- json(jsonData, status = 200) {
673
- if (handled) {
674
- console.warn("Response already sent, cannot send JSON");
675
- return;
676
- }
677
- ctx._handled = true;
678
- handled = true;
679
- applyResponseHeaders();
680
- res.writeHead(status, {
681
- "Content-Type": "application/json"
682
- });
683
- res.end(JSON.stringify(jsonData));
684
- },
685
- text(content, status = 200) {
686
- if (handled) {
687
- console.warn("Response already sent, cannot send text");
688
- return;
689
- }
690
- ctx._handled = true;
691
- handled = true;
692
- applyResponseHeaders();
693
- res.writeHead(status, {
694
- "Content-Type": "text/plain"
695
- });
696
- res.end(content);
697
- },
698
- html(content, status = 200) {
699
- if (handled) {
700
- console.warn("Response already sent, cannot send HTML");
701
- return;
702
- }
703
- ctx._handled = true;
704
- handled = true;
705
- applyResponseHeaders();
706
- res.writeHead(status, {
707
- "Content-Type": "text/html"
708
- });
709
- res.end(content);
710
- }
711
- };
712
- return ctx;
713
- }
714
- __name(createContext, "createContext");
10
+ var _chunkFJSWYIR7cjs = require('./chunk-FJSWYIR7.cjs');
715
11
 
716
- // src/middleware/manager.ts
717
- var fs = __toESM(require("fs"));
718
- var path = __toESM(require("path"));
719
12
 
720
- // src/utils/file-module.ts
721
- var import_node_url = require("url");
722
- function toFileModuleUrl(filePath) {
723
- return (0, import_node_url.pathToFileURL)(filePath).href;
724
- }
725
- __name(toFileModuleUrl, "toFileModuleUrl");
726
13
 
727
- // src/middleware/module.ts
728
- function isWebRequest(request) {
729
- return typeof Request !== "undefined" && request instanceof Request;
730
- }
731
- __name(isWebRequest, "isWebRequest");
732
- function toWebRequest(ctx) {
733
- if (isWebRequest(ctx.request)) {
734
- return ctx.request;
735
- }
736
- return createWebRequestFromFarmRequest(ctx.request, { origin: ctx.url.origin });
737
- }
738
- __name(toWebRequest, "toWebRequest");
739
- function createRequestMiddlewareContext(ctx) {
740
- const context2 = {
741
- get url() {
742
- return ctx.url;
743
- },
744
- get pathname() {
745
- return ctx.pathname;
746
- },
747
- get searchParams() {
748
- return ctx.searchParams;
749
- },
750
- get method() {
751
- return ctx.method;
752
- },
753
- get params() {
754
- return ctx.params;
755
- },
756
- get route() {
757
- return ctx.route;
758
- },
759
- get locals() {
760
- return ctx.locals;
761
- },
762
- get data() {
763
- return ctx.data;
764
- },
765
- get headers() {
766
- return ctx.headers;
767
- },
768
- get cookies() {
769
- return ctx.cookies;
770
- },
771
- get(key) {
772
- return ctx.locals.get(key);
773
- },
774
- has(key) {
775
- return ctx.locals.has(key);
776
- },
777
- set(key, value) {
778
- ctx.locals.set(key, value);
779
- },
780
- delete(key) {
781
- return ctx.locals.delete(key);
782
- },
783
- redirect(url, status) {
784
- ctx.redirect(url, status);
785
- },
786
- rewrite(url) {
787
- ctx.rewrite(url);
788
- },
789
- json(data, status) {
790
- ctx.json(data, status);
791
- },
792
- text(content, status) {
793
- ctx.text(content, status);
794
- },
795
- html(content, status) {
796
- ctx.html(content, status);
797
- }
798
- };
799
- return context2;
800
- }
801
- __name(createRequestMiddlewareContext, "createRequestMiddlewareContext");
802
- function normalizeMiddlewareModule(middlewareModule, routePath) {
803
- const module2 = middlewareModule;
804
- const defaultExport = module2.default;
805
- const namedExport = module2.middleware;
806
- const hasNamedExport = typeof namedExport === "function";
807
- if (namedExport !== void 0 && !hasNamedExport) {
808
- throw new TypeError("The named middleware export must be a function");
809
- }
810
- if (defaultExport && hasNamedExport) {
811
- throw new Error(
812
- "A middleware file cannot export both a default handler and a named middleware handler"
813
- );
814
- }
815
- if (hasNamedExport) {
816
- return {
817
- handlers: [
818
- async (ctx) => {
819
- return namedExport(toWebRequest(ctx), createRequestMiddlewareContext(ctx));
820
- }
821
- ],
822
- config: module2.config
823
- };
824
- }
825
- if (defaultExport && typeof defaultExport === "object" && "build" in defaultExport) {
826
- if (typeof defaultExport.setBasePath === "function") {
827
- defaultExport.setBasePath(routePath);
828
- }
829
- const built = defaultExport.build();
830
- const handlers = Array.isArray(built?.handlers) ? built.handlers.filter((handler) => typeof handler === "function") : [];
831
- return handlers.length > 0 ? {
832
- handlers,
833
- config: module2.config || built?.config
834
- } : null;
835
- }
836
- if (typeof defaultExport === "function") {
837
- return {
838
- handlers: [defaultExport],
839
- config: module2.config
840
- };
841
- }
842
- return null;
843
- }
844
- __name(normalizeMiddlewareModule, "normalizeMiddlewareModule");
845
14
 
846
- // src/utils/decode.ts
847
- function decodeRouteSegment(segment) {
848
- try {
849
- return decodeURIComponent(segment);
850
- } catch {
851
- return segment;
852
- }
853
- }
854
- __name(decodeRouteSegment, "decodeRouteSegment");
855
- function canonicalizeRequestPathSegments(pathname) {
856
- const segments = pathname.split("/").filter(Boolean);
857
- if (!pathname.includes("%")) return segments;
858
- return segments.map(decodeRouteSegment);
859
- }
860
- __name(canonicalizeRequestPathSegments, "canonicalizeRequestPathSegments");
861
- function canonicalizeRequestPathname(pathname) {
862
- const encoded = pathname.includes("%");
863
- if (!encoded && !pathname.includes("//")) return pathname;
864
- const collapsed = pathname.replace(/\/{2,}/g, "/");
865
- if (!encoded) return collapsed;
866
- return collapsed.split("/").map((segment) => {
867
- const decoded = decodeRouteSegment(segment);
868
- return decoded === segment ? segment : decoded.replace(/\//g, "%2F");
869
- }).join("/");
870
- }
871
- __name(canonicalizeRequestPathname, "canonicalizeRequestPathname");
15
+ var _chunkBYODCJD6cjs = require('./chunk-BYODCJD6.cjs');
872
16
 
873
- // src/utils.ts
874
- var logger = {
875
- info: /* @__PURE__ */ __name((message) => console.log(`[info] ${message}`), "info"),
876
- success: /* @__PURE__ */ __name((message) => console.log(`[success] ${message}`), "success"),
877
- warn: /* @__PURE__ */ __name((message) => console.warn(`\u26A0\uFE0F ${message}`), "warn"),
878
- error: /* @__PURE__ */ __name((message) => console.error(`\u274C ${message}`), "error"),
879
- ready: /* @__PURE__ */ __name((message) => console.log(`${message}`), "ready"),
880
- event: /* @__PURE__ */ __name((message) => console.log(` ${message}`), "event")
881
- };
882
17
 
883
- // src/server/response.ts
884
- function watchResponseEvent(res, events) {
885
- if (typeof res.once !== "function" || typeof res.removeListener !== "function") {
886
- return null;
887
- }
888
- let settled = false;
889
- const listeners = events.map(([event, value]) => {
890
- const listener = /* @__PURE__ */ __name(() => {
891
- if (settled) return;
892
- settled = true;
893
- dispose();
894
- resolvePromise(value);
895
- }, "listener");
896
- return { event, listener };
897
- });
898
- let resolvePromise;
899
- const promise = new Promise((resolve) => {
900
- resolvePromise = resolve;
901
- for (const { event, listener } of listeners) {
902
- res.once(event, listener);
903
- }
904
- });
905
- const dispose = /* @__PURE__ */ __name(() => {
906
- for (const { event, listener } of listeners) {
907
- res.removeListener(event, listener);
908
- }
909
- }, "dispose");
910
- return { promise, dispose };
911
- }
912
- __name(watchResponseEvent, "watchResponseEvent");
913
- async function waitForWritable(res) {
914
- if (res.writableEnded || res.destroyed) {
915
- return false;
916
- }
917
- const watcher = watchResponseEvent(res, [
918
- ["drain", true],
919
- ["close", false],
920
- ["error", false]
921
- ]);
922
- if (!watcher) {
923
- return false;
924
- }
925
- try {
926
- return await watcher.promise;
927
- } finally {
928
- watcher.dispose();
929
- }
930
- }
931
- __name(waitForWritable, "waitForWritable");
932
- function splitSetCookieHeader(value) {
933
- const cookies = [];
934
- let start = 0;
935
- for (let index = 0; index < value.length; index += 1) {
936
- if (value[index] !== ",") continue;
937
- let next = index + 1;
938
- while (value[next] === " " || value[next] === " ") next += 1;
939
- const equals = value.indexOf("=", next);
940
- if (equals === -1) continue;
941
- const separator = value.slice(next, equals);
942
- if (separator.length === 0 || /[;,\s]/.test(separator)) continue;
943
- cookies.push(value.slice(start, index).trim());
944
- start = next;
945
- index = next - 1;
946
- }
947
- cookies.push(value.slice(start).trim());
948
- return cookies.filter(Boolean);
949
- }
950
- __name(splitSetCookieHeader, "splitSetCookieHeader");
951
- function applyWebResponseHeaders(res, headers, options = {}) {
952
- const responseHeaders = headers;
953
- const rawSetCookies = responseHeaders.raw?.()["set-cookie"];
954
- const setCookies = responseHeaders.getSetCookie?.() || rawSetCookies || [];
955
- const existing = options.appendSetCookie && typeof res.getHeader === "function" ? res.getHeader("Set-Cookie") : void 0;
956
- const existingCookies = Array.isArray(existing) ? existing.map(String) : existing === void 0 ? [] : [String(existing)];
957
- let fallbackSetCookie = "";
958
- headers.forEach((value, key) => {
959
- if (key.toLowerCase() === "set-cookie") {
960
- fallbackSetCookie = value;
961
- return;
962
- }
963
- res.setHeader(key, value);
964
- });
965
- const cookies = setCookies.length > 0 ? setCookies : fallbackSetCookie ? splitSetCookieHeader(fallbackSetCookie) : [];
966
- if (cookies.length > 0) {
967
- res.setHeader("Set-Cookie", [...existingCookies, ...cookies]);
968
- }
969
- }
970
- __name(applyWebResponseHeaders, "applyWebResponseHeaders");
971
- async function sendWebResponse(res, response) {
972
- res.statusCode = response.status;
973
- applyWebResponseHeaders(res, response.headers, { appendSetCookie: true });
974
- if (!response.body) {
975
- res.end();
976
- return;
977
- }
978
- if (typeof res.write !== "function") {
979
- const body = await response.arrayBuffer();
980
- res.end(Buffer.from(body));
981
- return;
982
- }
983
- const reader = response.body.getReader();
984
- const disconnectWatcher = watchResponseEvent(res, [
985
- ["close", true],
986
- ["error", true]
987
- ]);
988
- try {
989
- while (true) {
990
- if (res.destroyed) {
991
- void reader.cancel().catch(() => {
992
- });
993
- return;
994
- }
995
- const read = reader.read().then((result) => ({ type: "read", result }));
996
- const next = disconnectWatcher ? await Promise.race([
997
- read,
998
- disconnectWatcher.promise.then(() => ({ type: "disconnect" }))
999
- ]) : await read;
1000
- if (next.type === "disconnect") {
1001
- void reader.cancel().catch(() => {
1002
- });
1003
- return;
1004
- }
1005
- const { done, value } = next.result;
1006
- if (done) {
1007
- break;
1008
- }
1009
- if (!value || value.byteLength === 0) {
1010
- continue;
1011
- }
1012
- if (!res.write(value)) {
1013
- if (!await waitForWritable(res)) {
1014
- void reader.cancel().catch(() => {
1015
- });
1016
- return;
1017
- }
1018
- }
1019
- }
1020
- res.end();
1021
- } catch (error) {
1022
- void reader.cancel(error).catch(() => {
1023
- });
1024
- if (!res.writableEnded) {
1025
- const responseError = error instanceof Error ? error : new Error(String(error));
1026
- if (typeof res.destroy === "function") {
1027
- res.destroy(responseError);
1028
- } else {
1029
- res.end();
1030
- }
1031
- }
1032
- throw error;
1033
- } finally {
1034
- disconnectWatcher?.dispose();
1035
- try {
1036
- reader.releaseLock();
1037
- } catch {
1038
- }
1039
- }
1040
- }
1041
- __name(sendWebResponse, "sendWebResponse");
1042
18
 
1043
- // src/tracing.ts
1044
- var import_api = require("@opentelemetry/api");
1045
- var FARM_TRACER_NAME = "@farm.js/core";
1046
- var ALL_SPAN_KINDS = [
1047
- "request",
1048
- "render",
1049
- "middleware",
1050
- "api",
1051
- "integration",
1052
- "storage",
1053
- "ppr",
1054
- "build",
1055
- "plugin"
1056
- ];
1057
- var DEFAULT_IGNORED_PATHS = [
1058
- "/@vite/",
1059
- "/@fs/",
1060
- "/@id/",
1061
- "/@react-refresh",
1062
- "/node_modules/",
1063
- "/__vite",
1064
- "/.well-known/appspecific/"
1065
- ];
1066
- var FARM_REQUEST_METHOD_CONTEXT_KEY = (0, import_api.createContextKey)("@farm.js/core/request-method");
1067
- var TRACING_RUNTIME = /* @__PURE__ */ Symbol.for("@farm.js/core/tracing-runtime/v1");
1068
- var runtime = globalThis;
1069
- var tracingState = runtime[TRACING_RUNTIME] ?? (runtime[TRACING_RUNTIME] = normalizeFarmTracingConfig(false));
1070
- function normalizeFarmTracingConfig(config) {
1071
- if (!config) {
1072
- return {
1073
- enabled: false,
1074
- spans: new Set(ALL_SPAN_KINDS),
1075
- recordEvents: true,
1076
- attributes: {},
1077
- ignorePaths: DEFAULT_IGNORED_PATHS
1078
- };
1079
- }
1080
- if (config === true) {
1081
- return {
1082
- enabled: true,
1083
- spans: new Set(ALL_SPAN_KINDS),
1084
- recordEvents: true,
1085
- attributes: {},
1086
- ignorePaths: DEFAULT_IGNORED_PATHS
1087
- };
1088
- }
1089
- return {
1090
- enabled: config.enabled ?? true,
1091
- spans: new Set(config.spans ?? ALL_SPAN_KINDS),
1092
- recordEvents: config.recordEvents ?? true,
1093
- attributes: { ...config.attributes },
1094
- ignorePaths: [...DEFAULT_IGNORED_PATHS, ...config.ignorePaths ?? []]
1095
- };
1096
- }
1097
- __name(normalizeFarmTracingConfig, "normalizeFarmTracingConfig");
1098
- function recordFarmEventTrace(event) {
1099
- if (!tracingState.enabled) return void 0;
1100
- const activeContext = import_api.context.active();
1101
- const activeSpan = import_api.trace.getSpan(activeContext);
1102
- const traceContext = getSpanTraceContext(activeSpan);
1103
- if (activeSpan && traceContext) {
1104
- if (event.type === "route.matched") {
1105
- const method = activeContext.getValue(FARM_REQUEST_METHOD_CONTEXT_KEY) ?? "HTTP";
1106
- activeSpan.updateName(`${method} ${event.route}`);
1107
- activeSpan.setAttribute("http.route", event.route);
1108
- activeSpan.setAttribute("farm.route", event.route);
1109
- }
1110
- if (tracingState.recordEvents) {
1111
- activeSpan.addEvent(event.type, toEventAttributes(event), event.timestamp);
1112
- }
1113
- const error = event.type === "request.error" ? void 0 : getEventError(event);
1114
- if (error !== void 0) {
1115
- if (event.type === "render.error") {
1116
- recordSpanException(activeSpan, error);
1117
- } else {
1118
- recordSpanError(activeSpan, error);
1119
- }
1120
- }
1121
- }
1122
- const completedTraceContext = recordCompletedEventSpan(event, activeContext);
1123
- return traceContext ?? completedTraceContext;
1124
- }
1125
- __name(recordFarmEventTrace, "recordFarmEventTrace");
1126
- function recordCompletedEventSpan(event, parentContext) {
1127
- const descriptor = getCompletedSpanDescriptor(event);
1128
- if (!descriptor || !tracingState.spans.has(descriptor.kind)) return void 0;
1129
- const tracer = import_api.trace.getTracer(FARM_TRACER_NAME);
1130
- const span = tracer.startSpan(
1131
- descriptor.name,
1132
- {
1133
- kind: import_api.SpanKind.INTERNAL,
1134
- startTime: event.timestamp - descriptor.durationMs,
1135
- attributes: {
1136
- ...tracingState.attributes,
1137
- ...toEventAttributes(event),
1138
- "farm.event.type": event.type
1139
- }
1140
- },
1141
- parentContext
1142
- );
1143
- const status = "status" in event && typeof event.status === "number" ? event.status : void 0;
1144
- if (status !== void 0) setResponseStatus(span, status);
1145
- const error = getEventError(event);
1146
- if (error !== void 0) recordSpanError(span, error);
1147
- const traceContext = getSpanTraceContext(span);
1148
- span.end(event.timestamp);
1149
- return traceContext;
1150
- }
1151
- __name(recordCompletedEventSpan, "recordCompletedEventSpan");
1152
- function getCompletedSpanDescriptor(event) {
1153
- if (!("durationMs" in event) || typeof event.durationMs !== "number") return void 0;
1154
- switch (event.type) {
1155
- case "render.complete":
1156
- return { kind: "render", name: `farm.render ${event.route}`, durationMs: event.durationMs };
1157
- case "render.stream.shellReady":
1158
- return {
1159
- kind: "render",
1160
- name: `farm.render.shell ${event.route}`,
1161
- durationMs: event.durationMs
1162
- };
1163
- case "render.stream.complete":
1164
- return {
1165
- kind: "render",
1166
- name: `farm.render.stream ${event.route}`,
1167
- durationMs: event.durationMs
1168
- };
1169
- case "middleware.complete":
1170
- return {
1171
- kind: "middleware",
1172
- name: `farm.middleware ${event.name ?? event.route ?? "anonymous"}`,
1173
- durationMs: event.durationMs
1174
- };
1175
- case "api.request.complete":
1176
- case "api.error":
1177
- return {
1178
- kind: "api",
1179
- name: `farm.api ${event.method} ${event.route}`,
1180
- durationMs: event.durationMs
1181
- };
1182
- case "integration.api.call.complete":
1183
- return {
1184
- kind: "integration",
1185
- name: `farm.integration ${event.integration}.${event.operation}`,
1186
- durationMs: event.durationMs
1187
- };
1188
- case "storage.query.complete":
1189
- return {
1190
- kind: "storage",
1191
- name: `farm.storage ${event.operation}`,
1192
- durationMs: event.durationMs
1193
- };
1194
- case "ppr.refresh.complete":
1195
- return {
1196
- kind: "ppr",
1197
- name: `farm.ppr.refresh ${event.route}`,
1198
- durationMs: event.durationMs
1199
- };
1200
- case "build.complete":
1201
- return {
1202
- kind: "build",
1203
- name: `farm.build${event.target ? ` ${event.target}` : ""}`,
1204
- durationMs: event.durationMs
1205
- };
1206
- case "plugin.hook.complete":
1207
- return {
1208
- kind: "plugin",
1209
- name: `farm.plugin ${event.plugin}.${event.hook}`,
1210
- durationMs: event.durationMs
1211
- };
1212
- default:
1213
- return void 0;
1214
- }
1215
- }
1216
- __name(getCompletedSpanDescriptor, "getCompletedSpanDescriptor");
1217
- function hashFarmCacheKey(value) {
1218
- let hash = 2166136261;
1219
- for (let index = 0; index < value.length; index++) {
1220
- hash ^= value.charCodeAt(index);
1221
- hash = Math.imul(hash, 16777619);
1222
- }
1223
- return (hash >>> 0).toString(16).padStart(8, "0");
1224
- }
1225
- __name(hashFarmCacheKey, "hashFarmCacheKey");
1226
- function toEventAttributes(event) {
1227
- const attributes = {};
1228
- const redactKey = typeof event.type === "string" && event.type.startsWith("cache.");
1229
- for (const [key, value] of Object.entries(event)) {
1230
- if (key === "timestamp" || key === "level" || key === "error" || key === "traceId" || key === "spanId" || key === "traceSampled" || value === void 0) {
1231
- continue;
1232
- }
1233
- if (redactKey && key === "key" && typeof value === "string") {
1234
- attributes["farm.key_hash"] = hashFarmCacheKey(value);
1235
- continue;
1236
- }
1237
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1238
- attributes[`farm.${key}`] = value;
1239
- } else if (Array.isArray(value)) {
1240
- if (value.every((entry) => typeof entry === "string")) {
1241
- attributes[`farm.${key}`] = value;
1242
- } else if (value.every((entry) => typeof entry === "number")) {
1243
- attributes[`farm.${key}`] = value;
1244
- } else if (value.every((entry) => typeof entry === "boolean")) {
1245
- attributes[`farm.${key}`] = value;
1246
- }
1247
- }
1248
- }
1249
- return attributes;
1250
- }
1251
- __name(toEventAttributes, "toEventAttributes");
1252
- function getEventError(event) {
1253
- return "error" in event ? event.error : void 0;
1254
- }
1255
- __name(getEventError, "getEventError");
1256
- function recordSpanException(span, error) {
1257
- const normalized = error instanceof Error ? error : new Error(String(error));
1258
- span.recordException(normalized);
1259
- return normalized;
1260
- }
1261
- __name(recordSpanException, "recordSpanException");
1262
- function recordSpanError(span, error) {
1263
- const normalized = recordSpanException(span, error);
1264
- span.setStatus({ code: import_api.SpanStatusCode.ERROR, message: normalized.message });
1265
- }
1266
- __name(recordSpanError, "recordSpanError");
1267
- function setResponseStatus(span, status) {
1268
- span.setAttribute("http.response.status_code", status);
1269
- if (status >= 500) {
1270
- span.setStatus({ code: import_api.SpanStatusCode.ERROR });
1271
- }
1272
- }
1273
- __name(setResponseStatus, "setResponseStatus");
1274
- function getSpanTraceContext(span) {
1275
- if (!span) return void 0;
1276
- const spanContext = span.spanContext();
1277
- if (!(0, import_api.isSpanContextValid)(spanContext)) return void 0;
1278
- return {
1279
- traceId: spanContext.traceId,
1280
- spanId: spanContext.spanId,
1281
- traceSampled: (spanContext.traceFlags & 1) === 1
1282
- };
1283
- }
1284
- __name(getSpanTraceContext, "getSpanTraceContext");
19
+ var _chunkY53ZSFN6cjs = require('./chunk-Y53ZSFN6.cjs');
1285
20
 
1286
- // src/observability.ts
1287
- var OBSERVABILITY_RUNTIME = /* @__PURE__ */ Symbol.for("@farm.js/core/observability-runtime/v1");
1288
- var runtime2 = globalThis;
1289
- var shared = runtime2[OBSERVABILITY_RUNTIME] ?? (runtime2[OBSERVABILITY_RUNTIME] = {
1290
- handlers: /* @__PURE__ */ new Set(),
1291
- unfilteredHandlers: /* @__PURE__ */ new Set(),
1292
- config: { logs: false, handlers: [], tracing: normalizeFarmTracingConfig(false) }
1293
- });
1294
- var runtimeHandlers = shared.handlers;
1295
- var unfilteredRuntimeHandlers = shared.unfilteredHandlers;
1296
- var observabilityState = shared.config;
1297
- function emitFarmEvent(input) {
1298
- const event = {
1299
- timestamp: Date.now(),
1300
- level: inferFarmEventLevel(input.type),
1301
- ...input
1302
- };
1303
- const traceContext = recordFarmEventTrace(event);
1304
- if (traceContext) {
1305
- event.traceId = traceContext.traceId;
1306
- event.spanId = traceContext.spanId;
1307
- event.traceSampled = traceContext.traceSampled;
1308
- }
1309
- notifyFarmEventHandlers(event, unfilteredRuntimeHandlers);
1310
- if (!shouldEmitFarmEvent(event)) return event;
1311
- if (observabilityState.logs) {
1312
- logFarmEvent(event);
1313
- }
1314
- notifyFarmEventHandlers(event, [...observabilityState.handlers, ...runtimeHandlers]);
1315
- return event;
1316
- }
1317
- __name(emitFarmEvent, "emitFarmEvent");
1318
- function notifyFarmEventHandlers(event, handlers) {
1319
- for (const handler of handlers) {
1320
- try {
1321
- Promise.resolve(handler(event)).catch((error) => {
1322
- console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);
1323
- });
1324
- } catch (error) {
1325
- console.warn(`[farm:observability] event handler failed: ${formatError(error)}`);
1326
- }
1327
- }
1328
- }
1329
- __name(notifyFarmEventHandlers, "notifyFarmEventHandlers");
1330
- function shouldEmitFarmEvent(event) {
1331
- if (!observabilityState.logs && observabilityState.handlers.length === 0 && runtimeHandlers.size === 0) {
1332
- return false;
1333
- }
1334
- if (observabilityState.events && !observabilityState.events.has(event.type)) {
1335
- return false;
1336
- }
1337
- return true;
1338
- }
1339
- __name(shouldEmitFarmEvent, "shouldEmitFarmEvent");
1340
- function inferFarmEventLevel(type) {
1341
- if (type === "error" || type.endsWith(".error") || type.endsWith(".failed")) {
1342
- return "error";
1343
- }
1344
- if (type.endsWith(".bypass") || type.endsWith(".invalidated") || type.endsWith(".stale") || type.endsWith(".notFound")) {
1345
- return "warn";
1346
- }
1347
- if (type.endsWith(".hit") || type.endsWith(".miss") || type.endsWith(".start") || type.endsWith(".shellReady")) {
1348
- return "debug";
1349
- }
1350
- return "info";
1351
- }
1352
- __name(inferFarmEventLevel, "inferFarmEventLevel");
1353
- function logFarmEvent(event) {
1354
- const message = `[farm:${event.level}] ${event.type}${formatFarmEventDetails(event)}`;
1355
- switch (event.level) {
1356
- case "error":
1357
- console.error(message);
1358
- break;
1359
- case "warn":
1360
- console.warn(message);
1361
- break;
1362
- default:
1363
- console.log(message);
1364
- break;
1365
- }
1366
- }
1367
- __name(logFarmEvent, "logFarmEvent");
1368
- function formatFarmEventDetails(event) {
1369
- const details = [];
1370
- const record = event;
1371
- for (const key of [
1372
- "route",
1373
- "pathname",
1374
- "method",
1375
- "status",
1376
- "key",
1377
- "tag",
1378
- "path",
1379
- "reason",
1380
- "durationMs",
1381
- "integration",
1382
- "server",
1383
- "tool",
1384
- "outcome",
1385
- "operation",
1386
- "plugin",
1387
- "hook",
1388
- "target",
1389
- "count"
1390
- ]) {
1391
- const value = record[key];
1392
- if (value !== void 0) {
1393
- details.push(`${key}=${formatDetailValue(value)}`);
1394
- }
1395
- }
1396
- return details.length > 0 ? ` ${details.join(" ")}` : "";
1397
- }
1398
- __name(formatFarmEventDetails, "formatFarmEventDetails");
1399
- function formatDetailValue(value) {
1400
- if (typeof value === "string") {
1401
- return value;
1402
- }
1403
- if (typeof value === "number" || typeof value === "boolean") {
1404
- return String(value);
1405
- }
1406
- try {
1407
- return JSON.stringify(value);
1408
- } catch {
1409
- return String(value);
1410
- }
1411
- }
1412
- __name(formatDetailValue, "formatDetailValue");
1413
- function formatError(error) {
1414
- return error instanceof Error ? error.message : String(error);
1415
- }
1416
- __name(formatError, "formatError");
1417
21
 
1418
- // src/navigation-errors.ts
1419
- var REDIRECT_ERROR_CODE = "FARM_REDIRECT";
1420
- var NOT_FOUND_ERROR_CODE = "FARM_NOT_FOUND";
1421
- var REDIRECT_ERROR_SYMBOL = /* @__PURE__ */ Symbol.for("farm.navigation.redirect");
1422
- var NOT_FOUND_ERROR_SYMBOL = /* @__PURE__ */ Symbol.for("farm.navigation.notFound");
1423
- function isFarmRedirectError(error) {
1424
- return Boolean(getFarmRedirectError(error));
1425
- }
1426
- __name(isFarmRedirectError, "isFarmRedirectError");
1427
- function getFarmRedirectError(error) {
1428
- if (!error || typeof error !== "object") return null;
1429
- const candidate = error;
1430
- if (candidate[REDIRECT_ERROR_SYMBOL]) {
1431
- return candidate[REDIRECT_ERROR_SYMBOL];
1432
- }
1433
- if (typeof candidate.digest === "string" && candidate.digest.startsWith(`${REDIRECT_ERROR_CODE};`)) {
1434
- const [, status, ...urlParts] = candidate.digest.split(";");
1435
- const parsedStatus = Number(status);
1436
- if (isFarmRedirectStatus(parsedStatus)) {
1437
- return {
1438
- status: parsedStatus,
1439
- url: urlParts.join(";")
1440
- };
1441
- }
1442
- }
1443
- return null;
1444
- }
1445
- __name(getFarmRedirectError, "getFarmRedirectError");
1446
- function isFarmNotFoundError(error) {
1447
- if (!error || typeof error !== "object") return false;
1448
- const candidate = error;
1449
- return Boolean(candidate[NOT_FOUND_ERROR_SYMBOL] || candidate.digest === NOT_FOUND_ERROR_CODE);
1450
- }
1451
- __name(isFarmNotFoundError, "isFarmNotFoundError");
1452
- function isFarmRedirectStatus(status) {
1453
- return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
1454
- }
1455
- __name(isFarmRedirectStatus, "isFarmRedirectStatus");
1456
22
 
1457
- // src/base-path.ts
1458
- var FARM_BASE_PATH = /* @__PURE__ */ Symbol.for("farm.basePath");
1459
- function getFarmGlobalState() {
1460
- return globalThis;
1461
- }
1462
- __name(getFarmGlobalState, "getFarmGlobalState");
1463
- function getFarmBasePath() {
1464
- return getFarmGlobalState()[FARM_BASE_PATH] ?? "";
1465
- }
1466
- __name(getFarmBasePath, "getFarmBasePath");
1467
- function stripFarmBasePath(pathname, basePath = getFarmBasePath()) {
1468
- const normalizedBasePath = normalizeFarmBasePath(basePath);
1469
- if (!normalizedBasePath) return pathname || "/";
1470
- if (pathname === normalizedBasePath) return "/";
1471
- if (!pathname.startsWith(`${normalizedBasePath}/`)) return pathname || "/";
1472
- return pathname.slice(normalizedBasePath.length) || "/";
1473
- }
1474
- __name(stripFarmBasePath, "stripFarmBasePath");
1475
- function normalizeFarmBasePath(basePath) {
1476
- if (!basePath || basePath === "/") return "";
1477
- const hasUnstableCharacters = /* @__PURE__ */ __name((candidate) => candidate.includes("\\") || Array.from(candidate).some((character) => {
1478
- const code = character.charCodeAt(0);
1479
- return code <= 31 || code >= 127 && code <= 159;
1480
- }), "hasUnstableCharacters");
1481
- if (hasUnstableCharacters(basePath)) {
1482
- throw new Error("Farm basePath cannot contain backslashes or control characters.");
1483
- }
1484
- const pathname = basePath.trim();
1485
- if (!pathname || pathname === "/") return "";
1486
- if (pathname.includes("?") || pathname.includes("#")) {
1487
- throw new Error("Farm basePath cannot contain a query string or hash.");
1488
- }
1489
- if (pathname.startsWith("//") || /^[a-z][a-z\d+.-]*:\/\//i.test(pathname)) {
1490
- throw new Error('Farm basePath must be a pathname such as "/docs", not a URL.');
1491
- }
1492
- for (const segment of pathname.split("/")) {
1493
- let decoded = segment;
1494
- try {
1495
- decoded = decodeURIComponent(segment);
1496
- } catch {
1497
- }
1498
- if (hasUnstableCharacters(decoded)) {
1499
- throw new Error("Farm basePath cannot contain backslashes or control characters.");
1500
- }
1501
- if (decoded.includes("/")) {
1502
- throw new Error("Farm basePath cannot contain percent-encoded path separators.");
1503
- }
1504
- if (decoded === "." || decoded === "..") {
1505
- throw new Error('Farm basePath cannot contain "." or ".." path segments.');
1506
- }
1507
- }
1508
- return `/${pathname}`.replace(/\/{2,}/g, "/").replace(/\/+$/, "");
1509
- }
1510
- __name(normalizeFarmBasePath, "normalizeFarmBasePath");
1511
23
 
1512
- // src/i18n/routing.ts
1513
- function resolveFarmLocalePath(pathname, config) {
1514
- const normalized = normalizePathname(stripFarmBasePath(pathname, config.basePath));
1515
- if (config.routing === "none") {
1516
- return { pathname: normalized, explicit: false };
1517
- }
1518
- const segments = normalized.split("/").filter(Boolean);
1519
- const firstSegment = segments[0];
1520
- const locale = config.locales.find(
1521
- (candidate) => candidate.toLowerCase() === firstSegment?.toLowerCase()
1522
- );
1523
- if (!locale) {
1524
- return { pathname: normalized, explicit: false };
1525
- }
1526
- const remaining = segments.slice(1);
1527
- return {
1528
- locale,
1529
- pathname: remaining.length > 0 ? `/${remaining.join("/")}` : "/",
1530
- explicit: true
1531
- };
1532
- }
1533
- __name(resolveFarmLocalePath, "resolveFarmLocalePath");
1534
- function stripFarmLocaleFromPathname(pathname, config) {
1535
- return resolveFarmLocalePath(pathname, config).pathname;
1536
- }
1537
- __name(stripFarmLocaleFromPathname, "stripFarmLocaleFromPathname");
1538
- function normalizePathname(pathname) {
1539
- const withLeadingSlash = pathname.startsWith("/") ? pathname : `/${pathname}`;
1540
- if (withLeadingSlash === "/") return "/";
1541
- return withLeadingSlash.replace(/\/{2,}/g, "/").replace(/\/$/, "") || "/";
1542
- }
1543
- __name(normalizePathname, "normalizePathname");
1544
24
 
1545
- // src/cli-colors.ts
1546
- var import_picocolors = __toESM(require("picocolors"));
1547
- function createCliColors(interactive = process.stdout.isTTY === true) {
1548
- return import_picocolors.default.createColors(interactive);
1549
- }
1550
- __name(createCliColors, "createCliColors");
1551
25
 
1552
- // src/middleware/path.ts
1553
- function appendMiddlewareRoutePath(routePath, directoryName) {
1554
- if (directoryName.startsWith("(") && directoryName.endsWith(")")) {
1555
- return routePath;
1556
- }
1557
- return routePath === "/" ? `/${directoryName}` : `${routePath}/${directoryName}`;
1558
- }
1559
- __name(appendMiddlewareRoutePath, "appendMiddlewareRoutePath");
26
+ var _chunkXGC343EYcjs = require('./chunk-XGC343EY.cjs');
27
+ require('./chunk-RG3ZOTG5.cjs');
28
+ require('./chunk-M2L4MYDQ.cjs');
29
+ require('./chunk-VQDBNVOO.cjs');
30
+ require('./chunk-HBTUGXHS.cjs');
31
+ require('./chunk-5QIKR7RR.cjs');
32
+ require('./chunk-QNPEUFHQ.cjs');
33
+ require('./chunk-UQZ4AYTH.cjs');
34
+ require('./chunk-E3UK5IIB.cjs');
35
+ require('./chunk-OX6O6WVA.cjs');
36
+ require('./chunk-5ZSWG4UX.cjs');
1560
37
 
1561
- // src/middleware/matcher.ts
1562
- var compiledConfigCache = /* @__PURE__ */ new WeakMap();
1563
- var compiledRouteCache = /* @__PURE__ */ new WeakMap();
1564
- function compileMiddlewareRoute(entry) {
1565
- const path4 = entry.path;
1566
- if (path4 === "/") return void 0;
1567
- const cached = compiledRouteCache.get(entry);
1568
- if (cached?.path === path4) return cached;
1569
- const compiled = {
1570
- path: path4,
1571
- exact: compilePattern(path4),
1572
- nested: compilePattern(`${path4}/:__farmRest*`)
1573
- };
1574
- compiledRouteCache.set(entry, compiled);
1575
- return compiled;
1576
- }
1577
- __name(compileMiddlewareRoute, "compileMiddlewareRoute");
1578
- function matchesMiddlewareRoute(pathname, entry) {
1579
- const compiled = compileMiddlewareRoute(entry);
1580
- if (!compiled) return { matched: true };
1581
- const canonicalPathname = canonicalizeRequestPathname(pathname);
1582
- const exactMatch = matchPattern2(compiled.exact, canonicalPathname);
1583
- if (exactMatch.matched) return exactMatch;
1584
- const nestedMatch = matchPattern2(compiled.nested, canonicalPathname);
1585
- if (!nestedMatch.matched) return { matched: false };
1586
- const params = { ...nestedMatch.params };
1587
- delete params.__farmRest;
1588
- return { matched: true, params: Object.keys(params).length > 0 ? params : void 0 };
1589
- }
1590
- __name(matchesMiddlewareRoute, "matchesMiddlewareRoute");
1591
- function sameEntries(current, previous) {
1592
- return current === void 0 || previous === void 0 ? current === previous : current.length === previous.length && current.every((entry, index) => entry === previous[index]);
1593
- }
1594
- __name(sameEntries, "sameEntries");
1595
- function toMatcherList(matcher) {
1596
- if (!matcher) return [];
1597
- return Array.isArray(matcher) ? matcher : [matcher];
1598
- }
1599
- __name(toMatcherList, "toMatcherList");
1600
- function escapeRegex(value) {
1601
- return value.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
1602
- }
1603
- __name(escapeRegex, "escapeRegex");
1604
- function parseColonParam(segment) {
1605
- const raw = segment.slice(1);
1606
- const last = raw[raw.length - 1];
1607
- const modifier = last === "*" || last === "+" || last === "?" ? last : void 0;
1608
- return {
1609
- name: modifier ? raw.slice(0, -1) : raw,
1610
- modifier
1611
- };
1612
- }
1613
- __name(parseColonParam, "parseColonParam");
1614
- function compilePathPattern(pattern, trailingSlash = false) {
1615
- const params = [];
1616
- const segments = pattern.split("/").filter(Boolean);
1617
- if (segments.length === 0) {
1618
- return { kind: "path", regex: /^\/$/, params };
1619
- }
1620
- const parts = segments.map((segment) => {
1621
- if (segment === "**") {
1622
- return "(?:/.*)?";
1623
- }
1624
- if (segment === "*") {
1625
- return "/[^/]+";
1626
- }
1627
- if (segment.startsWith(":")) {
1628
- const { name, modifier } = parseColonParam(segment);
1629
- params.push(name);
1630
- if (modifier === "*") {
1631
- return "(?:/(.*))?";
1632
- }
1633
- if (modifier === "+") {
1634
- return "/(.+)";
1635
- }
1636
- return "/([^/]+)";
1637
- }
1638
- if (segment.startsWith("[...") && segment.endsWith("]")) {
1639
- params.push(segment.slice(4, -1));
1640
- return "(?:/(.*))?";
1641
- }
1642
- if (segment.startsWith("[") && segment.endsWith("]")) {
1643
- params.push(segment.slice(1, -1));
1644
- return "/([^/]+)";
1645
- }
1646
- return `/${escapeRegex(segment).replace(/\\\*/g, "[^/]*")}`;
1647
- });
1648
- return {
1649
- kind: "path",
1650
- regex: new RegExp(`^${parts.join("")}${trailingSlash ? "/?" : ""}$`),
1651
- params
1652
- };
1653
- }
1654
- __name(compilePathPattern, "compilePathPattern");
1655
- function compileMatcherPattern(pattern) {
1656
- if (typeof pattern === "string" && pattern !== "*" && !pattern.endsWith("(.*)")) {
1657
- return compilePathPattern(pattern, true);
1658
- }
1659
- return compilePattern(pattern);
1660
- }
1661
- __name(compileMatcherPattern, "compileMatcherPattern");
1662
- function compilePattern(pattern) {
1663
- if (pattern instanceof RegExp) {
1664
- return { kind: "regexp", regex: pattern };
1665
- }
1666
- if (pattern === "*" || pattern === "/(.*)") {
1667
- return { kind: "all" };
1668
- }
1669
- if (pattern.endsWith("(.*)")) {
1670
- return {
1671
- kind: "subtree",
1672
- prefix: pattern.slice(0, -4).replace(/\/$/, "")
1673
- };
1674
- }
1675
- return compilePathPattern(pattern);
1676
- }
1677
- __name(compilePattern, "compilePattern");
1678
- function compileMiddlewareConfig(config) {
1679
- const compiled = {
1680
- matcher: config.matcher ? toMatcherList(config.matcher).map(
1681
- (matcher) => typeof matcher === "function" ? matcher : compileMatcherPattern(matcher)
1682
- ) : void 0,
1683
- exclude: config.exclude?.map(compilePattern)
1684
- };
1685
- compiledConfigCache.set(config, {
1686
- compiled,
1687
- matcher: config.matcher,
1688
- matcherEntries: Array.isArray(config.matcher) ? config.matcher.slice() : void 0,
1689
- excludeEntries: config.exclude?.slice()
1690
- });
1691
- return compiled;
1692
- }
1693
- __name(compileMiddlewareConfig, "compileMiddlewareConfig");
1694
- function matchPattern2(pattern, pathname) {
1695
- if (pattern.kind === "all") {
1696
- return { matched: true };
1697
- }
1698
- if (pattern.kind === "subtree") {
1699
- return {
1700
- matched: pathname === pattern.prefix || pathname.startsWith(`${pattern.prefix}/`)
1701
- };
1702
- }
1703
- pattern.regex.lastIndex = 0;
1704
- const match = pattern.regex.exec(pathname);
1705
- if (!match) {
1706
- return { matched: false };
1707
- }
1708
- if (pattern.kind === "regexp") {
1709
- return {
1710
- matched: true,
1711
- params: match.groups ? { ...match.groups } : void 0
1712
- };
1713
- }
1714
- const values = {};
1715
- pattern.params.forEach((param, index) => {
1716
- values[param] = match[index + 1] || "";
1717
- });
1718
- return {
1719
- matched: true,
1720
- params: Object.keys(values).length > 0 ? values : void 0
1721
- };
1722
- }
1723
- __name(matchPattern2, "matchPattern");
1724
- function matchesCompiledMiddlewareConfig(pathname, config, ctx) {
1725
- let canonicalPathname;
1726
- const getCanonicalPathname = /* @__PURE__ */ __name(() => canonicalPathname ?? (canonicalPathname = canonicalizeRequestPathname(pathname)), "getCanonicalPathname");
1727
- if (config.exclude) {
1728
- for (const pattern of config.exclude) {
1729
- if (matchPattern2(pattern, getCanonicalPathname()).matched) {
1730
- return { matched: false };
1731
- }
1732
- }
1733
- }
1734
- if (config.matcher) {
1735
- for (const matcher of config.matcher) {
1736
- if (typeof matcher === "function") {
1737
- if (matcher(ctx)) {
1738
- return { matched: true };
1739
- }
1740
- continue;
1741
- }
1742
- const result = matchPattern2(matcher, getCanonicalPathname());
1743
- if (result.matched) {
1744
- return result;
1745
- }
1746
- }
1747
- return { matched: false };
1748
- }
1749
- return { matched: true };
1750
- }
1751
- __name(matchesCompiledMiddlewareConfig, "matchesCompiledMiddlewareConfig");
1752
- function matchesMiddlewareConfig(pathname, config, ctx) {
1753
- const cached = compiledConfigCache.get(config);
1754
- const unchanged = cached && (Array.isArray(config.matcher) ? sameEntries(config.matcher, cached.matcherEntries) : config.matcher === cached.matcher) && sameEntries(config.exclude, cached.excludeEntries);
1755
- const compiled = unchanged ? cached.compiled : compileMiddlewareConfig(config);
1756
- return matchesCompiledMiddlewareConfig(pathname, compiled, ctx);
1757
- }
1758
- __name(matchesMiddlewareConfig, "matchesMiddlewareConfig");
1759
38
 
1760
- // src/middleware/manager.ts
1761
- function isMiddlewareResponse(value) {
1762
- return value instanceof Response;
1763
- }
1764
- __name(isMiddlewareResponse, "isMiddlewareResponse");
1765
- var _MiddlewareManager = class _MiddlewareManager {
1766
- constructor(appDir, viteServer, config, i18n, server) {
1767
- this.middleware = [];
1768
- this.configMiddleware = [];
1769
- this.appDirs = Array.isArray(appDir) ? [...appDir] : [appDir];
1770
- this.viteServer = viteServer;
1771
- this.i18n = i18n;
1772
- this.server = server;
1773
- this.configure(config);
1774
- }
1775
- configure(config) {
1776
- this.configMiddleware = [];
1777
- this.globalConfig = void 0;
1778
- if (!config) return;
1779
- const entries = Array.isArray(config) ? config : [config];
1780
- for (const [index, entry] of entries.entries()) {
1781
- const handlers = this.getConfigHandlers(entry);
1782
- const middlewareConfig = this.toMiddlewareConfig(entry);
1783
- compileMiddlewareConfig(middlewareConfig);
1784
- if (handlers.length === 0) {
1785
- this.globalConfig = middlewareConfig;
1786
- continue;
1787
- }
1788
- this.configMiddleware.push({
1789
- path: "/",
1790
- filePath: `farm.config.ts#middleware-${index}`,
1791
- handlers,
1792
- config: middlewareConfig,
1793
- source: "config"
1794
- });
1795
- }
1796
- }
1797
- /**
1798
- * Discover all middleware.ts files
1799
- */
1800
- async discover() {
1801
- const middlewareByPath = /* @__PURE__ */ new Map();
1802
- for (const appDir of this.appDirs) {
1803
- const discovered = [];
1804
- await this.discoverInDirectory(appDir, "/", discovered);
1805
- for (const middleware2 of discovered) {
1806
- compileMiddlewareRoute(middleware2);
1807
- middlewareByPath.set(middleware2.path, middleware2);
1808
- }
1809
- }
1810
- this.middleware = Array.from(middlewareByPath.values());
1811
- this.middleware.sort((a, b) => {
1812
- const depthA = a.path.split("/").filter(Boolean).length;
1813
- const depthB = b.path.split("/").filter(Boolean).length;
1814
- return depthA - depthB;
1815
- });
1816
- if (process.env.FARM_VERBOSE && this.middleware.length > 0) {
1817
- logger.success(`Discovered ${this.middleware.length} middleware files`);
1818
- for (const mw of this.middleware) {
1819
- logger.info(` ${mw.path} (${mw.handlers.length} handlers)`);
1820
- }
1821
- }
1822
- }
1823
- /**
1824
- * Recursively discover middleware files
1825
- */
1826
- async discoverInDirectory(dir, routePath, discovered) {
1827
- if (!fs.existsSync(dir)) {
1828
- return;
1829
- }
1830
- const middlewareFile = this.findMiddlewareFile(dir);
1831
- if (middlewareFile) {
1832
- const middleware2 = await this.loadMiddleware(middlewareFile, routePath);
1833
- if (middleware2) {
1834
- discovered.push(middleware2);
1835
- }
1836
- }
1837
- const entries = fs.readdirSync(dir, { withFileTypes: true });
1838
- for (const entry of entries) {
1839
- if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
1840
- const subPath = path.join(dir, entry.name);
1841
- const subRoutePath = appendMiddlewareRoutePath(routePath, entry.name);
1842
- await this.discoverInDirectory(subPath, subRoutePath, discovered);
1843
- }
1844
- }
1845
- }
1846
- /**
1847
- * Find middleware file in directory
1848
- */
1849
- findMiddlewareFile(dir) {
1850
- const extensions = [".ts", ".tsx", ".js", ".jsx"];
1851
- for (const ext of extensions) {
1852
- const filePath = path.join(dir, `middleware${ext}`);
1853
- if (fs.existsSync(filePath)) {
1854
- return filePath;
1855
- }
1856
- }
1857
- return null;
1858
- }
1859
- /**
1860
- * Load a middleware file
1861
- */
1862
- async loadMiddleware(filePath, routePath) {
1863
- try {
1864
- let module2;
1865
- if (this.viteServer) {
1866
- module2 = await this.viteServer.ssrLoadModule(filePath);
1867
- } else {
1868
- module2 = await import(
1869
- /* @vite-ignore */
1870
- toFileModuleUrl(filePath)
1871
- );
1872
- }
1873
- const normalized = normalizeMiddlewareModule(module2, routePath);
1874
- if (!normalized) {
1875
- throw new Error("must export a default handler or a named middleware handler");
1876
- }
1877
- if (normalized.config) {
1878
- compileMiddlewareConfig(normalized.config);
1879
- }
1880
- return {
1881
- path: routePath,
1882
- filePath,
1883
- handlers: normalized.handlers,
1884
- config: normalized.config,
1885
- source: "file"
1886
- };
1887
- } catch (error) {
1888
- throw new Error(`Failed to load middleware ${filePath}: ${error}`);
1889
- }
1890
- }
1891
- /**
1892
- * Execute middleware for a request
1893
- */
1894
- async execute(req, res) {
1895
- const url = resolveFarmRequestURL(req, { trustProxy: this.server?.trustProxy });
1896
- const pathname = url.pathname;
1897
- const routePathname = this.i18n?.enabled ? stripFarmLocaleFromPathname(pathname, this.i18n) : stripFarmBasePath(pathname, this.i18n?.basePath ?? "/");
1898
- const method = req.method || "GET";
1899
- const startTime = Date.now();
1900
- let parentData;
1901
- let ctx = createContext(req, res, this.viteServer, void 0, this.server);
1902
- if (this.globalConfig) {
1903
- const globalMatch = this.matchesConfig(routePathname, this.globalConfig, ctx);
1904
- if (!globalMatch.matched) {
1905
- return false;
1906
- }
1907
- if (globalMatch.params) {
1908
- ctx.params = { ...ctx.params, ...globalMatch.params };
1909
- }
1910
- }
1911
- const applicable = [
1912
- ...this.configMiddleware.map((mw) => ({ mw, routeMatch: { matched: true } })),
1913
- ...this.middleware.map((mw) => ({ mw, routeMatch: matchesMiddlewareRoute(routePathname, mw) })).filter((entry) => entry.routeMatch.matched)
1914
- ];
1915
- if (applicable.length === 0) {
1916
- return false;
1917
- }
1918
- const pc = createCliColors();
1919
- const log = [
1920
- pc.dim("[") + pc.bold(pc.blue("FARM")) + pc.dim("]"),
1921
- pc.dim("[") + pc.bold(pc.magenta("MIDDLEWARE")) + pc.dim("]"),
1922
- pc.dim("[") + pc.bold(pc.white(method.padEnd(3))) + pc.dim("]"),
1923
- pc.gray("Executing middleware: "),
1924
- pc.gray(pathname),
1925
- pc.dim(` (${(Date.now() - startTime).toFixed(2)}ms)`)
1926
- ].join(" ");
1927
- console.log(log);
1928
- for (const entry of applicable) {
1929
- const { mw, routeMatch } = entry;
1930
- const configMatch = mw.config ? this.matchesConfig(routePathname, mw.config, ctx) : { matched: true };
1931
- if (!configMatch.matched) {
1932
- continue;
1933
- }
1934
- if (routeMatch.params) {
1935
- ctx.params = { ...ctx.params, ...routeMatch.params };
1936
- }
1937
- if (configMatch.params) {
1938
- ctx.params = { ...ctx.params, ...configMatch.params };
1939
- }
1940
- if (parentData) {
1941
- ctx = createContext(req, res, this.viteServer, parentData, this.server);
1942
- if (routeMatch.params) {
1943
- ctx.params = { ...ctx.params, ...routeMatch.params };
1944
- }
1945
- if (configMatch.params) {
1946
- ctx.params = { ...ctx.params, ...configMatch.params };
1947
- }
1948
- }
1949
- const middlewareStartTime = Date.now();
1950
- const middlewareEvent = {
1951
- route: mw.path,
1952
- pathname,
1953
- name: mw.filePath
1954
- };
1955
- emitFarmEvent({ type: "middleware.start", ...middlewareEvent });
1956
- try {
1957
- let handlerIndex = 0;
1958
- let returnedResponse;
1959
- const executeNext = /* @__PURE__ */ __name(async () => {
1960
- if (handlerIndex < mw.handlers.length) {
1961
- const handler = mw.handlers[handlerIndex++];
1962
- const result2 = await handler(ctx, executeNext);
1963
- if (isMiddlewareResponse(result2)) {
1964
- returnedResponse = result2;
1965
- return result2;
1966
- }
1967
- }
1968
- return returnedResponse;
1969
- }, "executeNext");
1970
- const result = await executeNext();
1971
- const response = isMiddlewareResponse(result) ? result : returnedResponse;
1972
- if (response) {
1973
- if (!res.headersSent && !res.writableEnded) {
1974
- for (const [key, value] of ctx.headers) {
1975
- try {
1976
- res.setHeader(key, value);
1977
- } catch (error) {
1978
- }
1979
- }
1980
- }
1981
- emitFarmEvent({
1982
- type: "middleware.shortCircuit",
1983
- ...middlewareEvent,
1984
- status: response.status
1985
- });
1986
- await sendWebResponse(res, response);
1987
- return true;
1988
- }
1989
- if (ctx._handled || res.headersSent || res.writableEnded) {
1990
- emitFarmEvent({
1991
- type: "middleware.shortCircuit",
1992
- ...middlewareEvent,
1993
- status: res.statusCode
1994
- });
1995
- return true;
1996
- }
1997
- emitFarmEvent({
1998
- type: "middleware.complete",
1999
- ...middlewareEvent,
2000
- durationMs: Date.now() - middlewareStartTime
2001
- });
2002
- } catch (error) {
2003
- emitFarmEvent(
2004
- isFarmRedirectError(error) || isFarmNotFoundError(error) ? {
2005
- type: "middleware.shortCircuit",
2006
- ...middlewareEvent,
2007
- status: isFarmRedirectError(error) ? getFarmRedirectError(error).status : 404
2008
- } : { type: "middleware.error", ...middlewareEvent, error }
2009
- );
2010
- throw error;
2011
- }
2012
- parentData = {
2013
- data: new Map(ctx.data),
2014
- locals: new Map(ctx.locals),
2015
- headers: Object.fromEntries(ctx.headers)
2016
- };
2017
- }
2018
- if (!res.headersSent && !res.writableEnded) {
2019
- for (const [key, value] of ctx.headers) {
2020
- try {
2021
- res.setHeader(key, value);
2022
- } catch (error) {
2023
- }
2024
- }
2025
- }
2026
- req.__FARM_MIDDLEWARE_DATA__ = new Map(ctx.data);
2027
- req.__FARM_MIDDLEWARE_CONTEXT__ = new Map(ctx.locals);
2028
- return false;
2029
- }
2030
- /**
2031
- * Check if pathname matches middleware config
2032
- */
2033
- matchesConfig(pathname, config, ctx) {
2034
- return matchesMiddlewareConfig(pathname, config, ctx);
2035
- }
2036
- /**
2037
- * Reload middleware (for HMR)
2038
- */
2039
- async reload() {
2040
- await this.discover();
2041
- }
2042
- getMiddlewares() {
2043
- return [...this.configMiddleware, ...this.middleware];
2044
- }
2045
- hasMiddleware() {
2046
- return this.configMiddleware.length > 0 || this.middleware.length > 0;
2047
- }
2048
- getConfigHandlers(entry) {
2049
- const handlers = [];
2050
- if ("handler" in entry && typeof entry.handler === "function") {
2051
- handlers.push(entry.handler);
2052
- }
2053
- if ("handlers" in entry && Array.isArray(entry.handlers)) {
2054
- handlers.push(...entry.handlers.filter((handler) => typeof handler === "function"));
2055
- }
2056
- return handlers;
2057
- }
2058
- toMiddlewareConfig(entry) {
2059
- const { matcher, exclude, runtime: runtime3 } = entry;
2060
- return { matcher, exclude, runtime: runtime3 };
2061
- }
2062
- };
2063
- __name(_MiddlewareManager, "MiddlewareManager");
2064
- var MiddlewareManager = _MiddlewareManager;
39
+ var _chunkUS2QVW3Ecjs = require('./chunk-US2QVW3E.cjs');
40
+ require('./chunk-U4KT7QP3.cjs');
41
+ require('./chunk-BIDYX3SL.cjs');
42
+ require('./chunk-I57LW5VZ.cjs');
43
+ require('./chunk-NO3WWW3N.cjs');
44
+ require('./chunk-S3JO3N4H.cjs');
2065
45
 
2066
- // src/middleware/server.ts
2067
- var import_async_hooks = require("async_hooks");
2068
- var MIDDLEWARE_DATA_STORE_KEY = /* @__PURE__ */ Symbol.for("farm.middlewareDataStore");
2069
- var MIDDLEWARE_CONTEXT_STORE_KEY = /* @__PURE__ */ Symbol.for("farm.middlewareContextStore");
2070
- function getGlobalMiddlewareStore(key) {
2071
- const state = globalThis;
2072
- const existing = state[key];
2073
- if (existing instanceof import_async_hooks.AsyncLocalStorage) {
2074
- return existing;
2075
- }
2076
- const store = new import_async_hooks.AsyncLocalStorage();
2077
- state[key] = store;
2078
- return store;
2079
- }
2080
- __name(getGlobalMiddlewareStore, "getGlobalMiddlewareStore");
2081
- var middlewareStore = getGlobalMiddlewareStore(MIDDLEWARE_DATA_STORE_KEY);
2082
- var middlewareContextStore = getGlobalMiddlewareStore(MIDDLEWARE_CONTEXT_STORE_KEY);
2083
- function toMiddlewareMap(data) {
2084
- if (data instanceof Map) {
2085
- return new Map(data);
2086
- }
2087
- return new Map(Object.entries(data));
2088
- }
2089
- __name(toMiddlewareMap, "toMiddlewareMap");
2090
- async function _runWithMiddlewareData(data, fn) {
2091
- return middlewareStore.run(toMiddlewareMap(data), fn);
2092
- }
2093
- __name(_runWithMiddlewareData, "_runWithMiddlewareData");
2094
- async function _runWithMiddlewareContext(context2, fn) {
2095
- return middlewareContextStore.run(toMiddlewareMap(context2), fn);
2096
- }
2097
- __name(_runWithMiddlewareContext, "_runWithMiddlewareContext");
2098
- function getMiddlewareData() {
2099
- return middlewareStore.getStore() || /* @__PURE__ */ new Map();
2100
- }
2101
- __name(getMiddlewareData, "getMiddlewareData");
2102
- function getMiddlewareValue(key) {
2103
- const data = getMiddlewareData();
2104
- return data.get(key);
2105
- }
2106
- __name(getMiddlewareValue, "getMiddlewareValue");
2107
- function getMiddlewareContext() {
2108
- return middlewareContextStore.getStore() || /* @__PURE__ */ new Map();
2109
- }
2110
- __name(getMiddlewareContext, "getMiddlewareContext");
2111
46
 
2112
- // src/middleware/helpers.ts
2113
- function unwrapMiddleware(middleware2, defaults) {
2114
- if (!middleware2) {
2115
- return defaults || {};
2116
- }
2117
- const result = { ...defaults };
2118
- for (const [key, value] of middleware2.data) {
2119
- result[key] = value;
2120
- }
2121
- return result;
2122
- }
2123
- __name(unwrapMiddleware, "unwrapMiddleware");
2124
- function getFromMiddleware(middleware2, key, defaultValue) {
2125
- if (!middleware2) {
2126
- return defaultValue;
2127
- }
2128
- const value = middleware2.data.get(key);
2129
- return value !== void 0 ? value : defaultValue;
2130
- }
2131
- __name(getFromMiddleware, "getFromMiddleware");
2132
- function hasMiddlewareData(middleware2) {
2133
- if (!middleware2) return false;
2134
- return middleware2.data.size > 0;
2135
- }
2136
- __name(hasMiddlewareData, "hasMiddlewareData");
2137
47
 
2138
- // src/middleware/production-runtime.ts
2139
- var FARM_SET_COOKIE_HEADERS = /* @__PURE__ */ Symbol("farm.setCookieHeaders");
2140
- var _WebResponseHeaderMap = class _WebResponseHeaderMap extends Map {
2141
- constructor() {
2142
- super(...arguments);
2143
- this.setCookies = [];
2144
- }
2145
- set(key, value) {
2146
- if (key.toLowerCase() === "set-cookie") {
2147
- this.setCookies = [value];
2148
- super.set("Set-Cookie", value);
2149
- return this;
2150
- }
2151
- return super.set(key, value);
2152
- }
2153
- delete(key) {
2154
- if (key.toLowerCase() === "set-cookie") {
2155
- this.setCookies = [];
2156
- return super.delete("Set-Cookie") || super.delete("set-cookie");
2157
- }
2158
- return super.delete(key);
2159
- }
2160
- clear() {
2161
- this.setCookies = [];
2162
- super.clear();
2163
- }
2164
- appendSetCookie(value) {
2165
- this.setCookies.push(value);
2166
- super.set("Set-Cookie", value);
2167
- }
2168
- replaceSetCookies(values) {
2169
- this.setCookies = [...values];
2170
- super.delete("Set-Cookie");
2171
- super.delete("set-cookie");
2172
- if (this.setCookies.length > 0) {
2173
- super.set("Set-Cookie", this.setCookies[this.setCookies.length - 1]);
2174
- }
2175
- }
2176
- getSetCookies() {
2177
- return this.setCookies;
2178
- }
2179
- };
2180
- __name(_WebResponseHeaderMap, "WebResponseHeaderMap");
2181
- var WebResponseHeaderMap = _WebResponseHeaderMap;
2182
- var _WebCookieJar = class _WebCookieJar {
2183
- constructor(request, headers) {
2184
- this.headers = headers;
2185
- this.cookies = parseMiddlewareCookieHeader(request.headers.get("cookie"));
2186
- }
2187
- get(name) {
2188
- return this.cookies[name];
2189
- }
2190
- set(name, value, options = {}) {
2191
- this.cookies[name] = value;
2192
- const cookieString = serializeMiddlewareCookie(name, value, options);
2193
- this.headers.appendSetCookie(cookieString);
2194
- }
2195
- delete(name, options = {}) {
2196
- delete this.cookies[name];
2197
- this.headers.appendSetCookie(serializeMiddlewareCookieDeletion(name, options));
2198
- }
2199
- getAll() {
2200
- return { ...this.cookies };
2201
- }
2202
- };
2203
- __name(_WebCookieJar, "WebCookieJar");
2204
- var WebCookieJar = _WebCookieJar;
2205
- function mapToHeaders(map) {
2206
- const headers = new Headers();
2207
- for (const [key, value] of map) {
2208
- if (key.toLowerCase() === "set-cookie") continue;
2209
- headers.set(key, value);
2210
- }
2211
- for (const cookie of map.getSetCookies()) {
2212
- headers.append("Set-Cookie", cookie);
2213
- }
2214
- return headers;
2215
- }
2216
- __name(mapToHeaders, "mapToHeaders");
2217
- function headersToRecord(headers) {
2218
- return Object.fromEntries(headers);
2219
- }
2220
- __name(headersToRecord, "headersToRecord");
2221
- function isMiddlewareResponse2(value) {
2222
- return value instanceof Response;
2223
- }
2224
- __name(isMiddlewareResponse2, "isMiddlewareResponse");
2225
- function findHeaderName(headers, name) {
2226
- const normalizedName = name.toLowerCase();
2227
- return [...headers.keys()].find((key) => key.toLowerCase() === normalizedName);
2228
- }
2229
- __name(findHeaderName, "findHeaderName");
2230
- function createResponseShim(headers) {
2231
- const bodyChunks = [];
2232
- const encoder = new TextEncoder();
2233
- const response = {
2234
- headersSent: false,
2235
- writableEnded: false,
2236
- statusCode: 200,
2237
- statusMessage: "",
2238
- setHeader(name, value) {
2239
- const existingName = findHeaderName(headers, name);
2240
- if (existingName) headers.delete(existingName);
2241
- if (name.toLowerCase() === "set-cookie") {
2242
- headers.replaceSetCookies(Array.isArray(value) ? value.map(String) : [String(value)]);
2243
- } else {
2244
- headers.set(name, Array.isArray(value) ? value.join(", ") : String(value));
2245
- }
2246
- return this;
2247
- },
2248
- getHeader(name) {
2249
- if (name.toLowerCase() === "set-cookie") {
2250
- const cookies = headers.getSetCookies();
2251
- return cookies.length > 0 ? [...cookies] : void 0;
2252
- }
2253
- const existingName = findHeaderName(headers, name);
2254
- return existingName ? headers.get(existingName) : void 0;
2255
- },
2256
- hasHeader(name) {
2257
- return name.toLowerCase() === "set-cookie" ? headers.getSetCookies().length > 0 : findHeaderName(headers, name) !== void 0;
2258
- },
2259
- getHeaderNames() {
2260
- return [...headers.keys()].map((name) => name.toLowerCase());
2261
- },
2262
- getHeaders() {
2263
- return Object.fromEntries(
2264
- [...headers.keys()].map((name) => [name.toLowerCase(), this.getHeader(name)])
2265
- );
2266
- },
2267
- removeHeader(name) {
2268
- const existingName = findHeaderName(headers, name);
2269
- if (existingName) headers.delete(existingName);
2270
- },
2271
- appendHeader(name, value) {
2272
- const values = Array.isArray(value) ? value.map(String) : [String(value)];
2273
- if (name.toLowerCase() === "set-cookie") {
2274
- for (const item of values) headers.appendSetCookie(item);
2275
- return this;
2276
- }
2277
- const existing = this.getHeader(name);
2278
- return this.setHeader(name, existing ? `${String(existing)}, ${values.join(", ")}` : values);
2279
- },
2280
- writeHead(status, statusMessageOrHeaders, responseHeaders) {
2281
- this.statusCode = status;
2282
- const nextHeaders = typeof statusMessageOrHeaders === "string" ? responseHeaders : statusMessageOrHeaders;
2283
- if (typeof statusMessageOrHeaders === "string") {
2284
- this.statusMessage = statusMessageOrHeaders;
2285
- }
2286
- if (nextHeaders) {
2287
- for (const [key, value] of Object.entries(nextHeaders)) {
2288
- this.setHeader(key, value);
2289
- }
2290
- }
2291
- this.headersSent = true;
2292
- return this;
2293
- },
2294
- flushHeaders() {
2295
- this.headersSent = true;
2296
- },
2297
- write(chunk, encodingOrCallback, callback) {
2298
- bodyChunks.push(typeof chunk === "string" ? encoder.encode(chunk) : new Uint8Array(chunk));
2299
- this.headersSent = true;
2300
- const done = typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
2301
- done?.();
2302
- return true;
2303
- },
2304
- end(chunk, encodingOrCallback, callback) {
2305
- if (typeof chunk === "string" || chunk instanceof Uint8Array) {
2306
- bodyChunks.push(typeof chunk === "string" ? encoder.encode(chunk) : new Uint8Array(chunk));
2307
- }
2308
- this.headersSent = true;
2309
- this.writableEnded = true;
2310
- const done = typeof chunk === "function" ? chunk : typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
2311
- done?.();
2312
- return this;
2313
- }
2314
- };
2315
- return {
2316
- response,
2317
- getResponse(method) {
2318
- if (!response.headersSent && !response.writableEnded) return null;
2319
- const bodyLength = bodyChunks.reduce((total, chunk) => total + chunk.byteLength, 0);
2320
- const body = new Uint8Array(bodyLength);
2321
- let offset = 0;
2322
- for (const chunk of bodyChunks) {
2323
- body.set(chunk, offset);
2324
- offset += chunk.byteLength;
2325
- }
2326
- const bodyAllowed = method.toUpperCase() !== "HEAD" && response.statusCode !== 204 && response.statusCode !== 205 && response.statusCode !== 304;
2327
- return new Response(bodyAllowed && bodyLength > 0 ? body : null, {
2328
- status: response.statusCode,
2329
- statusText: response.statusMessage || void 0,
2330
- headers: mapToHeaders(headers)
2331
- });
2332
- }
2333
- };
2334
- }
2335
- __name(createResponseShim, "createResponseShim");
2336
- function withNodeRequestShape(request, trustProxy, clientAddress) {
2337
- const requestWithShape = request;
2338
- if (!requestWithShape.socket) {
2339
- const forwardedFor = trustProxy ? request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() : void 0;
2340
- try {
2341
- requestWithShape.socket = { remoteAddress: forwardedFor || clientAddress || void 0 };
2342
- } catch {
2343
- }
2344
- }
2345
- return requestWithShape;
2346
- }
2347
- __name(withNodeRequestShape, "withNodeRequestShape");
2348
- function createHandledResponse(body, init, headers) {
2349
- const responseHeaders = new Headers();
2350
- for (const [key, value] of headers) {
2351
- if (key.toLowerCase() === "set-cookie") continue;
2352
- responseHeaders.set(key, value);
2353
- }
2354
- for (const [key, value] of new Headers(init.headers)) {
2355
- responseHeaders.set(key, value);
2356
- }
2357
- for (const cookie of headers.getSetCookies()) {
2358
- responseHeaders.append("Set-Cookie", cookie);
2359
- }
2360
- return new Response(body, { ...init, headers: responseHeaders });
2361
- }
2362
- __name(createHandledResponse, "createHandledResponse");
2363
- function createWebMiddlewareContext(request, parent, trustProxy = false, clientAddress) {
2364
- let currentRequest = withNodeRequestShape(request, trustProxy, clientAddress);
2365
- let handledResponse = null;
2366
- const url = new URL(currentRequest.url);
2367
- const data = parent?.data ? new Map(parent.data) : /* @__PURE__ */ new Map();
2368
- const locals = parent?.locals ? new Map(parent.locals) : /* @__PURE__ */ new Map();
2369
- const headers = new WebResponseHeaderMap();
2370
- if (parent?.headers) {
2371
- for (const [key, value] of Object.entries(parent.headers)) {
2372
- if (key.toLowerCase() === "set-cookie") continue;
2373
- headers.set(key, value);
2374
- }
2375
- }
2376
- const parentCookies = parent?.[FARM_SET_COOKIE_HEADERS];
2377
- if (parentCookies) headers.replaceSetCookies(parentCookies);
2378
- const responseShim = createResponseShim(headers);
2379
- const ctx = {
2380
- request: currentRequest,
2381
- response: responseShim.response,
2382
- url,
2383
- pathname: url.pathname,
2384
- searchParams: url.searchParams,
2385
- method: currentRequest.method || "GET",
2386
- params: {},
2387
- route: url.pathname,
2388
- parent,
2389
- vite: {
2390
- isDev: false,
2391
- hmr: false
2392
- },
2393
- data,
2394
- locals,
2395
- headers,
2396
- cookies: new WebCookieJar(currentRequest, headers),
2397
- _handled: false,
2398
- _redirectUrl: void 0,
2399
- _rewriteUrl: void 0,
2400
- redirect(redirectUrl, status = 307) {
2401
- ctx._redirectUrl = redirectUrl;
2402
- ctx._handled = true;
2403
- handledResponse = createHandledResponse(
2404
- `Redirecting to ${redirectUrl}`,
2405
- {
2406
- status,
2407
- headers: {
2408
- Location: redirectUrl,
2409
- "Content-Type": "text/plain"
2410
- }
2411
- },
2412
- headers
2413
- );
2414
- },
2415
- rewrite(rewriteUrl) {
2416
- ctx._rewriteUrl = rewriteUrl;
2417
- const nextUrl = new URL(rewriteUrl, currentRequest.url);
2418
- currentRequest = withNodeRequestShape(
2419
- new Request(nextUrl, currentRequest),
2420
- trustProxy,
2421
- clientAddress
2422
- );
2423
- ctx.request = currentRequest;
2424
- ctx.url = nextUrl;
2425
- ctx.pathname = nextUrl.pathname;
2426
- ctx.searchParams = nextUrl.searchParams;
2427
- ctx.route = nextUrl.pathname;
2428
- },
2429
- json(jsonData, status = 200) {
2430
- ctx._handled = true;
2431
- handledResponse = createHandledResponse(
2432
- JSON.stringify(jsonData),
2433
- {
2434
- status,
2435
- headers: {
2436
- "Content-Type": "application/json"
2437
- }
2438
- },
2439
- headers
2440
- );
2441
- },
2442
- text(content, status = 200) {
2443
- ctx._handled = true;
2444
- handledResponse = createHandledResponse(
2445
- content,
2446
- {
2447
- status,
2448
- headers: {
2449
- "Content-Type": "text/plain"
2450
- }
2451
- },
2452
- headers
2453
- );
2454
- },
2455
- html(content, status = 200) {
2456
- ctx._handled = true;
2457
- handledResponse = createHandledResponse(
2458
- content,
2459
- {
2460
- status,
2461
- headers: {
2462
- "Content-Type": "text/html"
2463
- }
2464
- },
2465
- headers
2466
- );
2467
- }
2468
- };
2469
- return {
2470
- ctx,
2471
- headers,
2472
- getRequest: /* @__PURE__ */ __name(() => currentRequest, "getRequest"),
2473
- getResponse: /* @__PURE__ */ __name(() => handledResponse || responseShim.getResponse(currentRequest.method), "getResponse")
2474
- };
2475
- }
2476
- __name(createWebMiddlewareContext, "createWebMiddlewareContext");
2477
- function matchesMiddlewareConfig2(pathname, config, ctx) {
2478
- return matchesMiddlewareConfig(pathname, config, ctx);
2479
- }
2480
- __name(matchesMiddlewareConfig2, "matchesMiddlewareConfig");
2481
- function getConfigHandlers(entry) {
2482
- const handlers = [];
2483
- if ("handler" in entry && typeof entry.handler === "function") {
2484
- handlers.push(entry.handler);
2485
- }
2486
- if ("handlers" in entry && Array.isArray(entry.handlers)) {
2487
- handlers.push(...entry.handlers.filter((handler) => typeof handler === "function"));
2488
- }
2489
- return handlers;
2490
- }
2491
- __name(getConfigHandlers, "getConfigHandlers");
2492
- function toMiddlewareConfig(entry) {
2493
- const { matcher, exclude, runtime: runtime3 } = entry;
2494
- return { matcher, exclude, runtime: runtime3 };
2495
- }
2496
- __name(toMiddlewareConfig, "toMiddlewareConfig");
2497
- function normalizeConfigMiddleware(config) {
2498
- const entries = [];
2499
- let globalConfig;
2500
- if (!config) {
2501
- return { entries, globalConfig };
2502
- }
2503
- const configEntries = Array.isArray(config) ? config : [config];
2504
- for (const [index, entry] of configEntries.entries()) {
2505
- const handlers = getConfigHandlers(entry);
2506
- const middlewareConfig = toMiddlewareConfig(entry);
2507
- if (handlers.length === 0) {
2508
- globalConfig = middlewareConfig;
2509
- continue;
2510
- }
2511
- compileMiddlewareConfig(middlewareConfig);
2512
- entries.push({
2513
- path: "/",
2514
- filePath: `farm.config.ts#middleware-${index}`,
2515
- handlers,
2516
- config: middlewareConfig,
2517
- source: "config"
2518
- });
2519
- }
2520
- return { entries, globalConfig };
2521
- }
2522
- __name(normalizeConfigMiddleware, "normalizeConfigMiddleware");
2523
- function normalizeFileMiddleware(modules = []) {
2524
- const entries = [];
2525
- for (const moduleEntry of modules) {
2526
- const normalized = normalizeMiddlewareModule(moduleEntry.module, moduleEntry.path);
2527
- if (!normalized) {
2528
- continue;
2529
- }
2530
- if (normalized.config) compileMiddlewareConfig(normalized.config);
2531
- entries.push({
2532
- path: moduleEntry.path,
2533
- filePath: moduleEntry.filePath || moduleEntry.path,
2534
- handlers: normalized.handlers,
2535
- config: normalized.config,
2536
- source: "file"
2537
- });
2538
- }
2539
- return entries;
2540
- }
2541
- __name(normalizeFileMiddleware, "normalizeFileMiddleware");
2542
- async function executeHandlers(handlers, ctx) {
2543
- let handlerIndex = 0;
2544
- let returnedResponse;
2545
- const executeNext = /* @__PURE__ */ __name(async () => {
2546
- if (handlerIndex < handlers.length) {
2547
- const handler = handlers[handlerIndex++];
2548
- const result2 = await handler(ctx, executeNext);
2549
- if (isMiddlewareResponse2(result2)) {
2550
- returnedResponse = result2;
2551
- return result2;
2552
- }
2553
- }
2554
- return returnedResponse;
2555
- }, "executeNext");
2556
- const result = await executeNext();
2557
- return isMiddlewareResponse2(result) ? result : returnedResponse;
2558
- }
2559
- __name(executeHandlers, "executeHandlers");
2560
- function emptyResult(request) {
2561
- return {
2562
- request,
2563
- response: null,
2564
- data: /* @__PURE__ */ new Map(),
2565
- context: /* @__PURE__ */ new Map(),
2566
- headers: new Headers(),
2567
- handled: false
2568
- };
2569
- }
2570
- __name(emptyResult, "emptyResult");
2571
- function createProductionMiddlewareRunner(options = {}) {
2572
- const configMiddleware = normalizeConfigMiddleware(options.config);
2573
- const fileMiddleware = normalizeFileMiddleware(options.modules);
2574
- for (const entry of fileMiddleware) compileMiddlewareRoute(entry);
2575
- const entries = [...configMiddleware.entries, ...fileMiddleware];
2576
- const globalConfig = configMiddleware.globalConfig;
2577
- if (globalConfig) compileMiddlewareConfig(globalConfig);
2578
- return /* @__PURE__ */ __name(async function runProductionMiddleware(request, requestOptions = {}) {
2579
- if (!globalConfig && entries.length === 0) {
2580
- return emptyResult(request);
2581
- }
2582
- let contextState = createWebMiddlewareContext(
2583
- request,
2584
- void 0,
2585
- options.server?.trustProxy === true,
2586
- requestOptions.clientAddress
2587
- );
2588
- let ctx = contextState.ctx;
2589
- let currentRequest = contextState.getRequest();
2590
- const initialPathname = options.i18n?.enabled ? stripFarmLocaleFromPathname(ctx.pathname, options.i18n) : stripFarmBasePath(ctx.pathname, options.i18n?.basePath ?? "/");
2591
- let parentData;
2592
- if (globalConfig) {
2593
- const globalMatch = matchesMiddlewareConfig(initialPathname, globalConfig, ctx);
2594
- if (!globalMatch.matched) {
2595
- return emptyResult(request);
2596
- }
2597
- if (globalMatch.params) {
2598
- ctx.params = { ...ctx.params, ...globalMatch.params };
2599
- }
2600
- }
2601
- const applicable = entries.map((entry) => ({
2602
- entry,
2603
- routeMatch: entry.source === "config" ? { matched: true } : matchesMiddlewareRoute(initialPathname, entry)
2604
- })).filter((candidate) => candidate.routeMatch.matched);
2605
- if (applicable.length === 0) {
2606
- return {
2607
- request: currentRequest,
2608
- response: null,
2609
- data: new Map(ctx.data),
2610
- context: new Map(ctx.locals),
2611
- headers: mapToHeaders(contextState.headers),
2612
- handled: false
2613
- };
2614
- }
2615
- for (const candidate of applicable) {
2616
- const { entry, routeMatch } = candidate;
2617
- const configMatch = entry.config ? matchesMiddlewareConfig(initialPathname, entry.config, ctx) : { matched: true };
2618
- if (!configMatch.matched) {
2619
- continue;
2620
- }
2621
- if (parentData) {
2622
- contextState = createWebMiddlewareContext(
2623
- currentRequest,
2624
- parentData,
2625
- options.server?.trustProxy === true,
2626
- requestOptions.clientAddress
2627
- );
2628
- ctx = contextState.ctx;
2629
- }
2630
- if (routeMatch.params) {
2631
- ctx.params = { ...ctx.params, ...routeMatch.params };
2632
- }
2633
- if (configMatch.params) {
2634
- ctx.params = { ...ctx.params, ...configMatch.params };
2635
- }
2636
- const middlewareStartTime = Date.now();
2637
- const middlewareEvent = {
2638
- route: entry.path,
2639
- pathname: initialPathname,
2640
- name: entry.filePath
2641
- };
2642
- emitFarmEvent({ type: "middleware.start", ...middlewareEvent });
2643
- try {
2644
- const returnedResponse = await executeHandlers(entry.handlers, ctx);
2645
- currentRequest = contextState.getRequest();
2646
- if (returnedResponse) {
2647
- const response = applyProductionMiddlewareHeaders(
2648
- returnedResponse,
2649
- mapToHeaders(contextState.headers)
2650
- );
2651
- emitFarmEvent({
2652
- type: "middleware.shortCircuit",
2653
- ...middlewareEvent,
2654
- status: response.status
2655
- });
2656
- return {
2657
- request: currentRequest,
2658
- response,
2659
- data: new Map(ctx.data),
2660
- context: new Map(ctx.locals),
2661
- headers: mapToHeaders(contextState.headers),
2662
- handled: true
2663
- };
2664
- }
2665
- if (ctx._handled || ctx.response.headersSent || ctx.response.writableEnded) {
2666
- const response = contextState.getResponse() || new Response(null);
2667
- emitFarmEvent({
2668
- type: "middleware.shortCircuit",
2669
- ...middlewareEvent,
2670
- status: response.status
2671
- });
2672
- return {
2673
- request: currentRequest,
2674
- response,
2675
- data: new Map(ctx.data),
2676
- context: new Map(ctx.locals),
2677
- headers: mapToHeaders(contextState.headers),
2678
- handled: true
2679
- };
2680
- }
2681
- emitFarmEvent({
2682
- type: "middleware.complete",
2683
- ...middlewareEvent,
2684
- durationMs: Date.now() - middlewareStartTime
2685
- });
2686
- } catch (error) {
2687
- currentRequest = contextState.getRequest();
2688
- if (isFarmRedirectError(error)) {
2689
- const redirect = getFarmRedirectError(error);
2690
- const response = applyProductionMiddlewareHeaders(
2691
- new Response(null, { status: redirect.status, headers: { Location: redirect.url } }),
2692
- mapToHeaders(contextState.headers)
2693
- );
2694
- emitFarmEvent({
2695
- type: "middleware.shortCircuit",
2696
- ...middlewareEvent,
2697
- status: response.status
2698
- });
2699
- return {
2700
- request: currentRequest,
2701
- response,
2702
- data: new Map(ctx.data),
2703
- context: new Map(ctx.locals),
2704
- headers: mapToHeaders(contextState.headers),
2705
- handled: true
2706
- };
2707
- }
2708
- if (isFarmNotFoundError(error)) {
2709
- emitFarmEvent({ type: "middleware.shortCircuit", ...middlewareEvent, status: 404 });
2710
- return {
2711
- request: currentRequest,
2712
- response: null,
2713
- data: new Map(ctx.data),
2714
- context: new Map(ctx.locals),
2715
- headers: mapToHeaders(contextState.headers),
2716
- handled: true,
2717
- notFound: true
2718
- };
2719
- }
2720
- emitFarmEvent({
2721
- type: "middleware.error",
2722
- ...middlewareEvent,
2723
- error
2724
- });
2725
- throw error;
2726
- }
2727
- parentData = {
2728
- data: new Map(ctx.data),
2729
- locals: new Map(ctx.locals),
2730
- headers: headersToRecord(contextState.headers),
2731
- [FARM_SET_COOKIE_HEADERS]: [...contextState.headers.getSetCookies()]
2732
- };
2733
- }
2734
- return {
2735
- request: currentRequest,
2736
- response: null,
2737
- data: new Map(ctx.data),
2738
- context: new Map(ctx.locals),
2739
- headers: mapToHeaders(contextState.headers),
2740
- handled: false
2741
- };
2742
- }, "runProductionMiddleware");
2743
- }
2744
- __name(createProductionMiddlewareRunner, "createProductionMiddlewareRunner");
2745
- function applyProductionMiddlewareHeaders(response, middlewareHeaders) {
2746
- if (!middlewareHeaders || Array.from(middlewareHeaders.keys()).length === 0) {
2747
- return response;
2748
- }
2749
- const headers = new Headers(response.headers);
2750
- const getSetCookie = middlewareHeaders.getSetCookie;
2751
- const setCookies = getSetCookie ? getSetCookie.call(middlewareHeaders) : middlewareHeaders.get("set-cookie") ? [middlewareHeaders.get("set-cookie")] : [];
2752
- for (const [key, value] of middlewareHeaders) {
2753
- if (key.toLowerCase() === "set-cookie") continue;
2754
- if (headers.has(key)) continue;
2755
- headers.set(key, value);
2756
- }
2757
- for (const cookie of setCookies) {
2758
- headers.append("Set-Cookie", cookie);
2759
- }
2760
- return new Response(response.body, {
2761
- status: response.status,
2762
- statusText: response.statusText,
2763
- headers
2764
- });
2765
- }
2766
- __name(applyProductionMiddlewareHeaders, "applyProductionMiddlewareHeaders");
2767
48
 
2768
- // src/middleware/vite-plugin.ts
2769
- var import_node_fs = __toESM(require("fs"));
2770
- var import_node_path2 = __toESM(require("path"));
2771
49
 
2772
- // src/i18n/config.ts
2773
- var import_node_path = __toESM(require("path"));
2774
- var DEFAULT_FARM_I18N_COOKIE = "farm_locale";
2775
- var DEFAULT_FARM_I18N_COOKIE_MAX_AGE = 60 * 60 * 24 * 365;
2776
- var DEFAULT_DETECTION = ["url", "cookie", "accept-language"];
2777
- function resolveFarmI18nConfig(input, options = {}) {
2778
- const root = options.root || process.cwd();
2779
- const basePath = options.basePath || "/";
2780
- const strictByDefault = options.mode === "production";
2781
- if (!input) {
2782
- return {
2783
- enabled: false,
2784
- basePath,
2785
- locales: ["en"],
2786
- defaultLocale: "en",
2787
- messages: import_node_path.default.join(root, "src/messages"),
2788
- routing: "none",
2789
- detection: [],
2790
- fallbackLocale: "en",
2791
- strict: strictByDefault,
2792
- cookie: {
2793
- name: DEFAULT_FARM_I18N_COOKIE,
2794
- maxAge: DEFAULT_FARM_I18N_COOKIE_MAX_AGE,
2795
- path: "/",
2796
- sameSite: "lax",
2797
- secure: options.mode === "production"
2798
- },
2799
- direction: {}
2800
- };
2801
- }
2802
- if (!Array.isArray(input.locales) || input.locales.length === 0) {
2803
- throw new Error("i18n.locales must contain at least one locale.");
2804
- }
2805
- const locales = input.locales.map(canonicalizeLocale);
2806
- if (new Set(locales).size !== locales.length) {
2807
- throw new Error("i18n.locales must not contain duplicate locales.");
2808
- }
2809
- const defaultLocale = canonicalizeLocale(input.defaultLocale);
2810
- if (!locales.includes(defaultLocale)) {
2811
- throw new Error(`i18n.defaultLocale "${defaultLocale}" must be included in i18n.locales.`);
2812
- }
2813
- const fallbackLocale = canonicalizeLocale(input.fallbackLocale || defaultLocale);
2814
- if (!locales.includes(fallbackLocale)) {
2815
- throw new Error(`i18n.fallbackLocale "${fallbackLocale}" must be included in i18n.locales.`);
2816
- }
2817
- const detection = resolveDetection(input);
2818
- const sameSite = input.cookie?.sameSite ?? "lax";
2819
- if (sameSite !== "lax" && sameSite !== "strict" && sameSite !== "none") {
2820
- throw new Error('i18n.cookie.sameSite must be "lax", "strict", or "none".');
2821
- }
2822
- const direction = {};
2823
- for (const [rawLocale, value] of Object.entries(input.direction || {})) {
2824
- const locale = canonicalizeLocale(rawLocale);
2825
- if (!locales.includes(locale)) {
2826
- throw new Error(`i18n.direction contains unknown locale "${rawLocale}".`);
2827
- }
2828
- if (value !== "ltr" && value !== "rtl") {
2829
- throw new Error(`i18n.direction.${rawLocale} must be "ltr" or "rtl".`);
2830
- }
2831
- direction[locale] = value;
2832
- }
2833
- return {
2834
- enabled: true,
2835
- basePath,
2836
- locales,
2837
- defaultLocale,
2838
- messages: import_node_path.default.resolve(root, input.messages || "src/messages"),
2839
- routing: input.routing || "prefix-except-default",
2840
- detection,
2841
- fallbackLocale,
2842
- strict: input.strict ?? strictByDefault,
2843
- cookie: {
2844
- name: input.cookie?.name?.trim() || DEFAULT_FARM_I18N_COOKIE,
2845
- maxAge: normalizePositiveInteger(
2846
- input.cookie?.maxAge,
2847
- DEFAULT_FARM_I18N_COOKIE_MAX_AGE,
2848
- "i18n.cookie.maxAge"
2849
- ),
2850
- path: normalizeCookiePath(input.cookie?.path),
2851
- sameSite,
2852
- secure: input.cookie?.secure ?? options.mode === "production"
2853
- },
2854
- direction
2855
- };
2856
- }
2857
- __name(resolveFarmI18nConfig, "resolveFarmI18nConfig");
2858
- function canonicalizeLocale(locale) {
2859
- if (!locale || typeof locale !== "string") {
2860
- throw new Error("Farm i18n locales must be non-empty strings.");
2861
- }
2862
- try {
2863
- return Intl.getCanonicalLocales(locale)[0];
2864
- } catch {
2865
- throw new Error(`Invalid i18n locale "${locale}".`);
2866
- }
2867
- }
2868
- __name(canonicalizeLocale, "canonicalizeLocale");
2869
- function resolveDetection(input) {
2870
- if (input.detection === false || input.localeDetection === false) {
2871
- return ["url"];
2872
- }
2873
- const detection = input.detection || DEFAULT_DETECTION;
2874
- const allowed = /* @__PURE__ */ new Set(["url", "cookie", "accept-language"]);
2875
- const unique = [];
2876
- for (const signal of detection) {
2877
- if (!allowed.has(signal)) {
2878
- throw new Error(`Unsupported i18n detection signal "${signal}".`);
2879
- }
2880
- if (!unique.includes(signal)) unique.push(signal);
2881
- }
2882
- return unique;
2883
- }
2884
- __name(resolveDetection, "resolveDetection");
2885
- function normalizePositiveInteger(value, fallback, name) {
2886
- if (value === void 0) return fallback;
2887
- if (!Number.isInteger(value) || value < 0) {
2888
- throw new Error(`${name} must be a positive integer.`);
2889
- }
2890
- return value;
2891
- }
2892
- __name(normalizePositiveInteger, "normalizePositiveInteger");
2893
- function normalizeCookiePath(value) {
2894
- if (value === void 0) return "/";
2895
- if (typeof value !== "string") {
2896
- throw new Error("i18n.cookie.path must be a root-relative pathname.");
2897
- }
2898
- const hasUnstableCharacters = /* @__PURE__ */ __name((candidate) => candidate.includes("\\") || Array.from(candidate).some((character) => {
2899
- const code = character.charCodeAt(0);
2900
- return code <= 31 || code >= 127 && code <= 159;
2901
- }), "hasUnstableCharacters");
2902
- if (hasUnstableCharacters(value)) {
2903
- throw new Error("i18n.cookie.path cannot contain backslashes or control characters.");
2904
- }
2905
- const pathname = value.trim();
2906
- if (!pathname || !pathname.startsWith("/") || pathname.startsWith("//") || pathname.includes(";") || pathname.includes("?") || pathname.includes("#")) {
2907
- throw new Error(
2908
- "i18n.cookie.path must be a root-relative pathname without attributes, a query, or a hash."
2909
- );
2910
- }
2911
- for (const segment of pathname.split("/")) {
2912
- let decoded = segment;
2913
- try {
2914
- decoded = decodeURIComponent(segment);
2915
- } catch {
2916
- }
2917
- if (hasUnstableCharacters(decoded)) {
2918
- throw new Error("i18n.cookie.path cannot contain backslashes or control characters.");
2919
- }
2920
- if (decoded.includes("/")) {
2921
- throw new Error("i18n.cookie.path cannot contain percent-encoded path separators.");
2922
- }
2923
- if (decoded === "." || decoded === "..") {
2924
- throw new Error('i18n.cookie.path cannot contain "." or ".." path segments.');
2925
- }
2926
- }
2927
- return pathname;
2928
- }
2929
- __name(normalizeCookiePath, "normalizeCookiePath");
2930
50
 
2931
- // src/middleware/vite-plugin.ts
2932
- function getMiddlewareAppDirectory(root, srcDir) {
2933
- const sourceDirectory = import_node_path2.default.join(root, srcDir);
2934
- const appDirectory = import_node_path2.default.join(sourceDirectory, "app");
2935
- return import_node_fs.default.existsSync(appDirectory) ? appDirectory : sourceDirectory;
2936
- }
2937
- __name(getMiddlewareAppDirectory, "getMiddlewareAppDirectory");
2938
- function farmMiddlewarePlugin(options = {}) {
2939
- const srcDir = options.srcDir ?? "src";
2940
- let manager = null;
2941
- let discoveryComplete = false;
2942
- let discoveryPromise = null;
2943
- const discover = /* @__PURE__ */ __name(async (server) => {
2944
- const i18n = resolveFarmI18nConfig(false, {
2945
- root: server.config.root,
2946
- mode: server.config.mode === "production" ? "production" : "development",
2947
- basePath: options.basePath ?? "/"
2948
- });
2949
- manager = new MiddlewareManager(
2950
- getMiddlewareAppDirectory(server.config.root, srcDir),
2951
- server,
2952
- void 0,
2953
- i18n
2954
- );
2955
- await manager.discover();
2956
- discoveryComplete = true;
2957
- }, "discover");
2958
- return {
2959
- name: "@farm.js/core:middleware",
2960
- enforce: "pre",
2961
- configureServer(server) {
2962
- discoveryPromise = discover(server);
2963
- void discoveryPromise.catch((error) => {
2964
- console.error("[FARM] Middleware discovery error:", error);
2965
- });
2966
- const execute = /* @__PURE__ */ __name(async (req, res, _pathname, sharedData) => {
2967
- if (discoveryPromise) {
2968
- await discoveryPromise;
2969
- }
2970
- if (!manager) {
2971
- return false;
2972
- }
2973
- const handled = await manager.execute(req, res);
2974
- const middlewareData = req.__FARM_MIDDLEWARE_DATA__;
2975
- if (sharedData && middlewareData instanceof Map) {
2976
- for (const [key, value] of middlewareData) {
2977
- sharedData.set(key, value);
2978
- }
2979
- }
2980
- return handled;
2981
- }, "execute");
2982
- server.__farmMiddleware__ = {
2983
- execute,
2984
- getMiddlewares: /* @__PURE__ */ __name(() => manager?.getMiddlewares() ?? [], "getMiddlewares"),
2985
- isReady: /* @__PURE__ */ __name(() => discoveryComplete, "isReady"),
2986
- waitForDiscovery: /* @__PURE__ */ __name(() => discoveryPromise, "waitForDiscovery")
2987
- };
2988
- },
2989
- async handleHotUpdate({ file, server, modules }) {
2990
- if (!/^middleware\.[tj]sx?$/.test(import_node_path2.default.basename(file))) {
2991
- return;
2992
- }
2993
- for (const module2 of modules) {
2994
- server.moduleGraph.invalidateModule(module2);
2995
- }
2996
- await manager?.reload();
2997
- server.ws.send({ type: "full-reload", path: "*" });
2998
- return [];
2999
- }
3000
- };
3001
- }
3002
- __name(farmMiddlewarePlugin, "farmMiddlewarePlugin");
3003
- // Annotate the CommonJS export names for ESM import in node:
3004
- 0 && (module.exports = {
3005
- MiddlewareManager,
3006
- UnsupportedRateLimitStorageError,
3007
- _runWithMiddlewareContext,
3008
- _runWithMiddlewareData,
3009
- applyProductionMiddlewareHeaders,
3010
- canonicalizeRequestPathSegments,
3011
- createContext,
3012
- createProductionMiddlewareRunner,
3013
- farmMiddlewarePlugin,
3014
- getFromMiddleware,
3015
- getMiddlewareContext,
3016
- getMiddlewareData,
3017
- getMiddlewareValue,
3018
- getRateLimitStatus,
3019
- hasMiddlewareData,
3020
- matchesMiddlewareConfig,
3021
- memoryRateLimitStorage,
3022
- middleware,
3023
- unwrapMiddleware
3024
- });
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+ exports.MiddlewareManager = _chunkY53ZSFN6cjs.MiddlewareManager; exports.UnsupportedRateLimitStorageError = _chunkFJSWYIR7cjs.UnsupportedRateLimitStorageError; exports._runWithMiddlewareContext = _chunkXGC343EYcjs._runWithMiddlewareContext; exports._runWithMiddlewareData = _chunkXGC343EYcjs._runWithMiddlewareData; exports.applyProductionMiddlewareHeaders = _chunkBYODCJD6cjs.applyProductionMiddlewareHeaders; exports.canonicalizeRequestPathSegments = _chunkUS2QVW3Ecjs.canonicalizeRequestPathSegments; exports.createContext = _chunkY53ZSFN6cjs.createContext; exports.createProductionMiddlewareRunner = _chunkBYODCJD6cjs.createProductionMiddlewareRunner; exports.farmMiddlewarePlugin = _chunkFJSWYIR7cjs.farmMiddlewarePlugin; exports.getFromMiddleware = _chunkFJSWYIR7cjs.getFromMiddleware; exports.getMiddlewareContext = _chunkXGC343EYcjs.getMiddlewareContext; exports.getMiddlewareData = _chunkXGC343EYcjs.getMiddlewareData; exports.getMiddlewareValue = _chunkXGC343EYcjs.getMiddlewareValue; exports.getRateLimitStatus = _chunkFJSWYIR7cjs.getRateLimitStatus; exports.hasMiddlewareData = _chunkFJSWYIR7cjs.hasMiddlewareData; exports.matchesMiddlewareConfig = _chunkBYODCJD6cjs.matchesMiddlewareConfig; exports.memoryRateLimitStorage = _chunkFJSWYIR7cjs.memoryRateLimitStorage; exports.middleware = _chunkFJSWYIR7cjs.middleware; exports.unwrapMiddleware = _chunkFJSWYIR7cjs.unwrapMiddleware;