@farm.js/core 0.1.15 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/dist/agent-runtime.d.mts +5 -2
  2. package/dist/agent-runtime.d.ts +5 -2
  3. package/dist/api/client.cjs +62 -28
  4. package/dist/api/client.d.mts +3 -2
  5. package/dist/api/client.d.ts +3 -2
  6. package/dist/api/client.mjs +3 -3
  7. package/dist/api/route-manager.cjs +69 -32
  8. package/dist/api/route-manager.d.mts +5 -2
  9. package/dist/api/route-manager.d.ts +5 -2
  10. package/dist/api/route-manager.mjs +5 -5
  11. package/dist/api/runtime.cjs +65 -29
  12. package/dist/api/runtime.d.mts +3 -2
  13. package/dist/api/runtime.d.ts +3 -2
  14. package/dist/api/runtime.mjs +6 -3
  15. package/dist/{api-client-C8d7BZNp.d.mts → api-client-Cx54IR5g.d.mts} +2 -1
  16. package/dist/{api-client-BWrEbxfO.d.ts → api-client-DykpaKcY.d.ts} +2 -1
  17. package/dist/api.cjs +106 -33
  18. package/dist/api.d.mts +7 -4
  19. package/dist/api.d.ts +7 -4
  20. package/dist/api.mjs +8 -8
  21. package/dist/{app-wIYse61b.d.ts → app-BHY_10Lm.d.ts} +3 -3
  22. package/dist/{app-B3nVSjen.d.mts → app-BMk0do23.d.mts} +3 -3
  23. package/dist/app-markdown.d.mts +6 -3
  24. package/dist/app-markdown.d.ts +6 -3
  25. package/dist/app-markdown.mjs +3 -3
  26. package/dist/cache.cjs +62 -28
  27. package/dist/cache.d.mts +11 -1
  28. package/dist/cache.d.ts +11 -1
  29. package/dist/cache.mjs +1 -1
  30. package/dist/{chunk-FOGLGRDS.mjs → chunk-4OOBRCJX.mjs} +122 -8
  31. package/dist/{chunk-JRF3C33L.mjs → chunk-56DAX2BE.mjs} +172 -53
  32. package/dist/{chunk-B76DT5Y6.mjs → chunk-57J3Y7Y3.mjs} +1 -1
  33. package/dist/{chunk-MOQNHLTS.mjs → chunk-5QOEPUYE.mjs} +5 -2
  34. package/dist/{chunk-HKLRP3BN.mjs → chunk-5SPPCN5J.mjs} +1 -1
  35. package/dist/{chunk-LUC2FAGW.mjs → chunk-6VQIKZZO.mjs} +1 -1
  36. package/dist/{chunk-7ZWL7XOU.mjs → chunk-76DG3LF3.mjs} +1 -1
  37. package/dist/{chunk-EWDK36MM.mjs → chunk-A72YEUZ3.mjs} +1 -1
  38. package/dist/{chunk-ZHOIQC6U.mjs → chunk-ATERBVHQ.mjs} +2 -2
  39. package/dist/{chunk-27JNCYEK.mjs → chunk-EN7WTEAY.mjs} +2 -2
  40. package/dist/{chunk-IGO2HEV7.mjs → chunk-F6SJAKFJ.mjs} +62 -28
  41. package/dist/{chunk-GSDIZACQ.mjs → chunk-FG5H2VCJ.mjs} +2 -2
  42. package/dist/{chunk-LZK5CXDW.mjs → chunk-KLSSO6YD.mjs} +2 -2
  43. package/dist/{chunk-KUO3GBPK.mjs → chunk-L6V3P73N.mjs} +1 -1
  44. package/dist/{chunk-FBHGHMOA.mjs → chunk-MVIWBEJF.mjs} +37 -27
  45. package/dist/{chunk-KTGFMHET.mjs → chunk-N6UROPT7.mjs} +1 -1
  46. package/dist/{chunk-NDD2YVGU.mjs → chunk-NRVGEI5I.mjs} +10 -3
  47. package/dist/{chunk-GNTPTTLA.mjs → chunk-QGVJVSNX.mjs} +5 -5
  48. package/dist/{chunk-6SCB2MXB.mjs → chunk-SXHV42UQ.mjs} +16 -1
  49. package/dist/{chunk-OWTIOHON.mjs → chunk-SYGGPS4A.mjs} +2 -2
  50. package/dist/{chunk-NC333MFA.mjs → chunk-TSWW5BVH.mjs} +7 -4
  51. package/dist/{chunk-LK6FGAQR.mjs → chunk-UDBJCUPA.mjs} +7 -4
  52. package/dist/{chunk-NJ47VORC.mjs → chunk-UTBVHYS3.mjs} +2 -2
  53. package/dist/{chunk-76MNRHTS.mjs → chunk-UUYF3CHN.mjs} +2 -2
  54. package/dist/{chunk-S3QW3BIS.mjs → chunk-WD4YXVLV.mjs} +99 -6
  55. package/dist/{chunk-W7IVHTOP.mjs → chunk-WD5PNSOB.mjs} +16 -3
  56. package/dist/{chunk-DPZUDPVJ.mjs → chunk-XP777LRD.mjs} +1 -1
  57. package/dist/{chunk-KATQ6I56.mjs → chunk-XWAYMDLB.mjs} +1 -1
  58. package/dist/{chunk-UE75PB52.mjs → chunk-YD4J4XCI.mjs} +1 -1
  59. package/dist/{chunk-Q3MDL7TM.mjs → chunk-ZCNJKLA2.mjs} +30 -11
  60. package/dist/{client-plugins-CslwYp3E.d.ts → client-plugins-C089bQhN.d.ts} +16 -4
  61. package/dist/{client-plugins-C1EgdoJM.d.mts → client-plugins-JXXmZliS.d.mts} +16 -4
  62. package/dist/client-plugins.d.mts +5 -2
  63. package/dist/client-plugins.d.ts +5 -2
  64. package/dist/client.cjs +62 -28
  65. package/dist/client.d.mts +8 -7
  66. package/dist/client.d.ts +8 -7
  67. package/dist/client.mjs +6 -6
  68. package/dist/config.d.mts +5 -2
  69. package/dist/config.d.ts +5 -2
  70. package/dist/cron.mjs +2 -2
  71. package/dist/{devtools-PCGEBRSC.mjs → devtools-UFVTMQX5.mjs} +7 -7
  72. package/dist/docs.cjs +83 -4
  73. package/dist/docs.mjs +9 -9
  74. package/dist/{route-CHBaW55F.d.ts → endpoint-1zA994xL.d.ts} +3 -128
  75. package/dist/{route-C6UClI1z.d.mts → endpoint-DAc96i93.d.mts} +3 -128
  76. package/dist/env.cjs +135 -8
  77. package/dist/env.d.mts +22 -2
  78. package/dist/env.d.ts +22 -2
  79. package/dist/env.mjs +4 -1
  80. package/dist/index.cjs +516 -105
  81. package/dist/index.d.mts +16 -15
  82. package/dist/index.d.ts +16 -15
  83. package/dist/index.mjs +46 -34
  84. package/dist/integrations.d.mts +5 -2
  85. package/dist/integrations.d.ts +5 -2
  86. package/dist/internal/app-markdown-runtime.d.mts +5 -2
  87. package/dist/internal/app-markdown-runtime.d.ts +5 -2
  88. package/dist/internal/app-markdown-runtime.mjs +2 -2
  89. package/dist/internal/build-runtime.cjs +600 -284
  90. package/dist/internal/build-runtime.d.mts +7 -4
  91. package/dist/internal/build-runtime.d.ts +7 -4
  92. package/dist/internal/build-runtime.mjs +23 -23
  93. package/dist/internal/cli-runtime.cjs +143 -33
  94. package/dist/internal/cli-runtime.mjs +13 -13
  95. package/dist/internal/client-error-overlay.cjs +1 -1
  96. package/dist/internal/client-error-overlay.mjs +1 -1
  97. package/dist/internal/compression-runtime.d.mts +5 -2
  98. package/dist/internal/compression-runtime.d.ts +5 -2
  99. package/dist/internal/config-runtime.cjs +80 -4
  100. package/dist/internal/config-runtime.d.mts +6 -3
  101. package/dist/internal/config-runtime.d.ts +6 -3
  102. package/dist/internal/config-runtime.mjs +7 -7
  103. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  104. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  105. package/dist/internal/production-runtime.cjs +101 -41
  106. package/dist/internal/production-runtime.d.mts +11 -8
  107. package/dist/internal/production-runtime.d.ts +11 -8
  108. package/dist/internal/production-runtime.mjs +6 -6
  109. package/dist/markdown.cjs +16 -1
  110. package/dist/markdown.mjs +1 -1
  111. package/dist/{metadata-BsUcOEXg.d.ts → metadata-BcNJP4fq.d.ts} +1 -1
  112. package/dist/{metadata-B1bxCPUY.d.mts → metadata-C1Z9vLbb.d.mts} +1 -1
  113. package/dist/middleware.cjs +10 -3
  114. package/dist/middleware.d.mts +7 -4
  115. package/dist/middleware.d.ts +7 -4
  116. package/dist/middleware.mjs +4 -4
  117. package/dist/{nitro-ICBP5APY.mjs → nitro-CVZ36JM5.mjs} +8 -5
  118. package/dist/plugin.cjs +358 -106
  119. package/dist/plugin.d.mts +5 -2
  120. package/dist/plugin.d.ts +5 -2
  121. package/dist/plugin.mjs +19 -19
  122. package/dist/{production-runtime-BDllolVh.d.mts → production-runtime-jcrTlRTb.d.mts} +1 -1
  123. package/dist/{production-runtime-CsNn2-zx.d.ts → production-runtime-oKmC0WU-.d.ts} +1 -1
  124. package/dist/{render-plan-CNUlzylR.d.mts → render-plan-BLIfc4jt.d.mts} +1 -1
  125. package/dist/{render-plan-EG4hNFjy.d.ts → render-plan-DOB9cV-h.d.ts} +1 -1
  126. package/dist/renderer-client.cjs +62 -28
  127. package/dist/renderer-client.d.mts +5 -4
  128. package/dist/renderer-client.d.ts +5 -4
  129. package/dist/renderer-client.mjs +3 -3
  130. package/dist/{request-Blh_f7Z3.d.mts → request-Cr53NRHr.d.mts} +1 -1
  131. package/dist/{request-DsVSQVfD.d.ts → request-Dt2gNuQD.d.ts} +1 -1
  132. package/dist/request.d.mts +6 -3
  133. package/dist/request.d.ts +6 -3
  134. package/dist/route-B0XrsrFk.d.mts +128 -0
  135. package/dist/route-DOEpbyWZ.d.ts +128 -0
  136. package/dist/{route-rendering-hUETRCbM.d.ts → route-rendering-CWYd8Mv1.d.ts} +1 -1
  137. package/dist/{route-rendering-LT4XSoQK.d.mts → route-rendering-CeFBEAoZ.d.mts} +1 -1
  138. package/dist/routes.cjs +68 -31
  139. package/dist/routes.d.mts +5 -3
  140. package/dist/routes.d.ts +5 -3
  141. package/dist/routes.mjs +2 -2
  142. package/dist/server-fn-client.d.mts +3 -2
  143. package/dist/server-fn-client.d.ts +3 -2
  144. package/dist/server-fn.cjs +212 -32
  145. package/dist/server-fn.d.mts +72 -1
  146. package/dist/server-fn.d.ts +72 -1
  147. package/dist/server-fn.mjs +13 -2
  148. package/dist/server-plugins.d.mts +6 -3
  149. package/dist/server-plugins.d.ts +6 -3
  150. package/dist/server-query-client.cjs +62 -28
  151. package/dist/server-query-client.d.mts +1 -0
  152. package/dist/server-query-client.d.ts +1 -0
  153. package/dist/server-query-client.mjs +4 -4
  154. package/dist/server-query.cjs +131 -32
  155. package/dist/server-query.d.mts +6 -1
  156. package/dist/server-query.d.ts +6 -1
  157. package/dist/server-query.mjs +4 -3
  158. package/dist/server.cjs +393 -84
  159. package/dist/server.d.mts +9 -8
  160. package/dist/server.d.ts +9 -8
  161. package/dist/server.mjs +22 -22
  162. package/dist/{spa-router-csKR9Ebj.d.mts → spa-router-CQWiYGxS.d.mts} +2 -2
  163. package/dist/{spa-router-Y_2FSJQK.d.ts → spa-router-Wjiw-8hB.d.ts} +2 -2
  164. package/dist/testing.cjs +73 -32
  165. package/dist/testing.d.mts +5 -3
  166. package/dist/testing.d.ts +5 -3
  167. package/dist/testing.mjs +11 -7
  168. package/dist/{utils-jISOE9SD.d.ts → utils-B0XJmG_b.d.ts} +1 -1
  169. package/dist/{utils-DR2wfZAn.d.mts → utils-uUxF0K0P.d.mts} +1 -1
  170. package/dist/version.cjs +1 -1
  171. package/dist/version.mjs +1 -1
  172. package/dist/vite.cjs +500 -252
  173. package/dist/vite.d.mts +5 -2
  174. package/dist/vite.d.ts +5 -2
  175. package/dist/vite.mjs +19 -19
  176. package/dist/workflows.mjs +2 -2
  177. package/package.json +2 -2
  178. package/dist/{chunk-VO5SCWF5.mjs → chunk-BNGS6KJ6.mjs} +0 -0
  179. package/dist/{chunk-MUUZJLCI.mjs → chunk-EGJDUF4Q.mjs} +3 -3
  180. package/dist/{chunk-4L7SZOHZ.mjs → chunk-YHOCRI4H.mjs} +3 -3
@@ -31,6 +31,302 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  ));
32
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
33
 
34
+ // src/utils/runtime-env.ts
35
+ function getFarmRuntimeBindings() {
36
+ const runtimeBindings = globalThis.__env__;
37
+ return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
38
+ }
39
+ function readFarmEnvironmentValue(name2) {
40
+ const runtimeValue = getFarmRuntimeBindings()?.[name2];
41
+ if (typeof runtimeValue === "string") return runtimeValue;
42
+ return typeof process !== "undefined" ? process.env?.[name2] : void 0;
43
+ }
44
+ function isFarmDeployedRuntime() {
45
+ if (getFarmRuntimeBindings()) return true;
46
+ return readFarmEnvironmentValue("NODE_ENV") === "production";
47
+ }
48
+ var init_runtime_env = __esm({
49
+ "src/utils/runtime-env.ts"() {
50
+ "use strict";
51
+ __name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
52
+ __name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
53
+ __name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
54
+ }
55
+ });
56
+
57
+ // src/env.ts
58
+ function resolveEnv(config, source = getProcessEnv()) {
59
+ const resolved = {
60
+ server: resolveEnvScope(config?.server, source, "server"),
61
+ public: resolveEnvScope(config?.public, source, "public")
62
+ };
63
+ return resolved;
64
+ }
65
+ function createBundledEnv(env2, source = getProcessEnv()) {
66
+ const resolved = normalizeResolvedEnv(env2 ?? {});
67
+ const server = {};
68
+ const runtime3 = {};
69
+ for (const [key, value] of Object.entries(resolved.server)) {
70
+ const raw = source[key];
71
+ const type = getRuntimeEnvType(value);
72
+ if (raw !== void 0 && isSameEnvValue(coerceRuntimeEnvValue(raw, type), value)) {
73
+ runtime3[key] = type;
74
+ } else {
75
+ server[key] = value;
76
+ }
77
+ }
78
+ return {
79
+ server,
80
+ public: resolved.public,
81
+ ...Object.keys(runtime3).length > 0 ? { runtime: { server: runtime3 } } : {}
82
+ };
83
+ }
84
+ function setEnv(env2) {
85
+ currentEnv = prepareEnv(env2);
86
+ if (typeof window === "undefined") {
87
+ farmEnvGlobal[FARM_ENV_SYMBOL] = currentEnv;
88
+ }
89
+ }
90
+ function getResolvedEnv() {
91
+ const env2 = getCurrentEnv();
92
+ if (typeof window === "undefined") readRuntimeServerEnv(env2);
93
+ return env2;
94
+ }
95
+ function resolveEnvScope(shape, source, scope) {
96
+ if (!shape) {
97
+ return {};
98
+ }
99
+ const resolved = {};
100
+ for (const [key, parser] of Object.entries(shape)) {
101
+ try {
102
+ resolved[key] = parseEnvValue(parser, source[key], key, scope);
103
+ } catch (error) {
104
+ const message = error instanceof Error ? error.message : String(error);
105
+ throw new Error(`Invalid ${scope} env "${key}": ${message}`);
106
+ }
107
+ }
108
+ return resolved;
109
+ }
110
+ function parseEnvValue(parser, value, key, scope) {
111
+ if (typeof parser === "function") {
112
+ return parser(value, { key, scope });
113
+ }
114
+ if (parser && typeof parser.parse === "function") {
115
+ return parser.parse(value);
116
+ }
117
+ throw new Error("expected a parser function or schema with parse()");
118
+ }
119
+ function createEnvProxy(scope) {
120
+ return new Proxy(
121
+ {},
122
+ {
123
+ get(_target, property) {
124
+ if (typeof property === "symbol") {
125
+ return void 0;
126
+ }
127
+ const env2 = getEnvScope(scope);
128
+ return scope === "server" ? readServerEnvKey(env2, property) : env2[property];
129
+ },
130
+ ownKeys() {
131
+ return Reflect.ownKeys(getEnvScope(scope));
132
+ },
133
+ getOwnPropertyDescriptor(_target, property) {
134
+ const env2 = getEnvScope(scope);
135
+ if (!(property in env2)) {
136
+ return void 0;
137
+ }
138
+ return {
139
+ enumerable: true,
140
+ configurable: true,
141
+ value: env2[property]
142
+ };
143
+ },
144
+ has(_target, property) {
145
+ return property in getEnvScope(scope);
146
+ }
147
+ }
148
+ );
149
+ }
150
+ function getEnvScope(scope) {
151
+ const env2 = getCurrentEnv();
152
+ if (scope === "server") {
153
+ assertServerEnvAccess();
154
+ readRuntimeServerEnv(env2);
155
+ }
156
+ return env2[scope] || {};
157
+ }
158
+ function readServerEnvKey(server, key) {
159
+ const value = server[key];
160
+ if (value === void 0) {
161
+ const state = getCurrentEnv()[FARM_ENV_RUNTIME_SYMBOL];
162
+ if (state && key in state.pending && !state.warned.has(key)) {
163
+ state.warned.add(key);
164
+ console.warn(
165
+ `[Farm] Server env "${key}" was set when this app was built but is not set where the server runs, so it reads as undefined. Farm reads server env at runtime and does not store it in the build output; set "${key}" in the server's environment.`
166
+ );
167
+ }
168
+ }
169
+ return value;
170
+ }
171
+ function readRuntimeServerEnv(env2) {
172
+ const state = env2[FARM_ENV_RUNTIME_SYMBOL];
173
+ if (!state) return;
174
+ for (const [key, type] of Object.entries(state.pending)) {
175
+ const raw = readFarmEnvironmentValue(key);
176
+ if (raw === void 0) continue;
177
+ env2.server[key] = coerceRuntimeEnvValue(raw, type);
178
+ delete state.pending[key];
179
+ }
180
+ }
181
+ function getRuntimeEnvType(value) {
182
+ if (typeof value === "number") return "number";
183
+ if (typeof value === "boolean") return "boolean";
184
+ if (value !== null && typeof value === "object" && !(value instanceof Date)) return "json";
185
+ return "string";
186
+ }
187
+ function coerceRuntimeEnvValue(raw, type) {
188
+ if (type === "number") {
189
+ const value = Number(raw);
190
+ return raw.trim() !== "" && Number.isFinite(value) ? value : raw;
191
+ }
192
+ if (type === "boolean") {
193
+ if (/^(true|1)$/i.test(raw.trim())) return true;
194
+ if (/^(false|0|)$/i.test(raw.trim())) return false;
195
+ return raw;
196
+ }
197
+ if (type === "json") {
198
+ try {
199
+ return JSON.parse(raw);
200
+ } catch {
201
+ return raw;
202
+ }
203
+ }
204
+ return raw;
205
+ }
206
+ function isSameEnvValue(left, right) {
207
+ if (Object.is(left, right)) return true;
208
+ if (Array.isArray(left) || Array.isArray(right)) {
209
+ return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((item, index) => isSameEnvValue(item, right[index]));
210
+ }
211
+ if (!isPlainObject(left) || !isPlainObject(right)) return false;
212
+ const keys = Object.keys(left);
213
+ return keys.length === Object.keys(right).length && keys.every(
214
+ (key) => Object.prototype.hasOwnProperty.call(right, key) && isSameEnvValue(left[key], right[key])
215
+ );
216
+ }
217
+ function isPlainObject(value) {
218
+ if (!value || typeof value !== "object") return false;
219
+ const prototype = Object.getPrototypeOf(value);
220
+ return prototype === Object.prototype || prototype === null;
221
+ }
222
+ function prepareEnv(env2) {
223
+ const normalized = normalizeResolvedEnv(env2);
224
+ const runtime3 = env2.runtime?.server;
225
+ if (!isRecord(runtime3) || Object.keys(runtime3).length === 0) return normalized;
226
+ const prepared = { server: { ...normalized.server }, public: normalized.public };
227
+ Object.defineProperty(prepared, FARM_ENV_RUNTIME_SYMBOL, {
228
+ value: {
229
+ pending: { ...runtime3 },
230
+ warned: /* @__PURE__ */ new Set()
231
+ },
232
+ enumerable: false
233
+ });
234
+ return prepared;
235
+ }
236
+ function assertServerEnvAccess() {
237
+ if (typeof window !== "undefined") {
238
+ throw new Error("Farm server env is not available in the browser. Use publicEnv.");
239
+ }
240
+ }
241
+ function getInitialEnv() {
242
+ const injectedEnv = getInjectedEnv();
243
+ if (injectedEnv) {
244
+ return injectedEnv;
245
+ }
246
+ if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
247
+ return normalizeResolvedEnv(farmEnvGlobal[FARM_ENV_SYMBOL]);
248
+ }
249
+ return {
250
+ server: {},
251
+ public: getInjectedPublicEnv()
252
+ };
253
+ }
254
+ function getCurrentEnv() {
255
+ if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
256
+ return farmEnvGlobal[FARM_ENV_SYMBOL];
257
+ }
258
+ return currentEnv;
259
+ }
260
+ function getInjectedEnv() {
261
+ try {
262
+ if (typeof __FARM_ENV__ !== "undefined" && __FARM_ENV__) {
263
+ return prepareEnv(__FARM_ENV__);
264
+ }
265
+ } catch {
266
+ }
267
+ return null;
268
+ }
269
+ function getInjectedPublicEnv() {
270
+ try {
271
+ if (typeof __FARM_PUBLIC_ENV__ !== "undefined" && __FARM_PUBLIC_ENV__) {
272
+ return __FARM_PUBLIC_ENV__;
273
+ }
274
+ } catch {
275
+ }
276
+ return {};
277
+ }
278
+ function normalizeResolvedEnv(env2) {
279
+ return {
280
+ server: isRecord(env2.server) ? env2.server : {},
281
+ public: isRecord(env2.public) ? env2.public : {}
282
+ };
283
+ }
284
+ function isRecord(value) {
285
+ return !!value && typeof value === "object" && !Array.isArray(value);
286
+ }
287
+ function getProcessEnv() {
288
+ if (typeof process !== "undefined" && process.env) {
289
+ return process.env;
290
+ }
291
+ return {};
292
+ }
293
+ var FARM_ENV_SYMBOL, FARM_ENV_RUNTIME_SYMBOL, farmEnvGlobal, currentEnv, env, publicEnv;
294
+ var init_env = __esm({
295
+ "src/env.ts"() {
296
+ "use strict";
297
+ init_runtime_env();
298
+ FARM_ENV_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env");
299
+ FARM_ENV_RUNTIME_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env.runtime");
300
+ farmEnvGlobal = globalThis;
301
+ currentEnv = getInitialEnv();
302
+ __name(resolveEnv, "resolveEnv");
303
+ __name(createBundledEnv, "createBundledEnv");
304
+ __name(setEnv, "setEnv");
305
+ __name(getResolvedEnv, "getResolvedEnv");
306
+ env = createEnvProxy("server");
307
+ publicEnv = createEnvProxy("public");
308
+ __name(resolveEnvScope, "resolveEnvScope");
309
+ __name(parseEnvValue, "parseEnvValue");
310
+ __name(createEnvProxy, "createEnvProxy");
311
+ __name(getEnvScope, "getEnvScope");
312
+ __name(readServerEnvKey, "readServerEnvKey");
313
+ __name(readRuntimeServerEnv, "readRuntimeServerEnv");
314
+ __name(getRuntimeEnvType, "getRuntimeEnvType");
315
+ __name(coerceRuntimeEnvValue, "coerceRuntimeEnvValue");
316
+ __name(isSameEnvValue, "isSameEnvValue");
317
+ __name(isPlainObject, "isPlainObject");
318
+ __name(prepareEnv, "prepareEnv");
319
+ __name(assertServerEnvAccess, "assertServerEnvAccess");
320
+ __name(getInitialEnv, "getInitialEnv");
321
+ __name(getCurrentEnv, "getCurrentEnv");
322
+ __name(getInjectedEnv, "getInjectedEnv");
323
+ __name(getInjectedPublicEnv, "getInjectedPublicEnv");
324
+ __name(normalizeResolvedEnv, "normalizeResolvedEnv");
325
+ __name(isRecord, "isRecord");
326
+ __name(getProcessEnv, "getProcessEnv");
327
+ }
328
+ });
329
+
34
330
  // src/plugin-dependencies.ts
