@farm.js/core 0.1.0-beta.22 → 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.
Files changed (132) hide show
  1. package/dist/agent-runtime.d.mts +2 -1
  2. package/dist/agent-runtime.d.ts +2 -1
  3. package/dist/{app-DwsTpyNZ.d.mts → app-DrFCUMHY.d.mts} +6 -3
  4. package/dist/app-markdown.d.mts +2 -1
  5. package/dist/app-markdown.d.ts +2 -1
  6. package/dist/{app-BB8GCH1g.d.ts → app-pwvKG2B1.d.ts} +6 -3
  7. package/dist/chunk-4IVNW5QD.mjs +82 -0
  8. package/dist/chunk-4IVNW5QD.mjs.map +1 -0
  9. package/dist/chunk-D42BNPZH.mjs +79 -0
  10. package/dist/chunk-D42BNPZH.mjs.map +1 -0
  11. package/dist/{chunk-LLPN5SEZ.mjs → chunk-DVPRBMU2.mjs} +2 -2
  12. package/dist/chunk-GQVQESLY.mjs +25 -0
  13. package/dist/chunk-GQVQESLY.mjs.map +1 -0
  14. package/dist/chunk-H53KVQUU.mjs +48 -0
  15. package/dist/chunk-H53KVQUU.mjs.map +1 -0
  16. package/dist/chunk-HCGQYYHI.mjs +1 -0
  17. package/dist/chunk-HCGQYYHI.mjs.map +1 -0
  18. package/dist/{chunk-XBKXKJX5.mjs → chunk-HVJHNKSP.mjs} +220 -63
  19. package/dist/chunk-HVJHNKSP.mjs.map +1 -0
  20. package/dist/{chunk-ZP73P4VR.mjs → chunk-HXE4VGH2.mjs} +79 -20
  21. package/dist/chunk-HXE4VGH2.mjs.map +1 -0
  22. package/dist/{chunk-UCYWGN2P.mjs → chunk-OHNSROHS.mjs} +1 -1
  23. package/dist/{chunk-FRPWCMMG.mjs → chunk-SBWOTAX4.mjs} +63 -2
  24. package/dist/chunk-SBWOTAX4.mjs.map +1 -0
  25. package/dist/{chunk-DAUR3WUZ.mjs → chunk-WO466YX5.mjs} +2 -2
  26. package/dist/chunk-WO466YX5.mjs.map +1 -0
  27. package/dist/{chunk-CEVMYGDL.mjs → chunk-YD5IRKVS.mjs} +13 -9
  28. package/dist/chunk-YD5IRKVS.mjs.map +1 -0
  29. package/dist/{client-plugins-QQntVkrv.d.mts → client-plugins-CCilIb_G.d.mts} +6 -2
  30. package/dist/{client-plugins-CbRum1fj.d.ts → client-plugins-DuuleQKk.d.ts} +6 -2
  31. package/dist/client-plugins.d.mts +2 -1
  32. package/dist/client-plugins.d.ts +2 -1
  33. package/dist/client.cjs +122 -35
  34. package/dist/client.cjs.map +1 -1
  35. package/dist/client.d.mts +2 -0
  36. package/dist/client.d.ts +2 -0
  37. package/dist/client.mjs +13 -2
  38. package/dist/config.d.mts +2 -1
  39. package/dist/config.d.ts +2 -1
  40. package/dist/{devtools-52FYXIEK.mjs → devtools-326RBQCN.mjs} +7 -6
  41. package/dist/{devtools-52FYXIEK.mjs.map → devtools-326RBQCN.mjs.map} +1 -1
  42. package/dist/docs.cjs.map +1 -1
  43. package/dist/docs.mjs +6 -5
  44. package/dist/index.cjs +910 -414
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.mts +10 -7
  47. package/dist/index.d.ts +10 -7
  48. package/dist/index.mjs +66 -49
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/integrations.d.mts +2 -1
  51. package/dist/integrations.d.ts +2 -1
  52. package/dist/internal/build-runtime.cjs +720 -297
  53. package/dist/internal/build-runtime.cjs.map +1 -1
  54. package/dist/internal/build-runtime.d.mts +4 -3
  55. package/dist/internal/build-runtime.d.ts +4 -3
  56. package/dist/internal/build-runtime.mjs +15 -12
  57. package/dist/internal/config-runtime.cjs +41 -0
  58. package/dist/internal/config-runtime.cjs.map +1 -1
  59. package/dist/internal/config-runtime.d.mts +3 -2
  60. package/dist/internal/config-runtime.d.ts +3 -2
  61. package/dist/internal/config-runtime.mjs +5 -4
  62. package/dist/internal/production-runtime.cjs +178 -0
  63. package/dist/internal/production-runtime.cjs.map +1 -1
  64. package/dist/internal/production-runtime.d.mts +20 -6
  65. package/dist/internal/production-runtime.d.ts +20 -6
  66. package/dist/internal/production-runtime.mjs +13 -1
  67. package/dist/internal/production-runtime.mjs.map +1 -1
  68. package/dist/{metadata-B5jBJHq1.d.ts → metadata-DyPRG0wX.d.ts} +1 -1
  69. package/dist/{metadata-BxOJ4FJl.d.mts → metadata-_GHcAySx.d.mts} +1 -1
  70. package/dist/middleware.d.mts +4 -3
  71. package/dist/middleware.d.ts +4 -3
  72. package/dist/plugin.cjs +461 -155
  73. package/dist/plugin.cjs.map +1 -1
  74. package/dist/plugin.d.mts +2 -1
  75. package/dist/plugin.d.ts +2 -1
  76. package/dist/plugin.mjs +11 -8
  77. package/dist/{production-runtime-Bxua86uR.d.mts → production-runtime-C4cO3esK.d.mts} +1 -1
  78. package/dist/{production-runtime-CZqXjRVi.d.ts → production-runtime-DrEy8kBO.d.ts} +1 -1
  79. package/dist/{request-7V0GaZK_.d.mts → request-B2PpOxYK.d.mts} +1 -1
  80. package/dist/{request-B5XYBv5a.d.ts → request-D40lt6aN.d.ts} +1 -1
  81. package/dist/request.d.mts +3 -2
  82. package/dist/request.d.ts +3 -2
  83. package/dist/routes.d.mts +2 -1
  84. package/dist/routes.d.ts +2 -1
  85. package/dist/server-plugins.d.mts +3 -2
  86. package/dist/server-plugins.d.ts +3 -2
  87. package/dist/server.cjs +490 -167
  88. package/dist/server.cjs.map +1 -1
  89. package/dist/server.d.mts +8 -6
  90. package/dist/server.d.ts +8 -6
  91. package/dist/server.mjs +20 -11
  92. package/dist/server.mjs.map +1 -1
  93. package/dist/testing.d.mts +2 -1
  94. package/dist/testing.d.ts +2 -1
  95. package/dist/theme/client.cjs +115 -0
  96. package/dist/theme/client.cjs.map +1 -0
  97. package/dist/theme/client.d.mts +17 -0
  98. package/dist/theme/client.d.ts +17 -0
  99. package/dist/theme/client.mjs +16 -0
  100. package/dist/theme/client.mjs.map +1 -0
  101. package/dist/theme/index.cjs +71 -0
  102. package/dist/theme/index.cjs.map +1 -0
  103. package/dist/theme/index.d.mts +6 -0
  104. package/dist/theme/index.d.ts +6 -0
  105. package/dist/theme/index.mjs +9 -0
  106. package/dist/theme/index.mjs.map +1 -0
  107. package/dist/theme/server.cjs +191 -0
  108. package/dist/theme/server.cjs.map +1 -0
  109. package/dist/theme/server.d.mts +8 -0
  110. package/dist/theme/server.d.ts +8 -0
  111. package/dist/theme/server.mjs +18 -0
  112. package/dist/theme/server.mjs.map +1 -0
  113. package/dist/types-CsR8fpgF.d.mts +30 -0
  114. package/dist/types-CsR8fpgF.d.ts +30 -0
  115. package/dist/{utils-xTFxzu47.d.ts → utils-3sQgfkya.d.ts} +1 -1
  116. package/dist/{utils-s9pN0Yep.d.mts → utils-Bop7bly-.d.mts} +1 -1
  117. package/dist/version.cjs +1 -1
  118. package/dist/version.cjs.map +1 -1
  119. package/dist/version.mjs +1 -1
  120. package/dist/vite.cjs +485 -157
  121. package/dist/vite.cjs.map +1 -1
  122. package/dist/vite.d.mts +2 -1
  123. package/dist/vite.d.ts +2 -1
  124. package/dist/vite.mjs +11 -8
  125. package/package.json +25 -1
  126. package/dist/chunk-CEVMYGDL.mjs.map +0 -1
  127. package/dist/chunk-DAUR3WUZ.mjs.map +0 -1
  128. package/dist/chunk-FRPWCMMG.mjs.map +0 -1
  129. package/dist/chunk-XBKXKJX5.mjs.map +0 -1
  130. package/dist/chunk-ZP73P4VR.mjs.map +0 -1
  131. /package/dist/{chunk-LLPN5SEZ.mjs.map → chunk-DVPRBMU2.mjs.map} +0 -0
  132. /package/dist/{chunk-UCYWGN2P.mjs.map → chunk-OHNSROHS.mjs.map} +0 -0
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}`,
@@ -5632,6 +5632,52 @@ var init_config = __esm({
5632
5632
  }
5633
5633
  });
5634
5634
 
5635
+ // src/theme/config.ts
5636
+ function resolveFarmThemeConfig(config, basePath = "/") {
5637
+ if (config && "enabled" in config) {
5638
+ return config;
5639
+ }
5640
+ if (!config) {
5641
+ return {
5642
+ enabled: false,
5643
+ default: "system",
5644
+ storageKey: DEFAULT_FARM_THEME_STORAGE_KEY,
5645
+ cookiePath: normalizeCookiePath(basePath)
5646
+ };
5647
+ }
5648
+ const storageKey = config.storageKey?.trim() || DEFAULT_FARM_THEME_STORAGE_KEY;
5649
+ if (!STORAGE_KEY_PATTERN.test(storageKey)) {
5650
+ throw new Error(
5651
+ "theme.storageKey may only contain letters, numbers, dots, underscores, and hyphens."
5652
+ );
5653
+ }
5654
+ const defaultTheme = config.default ?? "system";
5655
+ if (defaultTheme !== "light" && defaultTheme !== "dark" && defaultTheme !== "system") {
5656
+ throw new Error('theme.default must be "light", "dark", or "system".');
5657
+ }
5658
+ return {
5659
+ enabled: true,
5660
+ default: defaultTheme,
5661
+ storageKey,
5662
+ cookiePath: normalizeCookiePath(basePath)
5663
+ };
5664
+ }
5665
+ function normalizeCookiePath(basePath) {
5666
+ const normalized = `/${basePath}`.replace(/\/{2,}/g, "/");
5667
+ if (normalized === "/") return normalized;
5668
+ return normalized.replace(/\/$/, "");
5669
+ }
5670
+ var DEFAULT_FARM_THEME_STORAGE_KEY, STORAGE_KEY_PATTERN;
5671
+ var init_config2 = __esm({
5672
+ "src/theme/config.ts"() {
5673
+ "use strict";
5674
+ DEFAULT_FARM_THEME_STORAGE_KEY = "farm-theme";
5675
+ STORAGE_KEY_PATTERN = /^[A-Za-z0-9._-]+$/;
5676
+ __name(resolveFarmThemeConfig, "resolveFarmThemeConfig");
5677
+ __name(normalizeCookiePath, "normalizeCookiePath");
5678
+ }
5679
+ });
5680
+
5635
5681
  // src/devtools-config.ts
5636
5682
  function resolveFarmDevtoolsConfig(config, mode = "development") {
5637
5683
  if (mode !== "development" || config === false) {
@@ -6029,11 +6075,11 @@ var init_type_generator = __esm({
6029
6075
  routeGroups.get(key).push(route);
6030
6076
  }
6031
6077
  const nestedStructure = {};
6032
- for (const [path27, routeList] of routeGroups) {
6078
+ for (const [path28, routeList] of routeGroups) {
6033
6079
  const route = routeList[0];
6034
6080
  const importPath = this.getRouteImportPath(route, options.outFile);
6035
6081
  const routeName = this.pathToRouteName(route.path);
6036
- const cleanPath = path27 === "/api" ? "" : path27.replace(/^\/api\//, "");
6082
+ const cleanPath = path28 === "/api" ? "" : path28.replace(/^\/api\//, "");
6037
6083
  const parts = cleanPath ? cleanPath.split("/") : [];
6038
6084
  const allMethods = routeList.flatMap((r) => r.methods);
6039
6085
  for (const method of allMethods) {
@@ -6092,8 +6138,8 @@ ${typeExports}
6092
6138
  const relativeImport = (0, import_path7.relative)((0, import_path7.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
6093
6139
  return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
6094
6140
  }
6095
- pathToRouteName(path27) {
6096
- 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, "");
6097
6143
  }
6098
6144
  structureToTypeString(obj, indent) {
6099
6145
  const spaces = " ".repeat(indent);
@@ -6113,15 +6159,15 @@ ${typeExports}
6113
6159
  toTypePropertyKey(key) {
6114
6160
  return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
6115
6161
  }
6116
- getBaseExportName(path27) {
6117
- const cleanPath = path27.replace(/^\/api\//, "");
6162
+ getBaseExportName(path28) {
6163
+ const cleanPath = path28.replace(/^\/api\//, "");
6118
6164
  if (cleanPath === "") {
6119
6165
  return "api";
6120
6166
  }
6121
6167
  return cleanPath;
6122
6168
  }
6123
- getExportName(path27, method) {
6124
- const cleanPath = path27.replace(/^\/api\//, "");
6169
+ getExportName(path28, method) {
6170
+ const cleanPath = path28.replace(/^\/api\//, "");
6125
6171
  if (cleanPath === "") {
6126
6172
  return method.toLowerCase();
6127
6173
  }
@@ -10527,37 +10573,37 @@ function sanitizeDocsConfig(config) {
10527
10573
  return cloneSerializable(config) || {};
10528
10574
  }
10529
10575
  async function findDocsConfigPath(rootDir, configPath) {
10530
- const { existsSync: existsSync16 } = await import("fs");
10576
+ const { existsSync: existsSync17 } = await import("fs");
10531
10577
  const root = import_path9.default.resolve(rootDir || process.cwd());
10532
10578
  if (configPath) {
10533
10579
  const resolvedPath = import_path9.default.isAbsolute(configPath) ? configPath : import_path9.default.join(root, configPath);
10534
- if (!existsSync16(resolvedPath)) {
10580
+ if (!existsSync17(resolvedPath)) {
10535
10581
  throw new Error(`Could not find docs config at ${configPath}.`);
10536
10582
  }
10537
10583
  return import_path9.default.resolve(resolvedPath);
10538
10584
  }
10539
10585
  for (const filename of DOCS_CONFIG_FILENAMES) {
10540
10586
  const resolvedPath = import_path9.default.join(root, filename);
10541
- if (existsSync16(resolvedPath)) {
10587
+ if (existsSync17(resolvedPath)) {
10542
10588
  return resolvedPath;
10543
10589
  }
10544
10590
  }
10545
10591
  return void 0;
10546
10592
  }
10547
10593
  async function loadDocsConfig(rootDir, configPath) {
10548
- const fs9 = await import("fs/promises");
10594
+ const fs10 = await import("fs/promises");
10549
10595
  const { pathToFileURL: pathToFileURL5 } = await import("url");
10550
10596
  const root = import_path9.default.resolve(rootDir || process.cwd());
10551
10597
  const resolvedPath = await findDocsConfigPath(root, configPath);
10552
10598
  if (!resolvedPath) return void 0;
10553
10599
  try {
10554
10600
  if (resolvedPath.endsWith(".json")) {
10555
- const content = await fs9.readFile(resolvedPath, "utf8");
10601
+ const content = await fs10.readFile(resolvedPath, "utf8");
10556
10602
  return { config: JSON.parse(content), configPath: resolvedPath };
10557
10603
  }
10558
10604
  const { build } = await import("esbuild");
10559
10605
  const configCacheDir = import_path9.default.join(root, ".farm", ".config-loader");
10560
- await fs9.mkdir(configCacheDir, { recursive: true });
10606
+ await fs10.mkdir(configCacheDir, { recursive: true });
10561
10607
  const modulePath = import_path9.default.join(
10562
10608
  configCacheDir,
10563
10609
  `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
