@farm.js/core 0.1.0-beta.23 → 0.1.0-beta.25

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.
package/dist/plugin.cjs CHANGED
@@ -785,11 +785,11 @@ function resolveFarmServerHealthConfig(config) {
785
785
  return Object.freeze({ enabled: true, livenessPath, readinessPath });
786
786
  }
787
787
  function normalizeHealthPath(value, optionName) {
788
- const path26 = value.trim();
789
- if (!path26.startsWith("/") || path26.includes("?") || path26.includes("#") || path26.includes("*")) {
788
+ const path27 = value.trim();
789
+ if (!path27.startsWith("/") || path27.includes("?") || path27.includes("#") || path27.includes("*")) {
790
790
  throw new TypeError(`${optionName} must be an absolute pathname without a query or wildcard`);
791
791
  }
792
- return path26.length > 1 ? path26.replace(/\/+$/, "") || "/" : path26;
792
+ return path27.length > 1 ? path27.replace(/\/+$/, "") || "/" : path27;
793
793
  }
794
794
  function parseBodySizeLimit(value, optionName = "bodySizeLimit") {
795
795
  if (typeof value === "number") {
@@ -886,7 +886,7 @@ async function readNodeRequestBody(request, limit) {
886
886
  request.resume?.();
887
887
  throw error;
888
888
  }
889
- return await new Promise((resolve6, reject) => {
889
+ return await new Promise((resolve7, reject) => {
890
890
  const chunks = [];
891
891
  let total = 0;
892
892
  let settled = false;
@@ -915,7 +915,7 @@ async function readNodeRequestBody(request, limit) {
915
915
  if (settled) return;
916
916
  settled = true;
917
917
  cleanup();
918
- resolve6(Buffer.concat(chunks, total));
918
+ resolve7(Buffer.concat(chunks, total));
919
919
  }, "onEnd");
920
920
  const onError = /* @__PURE__ */ __name((error) => rejectOnce(error), "onError");
921
921
  request.on("data", onData);
@@ -1144,22 +1144,22 @@ async function prepareFarmWorkflowsForNitro(config) {
1144
1144
  }
1145
1145
  const root = config.root || process.cwd();
1146
1146
  const distDir = config.distDir || ".farm";
1147
- const fs8 = await import("fs/promises");
1148
- const path26 = await import("path");
1149
- const generatedDir = path26.join(root, distDir, ".nitro", "farm-workflows");
1150
- await fs8.mkdir(generatedDir, { recursive: true });
1147
+ const fs9 = await import("fs/promises");
1148
+ const path27 = await import("path");
1149
+ const generatedDir = path27.join(root, distDir, ".nitro", "farm-workflows");
1150
+ await fs9.mkdir(generatedDir, { recursive: true });
1151
1151
  const tasks = {};
1152
1152
  const scheduledTasks = createScheduledTasks(workflows);
1153
1153
  for (const workflow of workflows) {
1154
- const wrapperPath = path26.join(generatedDir, `${safeFileName(workflow.id)}.mjs`);
1155
- await fs8.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1154
+ const wrapperPath = path27.join(generatedDir, `${safeFileName(workflow.id)}.mjs`);
1155
+ await fs9.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
1156
1156
  tasks[workflow.id] = {
1157
1157
  handler: wrapperPath,
1158
1158
  description: workflow.description || `Farm workflow ${workflow.id}`
1159
1159
  };
1160
1160
  }
1161
- const handlerPath = path26.join(generatedDir, "http-handler.mjs");
1162
- await fs8.writeFile(
1161
+ const handlerPath = path27.join(generatedDir, "http-handler.mjs");
1162
+ await fs9.writeFile(
1163
1163
  handlerPath,
1164
1164
  createNitroWorkflowHTTPHandler(
1165
1165
  workflowConfig,
@@ -1168,8 +1168,8 @@ async function prepareFarmWorkflowsForNitro(config) {
1168
1168
  ),
1169
1169
  "utf8"
1170
1170
  );
1171
- const manifestPath = path26.join(generatedDir, "manifest.json");
1172
- await fs8.writeFile(
1171
+ const manifestPath = path27.join(generatedDir, "manifest.json");
1172
+ await fs9.writeFile(
1173
1173
  manifestPath,
1174
1174
  JSON.stringify(
1175
1175
  {
@@ -1250,22 +1250,22 @@ function resolveWorkflowDefinition(module2) {
1250
1250
  return null;
1251
1251
  }
1252
1252
  async function findWorkflowFiles(root, dirs) {
1253
- const fs8 = await import("fs/promises");
1254
- const path26 = await import("path");
1253
+ const fs9 = await import("fs/promises");
1254
+ const path27 = await import("path");
1255
1255
  const files = [];
1256
1256
  for (const dir of dirs) {
1257
- const absoluteDir = path26.isAbsolute(dir) ? dir : path26.join(root, dir);
1257
+ const absoluteDir = path27.isAbsolute(dir) ? dir : path27.join(root, dir);
1258
1258
  if (!await pathExists(absoluteDir)) continue;
1259
1259
  await walkWorkflowDir(absoluteDir, files);
1260
1260
  }
1261
1261
  return files.sort();
1262
1262
  }
1263
1263
  async function walkWorkflowDir(dir, files) {
1264
- const fs8 = await import("fs/promises");
1265
- const path26 = await import("path");
1266
- const entries = await fs8.readdir(dir, { withFileTypes: true });
1264
+ const fs9 = await import("fs/promises");
1265
+ const path27 = await import("path");
1266
+ const entries = await fs9.readdir(dir, { withFileTypes: true });
1267
1267
  for (const entry of entries) {
1268
- const filePath = path26.join(dir, entry.name);
1268
+ const filePath = path27.join(dir, entry.name);
1269
1269
  if (entry.isDirectory()) {
1270
1270
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
1271
1271
  await walkWorkflowDir(filePath, files);
@@ -1277,20 +1277,20 @@ async function walkWorkflowDir(dir, files) {
1277
1277
  }
1278
1278
  }
1279
1279
  async function pathExists(filePath) {
1280
- const fs8 = await import("fs/promises");
1281
- return fs8.access(filePath).then(() => true).catch(() => false);
1280
+ const fs9 = await import("fs/promises");
1281
+ return fs9.access(filePath).then(() => true).catch(() => false);
1282
1282
  }
1283
1283
  function isWorkflowFile(fileName) {
1284
1284
  return /\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName);
1285
1285
  }
1286
1286
  async function loadWorkflowModule(filePath, root) {
1287
- const fs8 = await import("fs/promises");
1288
- const path26 = await import("path");
1287
+ const fs9 = await import("fs/promises");
1288
+ const path27 = await import("path");
1289
1289
  const { pathToFileURL: pathToFileURL5 } = await import("url");
1290
1290
  const { build } = await import("esbuild");
1291
- const outDir = path26.join(root, ".farm", ".workflow-loader");
1292
- await fs8.mkdir(outDir, { recursive: true });
1293
- const outfile = path26.join(
1291
+ const outDir = path27.join(root, ".farm", ".workflow-loader");
1292
+ await fs9.mkdir(outDir, { recursive: true });
1293
+ const outfile = path27.join(
1294
1294
  outDir,
1295
1295
  `workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
1296
1296
  );
@@ -1314,7 +1314,7 @@ async function loadWorkflowModule(filePath, root) {
1314
1314
  `${pathToFileURL5(outfile).href}?t=${Date.now()}`
1315
1315
  );
1316
1316
  } finally {
1317
- await fs8.unlink(outfile).catch(() => void 0);
1317
+ await fs9.unlink(outfile).catch(() => void 0);
1318
1318
  }
1319
1319
  }
1320
1320
  function workflowIdFromFile(root, filePath) {
@@ -1589,7 +1589,7 @@ function normalizeCronJob(name, job) {
1589
1589
  if (!job || typeof job !== "object" || Array.isArray(job)) {
1590
1590
  throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);
1591
1591
  }
1592
- const path26 = normalizeCronPath(name, job.path);
1592
+ const path27 = normalizeCronPath(name, job.path);
1593
1593
  const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
1594
1594
  const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name, value)))];
1595
1595
  if (schedule.length === 0) {
@@ -1598,7 +1598,7 @@ function normalizeCronJob(name, job) {
1598
1598
  return {
1599
1599
  name,
1600
1600
  schedule,
1601
- path: path26,
1601
+ path: path27,
1602
1602
  description: job.description?.trim() || void 0
1603
1603
  };
1604
1604
  }
@@ -1606,13 +1606,13 @@ function normalizeCronPath(name, value) {
1606
1606
  if (typeof value !== "string" || !value.trim().startsWith("/")) {
1607
1607
  throw new TypeError(`Farm cron ${JSON.stringify(name)} path must start with "/".`);
1608
1608
  }
1609
- const path26 = value.trim();
1610
- if (path26.startsWith("//") || path26.includes("?") || path26.includes("#")) {
1609
+ const path27 = value.trim();
1610
+ if (path27.startsWith("//") || path27.includes("?") || path27.includes("#")) {
1611
1611
  throw new TypeError(
1612
1612
  `Farm cron ${JSON.stringify(name)} path must be an application pathname without a host, query, or hash.`
1613
1613
  );
1614
1614
  }
1615
- return path26.length > 1 ? path26.replace(/\/+$/, "") : path26;
1615
+ return path27.length > 1 ? path27.replace(/\/+$/, "") : path27;
1616
1616
  }
1617
1617
  function normalizeCronExpression(name, value) {
1618
1618
  if (typeof value !== "string") {
@@ -2448,7 +2448,7 @@ var init_server_action_security = __esm({
2448
2448
 
2449
2449
  // src/image-config.ts
2450
2450
  function resolveFarmImageConfig(config) {
2451
- const path26 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
2451
+ const path27 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
2452
2452
  const deviceSizes = normalizeIntegerList(
2453
2453
  config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
2454
2454
  "images.deviceSizes"
@@ -2476,7 +2476,7 @@ function resolveFarmImageConfig(config) {
2476
2476
  );
2477
2477
  return Object.freeze({
2478
2478
  provider: config?.provider ?? "auto",
2479
- path: path26,
2479
+ path: path27,
2480
2480
  domains: Object.freeze([
2481
2481
  ...new Set(
2482
2482
  (config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
@@ -2515,11 +2515,11 @@ function getPublicFarmImageConfig(config) {
2515
2515
  };
2516
2516
  }
2517
2517
  function normalizeImagePath(value) {
2518
- const path26 = value.trim().replace(/\/+$/, "") || "/";
2519
- if (!path26.startsWith("/") || path26.includes("?") || path26.includes("#")) {
2518
+ const path27 = value.trim().replace(/\/+$/, "") || "/";
2519
+ if (!path27.startsWith("/") || path27.includes("?") || path27.includes("#")) {
2520
2520
  throw new TypeError("images.path must be an absolute pathname without a query or hash");
2521
2521
  }
2522
- return path26;
2522
+ return path27;
2523
2523
  }
2524
2524
  function normalizeIntegerList(values, name, max) {
2525
2525
  if (values.length === 0) {
@@ -2872,9 +2872,9 @@ function getFarmIntegrationPluginOwner(plugin) {
2872
2872
  const value = plugin[FARM_INTEGRATION_PLUGIN_OWNER];
2873
2873
  return value && typeof value === "object" ? value : void 0;
2874
2874
  }
2875
- function defineTypedIntegrationRoute(method, path26, input) {
2875
+ function defineTypedIntegrationRoute(method, path27, input) {
2876
2876
  return {
2877
- path: path26,
2877
+ path: path27,
2878
2878
  method,
2879
2879
  middleware: input.middleware,
2880
2880
  before: input.before,
@@ -2884,7 +2884,7 @@ function defineTypedIntegrationRoute(method, path26, input) {
2884
2884
  input: normalizeIntegrationRouteInputSchemas(input),
2885
2885
  handler: input.handler,
2886
2886
  __operation: defineIntegrationAPIOperation({
2887
- path: path26,
2887
+ path: path27,
2888
2888
  method,
2889
2889
  bodyFormat: input.bodyFormat,
2890
2890
  responseFormat: input.responseFormat,
@@ -2896,52 +2896,52 @@ function defineTypedIntegrationRoute(method, path26, input) {
2896
2896
  }
2897
2897
  function createIntegrationRouteFactory() {
2898
2898
  return {
2899
- get(path26, input) {
2899
+ get(path27, input) {
2900
2900
  return defineTypedIntegrationRoute(
2901
2901
  "GET",
2902
- path26,
2902
+ path27,
2903
2903
  input
2904
2904
  );
2905
2905
  },
2906
- post(path26, input) {
2906
+ post(path27, input) {
2907
2907
  return defineTypedIntegrationRoute(
2908
2908
  "POST",
2909
- path26,
2909
+ path27,
2910
2910
  {
2911
2911
  bodyFormat: "json",
2912
2912
  ...input
2913
2913
  }
2914
2914
  );
2915
2915
  },
2916
- put(path26, input) {
2916
+ put(path27, input) {
2917
2917
  return defineTypedIntegrationRoute(
2918
2918
  "PUT",
2919
- path26,
2919
+ path27,
2920
2920
  {
2921
2921
  bodyFormat: "json",
2922
2922
  ...input
2923
2923
  }
2924
2924
  );
2925
2925
  },
2926
- patch(path26, input) {
2927
- return defineTypedIntegrationRoute("PATCH", path26, {
2926
+ patch(path27, input) {
2927
+ return defineTypedIntegrationRoute("PATCH", path27, {
2928
2928
  bodyFormat: "json",
2929
2929
  ...input
2930
2930
  });
2931
2931
  },
2932
- delete(path26, input) {
2933
- return defineTypedIntegrationRoute("DELETE", path26, {
2932
+ delete(path27, input) {
2933
+ return defineTypedIntegrationRoute("DELETE", path27, {
2934
2934
  bodyFormat: "json",
2935
2935
  ...input
2936
2936
  });
2937
2937
  },
2938
- options(path26, input) {
2939
- return defineTypedIntegrationRoute("OPTIONS", path26, input);
2938
+ options(path27, input) {
2939
+ return defineTypedIntegrationRoute("OPTIONS", path27, input);
2940
2940
  },
2941
- head(path26, input) {
2941
+ head(path27, input) {
2942
2942
  return defineTypedIntegrationRoute(
2943
2943
  "HEAD",
2944
- path26,
2944
+ path27,
2945
2945
  input
2946
2946
  );
2947
2947
  }
@@ -3278,8 +3278,8 @@ function normalizeIntegrationValidationIssues(source, error) {
3278
3278
  }
3279
3279
  ];
3280
3280
  }
3281
- function normalizeIntegrationValidationPath(path26) {
3282
- return (path26 || []).map((segment) => {
3281
+ function normalizeIntegrationValidationPath(path27) {
3282
+ return (path27 || []).map((segment) => {
3283
3283
  const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
3284
3284
  return typeof key === "symbol" ? key.description || key.toString() : key;
3285
3285
  });
@@ -3982,8 +3982,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
3982
3982
  }
3983
3983
  );
3984
3984
  }
3985
- function createFarmDeploymentCookie(deploymentId, path26 = "/", secure = false) {
3986
- const normalizedPath = path26.startsWith("/") ? path26 : `/${path26}`;
3985
+ function createFarmDeploymentCookie(deploymentId, path27 = "/", secure = false) {
3986
+ const normalizedPath = path27.startsWith("/") ? path27 : `/${path27}`;
3987
3987
  return [
3988
3988
  `${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
3989
3989
  `Path=${normalizedPath}`,
@@ -4560,11 +4560,11 @@ var init_type_generator = __esm({
4560
4560
  routeGroups.get(key).push(route);
4561
4561
  }
4562
4562
  const nestedStructure = {};
4563
- for (const [path26, routeList] of routeGroups) {
4563
+ for (const [path27, routeList] of routeGroups) {
4564
4564
  const route = routeList[0];
4565
4565
  const importPath = this.getRouteImportPath(route, options.outFile);
4566
4566
  const routeName = this.pathToRouteName(route.path);
4567
- const cleanPath = path26 === "/api" ? "" : path26.replace(/^\/api\//, "");
4567
+ const cleanPath = path27 === "/api" ? "" : path27.replace(/^\/api\//, "");
4568
4568
  const parts = cleanPath ? cleanPath.split("/") : [];
4569
4569
  const allMethods = routeList.flatMap((r) => r.methods);
4570
4570
  for (const method of allMethods) {
@@ -4623,8 +4623,8 @@ ${typeExports}
4623
4623
  const relativeImport = (0, import_path7.relative)((0, import_path7.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
4624
4624
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
4625
4625
  }
4626
- pathToRouteName(path26) {
4627
- return (path26 === "/api" ? "root" : path26.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "");
4626
+ pathToRouteName(path27) {
4627
+ return (path27 === "/api" ? "root" : path27.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "");
4628
4628
  }
4629
4629
  structureToTypeString(obj, indent) {
4630
4630
  const spaces = " ".repeat(indent);
@@ -4644,15 +4644,15 @@ ${typeExports}
4644
4644
  toTypePropertyKey(key) {
4645
4645
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
4646
4646
  }
4647
- getBaseExportName(path26) {
4648
- const cleanPath = path26.replace(/^\/api\//, "");
4647
+ getBaseExportName(path27) {
4648
+ const cleanPath = path27.replace(/^\/api\//, "");
4649
4649
  if (cleanPath === "") {
4650
4650
  return "api";
4651
4651
  }
4652
4652
  return cleanPath;
4653
4653
  }
4654
- getExportName(path26, method) {
4655
- const cleanPath = path26.replace(/^\/api\//, "");
4654
+ getExportName(path27, method) {
4655
+ const cleanPath = path27.replace(/^\/api\//, "");
4656
4656
  if (cleanPath === "") {
4657
4657
  return method.toLowerCase();
4658
4658
  }
@@ -8851,37 +8851,37 @@ function sanitizeDocsConfig(config) {
8851
8851
  return cloneSerializable(config) || {};
8852
8852
  }
8853
8853
  async function findDocsConfigPath(rootDir, configPath) {
8854
- const { existsSync: existsSync16 } = await import("fs");
8854
+ const { existsSync: existsSync17 } = await import("fs");
8855
8855
  const root = import_path9.default.resolve(rootDir || process.cwd());
8856
8856
  if (configPath) {
8857
8857
  const resolvedPath = import_path9.default.isAbsolute(configPath) ? configPath : import_path9.default.join(root, configPath);
8858
- if (!existsSync16(resolvedPath)) {
8858
+ if (!existsSync17(resolvedPath)) {
8859
8859
  throw new Error(`Could not find docs config at ${configPath}.`);
8860
8860
  }
8861
8861
  return import_path9.default.resolve(resolvedPath);
8862
8862
  }
8863
8863
  for (const filename of DOCS_CONFIG_FILENAMES) {
8864
8864
  const resolvedPath = import_path9.default.join(root, filename);
8865
- if (existsSync16(resolvedPath)) {
8865
+ if (existsSync17(resolvedPath)) {
8866
8866
  return resolvedPath;
8867
8867
  }
8868
8868
  }
8869
8869
  return void 0;
8870
8870
  }
8871
8871
  async function loadDocsConfig(rootDir, configPath) {
8872
- const fs8 = await import("fs/promises");
8872
+ const fs9 = await import("fs/promises");
8873
8873
  const { pathToFileURL: pathToFileURL5 } = await import("url");
8874
8874
  const root = import_path9.default.resolve(rootDir || process.cwd());
8875
8875
  const resolvedPath = await findDocsConfigPath(root, configPath);
8876
8876
  if (!resolvedPath) return void 0;
8877
8877
  try {
8878
8878
  if (resolvedPath.endsWith(".json")) {
8879
- const content = await fs8.readFile(resolvedPath, "utf8");
8879
+ const content = await fs9.readFile(resolvedPath, "utf8");
8880
8880
  return { config: JSON.parse(content), configPath: resolvedPath };
8881
8881
  }
8882
8882
  const { build } = await import("esbuild");
8883
8883
  const configCacheDir = import_path9.default.join(root, ".farm", ".config-loader");
8884
- await fs8.mkdir(configCacheDir, { recursive: true });
8884
+ await fs9.mkdir(configCacheDir, { recursive: true });
8885
8885
  const modulePath = import_path9.default.join(
8886
8886
  configCacheDir,
8887
8887
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -8907,7 +8907,7 @@ async function loadDocsConfig(rootDir, configPath) {
8907
8907
  moduleUrl
8908
8908
  );
8909
8909
  } finally {
8910
- await fs8.unlink(modulePath).catch(() => void 0);
8910
+ await fs9.unlink(modulePath).catch(() => void 0);
8911
8911
  }
8912
8912
  return {
8913
8913
  config: importedConfig.default || importedConfig,
@@ -9790,8 +9790,8 @@ var init_generator = __esm({
9790
9790
  }
9791
9791
  routeGroups.get(key).push(route);
9792
9792
  }
9793
- for (const [path26, routeList] of routeGroups) {
9794
- const openAPIPath = this.convertToOpenAPIPath(path26);
9793
+ for (const [path27, routeList] of routeGroups) {
9794
+ const openAPIPath = this.convertToOpenAPIPath(path27);
9795
9795
  spec.paths[openAPIPath] = {};
9796
9796
  for (const route of routeList) {
9797
9797
  for (const method of route.methods) {
@@ -9805,8 +9805,8 @@ var init_generator = __esm({
9805
9805
  /**
9806
9806
  * Convert Farm.js API path to OpenAPI path format
9807
9807
  */
9808
- convertToOpenAPIPath(path26) {
9809
- return path26.replace(/^\/api/, "");
9808
+ convertToOpenAPIPath(path27) {
9809
+ return path27.replace(/^\/api/, "");
9810
9810
  }
9811
9811
  /**
9812
9812
  * Extract request body schema from endpoint
@@ -9968,8 +9968,8 @@ var init_generator = __esm({
9968
9968
  /**
9969
9969
  * Generate operation summary
9970
9970
  */
9971
- generateSummary(path26, method) {
9972
- const cleanPath = path26.replace(/^\/api\//, "");
9971
+ generateSummary(path27, method) {
9972
+ const cleanPath = path27.replace(/^\/api\//, "");
9973
9973
  const pathParts = cleanPath.split("/");
9974
9974
  const lastPart = pathParts[pathParts.length - 1];
9975
9975
  const action = method === "GET" ? "Get" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -9978,22 +9978,22 @@ var init_generator = __esm({
9978
9978
  /**
9979
9979
  * Generate operation description
9980
9980
  */
9981
- generateDescription(path26, method) {
9982
- const cleanPath = path26.replace(/^\/api\//, "");
9981
+ generateDescription(path27, method) {
9982
+ const cleanPath = path27.replace(/^\/api\//, "");
9983
9983
  return `${method} ${cleanPath} endpoint`;
9984
9984
  }
9985
9985
  /**
9986
9986
  * Generate operation ID
9987
9987
  */
9988
- generateOperationId(path26, method) {
9989
- const cleanPath = path26.replace(/^\/api\//, "").replace(/\//g, "_");
9988
+ generateOperationId(path27, method) {
9989
+ const cleanPath = path27.replace(/^\/api\//, "").replace(/\//g, "_");
9990
9990
  return `${method.toLowerCase()}_${cleanPath}`;
9991
9991
  }
9992
9992
  /**
9993
9993
  * Generate tags for grouping operations
9994
9994
  */
9995
- generateTags(path26) {
9996
- const cleanPath = path26.replace(/^\/api\//, "");
9995
+ generateTags(path27) {
9996
+ const cleanPath = path27.replace(/^\/api\//, "");
9997
9997
  const pathParts = cleanPath.split("/");
9998
9998
  if (pathParts.length > 1) {
9999
9999
  return [pathParts[0]];
@@ -10005,13 +10005,13 @@ var init_generator = __esm({
10005
10005
  */
10006
10006
  async generateSpecFile(routes, outputPath) {
10007
10007
  const spec = await this.generateSpec(routes);
10008
- const fs8 = require("fs");
10009
- const path26 = require("path");
10010
- const dir = path26.dirname(outputPath);
10011
- if (!fs8.existsSync(dir)) {
10012
- fs8.mkdirSync(dir, { recursive: true });
10008
+ const fs9 = require("fs");
10009
+ const path27 = require("path");
10010
+ const dir = path27.dirname(outputPath);
10011
+ if (!fs9.existsSync(dir)) {
10012
+ fs9.mkdirSync(dir, { recursive: true });
10013
10013
  }
10014
- fs8.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
10014
+ fs9.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
10015
10015
  }
10016
10016
  };
10017
10017
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -12271,8 +12271,8 @@ function toViteModuleId(filePath, root) {
12271
12271
  __name(toViteModuleId, "toViteModuleId");
12272
12272
  async function fileExists(filePath) {
12273
12273
  try {
12274
- const fs8 = await import("fs/promises");
12275
- await fs8.access(filePath);
12274
+ const fs9 = await import("fs/promises");
12275
+ await fs9.access(filePath);
12276
12276
  return true;
12277
12277
  } catch {
12278
12278
  return false;
@@ -13541,7 +13541,7 @@ function normalizePositiveDuration(value, fallback, name) {
13541
13541
  }
13542
13542
  __name(normalizePositiveDuration, "normalizePositiveDuration");
13543
13543
  function delay(ms) {
13544
- return new Promise((resolve6) => setTimeout(resolve6, ms));
13544
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
13545
13545
  }
13546
13546
  __name(delay, "delay");
13547
13547
  function normalizeCacheOptionsTags(options) {
@@ -13677,25 +13677,25 @@ function defineRoutes(input) {
13677
13677
  }
13678
13678
  __name(defineRoutes, "defineRoutes");
13679
13679
  var routesBuilder = {
13680
- page(path26, options) {
13680
+ page(path27, options) {
13681
13681
  return normalizeProgrammaticRoute({
13682
13682
  kind: "page",
13683
- path: path26,
13683
+ path: path27,
13684
13684
  ...options
13685
13685
  });
13686
13686
  },
13687
- layout(path26, options) {
13687
+ layout(path27, options) {
13688
13688
  return normalizeProgrammaticRoute({
13689
13689
  kind: "layout",
13690
- path: path26,
13690
+ path: path27,
13691
13691
  ...options
13692
13692
  });
13693
13693
  },
13694
- api(path26, options) {
13694
+ api(path27, options) {
13695
13695
  const { render, runtime, regions, maxDuration, ...methods } = options;
13696
13696
  return normalizeProgrammaticRoute({
13697
13697
  kind: "api",
13698
- path: path26,
13698
+ path: path27,
13699
13699
  render,
13700
13700
  runtime,
13701
13701
  regions,
@@ -13731,7 +13731,7 @@ function getProgrammaticRouteSearchClientOptions(search) {
13731
13731
  return Object.keys(options).length > 0 ? options : void 0;
13732
13732
  }
13733
13733
  __name(getProgrammaticRouteSearchClientOptions, "getProgrammaticRouteSearchClientOptions");
13734
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path26, routePath) {
13734
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path27, routePath) {
13735
13735
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
13736
13736
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
13737
13737
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -13740,7 +13740,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path26, routePa
13740
13740
  schema,
13741
13741
  rawSearch,
13742
13742
  parsedSearch: search,
13743
- path: path26
13743
+ path: path27
13744
13744
  });
13745
13745
  return { search, canonicalPath };
13746
13746
  }
@@ -13923,7 +13923,7 @@ function createRouteModuleFromProgrammaticPage(route) {
13923
13923
  mod.__farmRouteData = route.data;
13924
13924
  mod.__farmRouteParsesProps = true;
13925
13925
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
13926
- mod.__farmResolveRouteCanonicalPath = (rawSearch, path26) => resolveProgrammaticRouteSearch(route.search, rawSearch, path26, route.path).canonicalPath;
13926
+ mod.__farmResolveRouteCanonicalPath = (rawSearch, path27) => resolveProgrammaticRouteSearch(route.search, rawSearch, path27, route.path).canonicalPath;
13927
13927
  }
13928
13928
  if (route.pending || route.error || route.notFound) {
13929
13929
  mod.__farmRouteComponents = {
@@ -14677,6 +14677,37 @@ function stripUseClientDirective(content) {
14677
14677
  return content.replace(/^\s*(["'])use client\1\s*;?\s*/, "");
14678
14678
  }
14679
14679
  __name(stripUseClientDirective, "stripUseClientDirective");
14680
+ function hasAsyncDefaultExport(content) {
14681
+ if (!content) return false;
14682
+ const tokens = tokenizeModuleSource(content);
14683
+ for (let index = 0; index < tokens.length - 2; index++) {
14684
+ const token = tokens[index];
14685
+ if (token.kind !== "identifier" || token.value !== "export") continue;
14686
+ if (tokens[index - 1]?.value === ".") continue;
14687
+ if (tokens[index + 1]?.value !== "default") continue;
14688
+ const exported = tokens[index + 2];
14689
+ if (exported.kind === "identifier" && exported.value === "async") {
14690
+ return true;
14691
+ }
14692
+ if (exported.kind === "identifier" && !["function", "class"].includes(exported.value) && tokens[index + 3]?.value !== "(" && isAsyncLocalDeclaration(tokens, exported.value)) {
14693
+ return true;
14694
+ }
14695
+ }
14696
+ return false;
14697
+ }
14698
+ __name(hasAsyncDefaultExport, "hasAsyncDefaultExport");
14699
+ function isAsyncLocalDeclaration(tokens, name) {
14700
+ for (let index = 0; index < tokens.length - 2; index++) {
14701
+ if (tokens[index].value === "async" && tokens[index + 1]?.value === "function" && tokens[index + 2]?.value === name) {
14702
+ return true;
14703
+ }
14704
+ if (tokens[index].value === name && tokens[index + 1]?.value === "=" && tokens[index + 2]?.value === "async") {
14705
+ return true;
14706
+ }
14707
+ }
14708
+ return false;
14709
+ }
14710
+ __name(isAsyncLocalDeclaration, "isAsyncLocalDeclaration");
14680
14711
  function parseClientModuleMetadata(content, inspectIslandExport) {
14681
14712
  if (!content) {
14682
14713
  return {
@@ -14732,6 +14763,14 @@ function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandE
14732
14763
  }
14733
14764
  }
14734
14765
  const shouldHydrate = parsed.hasHydrateExport || importsClientBoundary;
14766
+ if (shouldHydrate && hasAsyncDefaultExport(content)) {
14767
+ return {
14768
+ isClientComponent: false,
14769
+ shouldHydrate: false,
14770
+ islandStrategy: null,
14771
+ suppressedAsyncHydration: true
14772
+ };
14773
+ }
14735
14774
  return {
14736
14775
  isClientComponent: false,
14737
14776
  shouldHydrate,
@@ -15447,6 +15486,7 @@ var _RouteManager = class _RouteManager {
15447
15486
  shouldHydrate: metadata.shouldHydrate,
15448
15487
  isClientComponent: metadata.isClientComponent,
15449
15488
  islandStrategy: metadata.islandStrategy,
15489
+ suppressedAsyncHydration: metadata.suppressedAsyncHydration,
15450
15490
  search: getProgrammaticRouteSearchClientOptions(programmaticPage?.search),
15451
15491
  segments: entry.route.segments.map((seg) => ({
15452
15492
  segment: seg.segment,
@@ -18690,6 +18730,15 @@ _setFarmThemeServerSnapshotResolver(() => {
18690
18730
  // src/server/renderer.ts
18691
18731
  var cachedClerkProvider = null;
18692
18732
  var importRuntimeModule = new Function("specifier", "return import(specifier);");
18733
+ var warnedSuppressedAsyncHydrationModules = /* @__PURE__ */ new Set();
18734
+ function warnSuppressedAsyncHydrationOnce(modulePath) {
18735
+ if (warnedSuppressedAsyncHydrationModules.has(modulePath)) return;
18736
+ warnedSuppressedAsyncHydrationModules.add(modulePath);
18737
+ logger.warn(
18738
+ `${modulePath} is an async server component that imports client components. React cannot hydrate async components in the browser, so this route stays server-rendered and its client imports are not interactive. Move the interactive UI into a "use client" child rendered by a synchronous page, or enable experimental server components support.`
18739
+ );
18740
+ }
18741
+ __name(warnSuppressedAsyncHydrationOnce, "warnSuppressedAsyncHydrationOnce");
18693
18742
  function hasRequestHeader(req, name) {
18694
18743
  const value = req.headers[name.toLowerCase()];
18695
18744
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
@@ -19364,6 +19413,9 @@ var _ServerRenderer = class _ServerRenderer {
19364
19413
  })
19365
19414
  );
19366
19415
  const shouldHydrate = moduleMetadata.shouldHydrate;
19416
+ if (moduleMetadata.suppressedAsyncHydration) {
19417
+ warnSuppressedAsyncHydrationOnce(route.modulePath);
19418
+ }
19367
19419
  const layoutHydrationMetadata = layouts.map((layout2) => {
19368
19420
  const manifestEntry = routeManifest.layouts.find(
19369
19421
  (entry) => entry.pattern === layout2.pattern
@@ -19861,7 +19913,7 @@ var _ServerRenderer = class _ServerRenderer {
19861
19913
  }
19862
19914
  }
19863
19915
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
19864
- return new Promise((resolve6, reject) => {
19916
+ return new Promise((resolve7, reject) => {
19865
19917
  const streamStartTime = Date.now();
19866
19918
  const observabilityRoute = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
19867
19919
  const deploymentId = this.getDeploymentId();
@@ -20061,7 +20113,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20061
20113
  route: observabilityRoute,
20062
20114
  durationMs: Date.now() - streamStartTime
20063
20115
  });
20064
- resolve6();
20116
+ resolve7();
20065
20117
  }
20066
20118
  });
20067
20119
  res.write(shell);
@@ -22583,8 +22635,8 @@ init_app_markdown();
22583
22635
  init_response();
22584
22636
  init_integrations();
22585
22637
  init_devtools_config();
22586
- var fs7 = __toESM(require("fs"));
22587
- var path25 = __toESM(require("path"));
22638
+ var fs8 = __toESM(require("fs"));
22639
+ var path26 = __toESM(require("path"));
22588
22640
  init_layers();
22589
22641
 
22590
22642
  // src/after.ts
@@ -22616,8 +22668,8 @@ __name(reportAfterError, "reportAfterError");
22616
22668
  function createAfterRequestState(reportError = defaultAfterErrorReporter) {
22617
22669
  let resolveResponseFinished;
22618
22670
  let responseFinished = false;
22619
- const responseFinishedPromise = new Promise((resolve6) => {
22620
- resolveResponseFinished = resolve6;
22671
+ const responseFinishedPromise = new Promise((resolve7) => {
22672
+ resolveResponseFinished = resolve7;
22621
22673
  });
22622
22674
  const state = {
22623
22675
  completion: Promise.resolve(),
@@ -22688,6 +22740,34 @@ function _withAfterNodeMiddleware(handler) {
22688
22740
  }
22689
22741
  __name(_withAfterNodeMiddleware, "_withAfterNodeMiddleware");
22690
22742
 
22743
+ // src/dev-static.ts
22744
+ var fs7 = __toESM(require("fs"));
22745
+ var path17 = __toESM(require("path"));
22746
+ function devServableFileExists(pathname, baseDirs) {
22747
+ let decodedPathname;
22748
+ try {
22749
+ decodedPathname = decodeURIComponent(pathname);
22750
+ } catch {
22751
+ return false;
22752
+ }
22753
+ const relativePathname = decodedPathname.replace(/^\/+/, "");
22754
+ if (!relativePathname) return false;
22755
+ for (const baseDir of baseDirs) {
22756
+ if (typeof baseDir !== "string" || baseDir.length === 0) continue;
22757
+ const resolvedBase = path17.resolve(baseDir);
22758
+ const candidate = path17.resolve(resolvedBase, relativePathname);
22759
+ if (!candidate.startsWith(resolvedBase + path17.sep)) continue;
22760
+ try {
22761
+ if (fs7.existsSync(candidate) && fs7.statSync(candidate).isFile()) {
22762
+ return true;
22763
+ }
22764
+ } catch {
22765
+ }
22766
+ }
22767
+ return false;
22768
+ }
22769
+ __name(devServableFileExists, "devServableFileExists");
22770
+
22691
22771
  // src/vite.ts
22692
22772
  init_deployment();
22693
22773
  init_image_config();
@@ -22983,11 +23063,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
22983
23063
  }
22984
23064
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
22985
23065
  function fileContainsProgrammaticPageRoute(file) {
22986
- if (!fs7.existsSync(file)) {
23066
+ if (!fs8.existsSync(file)) {
22987
23067
  return false;
22988
23068
  }
22989
23069
  try {
22990
- return scanProgrammaticPagePaths(fs7.readFileSync(file, "utf8")).length > 0;
23070
+ return scanProgrammaticPagePaths(fs8.readFileSync(file, "utf8")).length > 0;
22991
23071
  } catch {
22992
23072
  return false;
22993
23073
  }
@@ -22995,7 +23075,7 @@ function fileContainsProgrammaticPageRoute(file) {
22995
23075
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
22996
23076
  function rewriteEarlySsrRelativeImports(options) {
22997
23077
  const cleanId = options.id.split("?", 1)[0];
22998
- if (!path25.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
23078
+ if (!path26.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
22999
23079
  return null;
23000
23080
  }
23001
23081
  const replacements = [];
@@ -23015,7 +23095,7 @@ function rewriteEarlySsrRelativeImports(options) {
23015
23095
  const suffixIndex = source.value.search(/[?#]/);
23016
23096
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
23017
23097
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
23018
- const resolvedPath = path25.resolve(path25.dirname(cleanId), sourcePath);
23098
+ const resolvedPath = path26.resolve(path26.dirname(cleanId), sourcePath);
23019
23099
  replacements.push({
23020
23100
  start: source.start,
23021
23101
  end: source.end,
@@ -23094,7 +23174,7 @@ function farmPlugin(options = {}, initialPluginManager) {
23094
23174
  ...layerRoots.length ? {
23095
23175
  server: {
23096
23176
  fs: {
23097
- allow: [path25.resolve(options.root || process.cwd()), ...layerRoots]
23177
+ allow: [path26.resolve(options.root || process.cwd()), ...layerRoots]
23098
23178
  }
23099
23179
  }
23100
23180
  } : {}
@@ -23125,13 +23205,13 @@ function farmPlugin(options = {}, initialPluginManager) {
23125
23205
  },
23126
23206
  server
23127
23207
  );
23128
- const globalsCSSPath = path25.join(server.config.root, "src/app/globals.css");
23129
- if (!fs7.existsSync(globalsCSSPath)) {
23130
- const appDir = path25.join(server.config.root, "src/app");
23131
- if (!fs7.existsSync(appDir)) {
23132
- fs7.mkdirSync(appDir, { recursive: true });
23208
+ const globalsCSSPath = path26.join(server.config.root, "src/app/globals.css");
23209
+ if (!fs8.existsSync(globalsCSSPath)) {
23210
+ const appDir = path26.join(server.config.root, "src/app");
23211
+ if (!fs8.existsSync(appDir)) {
23212
+ fs8.mkdirSync(appDir, { recursive: true });
23133
23213
  }
23134
- fs7.writeFileSync(globalsCSSPath, defaultGlobalCSS);
23214
+ fs8.writeFileSync(globalsCSSPath, defaultGlobalCSS);
23135
23215
  }
23136
23216
  await farmApp.initialize();
23137
23217
  const farmConfig = farmApp.getConfig();
@@ -23150,10 +23230,10 @@ function farmPlugin(options = {}, initialPluginManager) {
23150
23230
  });
23151
23231
  }
23152
23232
  const sourceRoots = getFarmSourceRoots(farmConfig);
23153
- server.watcher.add(sourceRoots.map((source) => path25.join(source.root, source.srcDir)));
23233
+ server.watcher.add(sourceRoots.map((source) => path26.join(source.root, source.srcDir)));
23154
23234
  if (farmConfig.i18n.enabled) {
23155
23235
  server.watcher.add(
23156
- farmConfig.i18n.messages.includes("{locale}") ? path25.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
23236
+ farmConfig.i18n.messages.includes("{locale}") ? path26.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
23157
23237
  );
23158
23238
  }
23159
23239
  const workflowConfig = farmConfig.workflows;
@@ -23163,7 +23243,7 @@ function farmPlugin(options = {}, initialPluginManager) {
23163
23243
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
23164
23244
  ], "getExtraRouteTypes");
23165
23245
  const appDirSlugs = sourceRoots.map(
23166
- (source) => path25.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
23246
+ (source) => path26.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
23167
23247
  );
23168
23248
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
23169
23249
  try {
@@ -23203,7 +23283,7 @@ function farmPlugin(options = {}, initialPluginManager) {
23203
23283
  }, "generateTypeArtifacts");
23204
23284
  await generateTypeArtifacts("startup");
23205
23285
  const srcDirSlugs = sourceRoots.map(
23206
- (source) => path25.join(source.root, source.srcDir).replace(/\\/g, "/")
23286
+ (source) => path26.join(source.root, source.srcDir).replace(/\\/g, "/")
23207
23287
  );
23208
23288
  const layerConfigFiles = new Set(
23209
23289
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -23321,7 +23401,7 @@ function farmPlugin(options = {}, initialPluginManager) {
23321
23401
  await apiRouteManager.discoverRoutes();
23322
23402
  let discoveredWorkflows = [];
23323
23403
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
23324
- (dir) => fs7.existsSync(path25.isAbsolute(dir) ? dir : path25.join(farmConfig.root, dir))
23404
+ (dir) => fs8.existsSync(path26.isAbsolute(dir) ? dir : path26.join(farmConfig.root, dir))
23325
23405
  );
23326
23406
  if (hasWorkflowDirectory) {
23327
23407
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -23555,12 +23635,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
23555
23635
  }
23556
23636
  }
23557
23637
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
23558
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
23638
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs8.existsSync(farmDocsFontPath)) {
23559
23639
  res.statusCode = 200;
23560
23640
  res.setHeader("Content-Type", "font/woff2");
23561
23641
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
23562
23642
  if (requestMethod === "HEAD") res.end();
23563
- else fs7.createReadStream(farmDocsFontPath).pipe(res);
23643
+ else fs8.createReadStream(farmDocsFontPath).pipe(res);
23564
23644
  return;
23565
23645
  }
23566
23646
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -23658,7 +23738,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
23658
23738
  return null;
23659
23739
  }
23660
23740
  return {
23661
- source: await fs7.promises.readFile(sourcePath, "utf8"),
23741
+ source: await fs8.promises.readFile(sourcePath, "utf8"),
23662
23742
  filePath: sourcePath
23663
23743
  };
23664
23744
  }, "resolveSource")
@@ -23993,9 +24073,17 @@ window.__FARM_MANIFEST__ = ${inlineValue({
23993
24073
  res.end(JSON.stringify({ error: "API route not found", pathname: pathname2 }));
23994
24074
  return;
23995
24075
  }
23996
- if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules") || requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
24076
+ if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules")) {
23997
24077
  return next();
23998
24078
  }
24079
+ if (requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
24080
+ const matchesAppRoute = Boolean(
24081
+ farmApp?.getRouteManager()?.matchRoute(requestPathname)?.route
24082
+ );
24083
+ if (!matchesAppRoute || devServableFileExists(requestPathname, [server.config.publicDir, server.config.root])) {
24084
+ return next();
24085
+ }
24086
+ }
23999
24087
  if (req.url?.startsWith("/__farm/page-data")) {
24000
24088
  const urlObj = new URL(req.url, `http://${req.headers.host || "localhost:3000"}`);
24001
24089
  const targetPath = urlObj.searchParams.get("path") || "/";
@@ -24701,8 +24789,8 @@ if (import.meta.hot) {
24701
24789
  }
24702
24790
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
24703
24791
  logger.info("Pre-rendering SSG pages...");
24704
- const outDir = path25.join(server?.config.root || process.cwd(), options.outDir || "dist");
24705
- const clientDir = path25.join(outDir, "client");
24792
+ const outDir = path26.join(server?.config.root || process.cwd(), options.outDir || "dist");
24793
+ const clientDir = path26.join(outDir, "client");
24706
24794
  for (const page2 of ssgPages) {
24707
24795
  try {
24708
24796
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -24754,9 +24842,9 @@ if (import.meta.hot) {
24754
24842
  <script type="module" src="/assets/client.js"></script>
24755
24843
  </body>
24756
24844
  </html>`;
24757
- const outputPath = page2.urlPath === "/" ? path25.join(clientDir, "index.html") : path25.join(clientDir, page2.urlPath + ".html");
24758
- fs7.mkdirSync(path25.dirname(outputPath), { recursive: true });
24759
- fs7.writeFileSync(outputPath, fullHtml);
24845
+ const outputPath = page2.urlPath === "/" ? path26.join(clientDir, "index.html") : path26.join(clientDir, page2.urlPath + ".html");
24846
+ fs8.mkdirSync(path26.dirname(outputPath), { recursive: true });
24847
+ fs8.writeFileSync(outputPath, fullHtml);
24760
24848
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
24761
24849
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
24762
24850
  });
@@ -24764,8 +24852,8 @@ if (import.meta.hot) {
24764
24852
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
24765
24853
  }
24766
24854
  }
24767
- const manifestPath = path25.join(outDir, "__ssg_manifest.json");
24768
- fs7.writeFileSync(
24855
+ const manifestPath = path26.join(outDir, "__ssg_manifest.json");
24856
+ fs8.writeFileSync(
24769
24857
  manifestPath,
24770
24858
  JSON.stringify(
24771
24859
  ssgPages.map((p) => ({
@@ -24800,9 +24888,9 @@ if (import.meta.hot) {
24800
24888
  }
24801
24889
  const currentFarmConfig = farmApp?.getConfig();
24802
24890
  const normalizedFile = file.replace(/\\/g, "/");
24803
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path25.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
24891
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path26.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
24804
24892
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
24805
- logUpdate("PAGE", `updated ${path25.basename(file)}`);
24893
+ logUpdate("PAGE", `updated ${path26.basename(file)}`);
24806
24894
  for (const mod of modules) {
24807
24895
  server2.moduleGraph.invalidateModule(mod);
24808
24896
  }
@@ -25988,6 +26076,19 @@ async function tryHydrateImportedPage(
25988
26076
  const PageComponent = pageModule?.default;
25989
26077
  if (!PageComponent) return false;
25990
26078
 
26079
+ if (
26080
+ typeof PageComponent === 'function' &&
26081
+ PageComponent.constructor &&
26082
+ PageComponent.constructor.name === 'AsyncFunction'
26083
+ ) {
26084
+ console.warn(
26085
+ '[Farm.js] Skipping hydration for ' + modulePath +
26086
+ ': async server components cannot run in the browser. ' +
26087
+ 'Server-rendered HTML is preserved; move interactive UI into a "use client" child of a synchronous page.'
26088
+ );
26089
+ return false;
26090
+ }
26091
+
25991
26092
  currentPageComponent = PageComponent;
25992
26093
  currentPageProps = await buildRouteComponentProps(
25993
26094
  pageModule,