35
331
  function pluginShortName(name2) {
36
332
  return name2.slice(Math.max(name2.lastIndexOf(":"), name2.lastIndexOf("/")) + 1);
@@ -4101,8 +4397,16 @@ async function createMarkdownMirrorResponse(options) {
4101
4397
  if (!hasMarkdownExtension) {
4102
4398
  headersOut.set("Vary", "Accept");
4103
4399
  }
4400
+ for (const token of pageResponse.headers.get("vary")?.split(",") ?? []) {
4401
+ const name2 = token.trim();
4402
+ if (name2 && name2.toLowerCase() !== "accept") appendHeaderToken(headersOut, "Vary", name2);
4403
+ }
4404
+ const pageCacheControl = pageResponse.headers.get("cache-control");
4104
4405
  const cache = target.route?.cache ?? options.config?.cache ?? false;
4105
- headersOut.set("Cache-Control", createMarkdownCacheHeader(cache));
4406
+ headersOut.set(
4407
+ "Cache-Control",
4408
+ pageCacheControl && isPrivateCacheControl(pageCacheControl) ? pageCacheControl : createMarkdownCacheHeader(cache)
4409
+ );
4106
4410
  return new Response(options.request.method === "HEAD" ? null : markdown, {
4107
4411
  status: pageResponse.status,
4108
4412
  headers: headersOut
@@ -4253,6 +4557,17 @@ function isFarmMarkdownMirrorExposed(config, pathname) {
4253
4557
  function matchesFarmMarkdownRoutePattern(pattern, pathname) {
4254
4558
  return routeMatches(pattern, pathname);
4255
4559
  }
4560
+ function appendHeaderToken(headers, name2, token) {
4561
+ const current = headers.get(name2);
4562
+ if (!current) {
4563
+ headers.set(name2, token);
4564
+ return;
4565
+ }
4566
+ const tokens = current.split(",").map((value) => value.trim().toLowerCase());
4567
+ if (!tokens.includes(token.toLowerCase())) {
4568
+ headers.set(name2, `${current}, ${token}`);
4569
+ }
4570
+ }
4256
4571
  function findExposedMarkdownRoute(config, pathname) {
4257
4572
  if (config.expose === true) {
4258
4573
  return null;
@@ -4284,6 +4599,12 @@ function isHtmlResponse(response) {
4284
4599
  const contentType = response.headers.get("content-type") ?? "";
4285
4600
  return contentType.includes("text/html");
4286
4601
  }
4602
+ function isPrivateCacheControl(value) {
4603
+ return value.split(",").some((directive) => {
4604
+ const name2 = directive.split("=", 1)[0].trim().toLowerCase();
4605
+ return name2 === "private" || name2 === "no-store";
4606
+ });
4607
+ }
4287
4608
  function createMarkdownCacheHeader(cache) {
4288
4609
  if (cache === false || cache <= 0) {
4289
4610
  return "no-store";
@@ -4436,9 +4757,11 @@ var init_markdown = __esm({
4436
4757
  __name(getFarmMarkdownAlternatePath, "getFarmMarkdownAlternatePath");
4437
4758
  __name(isFarmMarkdownMirrorExposed, "isFarmMarkdownMirrorExposed");
4438
4759
  __name(matchesFarmMarkdownRoutePattern, "matchesFarmMarkdownRoutePattern");
4760
+ __name(appendHeaderToken, "appendHeaderToken");
4439
4761
  __name(findExposedMarkdownRoute, "findExposedMarkdownRoute");
4440
4762
  __name(routeMatches, "routeMatches");
4441
4763
  __name(isHtmlResponse, "isHtmlResponse");
4764
+ __name(isPrivateCacheControl, "isPrivateCacheControl");
4442
4765
  __name(createMarkdownCacheHeader, "createMarkdownCacheHeader");
4443
4766
  __name(extractHtmlTitle, "extractHtmlTitle");
4444
4767
  __name(extractHtmlBody, "extractHtmlBody");
@@ -4514,29 +4837,6 @@ var init_secret_compare = __esm({
4514
4837
  }
4515
4838
  });
4516
4839
 
4517
- // src/utils/runtime-env.ts
4518
- function getFarmRuntimeBindings() {
4519
- const runtimeBindings = globalThis.__env__;
4520
- return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
4521
- }
4522
- function readFarmEnvironmentValue(name2) {
4523
- const runtimeValue = getFarmRuntimeBindings()?.[name2];
4524
- if (typeof runtimeValue === "string") return runtimeValue;
4525
- return typeof process !== "undefined" ? process.env?.[name2] : void 0;
4526
- }
4527
- function isFarmDeployedRuntime() {
4528
- if (getFarmRuntimeBindings()) return true;
4529
- return readFarmEnvironmentValue("NODE_ENV") === "production";
4530
- }
4531
- var init_runtime_env = __esm({
4532
- "src/utils/runtime-env.ts"() {
4533
- "use strict";
4534
- __name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
4535
- __name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
4536
- __name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
4537
- }
4538
- });
4539
-
4540
4840
  // src/utils.ts
4541
4841
  function parseRoutePath(filePath) {
4542
4842
  const segments = [];
@@ -5786,168 +6086,6 @@ var init_cron = __esm({
5786
6086
  }
5787
6087
  });
5788
6088
 
5789
- // src/env.ts
5790
- function resolveEnv(config, source = getProcessEnv()) {
5791
- const resolved = {
5792
- server: resolveEnvScope(config?.server, source, "server"),
5793
- public: resolveEnvScope(config?.public, source, "public")
5794
- };
5795
- return resolved;
5796
- }
5797
- function setEnv(env2) {
5798
- currentEnv = normalizeResolvedEnv(env2);
5799
- if (typeof window === "undefined") {
5800
- farmEnvGlobal[FARM_ENV_SYMBOL] = currentEnv;
5801
- }
5802
- }
5803
- function getResolvedEnv() {
5804
- return getCurrentEnv();
5805
- }
5806
- function resolveEnvScope(shape, source, scope) {
5807
- if (!shape) {
5808
- return {};
5809
- }
5810
- const resolved = {};
5811
- for (const [key, parser] of Object.entries(shape)) {
5812
- try {
5813
- resolved[key] = parseEnvValue(parser, source[key], key, scope);
5814
- } catch (error) {
5815
- const message = error instanceof Error ? error.message : String(error);
5816
- throw new Error(`Invalid ${scope} env "${key}": ${message}`);
5817
- }
5818
- }
5819
- return resolved;
5820
- }
5821
- function parseEnvValue(parser, value, key, scope) {
5822
- if (typeof parser === "function") {
5823
- return parser(value, { key, scope });
5824
- }
5825
- if (parser && typeof parser.parse === "function") {
5826
- return parser.parse(value);
5827
- }
5828
- throw new Error("expected a parser function or schema with parse()");
5829
- }
5830
- function createEnvProxy(scope) {
5831
- return new Proxy(
5832
- {},
5833
- {
5834
- get(_target, property) {
5835
- if (typeof property === "symbol") {
5836
- return void 0;
5837
- }
5838
- const env2 = getEnvScope(scope);
5839
- return env2[property];
5840
- },
5841
- ownKeys() {
5842
- return Reflect.ownKeys(getEnvScope(scope));
5843
- },
5844
- getOwnPropertyDescriptor(_target, property) {
5845
- const env2 = getEnvScope(scope);
5846
- if (!(property in env2)) {
5847
- return void 0;
5848
- }
5849
- return {
5850
- enumerable: true,
5851
- configurable: true,
5852
- value: env2[property]
5853
- };
5854
- },
5855
- has(_target, property) {
5856
- return property in getEnvScope(scope);
5857
- }
5858
- }
5859
- );
5860
- }
5861
- function getEnvScope(scope) {
5862
- if (scope === "server") {
5863
- assertServerEnvAccess();
5864
- }
5865
- return getCurrentEnv()[scope] || {};
5866
- }
5867
- function assertServerEnvAccess() {
5868
- if (typeof window !== "undefined") {
5869
- throw new Error("Farm server env is not available in the browser. Use publicEnv.");
5870
- }
5871
- }
5872
- function getInitialEnv() {
5873
- const injectedEnv = getInjectedEnv();
5874
- if (injectedEnv) {
5875
- return injectedEnv;
5876
- }
5877
- if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
5878
- return normalizeResolvedEnv(farmEnvGlobal[FARM_ENV_SYMBOL]);
5879
- }
5880
- return {
5881
- server: {},
5882
- public: getInjectedPublicEnv()
5883
- };
5884
- }
5885
- function getCurrentEnv() {
5886
- if (typeof window === "undefined" && farmEnvGlobal[FARM_ENV_SYMBOL]) {
5887
- return farmEnvGlobal[FARM_ENV_SYMBOL];
5888
- }
5889
- return currentEnv;
5890
- }
5891
- function getInjectedEnv() {
5892
- try {
5893
- if (typeof __FARM_ENV__ !== "undefined" && __FARM_ENV__) {
5894
- return normalizeResolvedEnv(__FARM_ENV__);
5895
- }
5896
- } catch {
5897
- }
5898
- return null;
5899
- }
5900
- function getInjectedPublicEnv() {
5901
- try {
5902
- if (typeof __FARM_PUBLIC_ENV__ !== "undefined" && __FARM_PUBLIC_ENV__) {
5903
- return __FARM_PUBLIC_ENV__;
5904
- }
5905
- } catch {
5906
- }
5907
- return {};
5908
- }
5909
- function normalizeResolvedEnv(env2) {
5910
- return {
5911
- server: isRecord(env2.server) ? env2.server : {},
5912
- public: isRecord(env2.public) ? env2.public : {}
5913
- };
5914
- }
5915
- function isRecord(value) {
5916
- return !!value && typeof value === "object" && !Array.isArray(value);
5917
- }
5918
- function getProcessEnv() {
5919
- if (typeof process !== "undefined" && process.env) {
5920
- return process.env;
5921
- }
5922
- return {};
5923
- }
5924
- var FARM_ENV_SYMBOL, farmEnvGlobal, currentEnv, env, publicEnv;
5925
- var init_env = __esm({
5926
- "src/env.ts"() {
5927
- "use strict";
5928
- FARM_ENV_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env");
5929
- farmEnvGlobal = globalThis;
5930
- currentEnv = getInitialEnv();
5931
- __name(resolveEnv, "resolveEnv");
5932
- __name(setEnv, "setEnv");
5933
- __name(getResolvedEnv, "getResolvedEnv");
5934
- env = createEnvProxy("server");
5935
- publicEnv = createEnvProxy("public");
5936
- __name(resolveEnvScope, "resolveEnvScope");
5937
- __name(parseEnvValue, "parseEnvValue");
5938
- __name(createEnvProxy, "createEnvProxy");
5939
- __name(getEnvScope, "getEnvScope");
5940
- __name(assertServerEnvAccess, "assertServerEnvAccess");
5941
- __name(getInitialEnv, "getInitialEnv");
5942
- __name(getCurrentEnv, "getCurrentEnv");
5943
- __name(getInjectedEnv, "getInjectedEnv");
5944
- __name(getInjectedPublicEnv, "getInjectedPublicEnv");
5945
- __name(normalizeResolvedEnv, "normalizeResolvedEnv");
5946
- __name(isRecord, "isRecord");
5947
- __name(getProcessEnv, "getProcessEnv");
5948
- }
5949
- });
5950
-
5951
6089
  // src/app-markdown-config.ts
5952
6090
  function resolveMdxConfig(config) {
5953
6091
  return {
@@ -6780,7 +6918,7 @@ function mergeFarmLayerConfig(base, override) {
6780
6918
  output[key] = mergeConfigListResolvers(output[key], value);
6781
6919
  continue;
6782
6920
  }
6783
- if (isPlainObject(output[key]) && isPlainObject(value)) {
6921
+ if (isPlainObject2(output[key]) && isPlainObject2(value)) {
6784
6922
  output[key] = mergePlainObjects(output[key], value);
6785
6923
  continue;
6786
6924
  }
@@ -6792,7 +6930,7 @@ function mergePlainObjects(base, override) {
6792
6930
  const output = { ...base };
6793
6931
  for (const [key, value] of Object.entries(override)) {
6794
6932
  if (value === void 0) continue;
6795
- output[key] = isPlainObject(output[key]) && isPlainObject(value) ? mergePlainObjects(output[key], value) : value;
6933
+ output[key] = isPlainObject2(output[key]) && isPlainObject2(value) ? mergePlainObjects(output[key], value) : value;
6796
6934
  }
6797
6935
  return output;
6798
6936
  }
@@ -6807,7 +6945,7 @@ function toArray(value) {
6807
6945
  if (value === void 0 || value === null) return [];
6808
6946
  return Array.isArray(value) ? value : [value];
6809
6947
  }
6810
- function isPlainObject(value) {
6948
+ function isPlainObject2(value) {
6811
6949
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
6812
6950
  const prototype = Object.getPrototypeOf(value);
6813
6951
  return prototype === Object.prototype || prototype === null;
@@ -6884,7 +7022,7 @@ var init_layers = __esm({
6884
7022
  __name(mergeConfigListResolvers, "mergeConfigListResolvers");
6885
7023
  __name(resolveConfigList, "resolveConfigList");
6886
7024
  __name(toArray, "toArray");
6887
- __name(isPlainObject, "isPlainObject");
7025
+ __name(isPlainObject2, "isPlainObject");
6888
7026
  __name(isPathLayerSource, "isPathLayerSource");
6889
7027
  __name(normalizeRealPath, "normalizeRealPath");
6890
7028
  }
@@ -11966,6 +12104,8 @@ var init_cache = __esm({
11966
12104
  constructor(config = {}) {
11967
12105
  this.entries = /* @__PURE__ */ new Map();
11968
12106
  this.inflight = /* @__PURE__ */ new Map();
12107
+ /** Local entries by tag, so tag counts and pruning never scan unrelated entries. */
12108
+ this.entriesByTag = /* @__PURE__ */ new Map();
11969
12109
  this.invalidatedTagVersions = /* @__PURE__ */ new Map();
11970
12110
  this.activeGenerations = /* @__PURE__ */ new Set();
11971
12111
  this.version = 0;
@@ -11984,6 +12124,7 @@ var init_cache = __esm({
11984
12124
  configure(config = {}) {
11985
12125
  this.generation++;
11986
12126
  this.entries.clear();
12127
+ this.entriesByTag.clear();
11987
12128
  this.inflight.clear();
11988
12129
  this.invalidatedTagVersions.clear();
11989
12130
  this.activeGenerations.clear();
@@ -12150,14 +12291,12 @@ var init_cache = __esm({
12150
12291
  return entry;
12151
12292
  }
12152
12293
  delete(key) {
12153
- const deleted = this.entries.delete(key);
12154
- if (deleted) this.pruneInvalidatedTagVersions();
12294
+ const deleted = this.deleteLocalEntry(key);
12155
12295
  emitFarmEvent({ type: "cache.delete", key, deleted });
12156
12296
  return deleted;
12157
12297
  }
12158
12298
  async deleteAsync(key) {
12159
- const deleted = this.entries.delete(key);
12160
- if (deleted) this.pruneInvalidatedTagVersions();
12299
+ const deleted = this.deleteLocalEntry(key);
12161
12300
  if (this.adapter) {
12162
12301
  await this.adapter.delete(this.createAdapterKey(key));
12163
12302
  }
@@ -12168,6 +12307,7 @@ var init_cache = __esm({
12168
12307
  const count = this.entries.size;
12169
12308
  this.generation++;
12170
12309
  this.entries.clear();
12310
+ this.entriesByTag.clear();
12171
12311
  this.inflight.clear();
12172
12312
  this.invalidatedTagVersions.clear();
12173
12313
  this.activeGenerations.clear();
@@ -12253,23 +12393,32 @@ var init_cache = __esm({
12253
12393
  return cached.value;
12254
12394
  }
12255
12395
  const inflight = this.inflight.get(key);
12256
- if (inflight) {
12396
+ if (inflight && !this.wasInvalidatedSince(inflight.tags, inflight.startVersion)) {
12257
12397
  emitFarmEvent({ type: "cache.dedupe", key });
12258
- return inflight;
12398
+ return inflight.promise;
12259
12399
  }
12260
12400
  const tags = Array.from(normalizeCacheOptionsTags(options));
12261
12401
  const generation = this.generation;
12402
+ const startVersion = this.version;
12262
12403
  const promise = this.fillCacheEntry(key, producer, options, tags, generation).catch((error) => {
12263
12404
  emitFarmEvent({ type: "cache.error", key, operation: "set", error });
12264
12405
  throw error;
12265
12406
  }).finally(() => {
12266
- if (this.inflight.get(key) === promise) {
12407
+ if (this.inflight.get(key)?.promise === promise) {
12267
12408
  this.inflight.delete(key);
12268
12409
  }
12269
12410
  });
12270
- this.inflight.set(key, promise);
12411
+ this.inflight.set(key, { promise, tags, startVersion });
12271
12412
  return promise;
12272
12413
  }
12414
+ /** A fill that started before one of its tags was invalidated cannot satisfy later readers. */
12415
+ wasInvalidatedSince(tags, version2) {
12416
+ for (const tag of tags) {
12417
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
12418
+ if (invalidatedVersion !== void 0 && invalidatedVersion > version2) return true;
12419
+ }
12420
+ return false;
12421
+ }
12273
12422
  async fillCacheEntry(key, producer, options, tags, generation) {
12274
12423
  const adapter = this.adapter;
12275
12424
  const namespace = this.namespace;
@@ -12310,7 +12459,7 @@ var init_cache = __esm({
12310
12459
  return value;
12311
12460
  } finally {
12312
12461
  this.activeGenerations.delete(activeGeneration);
12313
- this.pruneInvalidatedTagVersions();
12462
+ this.pruneInvalidatedTagVersions(activeGeneration.tags);
12314
12463
  if (leaseToken && adapter?.releaseLease) {
12315
12464
  try {
12316
12465
  await adapter.releaseLease(leaseKey, leaseToken);
@@ -12355,18 +12504,9 @@ var init_cache = __esm({
12355
12504
  }
12356
12505
  return void 0;
12357
12506
  }
12358
- countEntriesForTag(tag) {
12359
- let count = 0;
12360
- for (const entry of this.entries.values()) {
12361
- if (entry.tags.has(tag)) {
12362
- count++;
12363
- }
12364
- }
12365
- return count;
12366
- }
12367
12507
  countEntriesForTags(tags) {
12368
12508
  let count = 0;
12369
- for (const entry of this.entries.values()) {
12509
+ for (const entry of this.entriesByTag.get(tags[0]) ?? []) {
12370
12510
  if (tags.every((tag) => entry.tags.has(tag))) {
12371
12511
  count++;
12372
12512
  }
@@ -12374,10 +12514,10 @@ var init_cache = __esm({
12374
12514
  return count;
12375
12515
  }
12376
12516
  invalidateTag(normalizedTag) {
12377
- const count = this.countEntriesForTag(normalizedTag);
12517
+ const count = this.entriesByTag.get(normalizedTag)?.size ?? 0;
12378
12518
  this.invalidatedTagVersions.delete(normalizedTag);
12379
12519
  this.invalidatedTagVersions.set(normalizedTag, ++this.version);
12380
- this.pruneInvalidatedTagVersions();
12520
+ this.pruneInvalidatedTagVersions([normalizedTag]);
12381
12521
  return count;
12382
12522
  }
12383
12523
  toPublicEntry(entry) {
@@ -12407,19 +12547,51 @@ var init_cache = __esm({
12407
12547
  this.entries.set(key, entry);
12408
12548
  }
12409
12549
  storeLocalEntry(entry) {
12410
- this.entries.delete(entry.key);
12550
+ const removed = [];
12551
+ const replaced = this.detachLocalEntry(entry.key);
12552
+ if (replaced) removed.push(replaced);
12411
12553
  this.entries.set(entry.key, entry);
12554
+ for (const tag of entry.tags) {
12555
+ let tagged = this.entriesByTag.get(tag);
12556
+ if (!tagged) this.entriesByTag.set(tag, tagged = /* @__PURE__ */ new Set());
12557
+ tagged.add(entry);
12558
+ }
12412
12559
  while (this.entries.size > this.maxEntries) {
12413
12560
  const oldestKey = this.entries.keys().next().value;
12414
12561
  if (oldestKey === void 0) break;
12415
- this.entries.delete(oldestKey);
12562
+ removed.push(this.detachLocalEntry(oldestKey));
12563
+ }
12564
+ for (const removedEntry of removed) this.pruneInvalidatedTagVersions(removedEntry.tags);
12565
+ }
12566
+ deleteLocalEntry(key) {
12567
+ const entry = this.detachLocalEntry(key);
12568
+ if (!entry) return false;
12569
+ this.pruneInvalidatedTagVersions(entry.tags);
12570
+ return true;
12571
+ }
12572
+ detachLocalEntry(key) {
12573
+ const entry = this.entries.get(key);
12574
+ if (!entry) return void 0;
12575
+ this.entries.delete(key);
12576
+ for (const tag of entry.tags) {
12577
+ const tagged = this.entriesByTag.get(tag);
12578
+ if (!tagged) continue;
12579
+ tagged.delete(entry);
12580
+ if (tagged.size === 0) this.entriesByTag.delete(tag);
12416
12581
  }
12417
- this.pruneInvalidatedTagVersions();
12582
+ return entry;
12418
12583
  }
12419
- pruneInvalidatedTagVersions() {
12420
- tags: for (const [tag, invalidatedVersion] of this.invalidatedTagVersions) {
12421
- for (const entry of this.entries.values()) {
12422
- if (entry.tags.has(tag) && entry.createdVersion < invalidatedVersion) continue tags;
12584
+ /**
12585
+ * Drop invalidation versions that no local entry or active fill can be stale against.
12586
+ * Callers pass only the tags whose dependents just changed, so the cost is bounded by
12587
+ * the entries sharing those tags rather than by the whole cache.
12588
+ */
12589
+ pruneInvalidatedTagVersions(tags) {
12590
+ tags: for (const tag of tags) {
12591
+ const invalidatedVersion = this.invalidatedTagVersions.get(tag);
12592
+ if (invalidatedVersion === void 0) continue;
12593
+ for (const entry of this.entriesByTag.get(tag) ?? []) {
12594
+ if (entry.createdVersion < invalidatedVersion) continue tags;
12423
12595
  }
12424
12596
  for (const generation of this.activeGenerations) {
12425
12597
  if (generation.tags.has(tag) && generation.createdVersion < invalidatedVersion)
@@ -12814,6 +12986,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
12814
12986
  }
12815
12987
  return rendererRuntime.createElement(...args);
12816
12988
  }, "createElement");
12989
+ const markFunctionComponent = /* @__PURE__ */ __name((component) => rendererRuntime?.markFunctionComponent?.(component) ?? component, "markFunctionComponent");
12817
12990
  const Component = route.component;
12818
12991
  if (route.pending) {
12819
12992
  const PendingComponent = route.pending;
@@ -12835,7 +13008,9 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
12835
13008
  throw error;
12836
13009
  }
12837
13010
  }, "FarmProgrammaticPageContent");
12838
- const PageContent = FarmProgrammaticPageContent2;
13011
+ const PageContent = markFunctionComponent(
13012
+ FarmProgrammaticPageContent2
13013
+ );
12839
13014
  const FarmProgrammaticPage = /* @__PURE__ */ __name(function FarmProgrammaticPage2(props) {
12840
13015
  return createElement2(
12841
13016
  rendererRuntime.Suspense,
@@ -12845,7 +13020,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
12845
13020
  createElement2(PageContent, props)
12846
13021
  );
12847
13022
  }, "FarmProgrammaticPage");
12848
- return FarmProgrammaticPage;
13023
+ return markFunctionComponent(FarmProgrammaticPage);
12849
13024
  }
12850
13025
  const FarmProgrammaticPageContent = /* @__PURE__ */ __name(async function FarmProgrammaticPageContent2(props) {
12851
13026
  try {
@@ -12864,7 +13039,7 @@ function createProgrammaticPageComponent(route, rendererRuntime) {
12864
13039
  throw error;
12865
13040
  }
12866
13041
  }, "FarmProgrammaticPageContent");
12867
- return FarmProgrammaticPageContent;
13042
+ return markFunctionComponent(FarmProgrammaticPageContent);
12868
13043
  }
12869
13044
  function readProgrammaticRouteProps(route, props, resources) {
12870
13045
  if (isProgrammaticRoutePropsResolved(props)) {
@@ -14524,7 +14699,7 @@ function resolveImportedModule(importerPath, specifier, root) {
14524
14699
  return { path: resolveImportedModuleSourcePath(importerPath, specifier, root), local: true };
14525
14700
  }
14526
14701
  const aliased = resolveProjectAliasSourcePath(specifier, root);
14527
- if (aliased !== void 0) return { path: aliased, local: true };
14702
+ if (aliased) return { path: aliased, local: true };
14528
14703
  return { path: resolvePackageModuleSourcePath(importerPath, specifier, root), local: false };
14529
14704
  }
14530
14705
  function resolveProjectAliasSourcePath(specifier, root) {
@@ -14537,11 +14712,12 @@ function resolveProjectAliasSourcePath(specifier, root) {
14537
14712
  if (!match || alias.prefix.length > match.alias.prefix.length) match = { alias, captured };
14538
14713
  }
14539
14714
  if (!match) return void 0;
14540
- return resolveSourceCandidate(
14715
+ const resolved = resolveSourceCandidate(
14541
14716
  match.alias.targets.map(
14542
14717
  (target) => import_path5.default.normalize(match.alias.wildcard ? target.replace("*", match.captured) : target)
14543
14718
  )
14544
14719
  );
14720
+ return resolved && /\.d\.[cm]?ts$/.test(resolved) ? null : resolved;
14545
14721
  }
14546
14722
  function matchProjectImportAlias(alias, specifier) {
14547
14723
  if (!alias.wildcard) return specifier === alias.prefix ? "" : null;
@@ -15261,6 +15437,7 @@ var init_route_manager = __esm({
15261
15437
  init_static_metadata_image();
15262
15438
  init_route_runtime();
15263
15439
  init_routing();
15440
+ init_base_path();
15264
15441
  init_redirect_query();
15265
15442
  init_route_slots();
15266
15443
  init_renderer();
@@ -16242,7 +16419,7 @@ var init_route_manager = __esm({
16242
16419
  }
16243
16420
  toRoutePathname(pathname) {
16244
16421
  const i18n = this.getI18nConfig();
16245
- return i18n ? stripFarmLocaleFromPathname(pathname, i18n) : pathname;
16422
+ return i18n ? stripFarmLocaleFromPathname(pathname, i18n) : stripFarmBasePath(pathname, this.config.basePath);
16246
16423
  }
16247
16424
  localizeRedirectDestination(destination, locale) {
16248
16425
  if (!locale || !destination.startsWith("/") || destination.startsWith("//")) {
@@ -17363,7 +17540,7 @@ async function readFarmI18nCatalogs(config) {
17363
17540
  return { catalogs, signatures };
17364
17541
  }
17365
17542
  function flattenFarmI18nCatalog(input, source = "i18n catalog") {
17366
- if (!isPlainObject2(input)) {
17543
+ if (!isPlainObject3(input)) {
17367
17544
  throw new Error(`${source} must contain a JSON object at its root.`);
17368
17545
  }
17369
17546
  const output = {};
@@ -17377,7 +17554,7 @@ function flattenFarmI18nCatalog(input, source = "i18n catalog") {
17377
17554
  output[key] = value;
17378
17555
  return;
17379
17556
  }
17380
- if (!isPlainObject2(value)) {
17557
+ if (!isPlainObject3(value)) {
17381
17558
  const key = segments.join(".") || "<root>";
17382
17559
  throw new Error(`${source} message "${key}" must be a string or nested object.`);
17383
17560
  }
@@ -17471,7 +17648,7 @@ function sameSignature(expected, actual) {
17471
17648
  const actualEntries = Object.entries(actual).sort(([a], [b]) => a.localeCompare(b));
17472
17649
  return JSON.stringify(expectedEntries) === JSON.stringify(actualEntries);
17473
17650
  }
17474
- function isPlainObject2(value) {
17651
+ function isPlainObject3(value) {
17475
17652
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
17476
17653
  }
17477
17654
  function messageOf(error) {
@@ -17491,7 +17668,7 @@ var init_catalog = __esm({
17491
17668
  __name(collectArguments, "collectArguments");
17492
17669
  __name(addArgument, "addArgument");
17493
17670
  __name(sameSignature, "sameSignature");
17494
- __name(isPlainObject2, "isPlainObject");
17671
+ __name(isPlainObject3, "isPlainObject");
17495
17672
  __name(messageOf, "messageOf");
17496
17673
  }
17497
17674
  });
@@ -20387,7 +20564,7 @@ var init_server3 = __esm({
20387
20564
  var version;
20388
20565
  var init_package = __esm({
20389
20566
  "package.json"() {
20390
- version = "0.1.15";
20567
+ version = "0.1.17";
20391
20568
  }
20392
20569
  });
20393
20570
 
@@ -20815,7 +20992,7 @@ function createPPRRefreshScript() {
20815
20992
  }
20816
20993
  function createPreHydrationClickQueueScript() {
20817
20994
  const selector = JSON.stringify(FARM_ISLAND_REPLAYABLE_SELECTOR);
20818
- return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function inHydrated(node){return !!(node&&node.closest&&node.closest('[data-farm-island-hydrated="true"]'))}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches(${selector}))return target;target=target.parentElement}return null}function announce(target,kind){document.dispatchEvent(new CustomEvent("farm:island-interaction",{detail:{target:target,kind:kind||null}}))}function hold(event,target,kind){if(queue.some(function(item){return item.target===target}))return;queue.push({target:target,kind:kind,createdAt:Date.now()});announce(target,kind);event.preventDefault();event.stopImmediatePropagation()}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]")||inHydrated(target))return;hold(event,target,"click")},true);document.addEventListener("submit",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented)return;var form=event.target;if(!form||form.nodeName!=="FORM"||inHydrated(form))return;hold(event,form,"submit")},true);function observe(event){if(window.__FARM_HYDRATED__)return;var target=event.target;if(!(target&&target.closest)||inHydrated(target))return;announce(target,null)}document.addEventListener("pointerdown",observe,true);document.addEventListener("focusin",observe,true);})();</script>`;
20995
+ return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function inHydrated(node){return !!(node&&node.closest&&node.closest('[data-farm-island-hydrated="true"]'))}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches(${selector}))return target;target=target.parentElement}return null}function announce(target,kind){document.dispatchEvent(new CustomEvent("farm:island-interaction",{detail:{target:target,kind:kind||null}}))}function hold(event,target,kind){if(!queue.some(function(item){return item.target===target})){queue.push({target:target,kind:kind,createdAt:Date.now()});announce(target,kind)}event.preventDefault();event.stopImmediatePropagation()}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]")||inHydrated(target))return;hold(event,target,"click")},true);document.addEventListener("submit",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented)return;var form=event.target;if(!form||form.nodeName!=="FORM"||inHydrated(form))return;hold(event,form,"submit")},true);function observe(event){if(window.__FARM_HYDRATED__)return;var target=event.target;if(!(target&&target.closest)||inHydrated(target))return;announce(target,null)}document.addEventListener("pointerdown",observe,true);document.addEventListener("focusin",observe,true);})();</script>`;
20819
20996
  }
20820
20997
  function createDocumentFooter(options) {
20821
20998
  return `</div>
@@ -23653,7 +23830,7 @@ function createEndpoint(pathOrOptions, optionsOrHandler, maybeHandler) {
23653
23830
  wrappedHandler
23654
23831
  );
23655
23832
  endpoint.__path = path47 || void 0;
23656
- endpoint.__method = options.method || "GET";
23833
+ endpoint.__method = options.method || (path47 ? "GET" : void 0);
23657
23834
  endpoint.__autoPath = !path47;
23658
23835
  endpoint.__handler = wrappedHandler;
23659
23836
  endpoint.__farmInvoke = (ctx) => runEndpointMiddleware(middleware, ctx, handler, error, options.invalidates);
@@ -24456,6 +24633,7 @@ var init_runtime2 = __esm({
24456
24633
  init_response_body();
24457
24634
  init_route_shape();
24458
24635
  init_route_schema();
24636
+ init_endpoint();
24459
24637
  init_plugin_route_runtime();
24460
24638
  init_route_pattern2();
24461
24639
  init_route_pattern2();
@@ -27717,6 +27895,7 @@ function createFarmDocsHandler(docs, options) {
27717
27895
  if (!isFarmDocsRequest(docs, request2)) return null;
27718
27896
  const page2 = loadPage(contentDir, docs, request2);
27719
27897
  if (!page2) return null;
27898
+ const negotiatesAccept = !requestUrl.pathname.endsWith(".md");
27720
27899
  if (shouldReturnMarkdown(request2)) {
27721
27900
  const origin = new URL(request2.url).origin;
27722
27901
  return omitFarmDocsHeadBody(
@@ -27731,7 +27910,8 @@ function createFarmDocsHandler(docs, options) {
27731
27910
  status: 200,
27732
27911
  headers: {
27733
27912
  "Content-Type": "text/markdown; charset=utf-8",
27734
- "Cache-Control": "public, max-age=60"
27913
+ "Cache-Control": "public, max-age=60",
27914
+ ...negotiatesAccept ? { Vary: "Accept" } : {}
27735
27915
  }
27736
27916
  }
27737
27917
  )
@@ -27761,6 +27941,7 @@ function createFarmDocsHandler(docs, options) {
27761
27941
  headers: {
27762
27942
  "Content-Type": "text/html; charset=utf-8",
27763
27943
  "Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
27944
+ Vary: "Accept",
27764
27945
  ...fontPreloadHeader ? { Link: fontPreloadHeader } : {}
27765
27946
  }
27766
27947
  }
@@ -28705,6 +28886,66 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
28705
28886
  }
28706
28887
  };
28707
28888
  }
28889
+ function mergeExternal(farmValue, userValue) {
28890
+ if (farmValue === void 0) return userValue;
28891
+ if (userValue === void 0) return farmValue;
28892
+ if (farmValue === true || userValue === true) return true;
28893
+ return Array.from(/* @__PURE__ */ new Set([...farmValue, ...userValue]));
28894
+ }
28895
+ function mergeFarmProductionViteConfig(farmConfig, userConfig = {}) {
28896
+ const {
28897
+ plugins: _plugins,
28898
+ root: _root,
28899
+ base: _base,
28900
+ mode: _mode,
28901
+ appType: _appType,
28902
+ publicDir: _publicDir,
28903
+ build: userBuild = {},
28904
+ css: userCss,
28905
+ define: userDefine,
28906
+ esbuild: userEsbuild,
28907
+ ...shared2
28908
+ } = userConfig;
28909
+ const {
28910
+ outDir: _outDir,
28911
+ emptyOutDir: _emptyOutDir,
28912
+ ssr: _ssr,
28913
+ ssrEmitAssets: _ssrEmitAssets,
28914
+ write: _write,
28915
+ lib: _lib,
28916
+ watch: _watch,
28917
+ rollupOptions: userRollupOptions,
28918
+ rolldownOptions: userRolldownOptions,
28919
+ ...userBuildOptions
28920
+ } = userBuild;
28921
+ const {
28922
+ input: _input,
28923
+ output: _output,
28924
+ ...userBundlerOptions
28925
+ } = {
28926
+ ...userRollupOptions,
28927
+ ...userRolldownOptions
28928
+ };
28929
+ const merged = mergeFarmViteConfig(farmConfig, shared2);
28930
+ return {
28931
+ ...merged,
28932
+ build: {
28933
+ ...userBuildOptions,
28934
+ ...farmConfig.build,
28935
+ rollupOptions: {
28936
+ ...userBundlerOptions,
28937
+ ...farmConfig.build?.rollupOptions
28938
+ }
28939
+ },
28940
+ css: farmConfig.css || userCss ? { ...farmConfig.css, ...userCss } : void 0,
28941
+ define: farmConfig.define || userDefine ? { ...userDefine, ...farmConfig.define } : void 0,
28942
+ esbuild: typeof userEsbuild === "object" && farmConfig.esbuild !== false ? { ...userEsbuild, ...farmConfig.esbuild } : farmConfig.esbuild ?? userEsbuild,
28943
+ ssr: {
28944
+ ...merged.ssr,
28945
+ external: mergeExternal(farmConfig.ssr?.external, userConfig.ssr?.external)
28946
+ }
28947
+ };
28948
+ }
28708
28949
  var import_node_path21, FARM_CLIENT_ENTRY_PATTERN, FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE;
28709
28950
  var init_vite_config = __esm({
28710
28951
  "src/server/vite-config.ts"() {
@@ -28733,6 +28974,8 @@ var init_vite_config = __esm({
28733
28974
  __name(mergeNoExternal, "mergeNoExternal");
28734
28975
  __name(mergeAlias, "mergeAlias");
28735
28976
  __name(mergeFarmViteConfig, "mergeFarmViteConfig");
28977
+ __name(mergeExternal, "mergeExternal");
28978
+ __name(mergeFarmProductionViteConfig, "mergeFarmProductionViteConfig");
28736
28979
  }
28737
28980
  });
28738
28981
 
@@ -30355,7 +30598,7 @@ function parseColonParam(segment) {
30355
30598
  modifier
30356
30599
  };
30357
30600
  }
30358
- function compilePathPattern(pattern) {
30601
+ function compilePathPattern(pattern, trailingSlash = false) {
30359
30602
  const params = [];
30360
30603
  const segments = pattern.split("/").filter(Boolean);
30361
30604
  if (segments.length === 0) {
@@ -30391,10 +30634,16 @@ function compilePathPattern(pattern) {
30391
30634
  });
30392
30635
  return {
30393
30636
  kind: "path",
30394
- regex: new RegExp(`^${parts.join("")}$`),
30637
+ regex: new RegExp(`^${parts.join("")}${trailingSlash ? "/?" : ""}$`),
30395
30638
  params
30396
30639
  };
30397
30640
  }
30641
+ function compileMatcherPattern(pattern) {
30642
+ if (typeof pattern === "string" && pattern !== "*" && !pattern.endsWith("(.*)")) {
30643
+ return compilePathPattern(pattern, true);
30644
+ }
30645
+ return compilePattern(pattern);
30646
+ }
30398
30647
  function compilePattern(pattern) {
30399
30648
  if (pattern instanceof RegExp) {
30400
30649
  return { kind: "regexp", regex: pattern };
@@ -30413,7 +30662,7 @@ function compilePattern(pattern) {
30413
30662
  function compileMiddlewareConfig(config) {
30414
30663
  const compiled = {
30415
30664
  matcher: config.matcher ? toMatcherList(config.matcher).map(
30416
- (matcher) => typeof matcher === "function" ? matcher : compilePattern(matcher)
30665
+ (matcher) => typeof matcher === "function" ? matcher : compileMatcherPattern(matcher)
30417
30666
  ) : void 0,
30418
30667
  exclude: config.exclude?.map(compilePattern)
30419
30668
  };
@@ -30501,6 +30750,7 @@ var init_matcher = __esm({
30501
30750
  __name(escapeRegex, "escapeRegex");
30502
30751
  __name(parseColonParam, "parseColonParam");
30503
30752
  __name(compilePathPattern, "compilePathPattern");
30753
+ __name(compileMatcherPattern, "compileMatcherPattern");
30504
30754
  __name(compilePattern, "compilePattern");
30505
30755
  __name(compileMiddlewareConfig, "compileMiddlewareConfig");
30506
30756
  __name(matchPattern, "matchPattern");
@@ -36471,7 +36721,7 @@ function getEnvDefines(config, configEnv) {
36471
36721
  )
36472
36722
  };
36473
36723
  if (configEnv?.isSsrBuild) {
36474
- defines.__FARM_ENV__ = JSON.stringify(getFullEnvDefine(config));
36724
+ defines.__FARM_ENV__ = JSON.stringify(createBundledEnv(getFullEnvDefine(config)));
36475
36725
  }
36476
36726
  return defines;
36477
36727
  }
@@ -36734,8 +36984,8 @@ function farmPlugin(options = {}, initialPluginManager) {
36734
36984
  }, "emitPluginError");
36735
36985
  farmApp = new FarmApp(
36736
36986
  {
36737
- root: server.config.root,
36738
- ...options
36987
+ ...options,
36988
+ root: resolveDevelopmentRoot(options.root, server.config.root)
36739
36989
  },
36740
36990
  server
36741
36991
  );
@@ -37322,7 +37572,8 @@ window.__FARM_MANIFEST__ = ${inlineValue({
37322
37572
  () => middlewareManager.execute(req, res)
37323
37573
  );
37324
37574
  }, "runAppMiddlewareForContentRoute");
37325
- if (openAPIManager && options.openapi?.specRoute && requestPathname === options.openapi.specRoute) {
37575
+ const openAPIRequestPathname = openAPIManager ? stripFarmBasePath(requestPathname, farmConfig.basePath) : requestPathname;
37576
+ if (openAPIManager && options.openapi?.specRoute && openAPIRequestPathname === options.openapi.specRoute) {
37326
37577
  if (await runAppMiddlewareForContentRoute()) return;
37327
37578
  if (requestMethod !== "GET" && requestMethod !== "HEAD") {
37328
37579
  res.statusCode = 405;
@@ -37339,7 +37590,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
37339
37590
  res.end(requestMethod === "HEAD" ? void 0 : body);
37340
37591
  return;
37341
37592
  }
37342
- if (openAPIManager && requestPathname === options.openapi?.route) {
37593
+ if (openAPIManager && openAPIRequestPathname === options.openapi?.route) {
37343
37594
  if (await runAppMiddlewareForContentRoute()) return;
37344
37595
  const docsHandler = openAPIManager.getDocsRouteHandler(parsedRequestUrl.origin);
37345
37596
  return docsHandler(req, res);
@@ -37817,6 +38068,21 @@ window.__FARM_MANIFEST__ = ${inlineValue({
37817
38068
  headers: request2.headers,
37818
38069
  signal: request2.signal
37819
38070
  });
38071
+ let middlewareMap = /* @__PURE__ */ new Map();
38072
+ let middlewareContext = /* @__PURE__ */ new Map();
38073
+ if (middlewareManager?.hasMiddleware()) {
38074
+ const targetNodeRequest = createPageDataMiddlewareRequest(req, targetRequestUrl);
38075
+ const handled = await runFarmMiddlewareWithNavigation(
38076
+ farmApp.getServerRenderer(),
38077
+ targetRequest,
38078
+ targetNodeRequest,
38079
+ res,
38080
+ () => middlewareManager.execute(targetNodeRequest, res)
38081
+ );
38082
+ if (handled) return;
38083
+ middlewareMap = targetNodeRequest.__FARM_MIDDLEWARE_DATA__ ?? middlewareMap;
38084
+ middlewareContext = targetNodeRequest.__FARM_MIDDLEWARE_CONTEXT__ ?? middlewareContext;
38085
+ }
37820
38086
  await farmApp.getServerRenderer().runWithRequestContext(targetRequest, async () => {
37821
38087
  const routeManager3 = farmApp.getRouteManager();
37822
38088
  if (pm) {
@@ -37890,7 +38156,8 @@ window.__FARM_MANIFEST__ = ${inlineValue({
37890
38156
  {
37891
38157
  params,
37892
38158
  searchParams: Promise.resolve(searchParams),
37893
- path: targetUrl.pathname
38159
+ path: targetUrl.pathname,
38160
+ middleware: middlewareMap.size > 0 ? { data: middlewareMap } : void 0
37894
38161
  },
37895
38162
  routeContext
37896
38163
  ),
@@ -37978,27 +38245,34 @@ window.__FARM_MANIFEST__ = ${inlineValue({
37978
38245
  parseFarmLayoutChainHeader(request2.headers.get("x-farm-layout-chain")),
37979
38246
  destinationLayoutPatterns
37980
38247
  );
37981
- const fragmentHtml = await farmApp.getServerRenderer().renderNavigationFragment({
37982
- PageComponent: routeModule.default,
37983
- LoadingComponent: loadingModule?.default,
37984
- pageProps: routeProps,
37985
- params,
37986
- layouts: layouts.map((layout2, index) => ({
37987
- pattern: layout2.pattern,
37988
- module: layoutModules[index]
37989
- })),
37990
- layoutStartIndex,
37991
- slots: routeSlots.map((slot) => ({
37992
- name: slot.name,
37993
- ownerPattern: slot.ownerPattern,
37994
- containerId: slot.containerId,
37995
- module: slot.renderModule,
37996
- props: slot.props
37997
- })),
37998
- pageShouldHydrate: shouldHydrate,
37999
- layoutShouldHydrate: shouldHydrateLayout,
38000
- islandStrategy: hydrationIslandStrategy
38001
- });
38248
+ const renderer = farmApp.getServerRenderer();
38249
+ const fragmentHtml = await _runWithMiddlewareData(
38250
+ middlewareMap,
38251
+ () => _runWithMiddlewareContext(
38252
+ middlewareContext,
38253
+ () => renderer.renderNavigationFragment({
38254
+ PageComponent: routeModule.default,
38255
+ LoadingComponent: loadingModule?.default,
38256
+ pageProps: routeProps,
38257
+ params,
38258
+ layouts: layouts.map((layout2, index) => ({
38259
+ pattern: layout2.pattern,
38260
+ module: layoutModules[index]
38261
+ })),
38262
+ layoutStartIndex,
38263
+ slots: routeSlots.map((slot) => ({
38264
+ name: slot.name,
38265
+ ownerPattern: slot.ownerPattern,
38266
+ containerId: slot.containerId,
38267
+ module: slot.renderModule,
38268
+ props: slot.props
38269
+ })),
38270
+ pageShouldHydrate: shouldHydrate,
38271
+ layoutShouldHydrate: shouldHydrateLayout,
38272
+ islandStrategy: hydrationIslandStrategy
38273
+ })
38274
+ )
38275
+ );
38002
38276
  const pageData = {
38003
38277
  props: {
38004
38278
  params: routeProps.params,
@@ -38008,7 +38282,9 @@ window.__FARM_MANIFEST__ = ${inlineValue({
38008
38282
  ...routeProps.__farmCanonicalPath ? {
38009
38283
  __farmCanonicalPath: routeProps.__farmCanonicalPath
38010
38284
  } : {},
38011
- ...routeProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {}
38285
+ ...routeProps.__farmRoutePropsResolved ? { __farmRoutePropsResolved: true } : {},
38286
+ // The same serialized shape a full load embeds in __FARM_PROPS__.
38287
+ ...middlewareMap.size > 0 ? { middleware: { data: Object.fromEntries(middlewareMap) } } : {}
38012
38288
  },
38013
38289
  canonicalPath: routeProps.__farmCanonicalPath,
38014
38290
  modulePath: toUrlPath(route.modulePath),
@@ -38756,6 +39032,24 @@ function runFarmMiddlewareWithNavigation(renderer, middlewareRequest, req, res,
38756
39032
  }
38757
39033
  });
38758
39034
  }
39035
+ function createPageDataMiddlewareRequest(req, target) {
39036
+ const targetNodeRequest = Object.create(req);
39037
+ targetNodeRequest.url = `${target.pathname}${target.search}`;
39038
+ targetNodeRequest.originalUrl = targetNodeRequest.url;
39039
+ targetNodeRequest.method = "GET";
39040
+ return targetNodeRequest;
39041
+ }
39042
+ function resolveDevelopmentRoot(farmRoot, viteRoot) {
39043
+ if (!farmRoot) return viteRoot;
39044
+ if (path43.resolve(farmRoot) === path43.resolve(viteRoot)) return farmRoot;
39045
+ try {
39046
+ if (fs15.realpathSync(farmRoot) === fs15.realpathSync(viteRoot)) {
39047
+ return path43.resolve(viteRoot);
39048
+ }
39049
+ } catch {
39050
+ }
39051
+ return farmRoot;
39052
+ }
38759
39053
  function isFarmClientVirtualId(id) {
38760
39054
  const pathname = id.split("?", 1)[0];
38761
39055
  return pathname === "/@farm/client" || pathname === "/@farm/client.js";
@@ -38770,16 +39064,18 @@ function generateProgrammaticRouteModule(moduleId, root, renderer = REACT_RENDER
38770
39064
  return generateProgrammaticApiRouteModule(parsed.routePath, routeFile);
38771
39065
  }
38772
39066
  return `
38773
- import {
38774
- createElement as __farmCreateElement,
38775
- Suspense as __farmSuspense,
38776
- } from ${JSON.stringify(renderer.server)};
39067
+ import * as __farmRendererRuntime from ${JSON.stringify(renderer.server)};
38777
39068
  import {
38778
39069
  createLayoutModuleFromProgrammaticLayout as __farmCreateLayoutRouteModule,
38779
39070
  createRouteModuleFromProgrammaticPage as __farmCreatePageRouteModule,
38780
39071
  } from "@farm.js/core/routes";
38781
39072
  import * as __farmRoutesModule from ${JSON.stringify(routeFile)};
38782
39073
 
39074
+ const __farmCreateElement = __farmRendererRuntime.createElement;
39075
+ const __farmSuspense = __farmRendererRuntime.Suspense;
39076
+ // Optional hook: only renderers that need it export markFunctionComponent.
39077
+ const __farmMarkFunctionComponent = Reflect.get(__farmRendererRuntime, "markFunctionComponent");
39078
+
38783
39079
  const __farmIsRouteDefinition = (value) => (
38784
39080
  value &&
38785
39081
  typeof value === "object" &&
@@ -38833,6 +39129,7 @@ const __farmRouteModule = __farmRoute.kind === "layout"
38833
39129
  : __farmCreatePageRouteModule(__farmRoute, {
38834
39130
  createElement: __farmCreateElement,
38835
39131
  Suspense: __farmSuspense,
39132
+ markFunctionComponent: __farmMarkFunctionComponent,
38836
39133
  });
38837
39134
 
38838
39135
  export const metadata = __farmRouteModule.metadata;
@@ -40437,6 +40734,11 @@ async function hydrate() {
40437
40734
  pendingPageHydrationController = hydrationController;
40438
40735
  await hydrateFarmIsolatedClientBoundaries(rootContainer, hydrationController.signal);
40439
40736
  if (hydrationController.signal.aborted) return;
40737
+ // The rest of the document is static server HTML with nothing to hydrate, so
40738
+ // stop holding its clicks and submits once the load-strategy islands are live.
40739
+ // Deferred islands capture their own interactions, and held targets outside an
40740
+ // island are not replayed into DOM no client code owns.
40741
+ markFarmHydrated();
40440
40742
  return;
40441
40743
  }` : ""}
40442
40744
  if (!shouldHydrate) {
@@ -40866,6 +41168,7 @@ var fs15, path43, import_node_url12, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifact
40866
41168
  var init_vite2 = __esm({
40867
41169
  "src/vite.ts"() {
40868
41170
  "use strict";
41171
+ init_env();
40869
41172
  init_app();
40870
41173
  init_utils();
40871
41174
  init_plugin();
@@ -40877,9 +41180,11 @@ var init_vite2 = __esm({
40877
41180
  init_server_path();
40878
41181
  init_runtime2();
40879
41182
  init_manager();
41183
+ init_server();
40880
41184
  init_type_artifacts();
40881
41185
  init_routes_shared();
40882
41186
  init_markdown();
41187
+ init_base_path();
40883
41188
  init_llms_txt();
40884
41189
  init_agent_crawlers();
40885
41190
  init_app_markdown();
@@ -41017,6 +41322,8 @@ async function mountFarmDocsSearch() {
41017
41322
  __name(hasViteAlias, "hasViteAlias");
41018
41323
  __name(farmPlugin, "farmPlugin");
41019
41324
  __name(runFarmMiddlewareWithNavigation, "runFarmMiddlewareWithNavigation");
41325
+ __name(createPageDataMiddlewareRequest, "createPageDataMiddlewareRequest");
41326
+ __name(resolveDevelopmentRoot, "resolveDevelopmentRoot");
41020
41327
  __name(isFarmClientVirtualId, "isFarmClientVirtualId");
41021
41328
  __name(generateProgrammaticRouteModule, "generateProgrammaticRouteModule");
41022
41329
  __name(generateProgrammaticApiRouteModule, "generateProgrammaticApiRouteModule");
@@ -41081,7 +41388,7 @@ export const farmRegistry: {
41081
41388
  clientManifest?: any;
41082
41389
  routePaths?: Record<string, string>;
41083
41390
  } = {
41084
- env: ${JSON.stringify(config.env || { server: {}, public: {} }, null, 2)},
41391
+ env: ${JSON.stringify(createBundledEnv(config.env), null, 2)},
41085
41392
  deploymentId: ${JSON.stringify(config.deploymentId)},
41086
41393
  basePath: ${JSON.stringify(config.basePath)},
41087
41394
  apiBasePath: ${JSON.stringify(apiBasePath)},
@@ -41585,7 +41892,7 @@ export default defineEventHandler(async (event: H3Event) => {
41585
41892
  farmRegistry.apiRouteManager = apiRouteManager;
41586
41893
  farmRegistry.routeManager = routeManager;
41587
41894
  farmRegistry.serverRenderer = serverRenderer;
41588
- farmRegistry.env = config.env || { server: {}, public: {} };
41895
+ farmRegistry.env = createBundledEnv(config.env);
41589
41896
  farmRegistry.deploymentId = config.deploymentId;
41590
41897
  farmRegistry.basePath = config.basePath;
41591
41898
  };
@@ -41650,6 +41957,7 @@ var import_path16;
41650
41957
  var init_nitro = __esm({
41651
41958
  "src/nitro/index.ts"() {
41652
41959
  "use strict";
41960
+ init_env();
41653
41961
  import_path16 = __toESM(require("path"));
41654
41962
  init_workflows();
41655
41963
  init_cron();
@@ -41672,6 +41980,7 @@ __export(build_runtime_exports, {
41672
41980
  module.exports = __toCommonJS(build_runtime_exports);
41673
41981
 
41674
41982
  // src/build/index.ts
41983
+ init_env();
41675
41984
  init_config4();
41676
41985
  var import_path17 = __toESM(require("path"));
41677
41986
  var import_node_fs14 = require("fs");
@@ -41682,6 +41991,7 @@ init_server_path();
41682
41991
  init_layers();
41683
41992
 
41684
41993
  // src/nitro/universal-build.ts
41994
+ init_env();
41685
41995
  init_config4();
41686
41996
 
41687
41997
  // src/nitro/client-css-href.ts
@@ -43793,7 +44103,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
43793
44103
  }
43794
44104
  }
43795
44105
  try {
43796
- await viteBuild({
44106
+ const clientViteConfig = {
43797
44107
  root,
43798
44108
  // Vite otherwise falls back to <root>/public, silently dropping every
43799
44109
  // asset in a custom config.publicDir from the production client output.
@@ -43929,7 +44239,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
43929
44239
  "@farm.js/core/headers"
43930
44240
  ]
43931
44241
  }
43932
- });
44242
+ };
44243
+ await viteBuild(mergeFarmProductionViteConfig(clientViteConfig, config.vite));
43933
44244
  await mergeBuiltFontCss(outputDir);
43934
44245
  await validateClientBuildOutput(root, srcDir, outputDir);
43935
44246
  } finally {
@@ -46275,7 +46586,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
46275
46586
  "react-dom/server"
46276
46587
  ];
46277
46588
  try {
46278
- await viteBuild({
46589
+ const serverViteConfig = {
46279
46590
  root,
46280
46591
  build: {
46281
46592
  target: "esnext",
@@ -46366,7 +46677,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
46366
46677
  },
46367
46678
  define: {
46368
46679
  __FARM_API_BASE_URL__: JSON.stringify(config.api.baseURL),
46369
- __FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
46680
+ __FARM_ENV__: JSON.stringify(createBundledEnv(config.env)),
46370
46681
  __FARM_PUBLIC_ENV__: JSON.stringify(config.env?.public || {})
46371
46682
  },
46372
46683
  plugins: [
@@ -46436,7 +46747,8 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
46436
46747
  // Route modules and the renderer adapter must share one runtime instance.
46437
46748
  dedupe: [...config.renderer.dedupe || []]
46438
46749
  }
46439
- });
46750
+ };
46751
+ await viteBuild(mergeFarmProductionViteConfig(serverViteConfig, config.vite));
46440
46752
  } finally {
46441
46753
  if (postcssConfigDir) {
46442
46754
  try {
@@ -48644,7 +48956,7 @@ function hasLocalRequestRoute(request, routePathname) {
48644
48956
  const pathname = new URL(request.url).pathname;
48645
48957
  if (
48646
48958
  farmOpenAPIReference &&
48647
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
48959
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.route)
48648
48960
  ) {
48649
48961
  return true;
48650
48962
  }
@@ -48680,7 +48992,7 @@ function getFarmPluginRequestOptions(request) {
48680
48992
  const route = { pathname };
48681
48993
  if (
48682
48994
  farmOpenAPIReference &&
48683
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
48995
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.route)
48684
48996
  ) {
48685
48997
  return {
48686
48998
  kind: "docs",
@@ -49009,9 +49321,10 @@ async function handleFarmRequest(request, adapterContext) {
49009
49321
  )` : "handleFarmRequestInContext(request, null, false, Date.now(), adapterContext, requestUrl)"};
49010
49322
  ${config.md?.enabled ? `const pathname = getFarmRoutePathname(requestUrl.pathname);
49011
49323
  if (matchPageRoute(pathname)) {
49324
+ // The Link header advertises the public .md URL, like the head alternate.
49012
49325
  return applyMarkdownNegotiationHeaders(response, {
49013
49326
  config: farmMarkdownConfig,
49014
- pathname,
49327
+ pathname: requestUrl.pathname,
49015
49328
  });
49016
49329
  }` : ""}
49017
49330
  return response;
@@ -49199,7 +49512,7 @@ async function handleFarmRequestInContext(
49199
49512
  if (
49200
49513
  farmOpenAPIReference &&
49201
49514
  farmOpenAPIReference.specRoute &&
49202
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.specRoute)
49515
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.specRoute)
49203
49516
  ) {
49204
49517
  const method = request.method.toUpperCase();
49205
49518
  const specResponse = method === "GET" || method === "HEAD"
@@ -49223,7 +49536,7 @@ async function handleFarmRequestInContext(
49223
49536
 
49224
49537
  if (
49225
49538
  farmOpenAPIReference &&
49226
- normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
49539
+ normalizeRuntimePath(stripFarmBasePath(pathname)) === normalizeRuntimePath(farmOpenAPIReference.route)
49227
49540
  ) {
49228
49541
  const method = request.method.toUpperCase();
49229
49542
  const response = method === "GET" || method === "HEAD"
@@ -49761,12 +50074,15 @@ async function handleFarmRequestInContext(
49761
50074
  const sharedCacheControl = getRouteSharedCacheControl(route, pprCanCache);
49762
50075
  const responseHeaders = {
49763
50076
  "Content-Type": "text/html; charset=utf-8",
49764
- "Cache-Control": renderedPage.stream || hasRequestScopedRender || !sharedCacheControl
49765
- ? "private, no-store"
49766
- : sharedCacheControl,
50077
+ "Cache-Control": sharedCacheControl,
49767
50078
  ...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
49768
50079
  ...(pprConfig.enabled ? getPPRHeaders(pprCanCache ? "miss" : "bypass", pprConfig) : {}),
49769
50080
  };
50081
+ // An error status or a request-scoped render is never shareable, even when
50082
+ // the PPR shell headers would otherwise grant a shared max-age.
50083
+ if (renderedPage.stream || hasRequestScopedRender || !sharedCacheControl) {
50084
+ responseHeaders["Cache-Control"] = "private, no-store";
50085
+ }
49770
50086
  const farmI18nSnapshot = getFarmI18nSnapshot();
49771
50087
  let html = renderedPage.html;
49772
50088
 
@@ -51817,7 +52133,7 @@ async function buildSSR(viteBuild, config, root, srcDir, outputDir) {
51817
52133
  },
51818
52134
  define: {
51819
52135
  __FARM_API_BASE_URL__: JSON.stringify(config.api.baseURL),
51820
- __FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
52136
+ __FARM_ENV__: JSON.stringify(createBundledEnv(config.env)),
51821
52137
  __FARM_PUBLIC_ENV__: JSON.stringify(config.env?.public || {})
51822
52138
  },
51823
52139
  plugins: [
@@ -51900,7 +52216,7 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
51900
52216
  farmRegistry.apiRouteManager = apiRouteManager;
51901
52217
  farmRegistry.routeManager = routeManager;
51902
52218
  farmRegistry.serverRenderer = serverRenderer;
51903
- farmRegistry.env = config.env || { server: {}, public: {} };
52219
+ farmRegistry.env = createBundledEnv(config.env);
51904
52220
  const routePaths = {};
51905
52221
  for (const [pattern, entry] of routeManager.getRoutes()) {
51906
52222
  const bundledPath = entry.modulePath.replace(/.*\/src\/app\//, "").replace(/\.(tsx?|jsx?)$/, ".js");