@@ -10583,7 +10629,7 @@ async function loadDocsConfig(rootDir, configPath) {
10583
10629
  moduleUrl
10584
10630
  );
10585
10631
  } finally {
10586
- await fs9.unlink(modulePath).catch(() => void 0);
10632
+ await fs10.unlink(modulePath).catch(() => void 0);
10587
10633
  }
10588
10634
  return {
10589
10635
  config: importedConfig.default || importedConfig,
@@ -10733,6 +10779,7 @@ async function resolveConfig(userConfig, mode) {
10733
10779
  routeRules,
10734
10780
  images: resolveFarmImageConfig(userConfig.images),
10735
10781
  performance: resolveFarmPerformanceConfig(userConfig.performance),
10782
+ theme: resolveFarmThemeConfig(userConfig.theme, userConfig.basePath || "/"),
10736
10783
  publicDir: userConfig.publicDir || "public",
10737
10784
  i18n: resolveFarmI18nConfig(userConfig.i18n, { root, mode }),
10738
10785
  openapi: {
@@ -10773,7 +10820,7 @@ async function resolveConfig(userConfig, mode) {
10773
10820
  return resolved;
10774
10821
  }
10775
10822
  async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "production" ? "production" : "development", loadEnvironment) {
10776
- const { existsSync: existsSync16 } = await import("fs");
10823
+ const { existsSync: existsSync17 } = await import("fs");
10777
10824
  const loadEnv = loadEnvironment || (await import("vite")).loadEnv;
10778
10825
  const root = rootDir || process.cwd();
10779
10826
  const loadedEnv = loadEnv(mode, root, "");
@@ -10797,7 +10844,7 @@ async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "
10797
10844
  try {
10798
10845
  const absolutePath = relativePath2.startsWith("/") ? relativePath2 : import_path9.default.join(root, relativePath2);
10799
10846
  const normalizedPath = import_path9.default.resolve(absolutePath);
10800
- if (!existsSync16(normalizedPath)) {
10847
+ if (!existsSync17(normalizedPath)) {
10801
10848
  continue;
10802
10849
  }
10803
10850
  const loadedConfig = await loadFarmConfigFile(normalizedPath, { root });
@@ -10810,7 +10857,7 @@ async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "
10810
10857
  return void 0;
10811
10858
  }
10812
10859
  var import_path9, FARM_RESOLVED_CUSTOM_CONTEXT, DOCS_CONFIG_FILENAMES;
10813
- var init_config2 = __esm({
10860
+ var init_config3 = __esm({
10814
10861
  "src/config.ts"() {
10815
10862
  "use strict";
10816
10863
  init_integrations();
@@ -10831,6 +10878,7 @@ var init_config2 = __esm({
10831
10878
  init_auth_config();
10832
10879
  init_preload();
10833
10880
  init_security();
10881
+ init_config2();
10834
10882
  init_config_entry();
10835
10883
  FARM_RESOLVED_CUSTOM_CONTEXT = /* @__PURE__ */ Symbol.for("farm.resolvedCustomContext");
10836
10884
  __name(normalizeDeployTarget, "normalizeDeployTarget");
@@ -11333,7 +11381,7 @@ var init_api = __esm({
11333
11381
  "src/docs/api.ts"() {
11334
11382
  "use strict";
11335
11383
  import_docs2 = require("@farming-labs/docs");
11336
- init_config2();
11384
+ init_config3();
11337
11385
  init_handler();
11338
11386
  __name(isRecord4, "isRecord");
11339
11387
  __name(isResolvedDocsConfig2, "isResolvedDocsConfig");
@@ -11627,8 +11675,8 @@ var init_generator = __esm({
11627
11675
  }
11628
11676
  routeGroups.get(key).push(route);
11629
11677
  }
11630
- for (const [path27, routeList] of routeGroups) {
11631
- const openAPIPath = this.convertToOpenAPIPath(path27);
11678
+ for (const [path28, routeList] of routeGroups) {
11679
+ const openAPIPath = this.convertToOpenAPIPath(path28);
11632
11680
  spec.paths[openAPIPath] = {};
11633
11681
  for (const route of routeList) {
11634
11682
  for (const method of route.methods) {
@@ -11642,8 +11690,8 @@ var init_generator = __esm({
11642
11690
  /**
11643
11691
  * Convert Farm.js API path to OpenAPI path format
11644
11692
  */
11645
- convertToOpenAPIPath(path27) {
11646
- return path27.replace(/^\/api/, "");
11693
+ convertToOpenAPIPath(path28) {
11694
+ return path28.replace(/^\/api/, "");
11647
11695
  }
11648
11696
  /**
11649
11697
  * Extract request body schema from endpoint
@@ -11805,8 +11853,8 @@ var init_generator = __esm({
11805
11853
  /**
11806
11854
  * Generate operation summary
11807
11855
  */
11808
- generateSummary(path27, method) {
11809
- const cleanPath = path27.replace(/^\/api\//, "");
11856
+ generateSummary(path28, method) {
11857
+ const cleanPath = path28.replace(/^\/api\//, "");
11810
11858
  const pathParts = cleanPath.split("/");
11811
11859
  const lastPart = pathParts[pathParts.length - 1];
11812
11860
  const action = method === "GET" ? "Get" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
@@ -11815,22 +11863,22 @@ var init_generator = __esm({
11815
11863
  /**
11816
11864
  * Generate operation description
11817
11865
  */
11818
- generateDescription(path27, method) {
11819
- const cleanPath = path27.replace(/^\/api\//, "");
11866
+ generateDescription(path28, method) {
11867
+ const cleanPath = path28.replace(/^\/api\//, "");
11820
11868
  return `${method} ${cleanPath} endpoint`;
11821
11869
  }
11822
11870
  /**
11823
11871
  * Generate operation ID
11824
11872
  */
11825
- generateOperationId(path27, method) {
11826
- const cleanPath = path27.replace(/^\/api\//, "").replace(/\//g, "_");
11873
+ generateOperationId(path28, method) {
11874
+ const cleanPath = path28.replace(/^\/api\//, "").replace(/\//g, "_");
11827
11875
  return `${method.toLowerCase()}_${cleanPath}`;
11828
11876
  }
11829
11877
  /**
11830
11878
  * Generate tags for grouping operations
11831
11879
  */
11832
- generateTags(path27) {
11833
- const cleanPath = path27.replace(/^\/api\//, "");
11880
+ generateTags(path28) {
11881
+ const cleanPath = path28.replace(/^\/api\//, "");
11834
11882
  const pathParts = cleanPath.split("/");
11835
11883
  if (pathParts.length > 1) {
11836
11884
  return [pathParts[0]];
@@ -11842,13 +11890,13 @@ var init_generator = __esm({
11842
11890
  */
11843
11891
  async generateSpecFile(routes, outputPath) {
11844
11892
  const spec = await this.generateSpec(routes);
11845
- const fs9 = require("fs");
11846
- const path27 = require("path");
11847
- const dir = path27.dirname(outputPath);
11848
- if (!fs9.existsSync(dir)) {
11849
- 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 });
11850
11898
  }
11851
- fs9.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
11899
+ fs10.writeFileSync(outputPath, JSON.stringify(spec, null, 2));
11852
11900
  }
11853
11901
  };
11854
11902
  __name(_OpenAPIGenerator, "OpenAPIGenerator");
@@ -12318,7 +12366,7 @@ var init_devtools = __esm({
12318
12366
  "src/devtools.ts"() {
12319
12367
  "use strict";
12320
12368
  import_node_path14 = __toESM(require("path"));
12321
- init_config2();
12369
+ init_config3();
12322
12370
  init_cron();
12323
12371
  init_route_runtime();
12324
12372
  __name(normalizePath, "normalizePath");
@@ -14025,6 +14073,8 @@ __export(server_exports, {
14025
14073
  getServerActionInvalidations: () => getServerActionInvalidations,
14026
14074
  getServerActionSignal: () => getServerActionSignal,
14027
14075
  getStorage: () => getStorage,
14076
+ getTheme: () => getTheme,
14077
+ getThemeSnapshot: () => getThemeSnapshot,
14028
14078
  globFiles: () => globFiles,
14029
14079
  initStorage: () => initStorage,
14030
14080
  invalidate: () => invalidate,
@@ -14201,8 +14251,8 @@ function toViteModuleId(filePath, root) {
14201
14251
  __name(toViteModuleId, "toViteModuleId");
14202
14252
  async function fileExists(filePath) {
14203
14253
  try {
14204
- const fs9 = await import("fs/promises");
14205
- await fs9.access(filePath);
14254
+ const fs10 = await import("fs/promises");
14255
+ await fs10.access(filePath);
14206
14256
  return true;
14207
14257
  } catch {
14208
14258
  return false;
@@ -15625,7 +15675,7 @@ function normalizePositiveDuration(value, fallback, name) {
15625
15675
  }
15626
15676
  __name(normalizePositiveDuration, "normalizePositiveDuration");
15627
15677
  function delay(ms) {
15628
- return new Promise((resolve6) => setTimeout(resolve6, ms));
15678
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
15629
15679
  }
15630
15680
  __name(delay, "delay");
15631
15681
  function normalizeCacheOptionsTags(options) {
@@ -15776,25 +15826,25 @@ function defineRoutes(input) {
15776
15826
  }
15777
15827
  __name(defineRoutes, "defineRoutes");
15778
15828
  var routesBuilder = {
15779
- page(path27, options) {
15829
+ page(path28, options) {
15780
15830
  return normalizeProgrammaticRoute({
15781
15831
  kind: "page",
15782
- path: path27,
15832
+ path: path28,
15783
15833
  ...options
15784
15834
  });
15785
15835
  },
15786
- layout(path27, options) {
15836
+ layout(path28, options) {
15787
15837
  return normalizeProgrammaticRoute({
15788
15838
  kind: "layout",
15789
- path: path27,
15839
+ path: path28,
15790
15840
  ...options
15791
15841
  });
15792
15842
  },
15793
- api(path27, options) {
15843
+ api(path28, options) {
15794
15844
  const { render, runtime, regions, maxDuration, ...methods } = options;
15795
15845
  return normalizeProgrammaticRoute({
15796
15846
  kind: "api",
15797
- path: path27,
15847
+ path: path28,
15798
15848
  render,
15799
15849
  runtime,
15800
15850
  regions,
@@ -15830,7 +15880,7 @@ function getProgrammaticRouteSearchClientOptions(search) {
15830
15880
  return Object.keys(options).length > 0 ? options : void 0;
15831
15881
  }
15832
15882
  __name(getProgrammaticRouteSearchClientOptions, "getProgrammaticRouteSearchClientOptions");
15833
- function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path27, routePath) {
15883
+ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path28, routePath) {
15834
15884
  const schema = getProgrammaticRouteSearchSchema(searchConfig);
15835
15885
  const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
15836
15886
  const options = getProgrammaticRouteSearchOptions(searchConfig);
@@ -15839,7 +15889,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path27, routePa
15839
15889
  schema,
15840
15890
  rawSearch,
15841
15891
  parsedSearch: search,
15842
- path: path27
15892
+ path: path28
15843
15893
  });
15844
15894
  return { search, canonicalPath };
15845
15895
  }
@@ -16022,7 +16072,7 @@ function createRouteModuleFromProgrammaticPage(route) {
16022
16072
  mod.__farmRouteData = route.data;
16023
16073
  mod.__farmRouteParsesProps = true;
16024
16074
  mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
16025
- 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;
16026
16076
  }
16027
16077
  if (route.pending || route.error || route.notFound) {
16028
16078
  mod.__farmRouteComponents = {
@@ -16776,6 +16826,37 @@ function stripUseClientDirective(content) {
16776
16826
  return content.replace(/^\s*(["'])use client\1\s*;?\s*/, "");
16777
16827
  }
16778
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");
16779
16860
  function parseClientModuleMetadata(content, inspectIslandExport) {
16780
16861
  if (!content) {
16781
16862
  return {
@@ -16831,6 +16912,14 @@ function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandE
16831
16912
  }
16832
16913
  }
16833
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
+ }
16834
16923
  return {
16835
16924
  isClientComponent: false,
16836
16925
  shouldHydrate,
@@ -17546,6 +17635,7 @@ var _RouteManager = class _RouteManager {
17546
17635
  shouldHydrate: metadata.shouldHydrate,
17547
17636
  isClientComponent: metadata.isClientComponent,
17548
17637
  islandStrategy: metadata.islandStrategy,
17638
+ suppressedAsyncHydration: metadata.suppressedAsyncHydration,
17549
17639
  search: getProgrammaticRouteSearchClientOptions(programmaticPage?.search),
17550
17640
  segments: entry.route.segments.map((seg) => ({
17551
17641
  segment: seg.segment,
@@ -20671,18 +20761,146 @@ function DefaultNotFoundPage(_props) {
20671
20761
  }
20672
20762
  __name(DefaultNotFoundPage, "DefaultNotFoundPage");
20673
20763
 
20764
+ // src/theme/server-runtime.ts
20765
+ init_config2();
20766
+ var THEME_SCRIPT_ID = "farm-theme-script";
20767
+ var THEME_STYLE_ID = "farm-theme-style";
20768
+ function createFarmThemeDocumentParts(input, basePath = "/", serverTheme) {
20769
+ const config = resolveFarmThemeConfig(input, basePath);
20770
+ if (!config.enabled) return { attributes: "", head: "" };
20771
+ const hydrationTheme = serverTheme ?? config.default;
20772
+ const initialTheme = hydrationTheme === "system" ? "light" : hydrationTheme;
20773
+ const script = createFarmThemeBootstrapScript(config, hydrationTheme);
20774
+ return {
20775
+ attributes: ` data-theme="${initialTheme}"`,
20776
+ head: `<style id="${THEME_STYLE_ID}">:root[data-theme="light"]{color-scheme:light}:root[data-theme="dark"]{color-scheme:dark}</style><script id="${THEME_SCRIPT_ID}">${script}</script>`
20777
+ };
20778
+ }
20779
+ __name(createFarmThemeDocumentParts, "createFarmThemeDocumentParts");
20780
+ function createFarmThemeBootstrapScript(config, serverTheme = config.default) {
20781
+ return `(function(config,serverTheme){
20782
+ var isTheme=function(value){return value==="light"||value==="dark"||value==="system";};
20783
+ var decode=function(value){try{return decodeURIComponent(value);}catch(_error){return value;}};
20784
+ var readCookie=function(){var entries=document.cookie.split(";");for(var index=0;index<entries.length;index++){var entry=entries[index];var separator=entry.indexOf("=");if(separator<0)continue;if(decode(entry.slice(0,separator).trim())===config.storageKey)return decode(entry.slice(separator+1).trim());}};
20785
+ var media=window.matchMedia("(prefers-color-scheme: dark)");
20786
+ var resolveTheme=function(theme){return theme==="system"?(media.matches?"dark":"light"):theme;};
20787
+ var storedTheme=readCookie();
20788
+ var preference=isTheme(storedTheme)?storedTheme:config.default;
20789
+ var serverSnapshot={theme:serverTheme,resolvedTheme:serverTheme==="system"?undefined:serverTheme,mounted:false};
20790
+ var apply=function(){var resolvedTheme=resolveTheme(preference);document.documentElement.dataset.theme=resolvedTheme;var snapshot={theme:preference,resolvedTheme:resolvedTheme,mounted:true};if(window.__FARM_THEME__)window.__FARM_THEME__.snapshot=snapshot;return snapshot;};
20791
+ var emit=function(){var snapshot=apply();window.dispatchEvent(new CustomEvent("farm:themechange",{detail:snapshot}));};
20792
+ var persist=function(theme){var secure=window.location.protocol==="https:"?"; Secure":"";document.cookie=encodeURIComponent(config.storageKey)+"="+encodeURIComponent(theme)+"; Path="+config.cookiePath+"; Max-Age=31536000; SameSite=Lax"+secure;try{localStorage.setItem(config.storageKey,theme);}catch(_error){}};
20793
+ var setTheme=function(theme){if(!isTheme(theme))throw new TypeError("Unknown FARMJS theme: "+String(theme));preference=theme;persist(theme);emit();};
20794
+ var initialSnapshot={theme:preference,resolvedTheme:resolveTheme(preference),mounted:true};
20795
+ window.__FARM_THEME__={config:config,serverSnapshot:serverSnapshot,snapshot:initialSnapshot,setTheme:setTheme};
20796
+ document.documentElement.dataset.theme=initialSnapshot.resolvedTheme;
20797
+ var handleSystemChange=function(){if(preference==="system")emit();};
20798
+ if(typeof media.addEventListener==="function")media.addEventListener("change",handleSystemChange);else if(typeof media.addListener==="function")media.addListener(handleSystemChange);
20799
+ window.addEventListener("storage",function(event){if(event.key!==config.storageKey||!isTheme(event.newValue))return;preference=event.newValue;persist(preference);emit();});
20800
+ })(${serializeInlineValue(config)},${serializeInlineValue(serverTheme)});`;
20801
+ }
20802
+ __name(createFarmThemeBootstrapScript, "createFarmThemeBootstrapScript");
20803
+ function serializeInlineValue(value) {
20804
+ return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
20805
+ }
20806
+ __name(serializeInlineValue, "serializeInlineValue");
20807
+
20808
+ // src/theme/bridge.ts
20809
+ var FALLBACK_SERVER_SNAPSHOT = Object.freeze({
20810
+ theme: "system",
20811
+ resolvedTheme: void 0,
20812
+ mounted: false
20813
+ });
20814
+ var FARM_THEME_SERVER_SNAPSHOT_RESOLVER = /* @__PURE__ */ Symbol.for("farm.js.theme.server-snapshot-resolver");
20815
+ function _setFarmThemeServerSnapshotResolver(resolver) {
20816
+ globalThis[FARM_THEME_SERVER_SNAPSHOT_RESOLVER] = resolver;
20817
+ }
20818
+ __name(_setFarmThemeServerSnapshotResolver, "_setFarmThemeServerSnapshotResolver");
20819
+
20820
+ // src/theme/server.ts
20821
+ init_config2();
20822
+ var defaultThemeConfig = resolveFarmThemeConfig(void 0);
20823
+ function _setDefaultFarmThemeConfig(config, basePath = "/") {
20824
+ defaultThemeConfig = resolveFarmThemeConfig(config, basePath);
20825
+ }
20826
+ __name(_setDefaultFarmThemeConfig, "_setDefaultFarmThemeConfig");
20827
+ function getTheme(request = getCurrentRequest()) {
20828
+ return readFarmThemePreference(request, defaultThemeConfig);
20829
+ }
20830
+ __name(getTheme, "getTheme");
20831
+ function getThemeSnapshot(request = getCurrentRequest()) {
20832
+ const theme = readFarmThemePreference(request, defaultThemeConfig);
20833
+ return {
20834
+ theme,
20835
+ resolvedTheme: theme === "system" ? void 0 : theme,
20836
+ mounted: false
20837
+ };
20838
+ }
20839
+ __name(getThemeSnapshot, "getThemeSnapshot");
20840
+ function readFarmThemePreference(request, config) {
20841
+ if (!config.enabled) return config.default;
20842
+ const stored = readCookie3(request.headers.get("cookie"), config.storageKey);
20843
+ return isFarmThemePreference(stored) ? stored : config.default;
20844
+ }
20845
+ __name(readFarmThemePreference, "readFarmThemePreference");
20846
+ function readCookie3(cookieHeader, name) {
20847
+ if (!cookieHeader) return void 0;
20848
+ for (const entry of cookieHeader.split(";")) {
20849
+ const separator = entry.indexOf("=");
20850
+ if (separator < 0) continue;
20851
+ const key = decodeCookieValue(entry.slice(0, separator).trim());
20852
+ if (key !== name) continue;
20853
+ return decodeCookieValue(entry.slice(separator + 1).trim());
20854
+ }
20855
+ return void 0;
20856
+ }
20857
+ __name(readCookie3, "readCookie");
20858
+ function decodeCookieValue(value) {
20859
+ try {
20860
+ return decodeURIComponent(value);
20861
+ } catch {
20862
+ return value;
20863
+ }
20864
+ }
20865
+ __name(decodeCookieValue, "decodeCookieValue");
20866
+ function isFarmThemePreference(value) {
20867
+ return value === "light" || value === "dark" || value === "system";
20868
+ }
20869
+ __name(isFarmThemePreference, "isFarmThemePreference");
20870
+ _setFarmThemeServerSnapshotResolver(() => {
20871
+ try {
20872
+ return getThemeSnapshot();
20873
+ } catch {
20874
+ const theme = defaultThemeConfig.default;
20875
+ return {
20876
+ theme,
20877
+ resolvedTheme: theme === "system" ? void 0 : theme,
20878
+ mounted: false
20879
+ };
20880
+ }
20881
+ });
20882
+
20674
20883
  // src/server/renderer.ts
20675
20884
  var cachedClerkProvider = null;
20676
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");
20677
20895
  function hasRequestHeader(req, name) {
20678
20896
  const value = req.headers[name.toLowerCase()];
20679
20897
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
20680
20898
  }
20681
20899
  __name(hasRequestHeader, "hasRequestHeader");
20682
- function serializeInlineValue(value) {
20900
+ function serializeInlineValue2(value) {
20683
20901
  return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
20684
20902
  }
20685
- __name(serializeInlineValue, "serializeInlineValue");
20903
+ __name(serializeInlineValue2, "serializeInlineValue");
20686
20904
  function escapeHtmlAttribute2(value) {
20687
20905
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
20688
20906
  }
@@ -20776,7 +20994,7 @@ function createDocumentFooter(options) {
20776
20994
  __name(createDocumentFooter, "createDocumentFooter");
20777
20995
  function createDeferredHydrationScript(records) {
20778
20996
  if (records.length === 0) return "";
20779
- return `<script>window.__FARM_DEFERRED_DATA__=${serializeInlineValue(
20997
+ return `<script>window.__FARM_DEFERRED_DATA__=${serializeInlineValue2(
20780
20998
  snapshotDeferredData(records)
20781
20999
  )};</script>`;
20782
21000
  }
@@ -21348,6 +21566,9 @@ var _ServerRenderer = class _ServerRenderer {
21348
21566
  })
21349
21567
  );
21350
21568
  const shouldHydrate = moduleMetadata.shouldHydrate;
21569
+ if (moduleMetadata.suppressedAsyncHydration) {
21570
+ warnSuppressedAsyncHydrationOnce(route.modulePath);
21571
+ }
21351
21572
  const layoutHydrationMetadata = layouts.map((layout2) => {
21352
21573
  const manifestEntry = routeManifest.layouts.find(
21353
21574
  (entry) => entry.pattern === layout2.pattern
@@ -21845,7 +22066,7 @@ var _ServerRenderer = class _ServerRenderer {
21845
22066
  }
21846
22067
  }
21847
22068
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
21848
- return new Promise((resolve6, reject) => {
22069
+ return new Promise((resolve7, reject) => {
21849
22070
  const streamStartTime = Date.now();
21850
22071
  const observabilityRoute = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
21851
22072
  const deploymentId = this.getDeploymentId();
@@ -21917,9 +22138,9 @@ var _ServerRenderer = class _ServerRenderer {
21917
22138
  slots: routeSlotPayload
21918
22139
  });
21919
22140
  const propsScript = `<script>
21920
- window.__FARM_PROPS__ = ${serializeInlineValue(deferredProps.data.page)};
21921
- window.__FARM_ROUTE_SLOTS__ = ${serializeInlineValue(deferredProps.data.slots)};
21922
- window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
22141
+ window.__FARM_PROPS__ = ${serializeInlineValue2(deferredProps.data.page)};
22142
+ window.__FARM_ROUTE_SLOTS__ = ${serializeInlineValue2(deferredProps.data.slots)};
22143
+ window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue2(deploymentId)};
21923
22144
  window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
21924
22145
  window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
21925
22146
  window.__FARM_PAGE_SHOULD_HYDRATE__ = ${JSON.stringify(
@@ -21937,7 +22158,7 @@ window.__FARM_LOADING_MODULE__ = ${JSON.stringify(
21937
22158
  )};
21938
22159
  window.__FARM_MANIFEST__ = ${JSON.stringify(clientManifest)};
21939
22160
  window.__FARM_INTEGRATION_API_MANIFEST__ = ${JSON.stringify(getRegisteredIntegrationAPIManifest())};
21940
- ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(getFarmI18nClientSnapshot())};` : ""}
22161
+ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(getFarmI18nClientSnapshot())};` : ""}
21941
22162
  </script>`;
21942
22163
  const hydrationClickQueueScript = isClientComponent || req.__FARM_SHOULD_HYDRATE__ === true || req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ === true ? createPreHydrationClickQueueScript() : "";
21943
22164
  const {
@@ -21948,6 +22169,11 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
21948
22169
  const i18nSnapshot = getFarmI18nClientSnapshot();
21949
22170
  const i18nAlternateTags = i18nSnapshot ? renderI18nAlternateLinks(req.__FARM_ROUTE__ || req.url || "/", i18nSnapshot) : "";
21950
22171
  const fontHead = renderFarmFontDevHead(this.config.root || process.cwd());
22172
+ const themeDocument = createFarmThemeDocumentParts(
22173
+ this.config.theme,
22174
+ this.config.basePath,
22175
+ getTheme()
22176
+ );
21951
22177
  const streamRoot = import_react5.default.createElement("div", { style: { display: "contents" } }, element);
21952
22178
  const { pipe } = (0, import_server2.renderToPipeableStream)(streamRoot, {
21953
22179
  onShellReady() {
@@ -21961,8 +22187,9 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
21961
22187
  console.log(`[FARM STREAM] onShellReady at ${shellReadyMs}ms`);
21962
22188
  }
21963
22189
  const shell = `<!DOCTYPE html>
21964
- <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}>
22190
+ <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
21965
22191
  <head>
22192
+ ${themeDocument.head}
21966
22193
  <meta charset="utf-8">
21967
22194
  <meta name="viewport" content="width=device-width, initial-scale=1">
21968
22195
  <meta name="farm-deployment-id" content="${escapeHtmlAttribute2(deploymentId)}">
@@ -22039,7 +22266,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
22039
22266
  route: observabilityRoute,
22040
22267
  durationMs: Date.now() - streamStartTime
22041
22268
  });
22042
- resolve6();
22269
+ resolve7();
22043
22270
  }
22044
22271
  });
22045
22272
  res.write(shell);
@@ -22164,15 +22391,21 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
22164
22391
  const i18nSnapshot = getFarmI18nClientSnapshot();
22165
22392
  const clientScript = isClientComponent ? ` <script type="module" src="/@farm/client.js"></script>` : "";
22166
22393
  const integrationManifestScript = `<script>
22167
- window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(this.getDeploymentId())};
22394
+ window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue2(this.getDeploymentId())};
22168
22395
  window.__FARM_INTEGRATION_API_MANIFEST__ = ${JSON.stringify(getRegisteredIntegrationAPIManifest())};
22169
- ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue(i18nSnapshot)};` : ""}
22396
+ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue2(i18nSnapshot)};` : ""}
22170
22397
  </script>`;
22171
22398
  const alternateLinks = i18nSnapshot ? renderI18nAlternateLinks(requestPath, i18nSnapshot) : "";
22172
22399
  const fontHead = renderFarmFontDevHead(this.config.root || process.cwd());
22400
+ const themeDocument = createFarmThemeDocumentParts(
22401
+ this.config.theme,
22402
+ this.config.basePath,
22403
+ getTheme()
22404
+ );
22173
22405
  return `<!DOCTYPE html>
22174
- <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}>
22406
+ <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
22175
22407
  <head>
22408
+ ${themeDocument.head}
22176
22409
  <meta charset="utf-8">
22177
22410
  <meta name="viewport" content="width=device-width, initial-scale=1">
22178
22411
  <meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">
@@ -22219,6 +22452,7 @@ init_config();
22219
22452
  init_auth_config();
22220
22453
  init_preload();
22221
22454
  init_security();
22455
+ init_config2();
22222
22456
  var defaultDocsConfig = {
22223
22457
  enabled: false,
22224
22458
  entry: "/docs",
@@ -22232,6 +22466,7 @@ var _FarmApp = class _FarmApp {
22232
22466
  constructor(config = {}, viteServer) {
22233
22467
  this.config = this.normalizeConfig(config);
22234
22468
  configureFarmObservability(this.config.observability);
22469
+ _setDefaultFarmThemeConfig(this.config.theme);
22235
22470
  this.i18nRuntime = createFarmI18nRuntime(this.config.i18n);
22236
22471
  _setDefaultFarmI18nRuntime(this.i18nRuntime);
22237
22472
  this.viteServer = viteServer;
@@ -22290,6 +22525,7 @@ var _FarmApp = class _FarmApp {
22290
22525
  security: resolveFarmSecurityConfig(config.security),
22291
22526
  images: resolveFarmImageConfig(config.images),
22292
22527
  performance: resolveFarmPerformanceConfig(config.performance),
22528
+ theme: resolveFarmThemeConfig(config.theme, config.basePath || "/"),
22293
22529
  i18n: isResolvedI18nConfig(config.i18n) ? config.i18n : resolveFarmI18nConfig(config.i18n, {
22294
22530
  root,
22295
22531
  mode: process.env.NODE_ENV === "production" ? "production" : "development"
@@ -24556,8 +24792,8 @@ init_app_markdown();
24556
24792
  init_response();
24557
24793
  init_integrations();
24558
24794
  init_devtools_config();
24559
- var fs7 = __toESM(require("fs"));
24560
- var path25 = __toESM(require("path"));
24795
+ var fs8 = __toESM(require("fs"));
24796
+ var path26 = __toESM(require("path"));
24561
24797
  init_layers();
24562
24798
 
24563
24799
  // src/environment-vite.ts
@@ -24904,7 +25140,7 @@ function transformError(id, message) {
24904
25140
  __name(transformError, "transformError");
24905
25141
 
24906
25142
  // package.json
24907
- var version = "0.1.0-beta.22";
25143
+ var version = "0.1.0-beta.24";
24908
25144
 
24909
25145
  // src/version.ts
24910
25146
  var FARM_VERSION = version;
@@ -24938,8 +25174,8 @@ __name(reportAfterError, "reportAfterError");
24938
25174
  function createAfterRequestState(reportError = defaultAfterErrorReporter) {
24939
25175
  let resolveResponseFinished;
24940
25176
  let responseFinished = false;
24941
- const responseFinishedPromise = new Promise((resolve6) => {
24942
- resolveResponseFinished = resolve6;
25177
+ const responseFinishedPromise = new Promise((resolve7) => {
25178
+ resolveResponseFinished = resolve7;
24943
25179
  });
24944
25180
  const state = {
24945
25181
  completion: Promise.resolve(),
@@ -25051,8 +25287,8 @@ function after(callback) {
25051
25287
  throw new Error("after() cannot schedule work after the request lifecycle has completed.");
25052
25288
  }
25053
25289
  let start;
25054
- const ready = new Promise((resolve6) => {
25055
- start = resolve6;
25290
+ const ready = new Promise((resolve7) => {
25291
+ start = resolve7;
25056
25292
  });
25057
25293
  const result = ready.then(callback);
25058
25294
  state.tasks.push({ result, start });
@@ -25101,6 +25337,34 @@ function _withAfterNodeMiddleware(handler) {
25101
25337
  }
25102
25338
  __name(_withAfterNodeMiddleware, "_withAfterNodeMiddleware");
25103
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
+
25104
25368
  // src/vite.ts
25105
25369
  init_deployment();
25106
25370
  init_image_config();
@@ -25305,6 +25569,32 @@ __name(mergeFarmViteConfig, "mergeFarmViteConfig");
25305
25569
  // src/vite.ts
25306
25570
  init_fonts();
25307
25571
  init_server_http();
25572
+
25573
+ // src/theme/vite.ts
25574
+ init_config2();
25575
+ var FARM_DARK_VARIANT = '@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));';
25576
+ function createFarmThemeCssPlugin(input, basePath = "/") {
25577
+ const config = resolveFarmThemeConfig(input, basePath);
25578
+ return {
25579
+ name: "farm:theme-css",
25580
+ enforce: "pre",
25581
+ transform(code, id) {
25582
+ if (!config.enabled || !/\.css(?:\?.*)?$/.test(id) || !/@import\s+["']tailwindcss["']/.test(code) || /@custom-variant\s+dark\b/.test(code)) {
25583
+ return null;
25584
+ }
25585
+ return {
25586
+ code: `${code.trimEnd()}
25587
+
25588
+ ${FARM_DARK_VARIANT}
25589
+ `,
25590
+ map: null
25591
+ };
25592
+ }
25593
+ };
25594
+ }
25595
+ __name(createFarmThemeCssPlugin, "createFarmThemeCssPlugin");
25596
+
25597
+ // src/vite.ts
25308
25598
  var ALL_TYPE_ARTIFACTS = {
25309
25599
  routes: true,
25310
25600
  api: true,
@@ -25520,11 +25810,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
25520
25810
  }
25521
25811
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
25522
25812
  function fileContainsProgrammaticPageRoute(file) {
25523
- if (!fs7.existsSync(file)) {
25813
+ if (!fs8.existsSync(file)) {
25524
25814
  return false;
25525
25815
  }
25526
25816
  try {
25527
- return scanProgrammaticPagePaths(fs7.readFileSync(file, "utf8")).length > 0;
25817
+ return scanProgrammaticPagePaths(fs8.readFileSync(file, "utf8")).length > 0;
25528
25818
  } catch {
25529
25819
  return false;
25530
25820
  }
@@ -25532,7 +25822,7 @@ function fileContainsProgrammaticPageRoute(file) {
25532
25822
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
25533
25823
  function rewriteEarlySsrRelativeImports(options) {
25534
25824
  const cleanId = options.id.split("?", 1)[0];
25535
- if (!path25.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
25825
+ if (!path26.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
25536
25826
  return null;
25537
25827
  }
25538
25828
  const replacements = [];
@@ -25552,7 +25842,7 @@ function rewriteEarlySsrRelativeImports(options) {
25552
25842
  const suffixIndex = source.value.search(/[?#]/);
25553
25843
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
25554
25844
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
25555
- const resolvedPath = path25.resolve(path25.dirname(cleanId), sourcePath);
25845
+ const resolvedPath = path26.resolve(path26.dirname(cleanId), sourcePath);
25556
25846
  replacements.push({
25557
25847
  start: source.start,
25558
25848
  end: source.end,
@@ -25631,7 +25921,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25631
25921
  ...layerRoots.length ? {
25632
25922
  server: {
25633
25923
  fs: {
25634
- allow: [path25.resolve(options.root || process.cwd()), ...layerRoots]
25924
+ allow: [path26.resolve(options.root || process.cwd()), ...layerRoots]
25635
25925
  }
25636
25926
  }
25637
25927
  } : {}
@@ -25662,13 +25952,13 @@ function farmPlugin(options = {}, initialPluginManager) {
25662
25952
  },
25663
25953
  server
25664
25954
  );
25665
- const globalsCSSPath = path25.join(server.config.root, "src/app/globals.css");
25666
- if (!fs7.existsSync(globalsCSSPath)) {
25667
- const appDir = path25.join(server.config.root, "src/app");
25668
- if (!fs7.existsSync(appDir)) {
25669
- 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 });
25670
25960
  }
25671
- fs7.writeFileSync(globalsCSSPath, defaultGlobalCSS);
25961
+ fs8.writeFileSync(globalsCSSPath, defaultGlobalCSS);
25672
25962
  }
25673
25963
  await farmApp.initialize();
25674
25964
  const farmConfig = farmApp.getConfig();
@@ -25687,10 +25977,10 @@ function farmPlugin(options = {}, initialPluginManager) {
25687
25977
  });
25688
25978
  }
25689
25979
  const sourceRoots = getFarmSourceRoots(farmConfig);
25690
- 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)));
25691
25981
  if (farmConfig.i18n.enabled) {
25692
25982
  server.watcher.add(
25693
- 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
25694
25984
  );
25695
25985
  }
25696
25986
  const workflowConfig = farmConfig.workflows;
@@ -25700,7 +25990,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25700
25990
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
25701
25991
  ], "getExtraRouteTypes");
25702
25992
  const appDirSlugs = sourceRoots.map(
25703
- (source) => path25.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
25993
+ (source) => path26.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
25704
25994
  );
25705
25995
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
25706
25996
  try {
@@ -25740,7 +26030,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25740
26030
  }, "generateTypeArtifacts");
25741
26031
  await generateTypeArtifacts("startup");
25742
26032
  const srcDirSlugs = sourceRoots.map(
25743
- (source) => path25.join(source.root, source.srcDir).replace(/\\/g, "/")
26033
+ (source) => path26.join(source.root, source.srcDir).replace(/\\/g, "/")
25744
26034
  );
25745
26035
  const layerConfigFiles = new Set(
25746
26036
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -25858,7 +26148,7 @@ function farmPlugin(options = {}, initialPluginManager) {
25858
26148
  await apiRouteManager.discoverRoutes();
25859
26149
  let discoveredWorkflows = [];
25860
26150
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
25861
- (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))
25862
26152
  );
25863
26153
  if (hasWorkflowDirectory) {
25864
26154
  const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
@@ -26092,12 +26382,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
26092
26382
  }
26093
26383
  }
26094
26384
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
26095
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
26385
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs8.existsSync(farmDocsFontPath)) {
26096
26386
  res.statusCode = 200;
26097
26387
  res.setHeader("Content-Type", "font/woff2");
26098
26388
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
26099
26389
  if (requestMethod === "HEAD") res.end();
26100
- else fs7.createReadStream(farmDocsFontPath).pipe(res);
26390
+ else fs8.createReadStream(farmDocsFontPath).pipe(res);
26101
26391
  return;
26102
26392
  }
26103
26393
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -26195,7 +26485,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
26195
26485
  return null;
26196
26486
  }
26197
26487
  return {
26198
- source: await fs7.promises.readFile(sourcePath, "utf8"),
26488
+ source: await fs8.promises.readFile(sourcePath, "utf8"),
26199
26489
  filePath: sourcePath
26200
26490
  };
26201
26491
  }, "resolveSource")
@@ -26530,9 +26820,17 @@ window.__FARM_MANIFEST__ = ${inlineValue({
26530
26820
  res.end(JSON.stringify({ error: "API route not found", pathname: pathname2 }));
26531
26821
  return;
26532
26822
  }
26533
- if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules") || requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
26823
+ if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules")) {
26534
26824
  return next();
26535
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
+ }
26536
26834
  if (req.url?.startsWith("/__farm/page-data")) {
26537
26835
  const urlObj = new URL(req.url, `http://${req.headers.host || "localhost:3000"}`);
26538
26836
  const targetPath = urlObj.searchParams.get("path") || "/";
@@ -27238,8 +27536,8 @@ if (import.meta.hot) {
27238
27536
  }
27239
27537
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
27240
27538
  logger.info("Pre-rendering SSG pages...");
27241
- const outDir = path25.join(server?.config.root || process.cwd(), options.outDir || "dist");
27242
- 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");
27243
27541
  for (const page2 of ssgPages) {
27244
27542
  try {
27245
27543
  const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
@@ -27291,9 +27589,9 @@ if (import.meta.hot) {
27291
27589
  <script type="module" src="/assets/client.js"></script>
27292
27590
  </body>
27293
27591
  </html>`;
27294
- const outputPath = page2.urlPath === "/" ? path25.join(clientDir, "index.html") : path25.join(clientDir, page2.urlPath + ".html");
27295
- fs7.mkdirSync(path25.dirname(outputPath), { recursive: true });
27296
- 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);
27297
27595
  const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
27298
27596
  logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
27299
27597
  });
@@ -27301,8 +27599,8 @@ if (import.meta.hot) {
27301
27599
  logger.error(` \u2717 ${page2.urlPath}: ${error}`);
27302
27600
  }
27303
27601
  }
27304
- const manifestPath = path25.join(outDir, "__ssg_manifest.json");
27305
- fs7.writeFileSync(
27602
+ const manifestPath = path26.join(outDir, "__ssg_manifest.json");
27603
+ fs8.writeFileSync(
27306
27604
  manifestPath,
27307
27605
  JSON.stringify(
27308
27606
  ssgPages.map((p) => ({
@@ -27337,9 +27635,9 @@ if (import.meta.hot) {
27337
27635
  }
27338
27636
  const currentFarmConfig = farmApp?.getConfig();
27339
27637
  const normalizedFile = file.replace(/\\/g, "/");
27340
- 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;
27341
27639
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
27342
- logUpdate("PAGE", `updated ${path25.basename(file)}`);
27640
+ logUpdate("PAGE", `updated ${path26.basename(file)}`);
27343
27641
  for (const mod of modules) {
27344
27642
  server2.moduleGraph.invalidateModule(mod);
27345
27643
  }
@@ -28525,6 +28823,19 @@ async function tryHydrateImportedPage(
28525
28823
  const PageComponent = pageModule?.default;
28526
28824
  if (!PageComponent) return false;
28527
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
+
28528
28839
  currentPageComponent = PageComponent;
28529
28840
  currentPageProps = await buildRouteComponentProps(
28530
28841
  pageModule,
@@ -28691,14 +29002,22 @@ async function renderPage(pageData) {
28691
29002
  if (!doc.documentElement || !doc.body) return false;
28692
29003
 
28693
29004
  resetReactRoots();
29005
+ const activeFarmTheme =
29006
+ window.__FARM_THEME__?.snapshot?.resolvedTheme ||
29007
+ document.documentElement.getAttribute('data-theme');
28694
29008
  Array.from(document.documentElement.attributes).forEach(function(attr) {
29009
+ if (attr.name === 'data-theme') return;
28695
29010
  if (!doc.documentElement.hasAttribute(attr.name)) {
28696
29011
  document.documentElement.removeAttribute(attr.name);
28697
29012
  }
28698
29013
  });
28699
29014
  Array.from(doc.documentElement.attributes).forEach(function(attr) {
29015
+ if (attr.name === 'data-theme') return;
28700
29016
  document.documentElement.setAttribute(attr.name, attr.value);
28701
29017
  });
29018
+ if (activeFarmTheme) {
29019
+ document.documentElement.setAttribute('data-theme', activeFarmTheme);
29020
+ }
28702
29021
 
28703
29022
  document.head.innerHTML = doc.head ? doc.head.innerHTML : '';
28704
29023
  document.body.innerHTML = doc.body.innerHTML;
@@ -28707,6 +29026,7 @@ async function renderPage(pageData) {
28707
29026
 
28708
29027
  setTimeout(function() {
28709
29028
  Array.from(document.querySelectorAll('script')).forEach(function(script) {
29029
+ if (script.id === 'farm-theme-script') return;
28710
29030
  const freshScript = document.createElement('script');
28711
29031
  Array.from(script.attributes).forEach(function(attr) {
28712
29032
  freshScript.setAttribute(attr.name, attr.value);
@@ -29069,7 +29389,7 @@ function generateClientManifest(bundle) {
29069
29389
  __name(generateClientManifest, "generateClientManifest");
29070
29390
  async function defineConfig2(config = {}) {
29071
29391
  const tailwindcss = (await import("@tailwindcss/vite")).default;
29072
- const appRoot = path25.resolve(config.root || process.cwd());
29392
+ const appRoot = path26.resolve(config.root || process.cwd());
29073
29393
  if (config.extends?.length) {
29074
29394
  const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
29075
29395
  ({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
@@ -29204,6 +29524,7 @@ async function defineConfig2(config = {}) {
29204
29524
  };
29205
29525
  return {
29206
29526
  plugins: [
29527
+ createFarmThemeCssPlugin(config.theme, config.basePath),
29207
29528
  tailwindcss(),
29208
29529
  viteBrowserExternalPlugin,
29209
29530
  farmI18nClientBridgePlugin(),
@@ -29683,8 +30004,8 @@ function assertServerQueryKey(key) {
29683
30004
  __name(assertServerQueryKey, "assertServerQueryKey");
29684
30005
 
29685
30006
  // src/server/create-server.ts
29686
- var import_vite2 = require("vite");
29687
- init_config2();
30007
+ var import_vite3 = require("vite");
30008
+ init_config3();
29688
30009
 
29689
30010
  // src/plugin.ts
29690
30011
  init_env();
@@ -30639,19 +30960,19 @@ async function createServer(config = {}) {
30639
30960
  try {
30640
30961
  const tailwindcss = (await import("@tailwindcss/vite")).default;
30641
30962
  tailwindVitePlugin = tailwindcss();
30642
- logger.info("\u{1F4E6} Enabled built-in Tailwind support (@tailwindcss/vite)");
30643
30963
  } catch (error) {
30644
30964
  logger.warn(
30645
30965
  `Tailwind plugin auto-enable failed; continuing without it: ${error.message}`
30646
30966
  );
30647
30967
  }
30648
30968
  }
30649
- const server = await (0, import_vite2.createServer)(
30969
+ const server = await (0, import_vite3.createServer)(
30650
30970
  mergeFarmViteConfig(
30651
30971
  {
30652
30972
  root: projectRoot,
30653
30973
  css: shouldUseProjectPostcss ? void 0 : { postcss: { plugins: [] } },
30654
30974
  plugins: [
30975
+ createFarmThemeCssPlugin(finalConfig.theme, finalConfig.basePath),
30655
30976
  ...tailwindVitePlugin ? [tailwindVitePlugin] : [],
30656
30977
  createDevDependencyStubsPlugin(),
30657
30978
  farmI18nClientBridgePlugin(),
@@ -30862,6 +31183,8 @@ __name(assertFunction, "assertFunction");
30862
31183
  getServerActionInvalidations,
30863
31184
  getServerActionSignal,
30864
31185
  getStorage,
31186
+ getTheme,
31187
+ getThemeSnapshot,
30865
31188
  globFiles,
30866
31189
  initStorage,
30867
31190
  invalidate,