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

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/server.cjs CHANGED
@@ -580,11 +580,11 @@ function resolveFarmServerHealthConfig(config) {
580
580
  return Object.freeze({ enabled: true, livenessPath, readinessPath });
581
581
  }
582
582
  function normalizeHealthPath(value, optionName) {
583
- const path27 = value.trim();
584
- if (!path27.startsWith("/") || path27.includes("?") || path27.includes("#") || path27.includes("*")) {
583
+ const path28 = value.trim();
584
+ if (!path28.startsWith("/") || path28.includes("?") || path28.includes("#") || path28.includes("*")) {
585
585
  throw new TypeError(`${optionName} must be an absolute pathname without a query or wildcard`);
586
586
  }
587
- return path27.length > 1 ? path27.replace(/\/+$/, "") || "/" : path27;
587
+ return path28.length > 1 ? path28.replace(/\/+$/, "") || "/" : path28;
588
588
  }
589
589
  function parseBodySizeLimit(value, optionName = "bodySizeLimit") {
590
590
  if (typeof value === "number") {
@@ -681,7 +681,7 @@ async function readNodeRequestBody(request, limit) {
681
681
  request.resume?.();
682
682
  throw error;
683
683
  }
684
- return await new Promise((resolve6, reject) => {
684
+ return await new Promise((resolve7, reject) => {
685
685
  const chunks = [];
686
686
  let total = 0;
687
687
  let settled = false;
@@ -710,7 +710,7 @@ async function readNodeRequestBody(request, limit) {
710
710
  if (settled) return;
711
711
  settled = true;
712
712
  cleanup();
713
- resolve6(Buffer.concat(chunks, total));
713
+ resolve7(Buffer.concat(chunks, total));
714
714
  }, "onEnd");
715
715
  const onError = /* @__PURE__ */ __name((error) => rejectOnce(error), "onError");
716
716
  request.on("data", onData);
@@ -939,22 +939,22 @@ async function prepareFarmWorkflowsForNitro(config) {
939
939
  }
940
940
  const root = config.root || process.cwd();
941
941
  const distDir = config.distDir || ".farm";
942
- const fs9 = await import("fs/promises");
943
- const path27 = await import("path");
944
- const generatedDir = path27.join(root, distDir, ".nitro", "farm-workflows");
945
- await fs9.mkdir(generatedDir, { recursive: true });
942
+ const fs10 = await import("fs/promises");
943
+ const path28 = await import("path");
944
+ const generatedDir = path28.join(root, distDir, ".nitro", "farm-workflows");
945
+ await fs10.mkdir(generatedDir, { recursive: true });
946
946
  const tasks = {};
947
947
  const scheduledTasks = createScheduledTasks(workflows);
948
948
  for (const workflow of workflows) {
949
- const wrapperPath = path27.join(generatedDir, `${safeFileName(workflow.id)}.mjs`);
950
- await fs9.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
949
+ const wrapperPath = path28.join(generatedDir, `${safeFileName(workflow.id)}.mjs`);
950
+ await fs10.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
951
951
  tasks[workflow.id] = {
952
952
  handler: wrapperPath,
953
953
  description: workflow.description || `Farm workflow ${workflow.id}`
954
954
  };
955
955
  }
956
- const handlerPath = path27.join(generatedDir, "http-handler.mjs");
957
- await fs9.writeFile(
956
+ const handlerPath = path28.join(generatedDir, "http-handler.mjs");
957
+ await fs10.writeFile(
958
958
  handlerPath,
959
959
  createNitroWorkflowHTTPHandler(
960
960
  workflowConfig,
@@ -963,8 +963,8 @@ async function prepareFarmWorkflowsForNitro(config) {
963
963
  ),
964
964
  "utf8"
965
965
  );
966
- const manifestPath = path27.join(generatedDir, "manifest.json");
967
- await fs9.writeFile(
966
+ const manifestPath = path28.join(generatedDir, "manifest.json");
967
+ await fs10.writeFile(
968
968
  manifestPath,
969
969
  JSON.stringify(
970
970
  {
@@ -1045,22 +1045,22 @@ function resolveWorkflowDefinition(module2) {
1045
1045
  return null;
1046
1046
  }
1047
1047
  async function findWorkflowFiles(root, dirs) {
1048
- const fs9 = await import("fs/promises");
1049
- const path27 = await import("path");
1048
+ const fs10 = await import("fs/promises");
1049
+ const path28 = await import("path");
1050
1050
  const files = [];
1051
1051
  for (const dir of dirs) {
1052
- const absoluteDir = path27.isAbsolute(dir) ? dir : path27.join(root, dir);
1052
+ const absoluteDir = path28.isAbsolute(dir) ? dir : path28.join(root, dir);
1053
1053
  if (!await pathExists(absoluteDir)) continue;
1054
1054
  await walkWorkflowDir(absoluteDir, files);
1055
1055
  }
1056
1056
  return files.sort();
1057
1057
  }
1058
1058
  async function walkWorkflowDir(dir, files) {
1059
- const fs9 = await import("fs/promises");
1060
- const path27 = await import("path");
1061
- const entries = await fs9.readdir(dir, { withFileTypes: true });
1059
+ const fs10 = await import("fs/promises");
1060
+ const path28 = await import("path");
1061
+ const entries = await fs10.readdir(dir, { withFileTypes: true });
1062
1062
  for (const entry of entries) {
1063
- const filePath = path27.join(dir, entry.name);
1063
+ const filePath = path28.join(dir, entry.name);
1064
1064
  if (entry.isDirectory()) {
1065
1065
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
1066
1066
  await walkWorkflowDir(filePath, files);
@@ -1072,20 +1072,20 @@ async function walkWorkflowDir(dir, files) {
1072
1072
  }
1073
1073
  }
1074
1074
  async function pathExists(filePath) {
1075
- const fs9 = await import("fs/promises");
1076
- return fs9.access(filePath).then(() => true).catch(() => false);
1075
+ const fs10 = await import("fs/promises");
1076
+ return fs10.access(filePath).then(() => true).catch(() => false);
1077
1077
  }
1078
1078
  function isWorkflowFile(fileName) {
1079
1079
  return /\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName);
1080
1080
  }
1081
1081
  async function loadWorkflowModule(filePath, root) {
1082
- const fs9 = await import("fs/promises");
1083
- const path27 = await import("path");
1082
+ const fs10 = await import("fs/promises");
1083
+ const path28 = await import("path");
1084
1084
  const { pathToFileURL: pathToFileURL5 } = await import("url");
1085
1085
  const { build } = await import("esbuild");
1086
- const outDir = path27.join(root, ".farm", ".workflow-loader");
1087
- await fs9.mkdir(outDir, { recursive: true });
1088
- const outfile = path27.join(
1086
+ const outDir = path28.join(root, ".farm", ".workflow-loader");
1087
+ await fs10.mkdir(outDir, { recursive: true });
1088
+ const outfile = path28.join(
1089
1089
  outDir,
1090
1090
  `workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
1091
1091
  );
@@ -1109,7 +1109,7 @@ async function loadWorkflowModule(filePath, root) {
1109
1109
  `${pathToFileURL5(outfile).href}?t=${Date.now()}`
1110
1110
  );
1111
1111
  } finally {
1112
- await fs9.unlink(outfile).catch(() => void 0);
1112
+ await fs10.unlink(outfile).catch(() => void 0);
1113
1113
  }
1114
1114
  }
1115
1115
  function workflowIdFromFile(root, filePath) {
@@ -1384,7 +1384,7 @@ function normalizeCronJob(name, job) {
1384
1384
  if (!job || typeof job !== "object" || Array.isArray(job)) {
1385
1385
  throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);
1386
1386
  }
1387
- const path27 = normalizeCronPath(name, job.path);
1387
+ const path28 = normalizeCronPath(name, job.path);
1388
1388
  const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
1389
1389
  const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name, value)))];
1390
1390
  if (schedule.length === 0) {
@@ -1393,7 +1393,7 @@ function normalizeCronJob(name, job) {
1393
1393
  return {
1394
1394
  name,
1395
1395
  schedule,
1396
- path: path27,
1396
+ path: path28,
1397
1397
  description: job.description?.trim() || void 0
1398
1398
  };
1399
1399
  }
@@ -1401,13 +1401,13 @@ function normalizeCronPath(name, value) {
1401
1401
  if (typeof value !== "string" || !value.trim().startsWith("/")) {
1402
1402
  throw new TypeError(`Farm cron ${JSON.stringify(name)} path must start with "/".`);
1403
1403
  }
1404
- const path27 = value.trim();
1405
- if (path27.startsWith("//") || path27.includes("?") || path27.includes("#")) {
1404
+ const path28 = value.trim();
1405
+ if (path28.startsWith("//") || path28.includes("?") || path28.includes("#")) {
1406
1406
  throw new TypeError(
1407
1407
  `Farm cron ${JSON.stringify(name)} path must be an application pathname without a host, query, or hash.`
1408
1408
  );
1409
1409
  }
1410
- return path27.length > 1 ? path27.replace(/\/+$/, "") : path27;
1410
+ return path28.length > 1 ? path28.replace(/\/+$/, "") : path28;
1411
1411
  }
1412
1412
  function normalizeCronExpression(name, value) {
1413
1413
  if (typeof value !== "string") {
@@ -2687,7 +2687,7 @@ var init_server_action_security = __esm({
2687
2687
 
2688
2688
  // src/image-config.ts
2689
2689
  function resolveFarmImageConfig(config) {
2690
- const path27 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
2690
+ const path28 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
2691
2691
  const deviceSizes = normalizeIntegerList(
2692
2692
  config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
2693
2693
  "images.deviceSizes"
@@ -2715,7 +2715,7 @@ function resolveFarmImageConfig(config) {
2715
2715
  );
2716
2716
  return Object.freeze({
2717
2717
  provider: config?.provider ?? "auto",
2718
- path: path27,
2718
+ path: path28,
2719
2719
  domains: Object.freeze([
2720
2720
  ...new Set(
2721
2721
  (config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
@@ -2754,11 +2754,11 @@ function getPublicFarmImageConfig(config) {
2754
2754
  };
2755
2755
  }
2756
2756
  function normalizeImagePath(value) {
2757
- const path27 = value.trim().replace(/\/+$/, "") || "/";
2758
- if (!path27.startsWith("/") || path27.includes("?") || path27.includes("#")) {
2757
+ const path28 = value.trim().replace(/\/+$/, "") || "/";
2758
+ if (!path28.startsWith("/") || path28.includes("?") || path28.includes("#")) {
2759
2759
  throw new TypeError("images.path must be an absolute pathname without a query or hash");
2760
2760
  }
2761
- return path27;
2761
+ return path28;
2762
2762
  }
2763
2763
  function normalizeIntegerList(values, name, max) {
2764
2764
  if (values.length === 0) {
@@ -3621,9 +3621,9 @@ function getFarmIntegrationPluginOwner(plugin) {
3621
3621
  const value = plugin[FARM_INTEGRATION_PLUGIN_OWNER];
3622
3622
  return value && typeof value === "object" ? value : void 0;
3623
3623
  }
3624
- function defineTypedIntegrationRoute(method, path27, input) {
3624
+ function defineTypedIntegrationRoute(method, path28, input) {
3625
3625
  return {
3626
- path: path27,
3626
+ path: path28,
3627
3627
  method,
3628
3628
  middleware: input.middleware,
3629
3629
  before: input.before,
@@ -3633,7 +3633,7 @@ function defineTypedIntegrationRoute(method, path27, input) {
3633
3633
  input: normalizeIntegrationRouteInputSchemas(input),
3634
3634
  handler: input.handler,
3635
3635
  __operation: defineIntegrationAPIOperation({
3636
- path: path27,
3636
+ path: path28,
3637
3637
  method,
3638
3638
  bodyFormat: input.bodyFormat,
3639
3639
  responseFormat: input.responseFormat,
@@ -3645,52 +3645,52 @@ function defineTypedIntegrationRoute(method, path27, input) {
3645
3645
  }
3646
3646
  function createIntegrationRouteFactory() {
3647
3647
  return {
3648
- get(path27, input) {
3648
+ get(path28, input) {
3649
3649
  return defineTypedIntegrationRoute(
3650
3650
  "GET",
3651
- path27,
3651
+ path28,
3652
3652
  input
3653
3653
  );
3654
3654
  },
3655
- post(path27, input) {
3655
+ post(path28, input) {
3656
3656
  return defineTypedIntegrationRoute(
3657
3657
  "POST",
3658
- path27,
3658
+ path28,
3659
3659
  {
3660
3660
  bodyFormat: "json",
3661
3661
  ...input
3662
3662
  }
3663
3663
  );
3664
3664
  },
3665
- put(path27, input) {
3665
+ put(path28, input) {
3666
3666
  return defineTypedIntegrationRoute(
3667
3667
  "PUT",
3668
- path27,
3668
+ path28,
3669
3669
  {
3670
3670
  bodyFormat: "json",
3671
3671
  ...input
3672
3672
  }
3673
3673
  );
3674
3674
  },
3675
- patch(path27, input) {
3676
- return defineTypedIntegrationRoute("PATCH", path27, {
3675
+ patch(path28, input) {
3676
+ return defineTypedIntegrationRoute("PATCH", path28, {
3677
3677
  bodyFormat: "json",
3678
3678
  ...input
3679
3679
  });
3680
3680
  },
3681
- delete(path27, input) {
3682
- return defineTypedIntegrationRoute("DELETE", path27, {
3681
+ delete(path28, input) {
3682
+ return defineTypedIntegrationRoute("DELETE", path28, {
3683
3683
  bodyFormat: "json",
3684
3684
  ...input
3685
3685
  });
3686
3686
  },
3687
- options(path27, input) {
3688
- return defineTypedIntegrationRoute("OPTIONS", path27, input);
3687
+ options(path28, input) {
3688
+ return defineTypedIntegrationRoute("OPTIONS", path28, input);
3689
3689
  },
3690
- head(path27, input) {
3690
+ head(path28, input) {
3691
3691
  return defineTypedIntegrationRoute(
3692
3692
  "HEAD",
3693
- path27,
3693
+ path28,
3694
3694
  input
3695
3695
  );
3696
3696
  }
@@ -3964,8 +3964,8 @@ async function parseIntegrationConfigSchema(integration, schema, value) {
3964
3964
  function createIntegrationConfigValidationError(integration, error) {
3965
3965
  const issues = Array.isArray(error.issues) && error.issues.length > 0 ? error.issues.map((issue) => {
3966
3966
  const normalizedPath = normalizeIntegrationValidationPath(issue.path);
3967
- const path27 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
3968
- return `${path27}${issue.message || "Invalid config"}`;
3967
+ const path28 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
3968
+ return `${path28}${issue.message || "Invalid config"}`;
3969
3969
  }).join("; ") : error.message || "Invalid config";
3970
3970
  return new Error(`Integration "${integration.type}" config validation failed: ${issues}`);
3971
3971
  }
@@ -4662,8 +4662,8 @@ function normalizeIntegrationValidationIssues(source, error) {
4662
4662
  }
4663
4663
  ];
4664
4664
  }
4665
- function normalizeIntegrationValidationPath(path27) {
4666
- return (path27 || []).map((segment) => {
4665
+ function normalizeIntegrationValidationPath(path28) {
4666
+ return (path28 || []).map((segment) => {
4667
4667
  const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
4668
4668
  return typeof key === "symbol" ? key.description || key.toString() : key;
4669
4669
  });
@@ -5461,8 +5461,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
5461
5461
  }
5462
5462
  );
5463
5463
  }
5464
- function createFarmDeploymentCookie(deploymentId, path27 = "/", secure = false) {
5465
- const normalizedPath = path27.startsWith("/") ? path27 : `/${path27}`;
5464
+ function createFarmDeploymentCookie(deploymentId, path28 = "/", secure = false) {
5465
+ const normalizedPath = path28.startsWith("/") ? path28 : `/${path28}`;
5466
5466
  return [
5467
5467
  `${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
5468
5468
  `Path=${normalizedPath}`,
@@ -6075,11 +6075,11 @@ var init_type_generator = __esm({
6075
6075
  routeGroups.get(key).push(route);
6076
6076
  }
6077
6077
  const nestedStructure = {};
6078
- for (const [path27, routeList] of routeGroups) {
6078
+ for (const [path28, routeList] of routeGroups) {
6079
6079
  const route = routeList[0];
6080
6080
  const importPath = this.getRouteImportPath(route, options.outFile);
6081
6081
  const routeName = this.pathToRouteName(route.path);
6082
- const cleanPath = path27 === "/api" ? "" : path27.replace(/^\/api\//, "");
6082
+ const cleanPath = path28 === "/api" ? "" : path28.replace(/^\/api\//, "");
6083
6083
  const parts = cleanPath ? cleanPath.split("/") : [];
6084
6084
  const allMethods = routeList.flatMap((r) => r.methods);
6085
6085
  for (const method of allMethods) {
@@ -6138,8 +6138,8 @@ ${typeExports}
6138
6138
  const relativeImport = (0, import_path7.relative)((0, import_path7.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
6139
6139
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
6140
6140
  }
6141
- pathToRouteName(path27) {
6142
- return (path27 === "/api" ? "root" : path27.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "");
6141
+ pathToRouteName(path28) {
6142
+ return (path28 === "/api" ? "root" : path28.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "");
6143
6143
  }
6144
6144
  structureToTypeString(obj, indent) {
6145
6145
  const spaces = " ".repeat(indent);
@@ -6159,15 +6159,15 @@ ${typeExports}
6159
6159
  toTypePropertyKey(key) {
6160
6160
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
6161
6161
  }
6162
- getBaseExportName(path27) {
6163
- const cleanPath = path27.replace(/^\/api\//, "");
6162
+ getBaseExportName(path28) {
6163
+ const cleanPath = path28.replace(/^\/api\//, "");
6164
6164
  if (cleanPath === "") {
6165
6165
  return "api";
6166
6166
  }
6167
6167
  return cleanPath;
6168
6168
  }
6169
- getExportName(path27, method) {
6170
- const cleanPath = path27.replace(/^\/api\//, "");
6169
+ getExportName(path28, method) {
6170
+ const cleanPath = path28.replace(/^\/api\//, "");
6171
6171
  if (cleanPath === "") {
6172
6172
  return method.toLowerCase();
6173
6173
  }
@@ -10573,37 +10573,37 @@ function sanitizeDocsConfig(config) {
10573
10573
  return cloneSerializable(config) || {};
10574
10574
  }
10575
10575
  async function findDocsConfigPath(rootDir, configPath) {
10576
- const { existsSync: existsSync16 } = await import("fs");
10576
+ const { existsSync: existsSync17 } = await import("fs");
10577
10577
  const root = import_path9.default.resolve(rootDir || process.cwd());
10578
10578
  if (configPath) {
10579
10579
  const resolvedPath = import_path9.default.isAbsolute(configPath) ? configPath : import_path9.default.join(root, configPath);
10580
- if (!existsSync16(resolvedPath)) {
10580
+ if (!existsSync17(resolvedPath)) {
10581
10581
  throw new Error(`Could not find docs config at ${configPath}.`);
10582
10582
  }
10583
10583
  return import_path9.default.resolve(resolvedPath);
10584
10584
  }
10585
10585
  for (const filename of DOCS_CONFIG_FILENAMES) {
10586
10586
  const resolvedPath = import_path9.default.join(root, filename);
10587
- if (existsSync16(resolvedPath)) {
10587
+ if (existsSync17(resolvedPath)) {
10588
10588
  return resolvedPath;
10589
10589
  }
10590
10590
  }
10591
10591
  return void 0;
10592
10592
  }
10593
10593
  async function loadDocsConfig(rootDir, configPath) {
10594
- const fs9 = await import("fs/promises");
10594
+ const fs10 = await import("fs/promises");
10595
10595
  const { pathToFileURL: pathToFileURL5 } = await import("url");
10596
10596
  const root = import_path9.default.resolve(rootDir || process.cwd());
10597
10597
  const resolvedPath = await findDocsConfigPath(root, configPath);
10598
10598
  if (!resolvedPath) return void 0;
10599
10599
  try {
10600
10600
  if (resolvedPath.endsWith(".json")) {
10601
- const content = await fs9.readFile(resolvedPath, "utf8");
10601
+ const content = await fs10.readFile(resolvedPath, "utf8");
10602
10602
  return { config: JSON.parse(content), configPath: resolvedPath };
10603
10603
  }
10604
10604
  const { build } = await import("esbuild");
10605
10605
  const configCacheDir = import_path9.default.join(root, ".farm", ".config-loader");
10606
- await fs9.mkdir(configCacheDir, { recursive: true });
10606
+ await fs10.mkdir(configCacheDir, { recursive: true });
10607
10607
  const modulePath = import_path9.default.join(
10608
10608
  configCacheDir,
10609
10609
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -10629,7 +10629,7 @@ async function loadDocsConfig(rootDir, configPath) {
10629
10629
  moduleUrl
10630
10630
  );
10631
10631
  } finally {
10632
- await fs9.unlink(modulePath).catch(() => void 0);
10632
+ await fs10.unlink(modulePath).catch(() => void 0);
10633
10633
  }
10634
10634
  return {
10635
10635
  config: importedConfig.default || importedConfig,
@@ -10820,7 +10820,7 @@ async function resolveConfig(userConfig, mode) {
10820
10820
  return resolved;
10821
10821
  }
10822
10822
  async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "production" ? "production" : "development", loadEnvironment) {
10823
- const { existsSync: existsSync16 } = await import("fs");
10823
+ const { existsSync: existsSync17 } = await import("fs");
10824
10824
  const loadEnv = loadEnvironment || (await import("vite")).loadEnv;
10825
10825
  const root = rootDir || process.cwd();
10826
10826
  const loadedEnv = loadEnv(mode, root, "");
@@ -10844,7 +10844,7 @@ async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "
10844
10844
  try {
10845
10845
  const absolutePath = relativePath2.startsWith("/") ? relativePath2 : import_path9.default.join(root, relativePath2);
10846
10846
  const normalizedPath = import_path9.default.resolve(absolutePath);
10847
- if (!existsSync16(normalizedPath)) {
10847
+ if (!existsSync17(normalizedPath)) {
10848
10848
  continue;
10849
10849
  }
10850
10850
  const loadedConfig = await loadFarmConfigFile(normalizedPath, { root });
@@ -11675,8 +11675,8 @@ var init_generator = __esm({
11675
11675
  }
11676
11676
  routeGroups.get(key).push(route);
11677
11677
  }
11678
- for (const [path27, routeList] of routeGroups) {
11679
- const openAPIPath = this.convertToOpenAPIPath(path27);
11678
+ for (const [path28, routeList] of routeGroups) {
11679
+ const openAPIPath = this.convertToOpenAPIPath(path28);
11680
11680
  spec.paths[openAPIPath] = {};
11681
11681
  for (const route of routeList) {
11682
11682
  for (const method of route.methods) {
@@ -11690,8 +11690,8 @@ var init_generator = __esm({
11690
11690
  /**
11691
11691
  * Convert Farm.js API path to OpenAPI path format
11692
11692
  */
11693
- convertToOpenAPIPath(path27) {
11694
- return path27.replace(/^\/api/, "");
11693
+ convertToOpenAPIPath(path28) {
11694
+ return path28.replace(/^\/api/, "");
11695
11695
  }
11696
11696
  /**
11697
11697
  * Extract request body schema from endpoint
@@ -11853,8 +11853,8 @@ var init_generator = __esm({
11853
11853
  /**
11854
11854
  * Generate operation summary
11855
11855
  */
11856
- generateSummary(path27, method) {
11857
- const cleanPath = path27.replace(/^\/api\//, "");
11856
+ generateSummary(path28, method) {
11857
+ const cleanPath = path28.replace(/^\/api\//, "");
11858
11858
  const pathParts = cleanPath.split("/");
11859
11859
  const lastPart = pathParts[pathParts.length - 1];
11860
11860
  const action = method === "GET" ? "Get" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -11863,22 +11863,22 @@ var init_generator = __esm({
11863
11863
  /**
11864
11864
  * Generate operation description
11865
11865
  */
11866
- generateDescription(path27, method) {
11867
- const cleanPath = path27.replace(/^\/api\//, "");
11866
+ generateDescription(path28, method) {
11867
+ const cleanPath = path28.replace(/^\/api\//, "");
11868
11868
  return `${method} ${cleanPath} endpoint`;
11869
11869
  }
11870
11870
  /**
11871
11871
  * Generate operation ID
11872
11872
  */
11873
- generateOperationId(path27, method) {
11874
- const cleanPath = path27.replace(/^\/api\//, "").replace(/\//g, "_");
11873
+ generateOperationId(path28, method) {
11874
+ const cleanPath = path28.replace(/^\/api\//, "").replace(/\//g, "_");
11875
11875
  return `${method.toLowerCase()}_${cleanPath}`;
11876
11876
  }
11877
11877
  /**
11878
11878
  * Generate tags for grouping operations
11879
11879
  */
11880
- generateTags(path27) {
11881
- const cleanPath = path27.replace(/^\/api\//, "");
11880
+ generateTags(path28) {
11881
+ const cleanPath = path28.replace(/^\/api\//, "");
11882
11882
  const pathParts = cleanPath.split("/");
11883
11883
  if (pathParts.length > 1) {
11884
11884
  return [pathParts[0]];
@@ -11890,13 +11890,13 @@ var init_generator = __esm({
11890
11890
  */
11891
11891
  async generateSpecFile(routes, outputPath) {
11892
11892
  const spec = await this.generateSpec(routes);
11893
- const fs9 = require("fs");
11894
- const path27 = require("path");
11895
- const dir = path27.dirname(outputPath);
11896
- if (!fs9.existsSync(dir)) {
11897
- fs9.mkdirSync(dir, { recursive: true });
11893
+ const fs10 = require("fs");
11894
+ const path28 = require("path");
11895
+ const dir = path28.dirname(outputPath);
11896
+ if (!fs10.existsSync(dir)) {
11897
+ fs10.mkdirSync(dir, { recursive: true });
11898
11898
  }
11899
- fs9.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
11899
+ fs10.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
11900
11900
  }
11901
11901
  };
11902
11902
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -14251,8 +14251,8 @@ function toViteModuleId(filePath, root) {
14251
14251
  __name(toViteModuleId, "toViteModuleId");
14252
14252
  async function fileExists(filePath) {
14253
14253
  try {
14254
- const fs9 = await import("fs/promises");
14255
- await fs9.access(filePath);
14254
+ const fs10 = await import("fs/promises");
14255
+ await fs10.access(filePath);
14256
14256
  return true;
14257
14257
  } catch {
14258
14258
  return false;
@@ -15675,7 +15675,7 @@ function normalizePositiveDuration(value, fallback, name) {
15675
15675
  }
15676
15676
  __name(normalizePositiveDuration, "normalizePositiveDuration");
15677
15677
  function delay(ms) {
15678
- return new Promise((resolve6) => setTimeout(resolve6, ms));
15678
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
15679
15679
  }
15680
15680
  __name(delay, "delay");
15681
15681
  function normalizeCacheOptionsTags(options) {
@@ -15826,25 +15826,25 @@ function defineRoutes(input) {
15826
15826
  }
15827
15827
  __name(defineRoutes, "defineRoutes");
15828
15828
  var routesBuilder = {
15829
- page(path27, options) {
15829
+ page(path28, options) {
15830
15830
  return normalizeProgrammaticRoute({
15831
15831
  kind: "page",
15832
- path: path27,
15832
+ path: path28,
15833
15833
  ...options
15834
15834
  });
15835
15835
  },
15836
- layout(path27, options) {
15836
+ layout(path28, options) {
15837
15837
  return normalizeProgrammaticRoute({
15838
15838
  kind: "layout",
15839
- path: path27,
15839
+ path: path28,
15840
15840
  ...options
15841
15841
  });
15842
15842
  },
15843
- api(path27, options) {
15843
+ api(path28, options) {
15844
15844
  const { render, runtime, regions, maxDuration, ...methods } = options;
15845
15845
  return normalizeProgrammaticRoute({
15846
15846
  kind: "api",
15847
- path: path27,
15847
+ path: path28,
15848
15848
  render,
15849
15849
  runtime,
15850
15850
  regions,
@@ -15880,7 +15880,7 @@ function getProgrammaticRouteSearchClientOptions(search) {
15880
15880
  return Object.keys(options).length > 0 ? options : void 0;
15881
15881
  }
15882
15882
  __name(getProgrammaticRouteSearchClientOptions, "getProgrammaticRouteSearchClientOptions");
15883
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path27, routePath) {
15883
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path28, routePath) {
15884
15884
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
15885
15885
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
15886
15886
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -15889,7 +15889,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path27, routePa
15889
15889
  schema,
15890
15890
  rawSearch,
15891
15891
  parsedSearch: search,
15892
- path: path27
15892
+ path: path28
15893
15893
  });
15894
15894
  return { search, canonicalPath };
15895
15895
  }
@@ -16072,7 +16072,7 @@ function createRouteModuleFromProgrammaticPage(route) {
16072
16072
  mod.__farmRouteData = route.data;
16073
16073
  mod.__farmRouteParsesProps = true;
16074
16074
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
16075
- mod.__farmResolveRouteCanonicalPath = (rawSearch, path27) => resolveProgrammaticRouteSearch(route.search, rawSearch, path27, route.path).canonicalPath;
16075
+ mod.__farmResolveRouteCanonicalPath = (rawSearch, path28) => resolveProgrammaticRouteSearch(route.search, rawSearch, path28, route.path).canonicalPath;
16076
16076
  }
16077
16077
  if (route.pending || route.error || route.notFound) {
16078
16078
  mod.__farmRouteComponents = {
@@ -16826,6 +16826,37 @@ function stripUseClientDirective(content) {
16826
16826
  return content.replace(/^\s*(["'])use client\1\s*;?\s*/, "");
16827
16827
  }
16828
16828
  __name(stripUseClientDirective, "stripUseClientDirective");
16829
+ function hasAsyncDefaultExport(content) {
16830
+ if (!content) return false;
16831
+ const tokens = tokenizeModuleSource(content);
16832
+ for (let index = 0; index < tokens.length - 2; index++) {
16833
+ const token = tokens[index];
16834
+ if (token.kind !== "identifier" || token.value !== "export") continue;
16835
+ if (tokens[index - 1]?.value === ".") continue;
16836
+ if (tokens[index + 1]?.value !== "default") continue;
16837
+ const exported = tokens[index + 2];
16838
+ if (exported.kind === "identifier" && exported.value === "async") {
16839
+ return true;
16840
+ }
16841
+ if (exported.kind === "identifier" && !["function", "class"].includes(exported.value) && tokens[index + 3]?.value !== "(" && isAsyncLocalDeclaration(tokens, exported.value)) {
16842
+ return true;
16843
+ }
16844
+ }
16845
+ return false;
16846
+ }
16847
+ __name(hasAsyncDefaultExport, "hasAsyncDefaultExport");
16848
+ function isAsyncLocalDeclaration(tokens, name) {
16849
+ for (let index = 0; index < tokens.length - 2; index++) {
16850
+ if (tokens[index].value === "async" && tokens[index + 1]?.value === "function" && tokens[index + 2]?.value === name) {
16851
+ return true;
16852
+ }
16853
+ if (tokens[index].value === name && tokens[index + 1]?.value === "=" && tokens[index + 2]?.value === "async") {
16854
+ return true;
16855
+ }
16856
+ }
16857
+ return false;
16858
+ }
16859
+ __name(isAsyncLocalDeclaration, "isAsyncLocalDeclaration");
16829
16860
  function parseClientModuleMetadata(content, inspectIslandExport) {
16830
16861
  if (!content) {
16831
16862
  return {
@@ -16881,6 +16912,14 @@ function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandE
16881
16912
  }
16882
16913
  }
16883
16914
  const shouldHydrate = parsed.hasHydrateExport || importsClientBoundary;
16915
+ if (shouldHydrate && hasAsyncDefaultExport(content)) {
16916
+ return {
16917
+ isClientComponent: false,
16918
+ shouldHydrate: false,
16919
+ islandStrategy: null,
16920
+ suppressedAsyncHydration: true
16921
+ };
16922
+ }
16884
16923
  return {
16885
16924
  isClientComponent: false,
16886
16925
  shouldHydrate,
@@ -17596,6 +17635,7 @@ var _RouteManager = class _RouteManager {
17596
17635
  shouldHydrate: metadata.shouldHydrate,
17597
17636
  isClientComponent: metadata.isClientComponent,
17598
17637
  islandStrategy: metadata.islandStrategy,
17638
+ suppressedAsyncHydration: metadata.suppressedAsyncHydration,
17599
17639
  search: getProgrammaticRouteSearchClientOptions(programmaticPage?.search),
17600
17640
  segments: entry.route.segments.map((seg) => ({
17601
17641
  segment: seg.segment,
@@ -20843,6 +20883,15 @@ _setFarmThemeServerSnapshotResolver(() => {
20843
20883
  // src/server/renderer.ts
20844
20884
  var cachedClerkProvider = null;
20845
20885
  var importRuntimeModule = new Function("specifier", "return import(specifier);");
20886
+ var warnedSuppressedAsyncHydrationModules = /* @__PURE__ */ new Set();
20887
+ function warnSuppressedAsyncHydrationOnce(modulePath) {
20888
+ if (warnedSuppressedAsyncHydrationModules.has(modulePath)) return;
20889
+ warnedSuppressedAsyncHydrationModules.add(modulePath);
20890
+ logger.warn(
20891
+ `${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.`
20892
+ );
20893
+ }
20894
+ __name(warnSuppressedAsyncHydrationOnce, "warnSuppressedAsyncHydrationOnce");
20846
20895
  function hasRequestHeader(req, name) {
20847
20896
  const value = req.headers[name.toLowerCase()];
20848
20897
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
@@ -21517,6 +21566,9 @@ var _ServerRenderer = class _ServerRenderer {
21517
21566
  })
21518
21567
  );
21519
21568
  const shouldHydrate = moduleMetadata.shouldHydrate;
21569
+ if (moduleMetadata.suppressedAsyncHydration) {
21570
+ warnSuppressedAsyncHydrationOnce(route.modulePath);
21571
+ }
21520
21572
  const layoutHydrationMetadata = layouts.map((layout2) => {
21521
21573
  const manifestEntry = routeManifest.layouts.find(
21522
21574
  (entry) => entry.pattern === layout2.pattern
@@ -22014,7 +22066,7 @@ var _ServerRenderer = class _ServerRenderer {
22014
22066
  }
22015
22067
  }
22016
22068
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
22017
- return new Promise((resolve6, reject) => {
22069
+ return new Promise((resolve7, reject) => {
22018
22070
  const streamStartTime = Date.now();
22019
22071
  const observabilityRoute = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
22020
22072
  const deploymentId = this.getDeploymentId();
@@ -22214,7 +22266,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
22214
22266
  route: observabilityRoute,
22215
22267
  durationMs: Date.now() - streamStartTime
22216
22268
  });
22217
- resolve6();
22269
+ resolve7();
22218
22270
  }
22219
22271
  });
22220
22272
  res.write(shell);
@@ -24740,8 +24792,8 @@ init_app_markdown();
24740
24792
  init_response();
24741
24793
  init_integrations();
24742
24794
  init_devtools_config();
24743
- var fs7 = __toESM(require("fs"));
24744
- var path25 = __toESM(require("path"));
24795
+ var fs8 = __toESM(require("fs"));
24796
+ var path26 = __toESM(require("path"));
24745
24797
  init_layers();
24746
24798
 
24747
24799
  // src/environment-vite.ts
@@ -25088,7 +25140,7 @@ function transformError(id, message) {
25088
25140
  __name(transformError, "transformError");
25089
25141
 
25090
25142
  // package.json
25091
- var version = "0.1.0-beta.23";
25143
+ var version = "0.1.0-beta.24";
25092
25144
 
25093
25145
  // src/version.ts
25094
25146
  var FARM_VERSION = version;
@@ -25122,8 +25174,8 @@ __name(reportAfterError, "reportAfterError");
25122
25174
  function createAfterRequestState(reportError = defaultAfterErrorReporter) {
25123
25175
  let resolveResponseFinished;
25124
25176
  let responseFinished = false;
25125
- const responseFinishedPromise = new Promise((resolve6) => {
25126
- resolveResponseFinished = resolve6;
25177
+ const responseFinishedPromise = new Promise((resolve7) => {
25178
+ resolveResponseFinished = resolve7;
25127
25179
  });
25128
25180
  const state = {
25129
25181
  completion: Promise.resolve(),
@@ -25235,8 +25287,8 @@ function after(callback) {
25235
25287
  throw new Error("after() cannot schedule work after the request lifecycle has completed.");
25236
25288
  }
25237
25289
  let start;
25238
- const ready = new Promise((resolve6) => {
25239
- start = resolve6;
25290
+ const ready = new Promise((resolve7) => {
25291
+ start = resolve7;
25240
25292
  });
25241
25293
  const result = ready.then(callback);
25242
25294
  state.tasks.push({ result, start });
@@ -25285,6 +25337,34 @@ function _withAfterNodeMiddleware(handler) {
25285
25337
  }
25286
25338
  __name(_withAfterNodeMiddleware, "_withAfterNodeMiddleware");
25287
25339
 
25340
+ // src/dev-static.ts
25341
+ var fs7 = __toESM(require("fs"));
25342
+ var path17 = __toESM(require("path"));
25343
+ function devServableFileExists(pathname, baseDirs) {
25344
+ let decodedPathname;
25345
+ try {
25346
+ decodedPathname = decodeURIComponent(pathname);
25347
+ } catch {
25348
+ return false;
25349
+ }
25350
+ const relativePathname = decodedPathname.replace(/^\/+/, "");
25351
+ if (!relativePathname) return false;
25352
+ for (const baseDir of baseDirs) {
25353
+ if (typeof baseDir !== "string" || baseDir.length === 0) continue;
25354
+ const resolvedBase = path17.resolve(baseDir);
25355
+ const candidate = path17.resolve(resolvedBase, relativePathname);
25356
+ if (!candidate.startsWith(resolvedBase + path17.sep)) continue;
25357
+ try {
25358
+ if (fs7.existsSync(candidate) && fs7.statSync(candidate).isFile()) {
25359
+ return true;
25360
+ }
25361
+ } catch {
25362
+ }
25363
+ }
25364
+ return false;
25365
+ }
25366
+ __name(devServableFileExists, "devServableFileExists");
25367
+
25288
25368
  // src/vite.ts
25289
25369
  init_deployment();
25290
25370
  init_image_config();
@@ -25730,11 +25810,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
25730
25810
  }
25731
25811
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
25732
25812
  function fileContainsProgrammaticPageRoute(file) {
25733
- if (!fs7.existsSync(file)) {
25813
+ if (!fs8.existsSync(file)) {
25734
25814
  return false;
25735
25815
  }
25736
25816
  try {
25737
- return scanProgrammaticPagePaths(fs7.readFileSync(file, "utf8")).length > 0;
25817
+ return scanProgrammaticPagePaths(fs8.readFileSync(file, "utf8")).length > 0;
25738
25818
  } catch {
25739
25819
  return false;
25740
25820
  }
@@ -25742,7 +25822,7 @@ function fileContainsProgrammaticPageRoute(file) {
25742
25822
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
25743
25823
  function rewriteEarlySsrRelativeImports(options) {
25744
25824
  const cleanId = options.id.split("?", 1)[0];
25745
- if (!path25.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
25825
+ if (!path26.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
25746
25826
  return null;
25747
25827
  }
25748
25828
  const replacements = [];
@@ -25762,7 +25842,7 @@ function rewriteEarlySsrRelativeImports(options) {
25762
25842
  const suffixIndex = source.value.search(/[?#]/);
25763
25843
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
25764
25844
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
25765
- const resolvedPath = path25.resolve(path25.dirname(cleanId), sourcePath);
25845
+ const resolvedPath = path26.resolve(path26.dirname(cleanId), sourcePath);
25766
25846
  replacements.push({
25767
25847
  start: source.start,
25768
25848
  end: source.end,
@@ -25841,7 +25921,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25841
25921
  ...layerRoots.length ? {
25842
25922
  server: {
25843
25923
  fs: {
25844
- allow: [path25.resolve(options.root || process.cwd()), ...layerRoots]
25924
+ allow: [path26.resolve(options.root || process.cwd()), ...layerRoots]
25845
25925
  }
25846
25926
  }
25847
25927
  } : {}
@@ -25872,13 +25952,13 @@ function farmPlugin(options = {}, initialPluginManager) {
25872
25952
  },
25873
25953
  server
25874
25954
  );
25875
- const globalsCSSPath = path25.join(server.config.root, "src/app/globals.css");
25876
- if (!fs7.existsSync(globalsCSSPath)) {
25877
- const appDir = path25.join(server.config.root, "src/app");
25878
- if (!fs7.existsSync(appDir)) {
25879
- fs7.mkdirSync(appDir, { recursive: true });
25955
+ const globalsCSSPath = path26.join(server.config.root, "src/app/globals.css");
25956
+ if (!fs8.existsSync(globalsCSSPath)) {
25957
+ const appDir = path26.join(server.config.root, "src/app");
25958
+ if (!fs8.existsSync(appDir)) {
25959
+ fs8.mkdirSync(appDir, { recursive: true });
25880
25960
  }
25881
- fs7.writeFileSync(globalsCSSPath, defaultGlobalCSS);
25961
+ fs8.writeFileSync(globalsCSSPath, defaultGlobalCSS);
25882
25962
  }
25883
25963
  await farmApp.initialize();
25884
25964
  const farmConfig = farmApp.getConfig();
@@ -25897,10 +25977,10 @@ function farmPlugin(options = {}, initialPluginManager) {
25897
25977
  });
25898
25978
  }
25899
25979
  const sourceRoots = getFarmSourceRoots(farmConfig);
25900
- server.watcher.add(sourceRoots.map((source) => path25.join(source.root, source.srcDir)));
25980
+ server.watcher.add(sourceRoots.map((source) => path26.join(source.root, source.srcDir)));
25901
25981
  if (farmConfig.i18n.enabled) {
25902
25982
  server.watcher.add(
25903
- farmConfig.i18n.messages.includes("{locale}") ? path25.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
25983
+ farmConfig.i18n.messages.includes("{locale}") ? path26.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
25904
25984
  );
25905
25985
  }
25906
25986
  const workflowConfig = farmConfig.workflows;
@@ -25910,7 +25990,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25910
25990
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
25911
25991
  ], "getExtraRouteTypes");
25912
25992
  const appDirSlugs = sourceRoots.map(
25913
- (source) => path25.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
25993
+ (source) => path26.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
25914
25994
  );
25915
25995
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
25916
25996
  try {
@@ -25950,7 +26030,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25950
26030
  }, "generateTypeArtifacts");
25951
26031
  await generateTypeArtifacts("startup");
25952
26032
  const srcDirSlugs = sourceRoots.map(
25953
- (source) => path25.join(source.root, source.srcDir).replace(/\\/g, "/")
26033
+ (source) => path26.join(source.root, source.srcDir).replace(/\\/g, "/")
25954
26034
  );
25955
26035
  const layerConfigFiles = new Set(
25956
26036
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -26068,7 +26148,7 @@ function farmPlugin(options = {}, initialPluginManager) {
26068
26148
  await apiRouteManager.discoverRoutes();
26069
26149
  let discoveredWorkflows = [];
26070
26150
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
26071
- (dir) => fs7.existsSync(path25.isAbsolute(dir) ? dir : path25.join(farmConfig.root, dir))
26151
+ (dir) => fs8.existsSync(path26.isAbsolute(dir) ? dir : path26.join(farmConfig.root, dir))
26072
26152
  );
26073
26153
  if (hasWorkflowDirectory) {
26074
26154
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -26302,12 +26382,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
26302
26382
  }
26303
26383
  }
26304
26384
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
26305
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
26385
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs8.existsSync(farmDocsFontPath)) {
26306
26386
  res.statusCode = 200;
26307
26387
  res.setHeader("Content-Type", "font/woff2");
26308
26388
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
26309
26389
  if (requestMethod === "HEAD") res.end();
26310
- else fs7.createReadStream(farmDocsFontPath).pipe(res);
26390
+ else fs8.createReadStream(farmDocsFontPath).pipe(res);
26311
26391
  return;
26312
26392
  }
26313
26393
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -26405,7 +26485,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
26405
26485
  return null;
26406
26486
  }
26407
26487
  return {
26408
- source: await fs7.promises.readFile(sourcePath, "utf8"),
26488
+ source: await fs8.promises.readFile(sourcePath, "utf8"),
26409
26489
  filePath: sourcePath
26410
26490
  };
26411
26491
  }, "resolveSource")
@@ -26740,9 +26820,17 @@ window.__FARM_MANIFEST__ = ${inlineValue({
26740
26820
  res.end(JSON.stringify({ error: "API route not found", pathname: pathname2 }));
26741
26821
  return;
26742
26822
  }
26743
- if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules") || requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
26823
+ if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules")) {
26744
26824
  return next();
26745
26825
  }
26826
+ if (requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
26827
+ const matchesAppRoute = Boolean(
26828
+ farmApp?.getRouteManager()?.matchRoute(requestPathname)?.route
26829
+ );
26830
+ if (!matchesAppRoute || devServableFileExists(requestPathname, [server.config.publicDir, server.config.root])) {
26831
+ return next();
26832
+ }
26833
+ }
26746
26834
  if (req.url?.startsWith("/__farm/page-data")) {
26747
26835
  const urlObj = new URL(req.url, `http://${req.headers.host || "localhost:3000"}`);
26748
26836
  const targetPath = urlObj.searchParams.get("path") || "/";
@@ -27448,8 +27536,8 @@ if (import.meta.hot) {
27448
27536
  }
27449
27537
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
27450
27538
  logger.info("Pre-rendering SSG pages...");
27451
- const outDir = path25.join(server?.config.root || process.cwd(), options.outDir || "dist");
27452
- const clientDir = path25.join(outDir, "client");
27539
+ const outDir = path26.join(server?.config.root || process.cwd(), options.outDir || "dist");
27540
+ const clientDir = path26.join(outDir, "client");
27453
27541
  for (const page2 of ssgPages) {
27454
27542
  try {
27455
27543
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -27501,9 +27589,9 @@ if (import.meta.hot) {
27501
27589
  <script type="module" src="/assets/client.js"></script>
27502
27590
  </body>
27503
27591
  </html>`;
27504
- const outputPath = page2.urlPath === "/" ? path25.join(clientDir, "index.html") : path25.join(clientDir, page2.urlPath + ".html");
27505
- fs7.mkdirSync(path25.dirname(outputPath), { recursive: true });
27506
- fs7.writeFileSync(outputPath, fullHtml);
27592
+ const outputPath = page2.urlPath === "/" ? path26.join(clientDir, "index.html") : path26.join(clientDir, page2.urlPath + ".html");
27593
+ fs8.mkdirSync(path26.dirname(outputPath), { recursive: true });
27594
+ fs8.writeFileSync(outputPath, fullHtml);
27507
27595
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
27508
27596
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
27509
27597
  });
@@ -27511,8 +27599,8 @@ if (import.meta.hot) {
27511
27599
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
27512
27600
  }
27513
27601
  }
27514
- const manifestPath = path25.join(outDir, "__ssg_manifest.json");
27515
- fs7.writeFileSync(
27602
+ const manifestPath = path26.join(outDir, "__ssg_manifest.json");
27603
+ fs8.writeFileSync(
27516
27604
  manifestPath,
27517
27605
  JSON.stringify(
27518
27606
  ssgPages.map((p) => ({
@@ -27547,9 +27635,9 @@ if (import.meta.hot) {
27547
27635
  }
27548
27636
  const currentFarmConfig = farmApp?.getConfig();
27549
27637
  const normalizedFile = file.replace(/\\/g, "/");
27550
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path25.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
27638
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path26.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
27551
27639
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
27552
- logUpdate("PAGE", `updated ${path25.basename(file)}`);
27640
+ logUpdate("PAGE", `updated ${path26.basename(file)}`);
27553
27641
  for (const mod of modules) {
27554
27642
  server2.moduleGraph.invalidateModule(mod);
27555
27643
  }
@@ -28735,6 +28823,19 @@ async function tryHydrateImportedPage(
28735
28823
  const PageComponent = pageModule?.default;
28736
28824
  if (!PageComponent) return false;
28737
28825
 
28826
+ if (
28827
+ typeof PageComponent === 'function' &&
28828
+ PageComponent.constructor &&
28829
+ PageComponent.constructor.name === 'AsyncFunction'
28830
+ ) {
28831
+ console.warn(
28832
+ '[Farm.js] Skipping hydration for ' + modulePath +
28833
+ ': async server components cannot run in the browser. ' +
28834
+ 'Server-rendered HTML is preserved; move interactive UI into a "use client" child of a synchronous page.'
28835
+ );
28836
+ return false;
28837
+ }
28838
+
28738
28839
  currentPageComponent = PageComponent;
28739
28840
  currentPageProps = await buildRouteComponentProps(
28740
28841
  pageModule,
@@ -29288,7 +29389,7 @@ function generateClientManifest(bundle) {
29288
29389
  __name(generateClientManifest, "generateClientManifest");
29289
29390
  async function defineConfig2(config = {}) {
29290
29391
  const tailwindcss = (await import("@tailwindcss/vite")).default;
29291
- const appRoot = path25.resolve(config.root || process.cwd());
29392
+ const appRoot = path26.resolve(config.root || process.cwd());
29292
29393
  if (config.extends?.length) {
29293
29394
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
29294
29395
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {