alepha 0.13.6 → 0.13.7

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 (134) hide show
  1. package/dist/api-audits/index.browser.js +116 -0
  2. package/dist/api-audits/index.browser.js.map +1 -0
  3. package/dist/api-audits/index.d.ts +1194 -0
  4. package/dist/api-audits/index.js +674 -0
  5. package/dist/api-audits/index.js.map +1 -0
  6. package/dist/api-notifications/index.d.ts +147 -147
  7. package/dist/api-parameters/index.browser.js +36 -5
  8. package/dist/api-parameters/index.browser.js.map +1 -1
  9. package/dist/api-parameters/index.d.ts +711 -33
  10. package/dist/api-parameters/index.js +831 -17
  11. package/dist/api-parameters/index.js.map +1 -1
  12. package/dist/api-users/index.d.ts +793 -780
  13. package/dist/api-users/index.js +699 -19
  14. package/dist/api-users/index.js.map +1 -1
  15. package/dist/api-verifications/index.js +2 -1
  16. package/dist/api-verifications/index.js.map +1 -1
  17. package/dist/bin/index.js +1 -0
  18. package/dist/bin/index.js.map +1 -1
  19. package/dist/cli/index.d.ts +85 -31
  20. package/dist/cli/index.js +205 -33
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/command/index.d.ts +67 -6
  23. package/dist/command/index.js +30 -3
  24. package/dist/command/index.js.map +1 -1
  25. package/dist/core/index.browser.js +241 -61
  26. package/dist/core/index.browser.js.map +1 -1
  27. package/dist/core/index.d.ts +170 -90
  28. package/dist/core/index.js +264 -67
  29. package/dist/core/index.js.map +1 -1
  30. package/dist/core/index.native.js +248 -65
  31. package/dist/core/index.native.js.map +1 -1
  32. package/dist/email/index.js +15 -10554
  33. package/dist/email/index.js.map +1 -1
  34. package/dist/logger/index.d.ts +4 -4
  35. package/dist/logger/index.js +77 -72
  36. package/dist/logger/index.js.map +1 -1
  37. package/dist/orm/index.d.ts +5 -1
  38. package/dist/orm/index.js +24 -7
  39. package/dist/orm/index.js.map +1 -1
  40. package/dist/queue/index.d.ts +4 -4
  41. package/dist/scheduler/index.d.ts +6 -6
  42. package/dist/server/index.d.ts +10 -1
  43. package/dist/server/index.js +20 -6
  44. package/dist/server/index.js.map +1 -1
  45. package/dist/server-auth/index.d.ts +163 -152
  46. package/dist/server-auth/index.js +40 -10
  47. package/dist/server-auth/index.js.map +1 -1
  48. package/dist/server-cookies/index.js +5 -1
  49. package/dist/server-cookies/index.js.map +1 -1
  50. package/dist/server-links/index.d.ts +33 -33
  51. package/dist/server-security/index.d.ts +9 -9
  52. package/dist/thread/index.js +2 -2
  53. package/dist/thread/index.js.map +1 -1
  54. package/dist/vite/index.d.ts +2 -2
  55. package/dist/vite/index.js +102 -45
  56. package/dist/vite/index.js.map +1 -1
  57. package/dist/websocket/index.browser.js +3 -3
  58. package/dist/websocket/index.browser.js.map +1 -1
  59. package/dist/websocket/index.js +4 -4
  60. package/dist/websocket/index.js.map +1 -1
  61. package/package.json +14 -9
  62. package/src/api-audits/controllers/AuditController.ts +186 -0
  63. package/src/api-audits/entities/audits.ts +132 -0
  64. package/src/api-audits/index.browser.ts +18 -0
  65. package/src/api-audits/index.ts +58 -0
  66. package/src/api-audits/primitives/$audit.ts +159 -0
  67. package/src/api-audits/schemas/auditQuerySchema.ts +23 -0
  68. package/src/api-audits/schemas/auditResourceSchema.ts +9 -0
  69. package/src/api-audits/schemas/createAuditSchema.ts +27 -0
  70. package/src/api-audits/services/AuditService.ts +412 -0
  71. package/src/api-parameters/controllers/ConfigController.ts +324 -0
  72. package/src/api-parameters/entities/parameters.ts +93 -10
  73. package/src/api-parameters/index.ts +43 -4
  74. package/src/api-parameters/primitives/$config.ts +291 -19
  75. package/src/api-parameters/schedulers/ConfigActivationScheduler.ts +30 -0
  76. package/src/api-parameters/services/ConfigStore.ts +491 -0
  77. package/src/api-users/atoms/realmAuthSettingsAtom.ts +19 -0
  78. package/src/api-users/controllers/UserRealmController.ts +0 -2
  79. package/src/api-users/index.ts +2 -0
  80. package/src/api-users/primitives/$userRealm.ts +18 -3
  81. package/src/api-users/providers/UserRealmProvider.ts +6 -3
  82. package/src/api-users/services/RegistrationService.ts +2 -1
  83. package/src/api-users/services/SessionService.ts +4 -0
  84. package/src/api-users/services/UserService.ts +3 -0
  85. package/src/api-verifications/index.ts +7 -1
  86. package/src/bin/index.ts +1 -0
  87. package/src/cli/assets/biomeJson.ts +1 -1
  88. package/src/cli/assets/dummySpecTs.ts +7 -0
  89. package/src/cli/assets/editorconfig.ts +13 -0
  90. package/src/cli/assets/mainTs.ts +14 -0
  91. package/src/cli/commands/BiomeCommands.ts +2 -0
  92. package/src/cli/commands/CoreCommands.ts +28 -9
  93. package/src/cli/commands/VerifyCommands.ts +2 -1
  94. package/src/cli/commands/ViteCommands.ts +8 -9
  95. package/src/cli/services/AlephaCliUtils.ts +214 -23
  96. package/src/command/helpers/Asker.ts +0 -1
  97. package/src/command/primitives/$command.ts +67 -0
  98. package/src/command/providers/CliProvider.ts +39 -8
  99. package/src/core/Alepha.ts +40 -30
  100. package/src/core/helpers/jsonSchemaToTypeBox.ts +307 -0
  101. package/src/core/index.shared.ts +1 -0
  102. package/src/core/index.ts +30 -3
  103. package/src/core/providers/EventManager.ts +1 -1
  104. package/src/core/providers/StateManager.ts +23 -12
  105. package/src/core/providers/TypeProvider.ts +26 -34
  106. package/src/logger/index.ts +8 -6
  107. package/src/logger/primitives/$logger.ts +1 -1
  108. package/src/logger/providers/{SimpleFormatterProvider.ts → PrettyFormatterProvider.ts} +10 -1
  109. package/src/orm/index.ts +6 -0
  110. package/src/orm/services/PgRelationManager.ts +2 -2
  111. package/src/orm/services/PostgresModelBuilder.ts +11 -7
  112. package/src/orm/services/Repository.ts +16 -7
  113. package/src/orm/services/SqliteModelBuilder.ts +10 -0
  114. package/src/server/index.ts +6 -0
  115. package/src/server/primitives/$action.ts +10 -1
  116. package/src/server/providers/ServerBodyParserProvider.ts +11 -5
  117. package/src/server/providers/ServerRouterProvider.ts +13 -7
  118. package/src/server-auth/primitives/$auth.ts +7 -0
  119. package/src/server-auth/providers/ServerAuthProvider.ts +51 -8
  120. package/src/server-cookies/index.ts +2 -1
  121. package/src/thread/primitives/$thread.ts +2 -2
  122. package/src/vite/index.ts +0 -2
  123. package/src/vite/tasks/buildServer.ts +3 -4
  124. package/src/vite/tasks/generateCloudflare.ts +35 -19
  125. package/src/vite/tasks/generateDocker.ts +18 -4
  126. package/src/vite/tasks/generateSitemap.ts +5 -7
  127. package/src/vite/tasks/generateVercel.ts +76 -41
  128. package/src/vite/tasks/runAlepha.ts +16 -1
  129. package/src/websocket/providers/NodeWebSocketServerProvider.ts +3 -11
  130. package/src/websocket/services/WebSocketClient.ts +3 -3
  131. package/dist/cli/dist-BlfFtOk2.js +0 -2770
  132. package/dist/cli/dist-BlfFtOk2.js.map +0 -1
  133. package/src/api-parameters/controllers/ParameterController.ts +0 -45
  134. package/src/api-parameters/services/ParameterStore.ts +0 -23
@@ -1,10 +1,9 @@
1
1
  import m, { createRequire } from "node:module";
2
- import { defineConfig } from "vite";
3
- import { access, cp, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
4
- import path, { dirname, join, resolve } from "node:path";
2
+ import { access, cp, mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
3
+ import path, { basename, dirname, join, resolve } from "node:path";
5
4
  import { AlephaError, OPTIONS } from "alepha";
6
5
  import { analyzer } from "vite-bundle-analyzer";
7
- import { existsSync, mkdirSync, promises, writeFileSync } from "node:fs";
6
+ import { promises } from "node:fs";
8
7
  import { promisify } from "node:util";
9
8
  import { brotliCompress, gzip } from "node:zlib";
10
9
  import { pathToFileURL } from "node:url";
@@ -317,6 +316,7 @@ async function buildServer(opts) {
317
316
  publicDir: false,
318
317
  ssr: { noExternal: true },
319
318
  build: {
319
+ sourcemap: true,
320
320
  ssr: opts.entry,
321
321
  outDir: `${opts.distDir}/server`,
322
322
  minify: true,
@@ -349,11 +349,10 @@ async function buildServer(opts) {
349
349
  });
350
350
  const entryFile = extractEntryFromBundle(opts.entry, result);
351
351
  let template = "";
352
- if (opts.clientDir) template = `process.env.REACT_SERVER_TEMPLATE ??= \`${(await readFile(`${opts.distDir}/${opts.clientDir}/index.html`, "utf-8")).replace(/>\s*</g, "><").trim()}\`;\n`;
352
+ if (opts.clientDir) template = `__alepha.set("alepha.react.server.template", \`${(await readFile(`${opts.distDir}/${opts.clientDir}/index.html`, "utf-8")).replace(/>\s*</g, "><").trim()}\`);\n`;
353
353
  await writeFile(`${opts.distDir}/index.js`, `// This file was automatically generated. DO NOT MODIFY.
354
354
  // Changes to this file will be lost when the code is regenerated.
355
- \nprocess.env.NODE_ENV ??= 'production';
356
- ${template}\nawait import('./server/${entryFile}');`.trim());
355
+ \nimport './server/${entryFile}';${template}`.trim());
357
356
  return { entryFile };
358
357
  }
359
358
  /**
@@ -420,32 +419,42 @@ const WARNING_COMMENT$1 = "// This file was automatically generated. DO NOT MODI
420
419
  * - worker.js entry point for Cloudflare Workers
421
420
  */
422
421
  async function generateCloudflare(opts = {}) {
423
- const dist = opts.distDir ?? "dist";
422
+ const distDir = opts.distDir ?? "dist";
424
423
  const root = process.cwd();
425
- const parts = root.split("/");
424
+ await writeWranglerConfig(root, distDir, basename(root));
425
+ await writeWorkerEntryPoint(root, distDir);
426
+ }
427
+ /**
428
+ * Write the wrangler.jsonc configuration file for Cloudflare Workers
429
+ */
430
+ async function writeWranglerConfig(root, distDir, name) {
426
431
  const wrangler = {
427
- name: parts[parts.length - 1],
428
- main: "./worker.js",
432
+ name,
433
+ main: "./main.cloudflare.js",
429
434
  compatibility_flags: ["nodejs_compat"],
430
435
  compatibility_date: "2025-11-17"
431
436
  };
432
- writeFileSync(join(root, dist, "wrangler.jsonc"), JSON.stringify(wrangler, null, 2));
437
+ await writeFile(join(root, distDir, "wrangler.jsonc"), JSON.stringify(wrangler, null, 2));
438
+ }
439
+ /**
440
+ * Write the worker entry point that bootstraps Alepha and handles fetch requests
441
+ */
442
+ async function writeWorkerEntryPoint(root, distDir) {
433
443
  const workerCode = `
434
- process.env.ALEPHA_SERVERLESS = "true";
435
-
436
- await import("./index.js");
444
+ import "./index.js";
437
445
 
438
446
  export default {
439
- fetch: async (request, env, ctx) => {
447
+ fetch: async (request) => {
448
+ const ctx = { req: request, res: undefined };
440
449
 
441
450
  await __alepha.start();
442
- const ev = { req: request, res: undefined };
443
- await __alepha.events.emit("web:request", ev);
444
- return ev.res;
451
+ await __alepha.events.emit("web:request", ctx);
452
+
453
+ return ctx.res;
445
454
  },
446
455
  };
447
456
  `.trim();
448
- writeFileSync(join(root, dist, "worker.js"), `${WARNING_COMMENT$1}\n${workerCode}`.trim());
457
+ await writeFile(join(root, distDir, "main.cloudflare.js"), `${WARNING_COMMENT$1}\n${workerCode}`.trim());
449
458
  }
450
459
 
451
460
  //#endregion
@@ -461,7 +470,19 @@ async function generateDocker(opts = {}) {
461
470
  const distDir = opts.distDir ?? "dist";
462
471
  const image = opts.image ?? "node:24-alpine";
463
472
  const command = opts.command ?? "node";
473
+ await copyDrizzleMigrations(distDir);
474
+ await writeDockerfile(distDir, image, command);
475
+ }
476
+ /**
477
+ * Copy drizzle migrations to the dist directory if they exist
478
+ */
479
+ async function copyDrizzleMigrations(distDir) {
464
480
  if (await fileExists("drizzle")) await cp("drizzle", `${distDir}/drizzle`, { recursive: true });
481
+ }
482
+ /**
483
+ * Write the Dockerfile with the specified base image and command
484
+ */
485
+ async function writeDockerfile(distDir, image, command) {
465
486
  const dockerfile = `# This file was automatically generated. DO NOT MODIFY.
466
487
  # Changes to this file will be lost when the code is regenerated.
467
488
  FROM ${image}
@@ -484,7 +505,8 @@ CMD ["${command}", "index.js"]
484
505
  * containing URLs for all accessible pages.
485
506
  */
486
507
  async function generateSitemap(opts) {
487
- const alepha = await importAlepha(opts.entry, { env: opts.template ? { REACT_SERVER_TEMPLATE: opts.template } : {} });
508
+ const alepha = await importAlepha(opts.entry);
509
+ if (opts.template) alepha.set("alepha.react.server.template", opts.template);
488
510
  if (!alepha.isConfigured()) {
489
511
  await alepha.events.emit("configure", alepha);
490
512
  alepha.configured = true;
@@ -541,17 +563,40 @@ async function generateVercel(opts = {}) {
541
563
  const clientDir = opts.clientDir ?? "public";
542
564
  const { loadEnv } = await importVite();
543
565
  const env = loadEnv("production", process.cwd(), "");
544
- if (!existsSync(`${distDir}/api`)) mkdirSync(`${distDir}/api`);
545
- writeFileSync(`${distDir}/api/index.js`, `${WARNING_COMMENT}
566
+ await writeApiEntryPoint(distDir);
567
+ await writeVercelConfig(distDir, clientDir, opts.config?.config);
568
+ const projectId = env.VERCEL_PROJECT_ID ?? opts.config?.projectId;
569
+ const projectName = env.VERCEL_PROJECT_NAME ?? opts.config?.projectName;
570
+ const orgId = env.VERCEL_ORG_ID ?? opts.config?.orgId;
571
+ if (projectId && orgId) await writeProjectConfig(distDir, projectId, projectName, orgId);
572
+ await ensureClientDir(distDir, clientDir);
573
+ }
574
+ /**
575
+ * Check if a file or directory exists at the given path
576
+ */
577
+ async function exists(path$1) {
578
+ return stat(path$1).then(() => true).catch(() => false);
579
+ }
580
+ /**
581
+ * Create the serverless function entry point that bootstraps Alepha and handles requests
582
+ */
583
+ async function writeApiEntryPoint(distDir) {
584
+ await mkdir(`${distDir}/api`, { recursive: true });
585
+ await writeFile(`${distDir}/api/index.js`, `${WARNING_COMMENT}
546
586
  import "../index.js";
547
587
 
548
- export default async function (req, res) {
588
+ export default async (req, res) => {
549
589
  \tawait __alepha.start();
550
- \t__alepha.events.emit("node:request", { req, res });
590
+ \tawait __alepha.events.emit("node:request", { req, res });
551
591
  }
552
592
  `);
553
- writeFileSync(`${distDir}/vercel.json`, JSON.stringify({
554
- ...opts?.config?.config,
593
+ }
594
+ /**
595
+ * Generate vercel.json with route rewrites to direct all traffic to the serverless function
596
+ */
597
+ async function writeVercelConfig(distDir, clientDir, config) {
598
+ await writeFile(`${distDir}/vercel.json`, JSON.stringify({
599
+ ...config,
555
600
  rewrites: [{
556
601
  source: "/(.*)",
557
602
  destination: "/api/index.js"
@@ -560,22 +605,26 @@ export default async function (req, res) {
560
605
  installCommand: "",
561
606
  outputDirectory: clientDir
562
607
  }, null, " "));
563
- const projectId = env.VERCEL_PROJECT_ID ?? opts.config?.projectId;
564
- const projectName = env.VERCEL_PROJECT_NAME ?? opts.config?.projectName;
565
- const orgId = env.VERCEL_ORG_ID ?? opts.config?.orgId;
566
- if (projectId && orgId) {
567
- try {
568
- mkdirSync(`${distDir}/.vercel`, { recursive: true });
569
- } catch (_e) {}
570
- writeFileSync(`${distDir}/.vercel/project.json`, JSON.stringify({
571
- projectId,
572
- projectName,
573
- orgId
574
- }, null, " "));
575
- }
576
- if (!existsSync(`${distDir}/${clientDir}`)) {
577
- mkdirSync(`${distDir}/${clientDir}`, { recursive: true });
578
- writeFileSync(`${distDir}/${clientDir}/.keep`, "");
608
+ }
609
+ /**
610
+ * Generate .vercel/project.json to link the deployment to a Vercel project
611
+ */
612
+ async function writeProjectConfig(distDir, projectId, projectName, orgId) {
613
+ await mkdir(`${distDir}/.vercel`, { recursive: true });
614
+ await writeFile(`${distDir}/.vercel/project.json`, JSON.stringify({
615
+ projectId,
616
+ projectName,
617
+ orgId
618
+ }, null, " "));
619
+ }
620
+ /**
621
+ * Create the client directory with a .keep file if it doesn't exist to avoid Vercel errors
622
+ */
623
+ async function ensureClientDir(distDir, clientDir) {
624
+ const path$1 = `${distDir}/${clientDir}`;
625
+ if (!await exists(path$1)) {
626
+ await mkdir(path$1, { recursive: true });
627
+ await writeFile(`${path$1}/.keep`, "");
579
628
  }
580
629
  }
581
630
 
@@ -681,6 +730,14 @@ var AlephaRunner = class {
681
730
  */
682
731
  async start(server) {
683
732
  const { loadEnv } = await importVite();
733
+ global.ssrFixStacktrace = (e) => {
734
+ server.ssrFixStacktrace(e);
735
+ let it = e;
736
+ do {
737
+ server.ssrFixStacktrace(it);
738
+ it = it.cause;
739
+ } while (it instanceof Error);
740
+ };
684
741
  if (this.state.started) {
685
742
  await this.restart(server, true);
686
743
  return;
@@ -703,7 +760,7 @@ var AlephaRunner = class {
703
760
  process.env.SERVER_PORT ??= String(server.config.server.port || "5173");
704
761
  try {
705
762
  const now = Date.now();
706
- await server.ssrLoadModule(fileUrl);
763
+ await server.ssrLoadModule(fileUrl, { fixStacktrace: true });
707
764
  this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);
708
765
  await new Promise((r) => setTimeout(r, 10));
709
766
  this.state.app = globalThis.__alepha;
@@ -1019,5 +1076,5 @@ function viteAlepha(options = {}) {
1019
1076
  */
1020
1077
 
1021
1078
  //#endregion
1022
- export { AlephaRunner, boot, buildClient, buildServer, compressFile, copyAssets, createAlephaRunner, createBufferedLogger, defineConfig, generateCloudflare, generateDocker, generateExternals, generateSitemap, generateVercel, isViteInternalPath, prerenderPages, viteAlepha, viteAlephaBuild, viteAlephaDev, viteCompress };
1079
+ export { AlephaRunner, boot, buildClient, buildServer, compressFile, copyAssets, createAlephaRunner, createBufferedLogger, generateCloudflare, generateDocker, generateExternals, generateSitemap, generateVercel, isViteInternalPath, prerenderPages, viteAlepha, viteAlephaBuild, viteAlephaDev, viteCompress };
1023
1080
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["path","match: RegExpExecArray | null","entries: BufferedLogEntry[]","path","_error","gzipCb","brotliCompress","brotliCompressCb","compressionTasks: Promise<void>[]","fs","gzip","plugins: any[]","compress: ViteCompressOptions | undefined","viteAnalyzer","viteBuildClientConfig: UserConfig","deps: Record<string, string>","plugins: any[]","viteAnalyzer","viteBuildServerConfig: UserConfig","result: vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[]","externals: string[]","WARNING_COMMENT","urls: string[]","path","it: any","path","rootConfig: UserConfig","plugins: (Plugin | Promise<Plugin>)[] & { [OPTIONS]?: any }"],"sources":["../../src/vite/helpers/boot.ts","../../src/vite/helpers/createBufferedLogger.ts","../../src/vite/helpers/fileExists.ts","../../src/vite/helpers/importVite.ts","../../src/vite/plugins/viteCompress.ts","../../src/vite/tasks/buildClient.ts","../../src/vite/tasks/generateExternals.ts","../../src/vite/tasks/buildServer.ts","../../src/vite/helpers/importAlepha.ts","../../src/vite/tasks/copyAssets.ts","../../src/vite/tasks/generateCloudflare.ts","../../src/vite/tasks/generateDocker.ts","../../src/vite/tasks/generateSitemap.ts","../../src/vite/tasks/generateVercel.ts","../../src/vite/tasks/prerenderPages.ts","../../src/vite/tasks/runAlepha.ts","../../src/vite/plugins/viteAlephaBuild.ts","../../src/vite/plugins/viteAlephaDev.ts","../../src/vite/plugins/viteAlepha.ts","../../src/vite/index.ts"],"sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AlephaError } from \"alepha\";\n\n/**\n * Remember:\n * At first, functions was inside alepha/vite package, but it's now used in alepha too.\n * For avoiding cli -> vite, all code moved here.\n */\n\n/**\n * Find browser/client entry file path.\n */\nconst getClientEntry = async (\n root = process.cwd(),\n): Promise<string | undefined> => {\n const indexPath = join(root, \"index.html\");\n try {\n const html = await readFile(indexPath, \"utf8\");\n return extractFirstModuleScriptSrc(html).replace(/\\\\/g, \"/\");\n } catch {\n return undefined;\n }\n};\n\n/**\n * Find server entry file path.\n */\nconst getServerEntry = async (\n root = process.cwd(),\n explicitEntry?: string,\n): Promise<string> => {\n if (explicitEntry) {\n const explicitPath = join(root, explicitEntry);\n try {\n await access(explicitPath);\n return explicitPath;\n } catch {\n throw new AlephaError(\n `Explicit server entry file \"${explicitEntry}\" not found.`,\n );\n }\n }\n\n const maybeEntry = [\n \"src/main.server.ts\",\n \"src/server-entry.ts\",\n \"src/main.server.tsx\",\n \"src/server-entry.tsx\",\n \"src/main.ts\",\n \"src/main.tsx\",\n ];\n\n for (const entry of maybeEntry) {\n try {\n const path = join(root, entry).replace(/\\\\/g, \"/\");\n await access(path);\n return path;\n } catch {\n // continue to next entry\n }\n }\n\n const clientEntry = await getClientEntry(root);\n if (clientEntry) {\n return clientEntry;\n }\n\n throw new AlephaError(\n `Could not find a server entry file. List of supported entry file: ${maybeEntry.join(\", \")}`,\n );\n};\n\n/**\n * Extract first module script src from HTML.\n */\nfunction extractFirstModuleScriptSrc(html: string): string {\n const scriptRegex = /<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi;\n let match: RegExpExecArray | null = scriptRegex.exec(html);\n\n while (match) {\n const tag = match[0];\n\n // Check for type=\"module\"\n if (/type=[\"']module[\"']/i.test(tag)) {\n // Extract the src value\n const srcMatch = tag.match(/\\bsrc=[\"']([^\"']+)[\"']/i);\n const entry = srcMatch?.[1];\n if (entry) {\n if (entry.startsWith(\"/\")) {\n return entry.substring(1); // Remove leading slash\n }\n return entry;\n }\n }\n\n match = scriptRegex.exec(html);\n }\n\n throw new AlephaError(`No module script found in the provided HTML.`);\n}\n\nexport const boot = {\n getClientEntry,\n getServerEntry,\n};\n","import type { Logger } from \"vite\";\n\ninterface BufferedLogEntry {\n level: \"info\" | \"warn\" | \"error\";\n msg: string;\n timestamp: Date;\n}\n\nexport interface BufferedLogger extends Logger {\n /**\n * Flush all buffered log messages to console.\n * Call this on build failure to show what happened.\n */\n flush(): void;\n\n /**\n * Get all buffered log entries.\n */\n getEntries(): BufferedLogEntry[];\n\n /**\n * Clear all buffered entries without printing.\n */\n clear(): void;\n}\n\n/**\n * Creates a Vite logger that buffers all messages instead of printing them.\n * Useful for silent builds that only show output on failure.\n *\n * @example\n * ```ts\n * const logger = createBufferedLogger();\n * try {\n * await viteBuild({ customLogger: logger, logLevel: 'info' });\n * } catch (error) {\n * logger.flush(); // Print all buffered logs\n * throw error;\n * }\n * ```\n */\nexport function createBufferedLogger(): BufferedLogger {\n const entries: BufferedLogEntry[] = [];\n const loggedErrors = new WeakSet<Error>();\n const warnedMessages = new Set<string>();\n let hasWarned = false;\n\n const logger: BufferedLogger = {\n get hasWarned() {\n return hasWarned;\n },\n\n info(msg: string) {\n entries.push({ level: \"info\", msg, timestamp: new Date() });\n },\n\n warn(msg: string) {\n hasWarned = true;\n entries.push({ level: \"warn\", msg, timestamp: new Date() });\n },\n\n warnOnce(msg: string) {\n if (warnedMessages.has(msg)) {\n return;\n }\n warnedMessages.add(msg);\n hasWarned = true;\n entries.push({ level: \"warn\", msg, timestamp: new Date() });\n },\n\n error(msg: string, options?: { error?: Error | null }) {\n if (options?.error) {\n loggedErrors.add(options.error);\n }\n entries.push({ level: \"error\", msg, timestamp: new Date() });\n },\n\n clearScreen() {\n // No-op in buffered mode - we don't clear anything\n },\n\n hasErrorLogged(error: Error): boolean {\n return loggedErrors.has(error);\n },\n\n flush() {\n for (const entry of entries) {\n const prefix =\n entry.level === \"error\"\n ? \"\\x1b[31m✖\\x1b[0m\"\n : entry.level === \"warn\"\n ? \"\\x1b[33m⚠\\x1b[0m\"\n : \"\\x1b[36mℹ\\x1b[0m\";\n console.log(`${prefix} ${entry.msg}`);\n }\n },\n\n getEntries() {\n return [...entries];\n },\n\n clear() {\n entries.length = 0;\n warnedMessages.clear();\n hasWarned = false;\n },\n };\n\n return logger;\n}\n","import { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport const fileExists = async (path: string): Promise<boolean> => {\n return await access(join(process.cwd(), path))\n .then(() => true)\n .catch(() => false);\n};\n","import { createRequire } from \"node:module\";\nimport type * as vite from \"vite\";\n\nexport const importVite = async (): Promise<typeof vite> => {\n try {\n return createRequire(import.meta.url)(\"rolldown-vite\");\n } catch (_error) {\n try {\n return createRequire(import.meta.url)(\"vite\");\n } catch (_error) {\n throw new Error(\n \"Vite is not installed. Please install it with `npm install vite`.\",\n );\n }\n }\n};\n","import { promises as fs } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport {\n type BrotliOptions,\n brotliCompress as brotliCompressCb,\n gzip as gzipCb,\n type ZlibOptions,\n} from \"node:zlib\";\nimport type { Plugin } from \"vite\";\n\nconst gzipCompress = promisify(gzipCb);\nconst brotliCompress = promisify(brotliCompressCb);\n\nexport interface ViteCompressOptions {\n /**\n * If true, the plugin will not compress the files.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * If true, the plugin will compress the files using brotli.\n * Can also be an object with brotli options.\n *\n * @default true\n */\n brotli?: boolean | BrotliOptions;\n\n /**\n * If true, the plugin will compress the files using gzip.\n * Can also be an object with gzip options.\n *\n * @default true\n */\n gzip?: boolean | ZlibOptions;\n\n /**\n * A filter to determine which files to compress.\n * Can be a RegExp or a function that returns true for files to compress.\n *\n * @default /\\.(js|mjs|cjs|css|wasm|svg|html)$/\n */\n filter?: RegExp | ((fileName: string) => boolean);\n}\n\nexport function viteCompress(options: ViteCompressOptions = {}): Plugin {\n const { disabled = false, filter = /\\.(js|mjs|cjs|css|wasm|svg)$/ } = options;\n\n return {\n name: \"compress\",\n apply: \"build\",\n async writeBundle(outputOptions, bundle) {\n if (disabled) {\n return;\n }\n\n const now = Date.now();\n\n const outputDir = outputOptions.dir || resolve(process.cwd(), \"dist\");\n\n const files = Object.keys(bundle)\n .filter((fileName) => {\n // [feature]: filter\n if (typeof filter === \"function\") {\n return filter(fileName);\n }\n return filter.test(fileName);\n })\n .map((fileName) => ({\n fileName,\n filePath: join(outputDir, fileName),\n }));\n\n // Compress each file\n const compressionTasks: Promise<void>[] = [];\n\n for (const { filePath } of files) {\n compressionTasks.push(compressFile(options, filePath));\n }\n\n // Wait for all compression tasks to complete\n await Promise.all(compressionTasks);\n\n this.info(\n `Compressed ${files.length} file${files.length > 1 ? \"s\" : \"\"} in ${Date.now() - now}ms.`,\n );\n },\n };\n}\n\nexport async function compressFile(\n options: ViteCompressOptions = {},\n filePath: string,\n) {\n const { brotli = true, gzip = true } = options;\n\n const compressionTasks: Promise<void>[] = [];\n\n const fileContentPromise = fs.readFile(filePath);\n\n if (gzip) {\n const gzipOptions =\n typeof gzip === \"object\"\n ? gzip\n : {\n level: 9, // default gzip compression level\n };\n compressionTasks.push(\n fileContentPromise.then(async (content) => {\n const compressed = await gzipCompress(content, gzipOptions);\n await fs.writeFile(`${filePath}.gz`, compressed);\n }),\n );\n }\n\n if (brotli) {\n const brotliOptions = typeof brotli === \"object\" ? brotli : {};\n compressionTasks.push(\n fileContentPromise.then(async (content) => {\n const compressed = await brotliCompress(content, brotliOptions);\n await fs.writeFile(`${filePath}.br`, compressed);\n }),\n );\n }\n\n await Promise.all(compressionTasks);\n}\n","import type { UserConfig } from \"vite\";\nimport { analyzer as viteAnalyzer } from \"vite-bundle-analyzer\";\nimport { createBufferedLogger } from \"../helpers/createBufferedLogger.ts\";\nimport { importVite } from \"../helpers/importVite.ts\";\nimport {\n type ViteCompressOptions,\n viteCompress,\n} from \"../plugins/viteCompress.ts\";\n\nexport interface BuildClientOptions {\n /**\n * Output directory for client build.\n */\n dist: string;\n\n /**\n * If true, precompress assets using gzip and brotli compression.\n *\n * @default false\n */\n precompress?: ViteCompressOptions | boolean;\n\n /**\n * If true, prerender all static routes found in the $pages directory.\n *\n * @default false\n */\n prerender?: boolean;\n\n /**\n * Build a sitemap.xml file based on the $pages routes.\n */\n sitemap?: {\n hostname: string;\n };\n\n /**\n * Override Vite config options.\n */\n config?: UserConfig;\n\n /**\n * If true, generate build stats report.\n */\n stats?: boolean;\n\n /**\n * If true, suppress build output. Logs are buffered and only shown on failure.\n *\n * @default false\n */\n silent?: boolean;\n}\n\n/**\n * Build client-side bundle with Vite.\n *\n * This task compiles the browser/client code for production,\n * including code splitting, minification, and optional compression.\n */\nexport async function buildClient(opts: BuildClientOptions): Promise<void> {\n const { build: viteBuild, mergeConfig } = await importVite();\n const plugins: any[] = [];\n\n const compress: ViteCompressOptions | undefined = opts.precompress\n ? typeof opts.precompress === \"object\"\n ? opts.precompress\n : {}\n : undefined;\n\n if (opts.stats) {\n plugins.push(\n viteAnalyzer({\n analyzerMode: \"static\",\n }),\n );\n }\n\n if (opts.precompress && compress) {\n plugins.push(viteCompress(compress));\n }\n\n // Create buffered logger for silent mode\n const logger = opts.silent ? createBufferedLogger() : undefined;\n\n const viteBuildClientConfig: UserConfig = {\n mode: \"production\",\n logLevel: opts.silent ? \"silent\" : undefined,\n define: {\n \"process.env.NODE_ENV\": '\"production\"',\n },\n publicDir: \"public\",\n build: {\n chunkSizeWarningLimit: 1000,\n outDir: opts.dist,\n rollupOptions: {\n output: {\n entryFileNames: \"entry.[hash].js\",\n chunkFileNames: \"chunk.[hash].js\",\n assetFileNames: \"asset.[hash][extname]\",\n },\n },\n },\n esbuild: { legalComments: \"none\" },\n customLogger: logger,\n plugins,\n };\n\n try {\n await viteBuild(mergeConfig(viteBuildClientConfig, opts.config ?? {}));\n } catch (error) {\n // Flush buffered logs on failure so user can see what happened\n logger?.flush();\n throw error;\n }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport m from \"node:module\";\nimport { join } from \"node:path\";\n\nexport interface GenerateExternalsOptions {\n /**\n * Output directory for package.json.\n */\n distDir: string;\n\n /**\n * List of external package names.\n */\n externals: string[];\n}\n\n/**\n * Generate minimal package.json with pinned external dependencies.\n *\n * This task creates a package.json in the dist directory containing\n * only the external dependencies needed at runtime, with their versions\n * pinned to the currently installed versions.\n */\nexport async function generateExternals(\n opts: GenerateExternalsOptions,\n): Promise<void> {\n const require = m.createRequire(import.meta.filename);\n const deps: Record<string, string> = {};\n\n for (const dep of opts.externals) {\n try {\n const requirePath = require.resolve(dep);\n const pkgPath = `${requirePath.split(`node_modules/${dep}`)[0]}node_modules/${dep}/package.json`;\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n deps[dep] = `^${pkg.version}`;\n } catch (_err) {\n console.warn(`[generateExternals] Cannot find '${dep}' in node_modules`);\n }\n }\n\n const minimalPkg = {\n type: \"module\",\n main: \"index.js\",\n dependencies: deps,\n };\n\n await mkdir(opts.distDir, { recursive: true });\n\n const target = join(opts.distDir, \"package.json\");\n await writeFile(target, JSON.stringify(minimalPkg, null, 2), \"utf-8\");\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AlephaError } from \"alepha\";\nimport type * as vite from \"vite\";\nimport type { UserConfig } from \"vite\";\nimport { analyzer as viteAnalyzer } from \"vite-bundle-analyzer\";\nimport { createBufferedLogger } from \"../helpers/createBufferedLogger.ts\";\nimport { importVite } from \"../helpers/importVite.ts\";\nimport { generateExternals } from \"./generateExternals.ts\";\n\nexport interface BuildServerOptions {\n /**\n * Path to the server entry file.\n */\n entry: string;\n\n /**\n * Output directory for server build.\n */\n distDir: string;\n\n /**\n * Optional client directory name (relative to distDir).\n * If provided, the client template will be embedded in the server output.\n */\n clientDir?: string;\n\n /**\n * Override Vite config options.\n */\n config?: UserConfig;\n\n /**\n * If true, generate build stats report.\n */\n stats?: boolean;\n\n /**\n * If true, suppress build output. Logs are buffered and only shown on failure.\n *\n * @default false\n */\n silent?: boolean;\n}\n\nexport interface BuildServerResult {\n /**\n * The filename of the built server entry (e.g., \"abc123.js\").\n */\n entryFile: string;\n}\n\n/**\n * Build server-side SSR bundle with Vite.\n *\n * This task compiles the server code for production,\n * generates the externals package.json, and creates\n * the dist/index.js entry wrapper.\n */\nexport async function buildServer(\n opts: BuildServerOptions,\n): Promise<BuildServerResult> {\n const { build: viteBuild, mergeConfig } = await importVite();\n const plugins: any[] = [];\n\n if (opts.stats) {\n plugins.push(\n viteAnalyzer({\n analyzerMode: \"static\",\n }),\n );\n }\n\n // Create buffered logger for silent mode\n const logger = opts.silent ? createBufferedLogger() : undefined;\n\n const viteBuildServerConfig: UserConfig = {\n mode: \"production\",\n logLevel: opts.silent ? \"silent\" : undefined,\n define: {\n \"process.env.NODE_ENV\": '\"production\"',\n },\n publicDir: false,\n ssr: {\n noExternal: true,\n },\n build: {\n ssr: opts.entry,\n outDir: `${opts.distDir}/server`,\n minify: true,\n chunkSizeWarningLimit: 10000,\n rollupOptions: {\n output: {\n entryFileNames: \"[hash].js\",\n chunkFileNames: \"[hash].js\",\n assetFileNames: \"[hash][extname]\",\n format: \"esm\",\n },\n },\n },\n esbuild: { legalComments: \"none\", keepNames: true },\n customLogger: logger,\n plugins,\n };\n\n let result: vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[];\n try {\n result = (await viteBuild(\n mergeConfig(viteBuildServerConfig, opts.config || {}),\n )) as vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[];\n } catch (error) {\n // Flush buffered logs on failure so user can see what happened\n logger?.flush();\n throw error;\n }\n\n // Extract resolved config to get externals\n const resolvedConfig = (result as any).resolvedConfig;\n const externals: string[] = resolvedConfig?.ssr?.external ?? [];\n\n // Generate package.json with externals\n await generateExternals({\n distDir: opts.distDir,\n externals,\n });\n\n const entryFile = extractEntryFromBundle(opts.entry, result);\n\n // Embed client template if client was built\n let template = \"\";\n if (opts.clientDir) {\n const index = await readFile(\n `${opts.distDir}/${opts.clientDir}/index.html`,\n \"utf-8\",\n );\n template = `process.env.REACT_SERVER_TEMPLATE ??= \\`${index.replace(/>\\s*</g, \"><\").trim()}\\`;\\n`;\n }\n\n const warning =\n \"// This file was automatically generated. DO NOT MODIFY.\" +\n \"\\n\" +\n \"// Changes to this file will be lost when the code is regenerated.\\n\";\n\n const forceProduction = \"process.env.NODE_ENV ??= 'production';\\n\";\n\n await writeFile(\n `${opts.distDir}/index.js`,\n `${warning}\\n${forceProduction}${template}\\nawait import('./server/${entryFile}');`.trim(),\n );\n\n return { entryFile };\n}\n\n/**\n * Extract entry filename from Vite build result.\n */\nfunction extractEntryFromBundle(\n entry: string,\n result:\n | vite.Rollup.RollupOutput\n | vite.Rollup.RollupOutput[]\n | vite.Rollup.RollupWatcher,\n): string {\n const entryFilePath = entry.startsWith(\"/\")\n ? entry\n : join(process.cwd(), entry);\n\n const rollupOutput = (\n Array.isArray(result) ? result[0] : result\n ) as vite.Rollup.RollupOutput;\n\n const entryFile = rollupOutput.output.find(\n (it) => \"facadeModuleId\" in it && it.facadeModuleId === entryFilePath,\n )?.fileName;\n\n if (!entryFile) {\n throw new AlephaError(\n `Could not find the entry file \"${entryFilePath}\" in the build output. Please check your entry file and try again.`,\n );\n }\n\n return entryFile;\n}\n","import { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { type Alepha, AlephaError } from \"alepha\";\nimport { importVite } from \"./importVite.ts\";\n\n/**\n * Import Alepha instance from a transpiled server entry file.\n */\nexport const importAlepha = async (\n entry: string,\n options?: {\n env: Record<string, string>;\n },\n): Promise<Alepha> => {\n if (global.__cli_alepha) {\n return global.__cli_alepha as Alepha;\n }\n\n const { loadEnv } = await importVite();\n\n const env = loadEnv(\"development\", process.cwd(), \"\");\n\n for (const key in env) {\n process.env[key] = env[key];\n }\n\n if (options?.env) {\n for (const key in options.env) {\n process.env[key] = options.env[key];\n }\n }\n\n process.env.ALEPHA_CLI_IMPORT = \"true\";\n process.env.LOG_LEVEL = \"error\";\n process.env.LOG_FORMAT = \"pretty\";\n process.env.NODE_ENV = \"production\";\n\n const entryFile = pathToFileURL(join(process.cwd(), entry)).href;\n const mod = await import(entryFile);\n\n // check if alepha is correctly exported\n if (mod.default) {\n return mod.default;\n }\n\n // else, try with global variable\n const alepha = global.__cli_alepha as Alepha | undefined;\n if (!alepha) {\n throw new AlephaError(\n \"Alepha instance not found. Ensure Alepha is initialized.\",\n );\n }\n\n return alepha;\n};\n","import { cp, mkdir } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { importAlepha } from \"../helpers/importAlepha.ts\";\n\nexport interface CopyAssetsOptions {\n /**\n * Entry point for the built Alepha application.\n */\n entry: string;\n\n /**\n * Output directory for copied assets.\n */\n distDir: string;\n}\n\n/**\n * Copy assets from Alepha packages to the build output directory.\n *\n * This task loads the built Alepha application, reads the\n * `alepha.build.assets` state to find packages with assets,\n * and copies their `/assets` directories to the build output.\n *\n * Used by modules like AlephaServerSwagger to distribute UI files.\n */\nexport async function copyAssets(opts: CopyAssetsOptions): Promise<void> {\n const root = process.cwd();\n const alepha = await importAlepha(opts.entry);\n const assets = alepha.store.get(\"alepha.build.assets\");\n\n if (!assets || assets.length === 0) {\n return;\n }\n\n const require = createRequire(join(root, opts.entry));\n const buildAssetsDir = join(root, `${opts.distDir}/assets`);\n await mkdir(buildAssetsDir).catch(() => null);\n\n for (const pkgName of assets ?? []) {\n const pkgDir = dirname(require.resolve(`${pkgName}/package.json`));\n const assetsPkgDir = resolve(pkgDir, \"assets\");\n await cp(assetsPkgDir, buildAssetsDir, { recursive: true });\n }\n}\n","import { writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface GenerateCloudflareOptions {\n /**\n * The directory where the build output is placed.\n *\n * @default \"dist\"\n */\n distDir?: string;\n}\n\nconst WARNING_COMMENT =\n \"// This file was automatically generated. DO NOT MODIFY.\\n\" +\n \"// Changes to this file will be lost when the code is regenerated.\\n\";\n\n/**\n * Generate Cloudflare Workers deployment configuration.\n *\n * This task creates:\n * - wrangler.jsonc with worker configuration\n * - worker.js entry point for Cloudflare Workers\n */\nexport async function generateCloudflare(\n opts: GenerateCloudflareOptions = {},\n): Promise<void> {\n const dist = opts.distDir ?? \"dist\";\n const root = process.cwd();\n\n // Get current directory name for worker name\n const parts = root.split(\"/\");\n const name = parts[parts.length - 1];\n\n const wrangler = {\n name: name,\n main: \"./worker.js\",\n compatibility_flags: [\"nodejs_compat\"],\n compatibility_date: \"2025-11-17\",\n };\n\n writeFileSync(\n join(root, dist, \"wrangler.jsonc\"),\n JSON.stringify(wrangler, null, 2),\n );\n\n const workerCode = `\nprocess.env.ALEPHA_SERVERLESS = \"true\";\n\nawait import(\"./index.js\");\n\nexport default {\n fetch: async (request, env, ctx) => {\n\n await __alepha.start();\n const ev = { req: request, res: undefined };\n await __alepha.events.emit(\"web:request\", ev);\n return ev.res;\n },\n};\n`.trim();\n\n writeFileSync(\n join(root, dist, \"worker.js\"),\n `${WARNING_COMMENT}\\n${workerCode}`.trim(),\n );\n}\n","import { cp, writeFile } from \"node:fs/promises\";\nimport { fileExists } from \"../helpers/fileExists.ts\";\n\nexport interface GenerateDockerOptions {\n /**\n * The directory where the build output is placed.\n *\n * @default \"dist\"\n */\n distDir?: string;\n\n /**\n * Docker image name to use in the Dockerfile.\n *\n * @default \"node:24-alpine\"\n */\n image?: string;\n\n /**\n * Command to run in the Docker container.\n *\n * @default \"node\"\n */\n command?: string;\n}\n\n/**\n * Generate Docker deployment configuration.\n *\n * This task creates:\n * - Dockerfile with configurable Node image\n * - Copies drizzle migrations if they exist\n */\nexport async function generateDocker(\n opts: GenerateDockerOptions = {},\n): Promise<void> {\n const distDir = opts.distDir ?? \"dist\";\n const image = opts.image ?? \"node:24-alpine\";\n const command = opts.command ?? \"node\";\n\n // Copy drizzle migrations if they exist\n const hasMigrations = await fileExists(\"drizzle\");\n if (hasMigrations) {\n await cp(\"drizzle\", `${distDir}/drizzle`, {\n recursive: true,\n });\n }\n\n const dockerfile = `# This file was automatically generated. DO NOT MODIFY.\n# Changes to this file will be lost when the code is regenerated.\nFROM ${image}\nWORKDIR /app\n\nCOPY . .\n\nCMD [\"${command}\", \"index.js\"]\n`;\n\n await writeFile(`${distDir}/Dockerfile`, dockerfile);\n}\n","import type { Alepha } from \"alepha\";\nimport { importAlepha } from \"../helpers/importAlepha.ts\";\n\nexport interface GenerateSitemapOptions {\n /**\n * Entry point for the built Alepha application.\n */\n entry: string;\n\n /**\n * Base URL for the sitemap (e.g., \"https://example.com\").\n */\n baseUrl: string;\n\n /**\n * Optional HTML template (for React SSR).\n */\n template?: string;\n}\n\n/**\n * Generate sitemap.xml from Alepha page primitives.\n *\n * This task loads the built Alepha application,\n * queries all page primitives, and generates a sitemap.xml\n * containing URLs for all accessible pages.\n */\nexport async function generateSitemap(\n opts: GenerateSitemapOptions,\n): Promise<string> {\n const alepha = await importAlepha(opts.entry, {\n env: opts.template\n ? {\n REACT_SERVER_TEMPLATE: opts.template,\n }\n : {},\n });\n\n if (!alepha.isConfigured()) {\n await alepha.events.emit(\"configure\", alepha);\n (alepha as any).configured = true;\n }\n\n return generateSitemapFromAlepha(alepha, opts.baseUrl);\n}\n\nfunction generateSitemapFromAlepha(alepha: Alepha, baseUrl: string): string {\n const pages = alepha.primitives(\"page\") as any[];\n const urls: string[] = [];\n\n for (const page of pages) {\n const options = page.options;\n\n // Skip pages with children (parent pages that can't be rendered directly)\n if (options.children) {\n continue;\n }\n\n // Only include static pages or pages without parameters\n if (!options.schema?.params) {\n // Simple page without parameters\n const path = options.path || \"\";\n const url = `${baseUrl.replace(/\\/$/, \"\")}${path === \"\" ? \"/\" : path}`;\n urls.push(url);\n } else if (\n options.static &&\n typeof options.static === \"object\" &&\n options.static.entries\n ) {\n // Static page with predefined entries\n for (const entry of options.static.entries) {\n const path = buildPathFromParams(\n options.path || \"\",\n entry.params || {},\n );\n const url = `${baseUrl.replace(/\\/$/, \"\")}${path}`;\n urls.push(url);\n }\n }\n }\n\n return buildSitemapXml(urls);\n}\n\nfunction buildPathFromParams(\n pathPattern: string,\n params: Record<string, any>,\n): string {\n let path = pathPattern;\n\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`:${key}`, String(value));\n }\n\n return path || \"/\";\n}\n\nfunction buildSitemapXml(urls: string[]): string {\n const lastMod = new Date().toISOString().split(\"T\")[0];\n const urlEntries = urls\n .map(\n (url) =>\n ` <url>\\n <loc>${escapeXml(url)}</loc>\\n\\t\\t<lastmod>${lastMod}</lastmod>\\n </url>`,\n )\n .join(\"\\n\");\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urlEntries}\n</urlset>`;\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { importVite } from \"../helpers/importVite.ts\";\n\nexport interface GenerateVercelOptions {\n /**\n * The directory where the build output is placed.\n *\n * @default \"dist\"\n */\n distDir?: string;\n\n /**\n * The name of the client directory.\n *\n * @default \"public\"\n */\n clientDir?: string;\n\n /**\n * Vercel configuration options.\n */\n config?: VercelConfig;\n}\n\nexport interface VercelConfig {\n projectName?: string;\n orgId?: string;\n projectId?: string;\n config?: Record<string, any> & {\n crons?: Array<{\n path: string;\n schedule: string;\n }>;\n };\n}\n\nconst WARNING_COMMENT =\n \"// This file was automatically generated. DO NOT MODIFY.\\n\" +\n \"// Changes to this file will be lost when the code is regenerated.\\n\";\n\n/**\n * Generate Vercel deployment configuration.\n *\n * This task creates:\n * - vercel.json with route rewrites\n * - api/index.js entry point for Vercel serverless function\n * - .vercel/project.json if VERCEL_PROJECT_ID and VERCEL_ORG_ID are set\n */\nexport async function generateVercel(\n opts: GenerateVercelOptions = {},\n): Promise<void> {\n const distDir = opts.distDir ?? \"dist\";\n const clientDir = opts.clientDir ?? \"public\";\n const { loadEnv } = await importVite();\n\n const env = loadEnv(\"production\", process.cwd(), \"\");\n\n // Ensure the api directory exists\n if (!existsSync(`${distDir}/api`)) {\n mkdirSync(`${distDir}/api`);\n }\n\n // Add the only one entry point for Vercel\n writeFileSync(\n `${distDir}/api/index.js`,\n `${WARNING_COMMENT}\nimport \"../index.js\";\n\nexport default async function (req, res) {\n\\tawait __alepha.start();\n\\t__alepha.events.emit(\"node:request\", { req, res });\n}\n`,\n );\n\n // Always generate a vercel.json file\n writeFileSync(\n `${distDir}/vercel.json`,\n JSON.stringify(\n {\n ...opts?.config?.config,\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/api/index.js\",\n },\n ],\n buildCommand: \"\",\n installCommand: \"\",\n outputDirectory: clientDir,\n },\n null,\n \" \",\n ),\n );\n\n // Generate .vercel/project.json if VERCEL_PROJECT_ID and VERCEL_ORG_ID are set\n const projectId = env.VERCEL_PROJECT_ID ?? opts.config?.projectId;\n const projectName = env.VERCEL_PROJECT_NAME ?? opts.config?.projectName;\n const orgId = env.VERCEL_ORG_ID ?? opts.config?.orgId;\n\n if (projectId && orgId) {\n try {\n mkdirSync(`${distDir}/.vercel`, { recursive: true });\n } catch (_e) {\n // Ignore error if directory already exists\n }\n\n writeFileSync(\n `${distDir}/.vercel/project.json`,\n JSON.stringify(\n {\n projectId,\n projectName,\n orgId,\n },\n null,\n \" \",\n ),\n );\n }\n\n // If /public does not exist, create an empty one to avoid Vercel errors\n if (!existsSync(`${distDir}/${clientDir}`)) {\n mkdirSync(`${distDir}/${clientDir}`, { recursive: true });\n writeFileSync(`${distDir}/${clientDir}/.keep`, \"\");\n }\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport type { Alepha } from \"alepha\";\nimport { importAlepha } from \"../helpers/importAlepha.ts\";\nimport {\n compressFile,\n type ViteCompressOptions,\n} from \"../plugins/viteCompress.ts\";\n\nexport interface PrerenderPagesOptions {\n /**\n * Entry point for the built Alepha application.\n */\n entry: string;\n\n /**\n * Client dist directory for output files.\n */\n dist: string;\n\n /**\n * Optional compression options.\n */\n compress?: ViteCompressOptions | boolean;\n}\n\nexport interface PrerenderPagesResult {\n /**\n * Number of pages pre-rendered.\n */\n count: number;\n}\n\n/**\n * Pre-render static pages defined in the Alepha application.\n *\n * This task loads the built Alepha application, queries all page\n * primitives with `static: true`, and generates static HTML files\n * for each page. Supports pages with parameterized routes via\n * `static.entries` configuration.\n */\nexport async function prerenderPages(\n opts: PrerenderPagesOptions,\n): Promise<PrerenderPagesResult> {\n const alepha = await importAlepha(opts.entry);\n\n const now = Date.now();\n\n if (!alepha.isConfigured()) {\n await alepha.events.emit(\"configure\", alepha);\n (alepha as any).configured = true;\n }\n\n return await prerenderFromAlepha(alepha, opts.dist, opts.compress);\n}\n\nasync function prerenderFromAlepha(\n alepha: Alepha,\n dist: string,\n compress?: ViteCompressOptions | boolean,\n): Promise<PrerenderPagesResult> {\n let count = 0;\n const pages = alepha.primitives(\"page\") as any[];\n\n for (const page of pages) {\n const options = page.options;\n\n if (options.children) {\n continue;\n }\n\n if (!options.static) {\n continue;\n }\n\n const config = typeof options.static === \"object\" ? options.static : {};\n\n if (!options.schema?.params) {\n count += 1;\n await renderFile(page, {}, dist, compress);\n continue;\n }\n\n if (config.entries) {\n for (const entry of config.entries) {\n count += 1;\n await renderFile(page, entry, dist, compress);\n }\n }\n }\n\n return { count };\n}\n\nasync function renderFile(\n page: any,\n options: any,\n dist: string,\n compress?: ViteCompressOptions | boolean,\n) {\n const { html, state } = await page.render({\n html: true,\n ...options,\n });\n\n const pathname = state.url.pathname;\n const filepath = `${dist}${pathname === \"/\" ? \"/index\" : pathname}.html`;\n\n await mkdir(filepath.substring(0, filepath.lastIndexOf(\"/\")), {\n recursive: true,\n });\n\n await writeFile(filepath, html);\n\n if (compress) {\n await compressFile(typeof compress === \"object\" ? compress : {}, filepath);\n }\n}\n","import path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { Alepha, State } from \"alepha\";\nimport type { ResolvedConfig, ViteDevServer } from \"vite\";\nimport { importVite } from \"../helpers/importVite.ts\";\n\nexport interface AlephaRunnerOptions {\n /**\n * Path to the server entry file.\n */\n entry: string;\n\n /**\n * Enable debug logging.\n */\n debug?: boolean;\n}\n\nexport interface AlephaRunnerState {\n root: string;\n started: boolean;\n app?: Alepha;\n config?: ResolvedConfig;\n lock?: PromiseWithResolvers<void>;\n log: (...msg: string[]) => void;\n entry: string;\n onReload?: () => void;\n}\n\n/**\n * Create an Alepha runner for development.\n *\n * The runner manages the lifecycle of an Alepha application during\n * Vite dev server operation, handling start/stop/restart and HMR.\n */\nexport function createAlephaRunner(opts: AlephaRunnerOptions): AlephaRunner {\n const state: AlephaRunnerState = {\n root: process.cwd().replace(/\\\\/g, \"/\"),\n started: false,\n log: opts.debug ? (...msg: string[]) => console.log(...msg) : () => {},\n entry: opts.entry,\n onReload: () => {},\n };\n\n return new AlephaRunner(state);\n}\n\nexport class AlephaRunner {\n protected state: AlephaRunnerState;\n\n constructor(state: AlephaRunnerState) {\n this.state = state;\n }\n\n /**\n * Set resolved Vite config.\n */\n setConfig(config: ResolvedConfig): void {\n this.state.config = config;\n }\n\n /**\n * Check if SSR is enabled for the running app.\n */\n isSsrEnabled(): boolean {\n if (!this.state.app) return false;\n return (\n (this.state.app.store.get(\"alepha.react.server.ssr\" as keyof State) as\n | boolean\n | undefined) ?? false\n );\n }\n\n /**\n * Check if app is started.\n */\n get isStarted(): boolean {\n return this.state.started;\n }\n\n /**\n * Get the running Alepha app instance.\n */\n get app(): Alepha | undefined {\n return this.state.app;\n }\n\n /**\n * Start the Alepha application.\n */\n async start(server: ViteDevServer): Promise<void> {\n const { loadEnv } = await importVite();\n\n if (this.state.started) {\n await this.restart(server, true);\n return;\n }\n\n if (!this.state.config) {\n this.state.log(\"[DEBUG] No config - skip starting\");\n return;\n }\n\n this.state.onReload?.();\n\n this.state.log(\"[DEBUG] Starting Alepha app...\");\n\n this.state.started = false;\n this.state.app = undefined;\n\n const serverEntryPath = path.resolve(\n this.state.config.root,\n this.state.entry,\n );\n const fileUrl = pathToFileURL(`${serverEntryPath}`).href;\n const env = loadEnv(\"development\", this.state.config.root, \"\");\n const before = { ...process.env };\n\n for (const key in env) {\n process.env[key] = env[key];\n }\n\n process.env.NODE_ENV ??= \"development\";\n process.env.VITE_ALEPHA_DEV = \"true\";\n process.env.SERVER_HOST ??=\n typeof server.config.server.host === \"string\"\n ? server.config.server.host\n : \"localhost\";\n process.env.SERVER_PORT ??= String(server.config.server.port || \"5173\");\n\n try {\n const now = Date.now();\n await server.ssrLoadModule(fileUrl);\n this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);\n await new Promise((r) => setTimeout(r, 10));\n\n this.state.app = (globalThis as any).__alepha;\n if (!this.state.app) {\n this.state.log(\"[DEBUG] No app found - skip starting\");\n return;\n }\n\n this.state.app.store.set(\"alepha.node.server\" as any, server.httpServer);\n\n await this.state.app.start();\n this.state.started = true;\n\n process.env = { ...before };\n\n this.state.log(\"[DEBUG] Starting Done!\");\n } catch (e) {\n if (e instanceof Error) {\n let it: any = e;\n do {\n server.ssrFixStacktrace(it);\n it = it.cause;\n } while (it instanceof Error);\n\n server.ssrFixStacktrace(e);\n if (e.cause instanceof Error) {\n server.ssrFixStacktrace(e.cause);\n }\n this.state.app?.log?.error(\"App failed to start:\", e);\n this.state.app?.log?.info(\"Waiting for changes to restart...\");\n }\n this.state.log(\"[DEBUG] Alepha app start error\");\n this.state.started = false;\n }\n }\n\n /**\n * Stop the Alepha application.\n */\n async stop(): Promise<void> {\n if (this.state.app?.stop && this.state.started) {\n this.state.log(\"[DEBUG] Stopping Alepha app...\");\n await this.state.app.stop();\n this.state.started = false;\n this.state.log(\"[DEBUG] Stopping Done!\");\n } else {\n this.state.log(\"[DEBUG] Alepha app not started - skip stop\");\n }\n }\n\n /**\n * Restart the Alepha application.\n *\n * @returns true if the restart was skipped due to locking\n */\n async restart(server: ViteDevServer, invalidate?: boolean): Promise<boolean> {\n if (this.state.lock) {\n this.state.log(\"[DEBUG] STILL LOCKING\");\n return true;\n }\n\n this.state.log(\"[DEBUG] LOCK RESTART\");\n this.state.lock = Promise.withResolvers();\n\n const now = Date.now();\n this.state.log(\"[DEBUG] RESTART\");\n await this.stop();\n this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);\n\n if (invalidate) {\n server.moduleGraph.invalidateAll();\n }\n\n await this.start(server);\n this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);\n\n setTimeout(() => {\n this.state.log(\"[DEBUG] UNLOCK RESTART\");\n this.state.lock?.resolve();\n this.state.lock = undefined;\n }, 500);\n\n return false;\n }\n\n /**\n * Send reload event to client.\n */\n sendReload(server: ViteDevServer): void {\n server.ws.send({\n type: \"custom\",\n event: \"alepha:reload\",\n data: {},\n });\n }\n}\n\n/**\n * Check if a URL path is a Vite internal file.\n */\nexport function isViteInternalPath(pathname: string): boolean {\n const [path] = pathname.split(\"?\");\n\n // Vite internal files\n if (\n path.startsWith(\"/@\") ||\n path.startsWith(\"/src\") ||\n path.includes(\"/node_modules/\")\n ) {\n return true;\n }\n\n return false;\n}\n","import { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport type { Plugin, UserConfig } from \"vite\";\nimport { boot } from \"../helpers/boot.ts\";\nimport { fileExists } from \"../helpers/fileExists.ts\";\nimport {\n type BuildClientOptions,\n buildClient,\n buildServer,\n copyAssets,\n type GenerateDockerOptions,\n generateCloudflare,\n generateDocker,\n generateSitemap,\n generateVercel,\n prerenderPages,\n type VercelConfig,\n} from \"../tasks/index.ts\";\n\nexport interface ViteAlephaBuildOptions {\n /**\n * Path to the entry file for the server build.\n * If empty, SSR build will be skipped.\n */\n serverEntry?: string | false;\n\n /**\n * Set false to skip the client build.\n * This is useful if you only want to build the server-side application.\n */\n client?: false | Partial<BuildClientOptions>;\n\n /**\n * If true, the build will be optimized for Vercel deployment.\n *\n * If `VERCEL_PROJECT_ID` and `VERCEL_ORG_ID` environment variables are set, .vercel will be generated with the correct configuration.\n *\n * @default false\n */\n vercel?: boolean | VercelConfig;\n\n /**\n * If true, the build will generate Cloudflare Workers configuration.\n *\n * @default false\n */\n cloudflare?: boolean;\n\n /**\n * If true, the build will be optimized for Docker deployment.\n * Additionally, it will generate a Dockerfile in the dist directory.\n */\n docker?: boolean | Omit<GenerateDockerOptions, \"distDir\">;\n\n /**\n * If true, build statistics will be printed after the build completes.\n */\n stats?: boolean;\n}\n\n/**\n * Build modes controlled by ALEPHA_BUILD_MODE environment variable:\n * - \"cli\": Skip plugin entirely, CLI handles all tasks\n * - \"client\": Only build client bundle\n * - \"server\": Only build server bundle\n * - undefined/other: Full build (default behavior)\n */\nexport type AlephaBuildMode = \"cli\" | \"client\" | \"server\";\n\n/**\n * Alepha build plugin for Vite.\n *\n * This plugin orchestrates the complete build process:\n * 1. Build client (if index.html exists)\n * 2. Build server (SSR)\n * 3. Copy assets from packages\n * 4. Pre-render static pages (if enabled)\n * 5. Generate sitemap (if enabled)\n * 6. Generate deployment config (Vercel/Cloudflare/Docker)\n *\n * Build mode can be controlled via ALEPHA_BUILD_MODE env var for CLI integration.\n */\nexport async function viteAlephaBuild(\n options: ViteAlephaBuildOptions = {},\n): Promise<Plugin> {\n const entry = options.serverEntry ?? (await boot.getServerEntry());\n const distDir = \"dist\";\n const clientDir = \"public\";\n\n let rootConfig: UserConfig = {};\n\n return {\n name: \"alepha-build\",\n apply: \"build\",\n config(config, ctx) {\n const buildMode = process.env.ALEPHA_BUILD_MODE as\n | AlephaBuildMode\n | undefined;\n\n // CLI mode: plugin does nothing, CLI handles everything\n if (buildMode === \"cli\") {\n return;\n }\n\n // For now, we run two separate builds: one for the client and one for the server\n // We distinguish them using an environment variable\n if (!process.env.VITE_DOUBLE_BUILD_DONE) {\n rootConfig = config;\n }\n\n if (ctx.isSsrBuild || !process.env.VITE_DOUBLE_BUILD_DONE) {\n // Server build, so we don't need the public directory\n config.publicDir = false;\n } else {\n // Client build, so we need the public directory\n config.publicDir = \"public\";\n }\n },\n async buildStart() {\n const buildMode = process.env.ALEPHA_BUILD_MODE as\n | AlephaBuildMode\n | undefined;\n\n // CLI mode: skip entirely\n if (buildMode === \"cli\") {\n return;\n }\n\n if (process.env.VITE_DOUBLE_BUILD_DONE === \"true\") {\n return;\n }\n\n process.env.VITE_DOUBLE_BUILD_DONE = \"true\";\n\n const hasClient =\n options.client !== false && (await fileExists(\"index.html\"));\n\n const buildClientOptions =\n typeof options.client === \"object\" ? options.client : {};\n\n const stats = options.stats ?? process.env.ALEPHA_BUILD_STATS === \"true\";\n\n // Client-only mode\n if (buildMode === \"client\") {\n if (hasClient) {\n await buildClient({\n ...buildClientOptions,\n config: rootConfig,\n dist: `${distDir}/${clientDir}`,\n stats,\n });\n }\n process.exit(0);\n }\n\n // Server-only mode\n if (buildMode === \"server\") {\n if (entry) {\n // Check if client was already built (template exists)\n let clientBuilt = false;\n try {\n await readFile(`${distDir}/${clientDir}/index.html`, \"utf-8\");\n clientBuilt = true;\n } catch {\n // No client build\n }\n\n await buildServer({\n config: {\n base: rootConfig.base || \"\",\n },\n entry,\n distDir,\n clientDir: clientBuilt ? clientDir : undefined,\n stats,\n });\n }\n process.exit(0);\n }\n\n // Full build mode (default)\n\n // Task 1: Build client\n if (hasClient) {\n await buildClient({\n ...buildClientOptions,\n config: rootConfig,\n dist: `${distDir}/${clientDir}`,\n stats,\n });\n }\n\n let template = \"\";\n if (hasClient) {\n // Load output index.html for template embedding\n template = await readFile(\n `${distDir}/${clientDir}/index.html`,\n \"utf-8\",\n );\n }\n\n // Task 2: Build server\n if (entry) {\n await buildServer({\n config: {\n base: rootConfig.base || \"\",\n },\n entry,\n distDir,\n clientDir: hasClient ? clientDir : undefined,\n stats,\n });\n\n // Server will handle index.html if both client & server are built\n if (hasClient && options.serverEntry !== false) {\n await unlink(`${distDir}/${clientDir}/index.html`);\n }\n\n // Task 3: Copy assets (swagger ui & others)\n await copyAssets({\n entry: `${distDir}/index.js`,\n distDir,\n });\n }\n\n // Task 4: Generate sitemap\n if (buildClientOptions.sitemap && entry) {\n await writeFile(\n `${distDir}/${clientDir}/sitemap.xml`,\n await generateSitemap({\n entry: `${distDir}/index.js`,\n baseUrl: buildClientOptions.sitemap.hostname,\n }),\n );\n }\n\n // Task 5: Pre-render static pages\n if (buildClientOptions.prerender && template) {\n await prerenderPages({\n dist: `${distDir}/${clientDir}`,\n entry: `${distDir}/index.js`,\n compress: buildClientOptions.precompress,\n });\n }\n\n // Task 6: Generate deployment configurations\n if (options.vercel) {\n const config =\n typeof options.vercel === \"boolean\" ? {} : options.vercel;\n await generateVercel({\n distDir,\n clientDir,\n config,\n });\n }\n\n if (options.cloudflare) {\n await generateCloudflare({\n distDir,\n });\n }\n\n if (options.docker) {\n const dockerOpts =\n typeof options.docker === \"boolean\" ? {} : options.docker;\n await generateDocker({\n distDir,\n ...dockerOpts,\n });\n }\n\n // Prevent the default build from running again\n process.exit(0);\n },\n };\n}\n","import type { Plugin, ResolvedConfig } from \"vite\";\nimport { boot } from \"../helpers/boot.ts\";\nimport { createAlephaRunner, isViteInternalPath } from \"../tasks/runAlepha.ts\";\n\nexport interface ViteAlephaDevOptions {\n /**\n * Path to the entry file for the server build.\n * If empty, plugin will be disabled.\n */\n serverEntry?: string | false;\n\n /**\n * If true, enables debug logging.\n *\n * @default false\n */\n debug?: boolean;\n}\n\n/**\n * Plug Alepha into Vite development server.\n *\n * This plugin manages the Alepha application lifecycle during development,\n * handling hot module replacement and request forwarding.\n */\nexport async function viteAlephaDev(\n options: ViteAlephaDevOptions = {},\n): Promise<Plugin> {\n let entry = options.serverEntry;\n if (!entry) {\n entry = await boot.getServerEntry();\n if (!entry) {\n return {\n name: \"alepha-dev\",\n apply: \"serve\",\n config() {},\n };\n }\n }\n\n const runner = createAlephaRunner({\n entry,\n debug: options.debug,\n });\n\n return {\n name: \"alepha-dev\",\n apply: \"serve\",\n configResolved(resolvedConfig: ResolvedConfig) {\n runner.setConfig(resolvedConfig);\n },\n async handleHotUpdate(ctx) {\n if (options.debug) {\n console.log(\"[DEBUG] HMR\", ctx.file);\n }\n\n if (ctx.file.includes(\"/.idea/\")) {\n return [];\n }\n\n const isServerOnly = !ctx.modules[0]?._clientModule;\n const isBrowserOnly = !ctx.modules[0]?._ssrModule;\n const isSsrEnabled = runner.isSsrEnabled();\n\n if (isBrowserOnly) {\n if (options.debug) {\n console.log(\n \"[DEBUG] HMR - browser only - no reason to reload server\",\n );\n }\n return;\n }\n\n const root = process.cwd().replace(/\\\\/g, \"/\");\n const invalidate = !ctx.file.startsWith(root);\n if (invalidate && options.debug) {\n console.log(\"[DEBUG] HMR - outside root - invalidate all\");\n }\n\n if (!isSsrEnabled && isServerOnly) {\n await runner.restart(ctx.server, invalidate);\n return [];\n }\n\n if (isSsrEnabled && ctx.modules[0]) {\n const skip = await runner.restart(ctx.server, invalidate);\n if (skip) {\n return [];\n }\n\n if (!runner.isStarted) {\n if (options.debug) {\n console.log(\"[DEBUG] HMR - abort due to app not started\");\n }\n return [];\n }\n\n if (isServerOnly && runner.isStarted) {\n runner.sendReload(ctx.server);\n return [];\n }\n }\n },\n async configureServer(server) {\n // Forward vite request to alepha server\n server.middlewares.use((req, res, next) => {\n if (\n runner.isStarted &&\n runner.app &&\n req.url &&\n !isViteInternalPath(req.url)\n ) {\n // Patch res.end to detect if alepha handled the request\n // If not, we call next() to let vite handle it (e.g. for static files)\n let ended = false;\n\n const writeHead = res.writeHead.bind(res);\n res.writeHead = (...args: any[]) => {\n ended = true;\n return writeHead(args[0], args[1], args[2]);\n };\n\n return runner.app.events\n .emit(\"node:request\" as any, { req, res })\n .then(() => {\n if (!ended) {\n next();\n }\n });\n }\n next();\n });\n\n server.config.logger.info = (msg: string) => {\n runner.app?.log?.info(msg.trim());\n };\n\n server.config.logger.clearScreen = () => {};\n\n await runner.start(server);\n },\n async closeBundle() {\n // Cleanup handled by runner\n },\n };\n}\n","import { createRequire } from \"node:module\";\nimport { OPTIONS } from \"alepha\";\nimport type { Plugin } from \"vite\";\nimport {\n type ViteAlephaBuildOptions,\n viteAlephaBuild,\n} from \"./viteAlephaBuild.ts\";\nimport { type ViteAlephaDevOptions, viteAlephaDev } from \"./viteAlephaDev.ts\";\n\nexport type ViteAlephaOptions = ViteAlephaDevOptions &\n ViteAlephaBuildOptions & {\n react?: false;\n };\n\nexport function viteAlepha(\n options: ViteAlephaOptions = {},\n): (Plugin | Promise<Plugin>)[] {\n if (process.env.NODE_ENV === \"test\") {\n return [];\n }\n\n const plugins: (Plugin | Promise<Plugin>)[] & { [OPTIONS]?: any } = [];\n\n if (options.react !== false) {\n try {\n const { default: viteReact } = createRequire(import.meta.url)(\n \"@vitejs/plugin-react\",\n );\n plugins.push(viteReact());\n } catch (e) {}\n }\n\n plugins.push(viteAlephaDev(options), viteAlephaBuild(options));\n plugins[OPTIONS] = options;\n\n return plugins;\n}\n","import type { Alepha } from \"alepha\";\n\n// Vite re-exports\nexport { defineConfig } from \"vite\";\n// Helpers (for advanced use)\nexport * from \"./helpers/boot.ts\";\nexport * from \"./helpers/createBufferedLogger.ts\";\n// Plugins (public API)\nexport * from \"./plugins/viteAlepha.ts\";\nexport * from \"./plugins/viteAlephaBuild.ts\";\nexport * from \"./plugins/viteAlephaDev.ts\";\nexport * from \"./plugins/viteCompress.ts\";\n// Tasks (for CLI integration)\nexport * from \"./tasks/index.ts\";\n\ndeclare global {\n var __cli_alepha: Alepha;\n}\n\n/**\n * Plugin vite for Alepha framework.\n *\n * This module provides Vite plugins and configurations to integrate Alepha applications with Vite's build and development processes.\n *\n * @example\n * ```ts\n * import { defineConfig } from \"vite\";\n * import { viteAlepha } from \"alepha/vite\";\n *\n * export default defineConfig({\n * plugins: [viteAlepha()],\n * // other Vite configurations...\n * });\n * ```\n *\n * @module alepha.vite\n */\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["path","match: RegExpExecArray | null","entries: BufferedLogEntry[]","path","_error","gzipCb","brotliCompress","brotliCompressCb","compressionTasks: Promise<void>[]","fs","gzip","plugins: any[]","compress: ViteCompressOptions | undefined","viteAnalyzer","viteBuildClientConfig: UserConfig","deps: Record<string, string>","plugins: any[]","viteAnalyzer","viteBuildServerConfig: UserConfig","result: vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[]","externals: string[]","WARNING_COMMENT","urls: string[]","path","path","it: any","path","rootConfig: UserConfig","plugins: (Plugin | Promise<Plugin>)[] & { [OPTIONS]?: any }"],"sources":["../../src/vite/helpers/boot.ts","../../src/vite/helpers/createBufferedLogger.ts","../../src/vite/helpers/fileExists.ts","../../src/vite/helpers/importVite.ts","../../src/vite/plugins/viteCompress.ts","../../src/vite/tasks/buildClient.ts","../../src/vite/tasks/generateExternals.ts","../../src/vite/tasks/buildServer.ts","../../src/vite/helpers/importAlepha.ts","../../src/vite/tasks/copyAssets.ts","../../src/vite/tasks/generateCloudflare.ts","../../src/vite/tasks/generateDocker.ts","../../src/vite/tasks/generateSitemap.ts","../../src/vite/tasks/generateVercel.ts","../../src/vite/tasks/prerenderPages.ts","../../src/vite/tasks/runAlepha.ts","../../src/vite/plugins/viteAlephaBuild.ts","../../src/vite/plugins/viteAlephaDev.ts","../../src/vite/plugins/viteAlepha.ts","../../src/vite/index.ts"],"sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AlephaError } from \"alepha\";\n\n/**\n * Remember:\n * At first, functions was inside alepha/vite package, but it's now used in alepha too.\n * For avoiding cli -> vite, all code moved here.\n */\n\n/**\n * Find browser/client entry file path.\n */\nconst getClientEntry = async (\n root = process.cwd(),\n): Promise<string | undefined> => {\n const indexPath = join(root, \"index.html\");\n try {\n const html = await readFile(indexPath, \"utf8\");\n return extractFirstModuleScriptSrc(html).replace(/\\\\/g, \"/\");\n } catch {\n return undefined;\n }\n};\n\n/**\n * Find server entry file path.\n */\nconst getServerEntry = async (\n root = process.cwd(),\n explicitEntry?: string,\n): Promise<string> => {\n if (explicitEntry) {\n const explicitPath = join(root, explicitEntry);\n try {\n await access(explicitPath);\n return explicitPath;\n } catch {\n throw new AlephaError(\n `Explicit server entry file \"${explicitEntry}\" not found.`,\n );\n }\n }\n\n const maybeEntry = [\n \"src/main.server.ts\",\n \"src/server-entry.ts\",\n \"src/main.server.tsx\",\n \"src/server-entry.tsx\",\n \"src/main.ts\",\n \"src/main.tsx\",\n ];\n\n for (const entry of maybeEntry) {\n try {\n const path = join(root, entry).replace(/\\\\/g, \"/\");\n await access(path);\n return path;\n } catch {\n // continue to next entry\n }\n }\n\n const clientEntry = await getClientEntry(root);\n if (clientEntry) {\n return clientEntry;\n }\n\n throw new AlephaError(\n `Could not find a server entry file. List of supported entry file: ${maybeEntry.join(\", \")}`,\n );\n};\n\n/**\n * Extract first module script src from HTML.\n */\nfunction extractFirstModuleScriptSrc(html: string): string {\n const scriptRegex = /<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi;\n let match: RegExpExecArray | null = scriptRegex.exec(html);\n\n while (match) {\n const tag = match[0];\n\n // Check for type=\"module\"\n if (/type=[\"']module[\"']/i.test(tag)) {\n // Extract the src value\n const srcMatch = tag.match(/\\bsrc=[\"']([^\"']+)[\"']/i);\n const entry = srcMatch?.[1];\n if (entry) {\n if (entry.startsWith(\"/\")) {\n return entry.substring(1); // Remove leading slash\n }\n return entry;\n }\n }\n\n match = scriptRegex.exec(html);\n }\n\n throw new AlephaError(`No module script found in the provided HTML.`);\n}\n\nexport const boot = {\n getClientEntry,\n getServerEntry,\n};\n","import type { Logger } from \"vite\";\n\ninterface BufferedLogEntry {\n level: \"info\" | \"warn\" | \"error\";\n msg: string;\n timestamp: Date;\n}\n\nexport interface BufferedLogger extends Logger {\n /**\n * Flush all buffered log messages to console.\n * Call this on build failure to show what happened.\n */\n flush(): void;\n\n /**\n * Get all buffered log entries.\n */\n getEntries(): BufferedLogEntry[];\n\n /**\n * Clear all buffered entries without printing.\n */\n clear(): void;\n}\n\n/**\n * Creates a Vite logger that buffers all messages instead of printing them.\n * Useful for silent builds that only show output on failure.\n *\n * @example\n * ```ts\n * const logger = createBufferedLogger();\n * try {\n * await viteBuild({ customLogger: logger, logLevel: 'info' });\n * } catch (error) {\n * logger.flush(); // Print all buffered logs\n * throw error;\n * }\n * ```\n */\nexport function createBufferedLogger(): BufferedLogger {\n const entries: BufferedLogEntry[] = [];\n const loggedErrors = new WeakSet<Error>();\n const warnedMessages = new Set<string>();\n let hasWarned = false;\n\n const logger: BufferedLogger = {\n get hasWarned() {\n return hasWarned;\n },\n\n info(msg: string) {\n entries.push({ level: \"info\", msg, timestamp: new Date() });\n },\n\n warn(msg: string) {\n hasWarned = true;\n entries.push({ level: \"warn\", msg, timestamp: new Date() });\n },\n\n warnOnce(msg: string) {\n if (warnedMessages.has(msg)) {\n return;\n }\n warnedMessages.add(msg);\n hasWarned = true;\n entries.push({ level: \"warn\", msg, timestamp: new Date() });\n },\n\n error(msg: string, options?: { error?: Error | null }) {\n if (options?.error) {\n loggedErrors.add(options.error);\n }\n entries.push({ level: \"error\", msg, timestamp: new Date() });\n },\n\n clearScreen() {\n // No-op in buffered mode - we don't clear anything\n },\n\n hasErrorLogged(error: Error): boolean {\n return loggedErrors.has(error);\n },\n\n flush() {\n for (const entry of entries) {\n const prefix =\n entry.level === \"error\"\n ? \"\\x1b[31m✖\\x1b[0m\"\n : entry.level === \"warn\"\n ? \"\\x1b[33m⚠\\x1b[0m\"\n : \"\\x1b[36mℹ\\x1b[0m\";\n console.log(`${prefix} ${entry.msg}`);\n }\n },\n\n getEntries() {\n return [...entries];\n },\n\n clear() {\n entries.length = 0;\n warnedMessages.clear();\n hasWarned = false;\n },\n };\n\n return logger;\n}\n","import { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport const fileExists = async (path: string): Promise<boolean> => {\n return await access(join(process.cwd(), path))\n .then(() => true)\n .catch(() => false);\n};\n","import { createRequire } from \"node:module\";\nimport type * as vite from \"vite\";\n\nexport const importVite = async (): Promise<typeof vite> => {\n try {\n return createRequire(import.meta.url)(\"rolldown-vite\");\n } catch (_error) {\n try {\n return createRequire(import.meta.url)(\"vite\");\n } catch (_error) {\n throw new Error(\n \"Vite is not installed. Please install it with `npm install vite`.\",\n );\n }\n }\n};\n","import { promises as fs } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport {\n type BrotliOptions,\n brotliCompress as brotliCompressCb,\n gzip as gzipCb,\n type ZlibOptions,\n} from \"node:zlib\";\nimport type { Plugin } from \"vite\";\n\nconst gzipCompress = promisify(gzipCb);\nconst brotliCompress = promisify(brotliCompressCb);\n\nexport interface ViteCompressOptions {\n /**\n * If true, the plugin will not compress the files.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * If true, the plugin will compress the files using brotli.\n * Can also be an object with brotli options.\n *\n * @default true\n */\n brotli?: boolean | BrotliOptions;\n\n /**\n * If true, the plugin will compress the files using gzip.\n * Can also be an object with gzip options.\n *\n * @default true\n */\n gzip?: boolean | ZlibOptions;\n\n /**\n * A filter to determine which files to compress.\n * Can be a RegExp or a function that returns true for files to compress.\n *\n * @default /\\.(js|mjs|cjs|css|wasm|svg|html)$/\n */\n filter?: RegExp | ((fileName: string) => boolean);\n}\n\nexport function viteCompress(options: ViteCompressOptions = {}): Plugin {\n const { disabled = false, filter = /\\.(js|mjs|cjs|css|wasm|svg)$/ } = options;\n\n return {\n name: \"compress\",\n apply: \"build\",\n async writeBundle(outputOptions, bundle) {\n if (disabled) {\n return;\n }\n\n const now = Date.now();\n\n const outputDir = outputOptions.dir || resolve(process.cwd(), \"dist\");\n\n const files = Object.keys(bundle)\n .filter((fileName) => {\n // [feature]: filter\n if (typeof filter === \"function\") {\n return filter(fileName);\n }\n return filter.test(fileName);\n })\n .map((fileName) => ({\n fileName,\n filePath: join(outputDir, fileName),\n }));\n\n // Compress each file\n const compressionTasks: Promise<void>[] = [];\n\n for (const { filePath } of files) {\n compressionTasks.push(compressFile(options, filePath));\n }\n\n // Wait for all compression tasks to complete\n await Promise.all(compressionTasks);\n\n this.info(\n `Compressed ${files.length} file${files.length > 1 ? \"s\" : \"\"} in ${Date.now() - now}ms.`,\n );\n },\n };\n}\n\nexport async function compressFile(\n options: ViteCompressOptions = {},\n filePath: string,\n) {\n const { brotli = true, gzip = true } = options;\n\n const compressionTasks: Promise<void>[] = [];\n\n const fileContentPromise = fs.readFile(filePath);\n\n if (gzip) {\n const gzipOptions =\n typeof gzip === \"object\"\n ? gzip\n : {\n level: 9, // default gzip compression level\n };\n compressionTasks.push(\n fileContentPromise.then(async (content) => {\n const compressed = await gzipCompress(content, gzipOptions);\n await fs.writeFile(`${filePath}.gz`, compressed);\n }),\n );\n }\n\n if (brotli) {\n const brotliOptions = typeof brotli === \"object\" ? brotli : {};\n compressionTasks.push(\n fileContentPromise.then(async (content) => {\n const compressed = await brotliCompress(content, brotliOptions);\n await fs.writeFile(`${filePath}.br`, compressed);\n }),\n );\n }\n\n await Promise.all(compressionTasks);\n}\n","import type { UserConfig } from \"vite\";\nimport { analyzer as viteAnalyzer } from \"vite-bundle-analyzer\";\nimport { createBufferedLogger } from \"../helpers/createBufferedLogger.ts\";\nimport { importVite } from \"../helpers/importVite.ts\";\nimport {\n type ViteCompressOptions,\n viteCompress,\n} from \"../plugins/viteCompress.ts\";\n\nexport interface BuildClientOptions {\n /**\n * Output directory for client build.\n */\n dist: string;\n\n /**\n * If true, precompress assets using gzip and brotli compression.\n *\n * @default false\n */\n precompress?: ViteCompressOptions | boolean;\n\n /**\n * If true, prerender all static routes found in the $pages directory.\n *\n * @default false\n */\n prerender?: boolean;\n\n /**\n * Build a sitemap.xml file based on the $pages routes.\n */\n sitemap?: {\n hostname: string;\n };\n\n /**\n * Override Vite config options.\n */\n config?: UserConfig;\n\n /**\n * If true, generate build stats report.\n */\n stats?: boolean;\n\n /**\n * If true, suppress build output. Logs are buffered and only shown on failure.\n *\n * @default false\n */\n silent?: boolean;\n}\n\n/**\n * Build client-side bundle with Vite.\n *\n * This task compiles the browser/client code for production,\n * including code splitting, minification, and optional compression.\n */\nexport async function buildClient(opts: BuildClientOptions): Promise<void> {\n const { build: viteBuild, mergeConfig } = await importVite();\n const plugins: any[] = [];\n\n const compress: ViteCompressOptions | undefined = opts.precompress\n ? typeof opts.precompress === \"object\"\n ? opts.precompress\n : {}\n : undefined;\n\n if (opts.stats) {\n plugins.push(\n viteAnalyzer({\n analyzerMode: \"static\",\n }),\n );\n }\n\n if (opts.precompress && compress) {\n plugins.push(viteCompress(compress));\n }\n\n // Create buffered logger for silent mode\n const logger = opts.silent ? createBufferedLogger() : undefined;\n\n const viteBuildClientConfig: UserConfig = {\n mode: \"production\",\n logLevel: opts.silent ? \"silent\" : undefined,\n define: {\n \"process.env.NODE_ENV\": '\"production\"',\n },\n publicDir: \"public\",\n build: {\n chunkSizeWarningLimit: 1000,\n outDir: opts.dist,\n rollupOptions: {\n output: {\n entryFileNames: \"entry.[hash].js\",\n chunkFileNames: \"chunk.[hash].js\",\n assetFileNames: \"asset.[hash][extname]\",\n },\n },\n },\n esbuild: { legalComments: \"none\" },\n customLogger: logger,\n plugins,\n };\n\n try {\n await viteBuild(mergeConfig(viteBuildClientConfig, opts.config ?? {}));\n } catch (error) {\n // Flush buffered logs on failure so user can see what happened\n logger?.flush();\n throw error;\n }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport m from \"node:module\";\nimport { join } from \"node:path\";\n\nexport interface GenerateExternalsOptions {\n /**\n * Output directory for package.json.\n */\n distDir: string;\n\n /**\n * List of external package names.\n */\n externals: string[];\n}\n\n/**\n * Generate minimal package.json with pinned external dependencies.\n *\n * This task creates a package.json in the dist directory containing\n * only the external dependencies needed at runtime, with their versions\n * pinned to the currently installed versions.\n */\nexport async function generateExternals(\n opts: GenerateExternalsOptions,\n): Promise<void> {\n const require = m.createRequire(import.meta.filename);\n const deps: Record<string, string> = {};\n\n for (const dep of opts.externals) {\n try {\n const requirePath = require.resolve(dep);\n const pkgPath = `${requirePath.split(`node_modules/${dep}`)[0]}node_modules/${dep}/package.json`;\n const pkg = JSON.parse(await readFile(pkgPath, \"utf-8\"));\n deps[dep] = `^${pkg.version}`;\n } catch (_err) {\n console.warn(`[generateExternals] Cannot find '${dep}' in node_modules`);\n }\n }\n\n const minimalPkg = {\n type: \"module\",\n main: \"index.js\",\n dependencies: deps,\n };\n\n await mkdir(opts.distDir, { recursive: true });\n\n const target = join(opts.distDir, \"package.json\");\n await writeFile(target, JSON.stringify(minimalPkg, null, 2), \"utf-8\");\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { AlephaError } from \"alepha\";\nimport type * as vite from \"vite\";\nimport type { UserConfig } from \"vite\";\nimport { analyzer as viteAnalyzer } from \"vite-bundle-analyzer\";\nimport { createBufferedLogger } from \"../helpers/createBufferedLogger.ts\";\nimport { importVite } from \"../helpers/importVite.ts\";\nimport { generateExternals } from \"./generateExternals.ts\";\n\nexport interface BuildServerOptions {\n /**\n * Path to the server entry file.\n */\n entry: string;\n\n /**\n * Output directory for server build.\n */\n distDir: string;\n\n /**\n * Optional client directory name (relative to distDir).\n * If provided, the client template will be embedded in the server output.\n */\n clientDir?: string;\n\n /**\n * Override Vite config options.\n */\n config?: UserConfig;\n\n /**\n * If true, generate build stats report.\n */\n stats?: boolean;\n\n /**\n * If true, suppress build output. Logs are buffered and only shown on failure.\n *\n * @default false\n */\n silent?: boolean;\n}\n\nexport interface BuildServerResult {\n /**\n * The filename of the built server entry (e.g., \"abc123.js\").\n */\n entryFile: string;\n}\n\n/**\n * Build server-side SSR bundle with Vite.\n *\n * This task compiles the server code for production,\n * generates the externals package.json, and creates\n * the dist/index.js entry wrapper.\n */\nexport async function buildServer(\n opts: BuildServerOptions,\n): Promise<BuildServerResult> {\n const { build: viteBuild, mergeConfig } = await importVite();\n const plugins: any[] = [];\n\n if (opts.stats) {\n plugins.push(\n viteAnalyzer({\n analyzerMode: \"static\",\n }),\n );\n }\n\n // Create buffered logger for silent mode\n const logger = opts.silent ? createBufferedLogger() : undefined;\n\n const viteBuildServerConfig: UserConfig = {\n mode: \"production\",\n logLevel: opts.silent ? \"silent\" : undefined,\n define: {\n \"process.env.NODE_ENV\": '\"production\"',\n },\n publicDir: false,\n ssr: {\n noExternal: true,\n },\n build: {\n sourcemap: true, // or \"hidden\" if you don't want to expose source maps\n ssr: opts.entry,\n outDir: `${opts.distDir}/server`,\n minify: true,\n chunkSizeWarningLimit: 10000,\n rollupOptions: {\n output: {\n entryFileNames: \"[hash].js\",\n chunkFileNames: \"[hash].js\",\n assetFileNames: \"[hash][extname]\",\n format: \"esm\",\n },\n },\n },\n esbuild: { legalComments: \"none\", keepNames: true },\n customLogger: logger,\n plugins,\n };\n\n let result: vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[];\n try {\n result = (await viteBuild(\n mergeConfig(viteBuildServerConfig, opts.config || {}),\n )) as vite.Rollup.RollupOutput | vite.Rollup.RollupOutput[];\n } catch (error) {\n // Flush buffered logs on failure so user can see what happened\n logger?.flush();\n throw error;\n }\n\n // Extract resolved config to get externals\n const resolvedConfig = (result as any).resolvedConfig;\n const externals: string[] = resolvedConfig?.ssr?.external ?? [];\n\n // Generate package.json with externals\n await generateExternals({\n distDir: opts.distDir,\n externals,\n });\n\n const entryFile = extractEntryFromBundle(opts.entry, result);\n\n // Embed client template if client was built\n let template = \"\";\n if (opts.clientDir) {\n const index = await readFile(\n `${opts.distDir}/${opts.clientDir}/index.html`,\n \"utf-8\",\n );\n template = `__alepha.set(\"alepha.react.server.template\", \\`${index.replace(/>\\s*</g, \"><\").trim()}\\`);\\n`;\n }\n\n const warning =\n \"// This file was automatically generated. DO NOT MODIFY.\" +\n \"\\n\" +\n \"// Changes to this file will be lost when the code is regenerated.\\n\";\n\n await writeFile(\n `${opts.distDir}/index.js`,\n `${warning}\\nimport './server/${entryFile}';${template}`.trim(),\n );\n\n return { entryFile };\n}\n\n/**\n * Extract entry filename from Vite build result.\n */\nfunction extractEntryFromBundle(\n entry: string,\n result:\n | vite.Rollup.RollupOutput\n | vite.Rollup.RollupOutput[]\n | vite.Rollup.RollupWatcher,\n): string {\n const entryFilePath = entry.startsWith(\"/\")\n ? entry\n : join(process.cwd(), entry);\n\n const rollupOutput = (\n Array.isArray(result) ? result[0] : result\n ) as vite.Rollup.RollupOutput;\n\n const entryFile = rollupOutput.output.find(\n (it) => \"facadeModuleId\" in it && it.facadeModuleId === entryFilePath,\n )?.fileName;\n\n if (!entryFile) {\n throw new AlephaError(\n `Could not find the entry file \"${entryFilePath}\" in the build output. Please check your entry file and try again.`,\n );\n }\n\n return entryFile;\n}\n","import { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { type Alepha, AlephaError } from \"alepha\";\nimport { importVite } from \"./importVite.ts\";\n\n/**\n * Import Alepha instance from a transpiled server entry file.\n */\nexport const importAlepha = async (\n entry: string,\n options?: {\n env: Record<string, string>;\n },\n): Promise<Alepha> => {\n if (global.__cli_alepha) {\n return global.__cli_alepha as Alepha;\n }\n\n const { loadEnv } = await importVite();\n\n const env = loadEnv(\"development\", process.cwd(), \"\");\n\n for (const key in env) {\n process.env[key] = env[key];\n }\n\n if (options?.env) {\n for (const key in options.env) {\n process.env[key] = options.env[key];\n }\n }\n\n process.env.ALEPHA_CLI_IMPORT = \"true\";\n process.env.LOG_LEVEL = \"error\";\n process.env.LOG_FORMAT = \"pretty\";\n process.env.NODE_ENV = \"production\";\n\n const entryFile = pathToFileURL(join(process.cwd(), entry)).href;\n const mod = await import(entryFile);\n\n // check if alepha is correctly exported\n if (mod.default) {\n return mod.default;\n }\n\n // else, try with global variable\n const alepha = global.__cli_alepha as Alepha | undefined;\n if (!alepha) {\n throw new AlephaError(\n \"Alepha instance not found. Ensure Alepha is initialized.\",\n );\n }\n\n return alepha;\n};\n","import { cp, mkdir } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { importAlepha } from \"../helpers/importAlepha.ts\";\n\nexport interface CopyAssetsOptions {\n /**\n * Entry point for the built Alepha application.\n */\n entry: string;\n\n /**\n * Output directory for copied assets.\n */\n distDir: string;\n}\n\n/**\n * Copy assets from Alepha packages to the build output directory.\n *\n * This task loads the built Alepha application, reads the\n * `alepha.build.assets` state to find packages with assets,\n * and copies their `/assets` directories to the build output.\n *\n * Used by modules like AlephaServerSwagger to distribute UI files.\n */\nexport async function copyAssets(opts: CopyAssetsOptions): Promise<void> {\n const root = process.cwd();\n const alepha = await importAlepha(opts.entry);\n const assets = alepha.store.get(\"alepha.build.assets\");\n\n if (!assets || assets.length === 0) {\n return;\n }\n\n const require = createRequire(join(root, opts.entry));\n const buildAssetsDir = join(root, `${opts.distDir}/assets`);\n await mkdir(buildAssetsDir).catch(() => null);\n\n for (const pkgName of assets ?? []) {\n const pkgDir = dirname(require.resolve(`${pkgName}/package.json`));\n const assetsPkgDir = resolve(pkgDir, \"assets\");\n await cp(assetsPkgDir, buildAssetsDir, { recursive: true });\n }\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\n\nexport interface GenerateCloudflareOptions {\n /**\n * The directory where the build output is placed.\n *\n * @default \"dist\"\n */\n distDir?: string;\n}\n\nconst WARNING_COMMENT =\n \"// This file was automatically generated. DO NOT MODIFY.\\n\" +\n \"// Changes to this file will be lost when the code is regenerated.\\n\";\n\n/**\n * Generate Cloudflare Workers deployment configuration.\n *\n * This task creates:\n * - wrangler.jsonc with worker configuration\n * - worker.js entry point for Cloudflare Workers\n */\nexport async function generateCloudflare(\n opts: GenerateCloudflareOptions = {},\n): Promise<void> {\n const distDir = opts.distDir ?? \"dist\";\n const root = process.cwd();\n const name = basename(root);\n\n await writeWranglerConfig(root, distDir, name);\n await writeWorkerEntryPoint(root, distDir);\n}\n\n/**\n * Write the wrangler.jsonc configuration file for Cloudflare Workers\n */\nasync function writeWranglerConfig(\n root: string,\n distDir: string,\n name: string,\n): Promise<void> {\n const wrangler = {\n name,\n main: \"./main.cloudflare.js\",\n compatibility_flags: [\"nodejs_compat\"],\n compatibility_date: \"2025-11-17\",\n };\n\n await writeFile(\n join(root, distDir, \"wrangler.jsonc\"),\n JSON.stringify(wrangler, null, 2),\n );\n}\n\n/**\n * Write the worker entry point that bootstraps Alepha and handles fetch requests\n */\nasync function writeWorkerEntryPoint(\n root: string,\n distDir: string,\n): Promise<void> {\n const workerCode = `\nimport \"./index.js\";\n\nexport default {\n fetch: async (request) => {\n const ctx = { req: request, res: undefined };\n\n await __alepha.start();\n await __alepha.events.emit(\"web:request\", ctx);\n\n return ctx.res;\n },\n};\n`.trim();\n\n await writeFile(\n join(root, distDir, \"main.cloudflare.js\"),\n `${WARNING_COMMENT}\\n${workerCode}`.trim(),\n );\n}\n","import { cp, writeFile } from \"node:fs/promises\";\nimport { fileExists } from \"../helpers/fileExists.ts\";\n\nexport interface GenerateDockerOptions {\n /**\n * The directory where the build output is placed.\n *\n * @default \"dist\"\n */\n distDir?: string;\n\n /**\n * Docker image name to use in the Dockerfile.\n *\n * @default \"node:24-alpine\"\n */\n image?: string;\n\n /**\n * Command to run in the Docker container.\n *\n * @default \"node\"\n */\n command?: string;\n}\n\n/**\n * Generate Docker deployment configuration.\n *\n * This task creates:\n * - Dockerfile with configurable Node image\n * - Copies drizzle migrations if they exist\n */\nexport async function generateDocker(\n opts: GenerateDockerOptions = {},\n): Promise<void> {\n const distDir = opts.distDir ?? \"dist\";\n const image = opts.image ?? \"node:24-alpine\";\n const command = opts.command ?? \"node\";\n\n await copyDrizzleMigrations(distDir);\n await writeDockerfile(distDir, image, command);\n}\n\n/**\n * Copy drizzle migrations to the dist directory if they exist\n */\nasync function copyDrizzleMigrations(distDir: string): Promise<void> {\n const hasMigrations = await fileExists(\"drizzle\");\n if (hasMigrations) {\n await cp(\"drizzle\", `${distDir}/drizzle`, { recursive: true });\n }\n}\n\n/**\n * Write the Dockerfile with the specified base image and command\n */\nasync function writeDockerfile(\n distDir: string,\n image: string,\n command: string,\n): Promise<void> {\n const dockerfile = `# This file was automatically generated. DO NOT MODIFY.\n# Changes to this file will be lost when the code is regenerated.\nFROM ${image}\nWORKDIR /app\n\nCOPY . .\n\nCMD [\"${command}\", \"index.js\"]\n`;\n\n await writeFile(`${distDir}/Dockerfile`, dockerfile);\n}\n","import type { Alepha } from \"alepha\";\nimport { importAlepha } from \"../helpers/importAlepha.ts\";\n\nexport interface GenerateSitemapOptions {\n /**\n * Entry point for the built Alepha application.\n */\n entry: string;\n\n /**\n * Base URL for the sitemap (e.g., \"https://example.com\").\n */\n baseUrl: string;\n\n /**\n * Optional HTML template (for React SSR).\n */\n template?: string;\n}\n\n/**\n * Generate sitemap.xml from Alepha page primitives.\n *\n * This task loads the built Alepha application,\n * queries all page primitives, and generates a sitemap.xml\n * containing URLs for all accessible pages.\n */\nexport async function generateSitemap(\n opts: GenerateSitemapOptions,\n): Promise<string> {\n const alepha = await importAlepha(opts.entry);\n\n if (opts.template) {\n alepha.set(\"alepha.react.server.template\", opts.template);\n }\n\n if (!alepha.isConfigured()) {\n await alepha.events.emit(\"configure\", alepha);\n (alepha as any).configured = true;\n }\n\n return generateSitemapFromAlepha(alepha, opts.baseUrl);\n}\n\nfunction generateSitemapFromAlepha(alepha: Alepha, baseUrl: string): string {\n const pages = alepha.primitives(\"page\") as any[];\n const urls: string[] = [];\n\n for (const page of pages) {\n const options = page.options;\n\n // Skip pages with children (parent pages that can't be rendered directly)\n if (options.children) {\n continue;\n }\n\n // Only include static pages or pages without parameters\n if (!options.schema?.params) {\n // Simple page without parameters\n const path = options.path || \"\";\n const url = `${baseUrl.replace(/\\/$/, \"\")}${path === \"\" ? \"/\" : path}`;\n urls.push(url);\n } else if (\n options.static &&\n typeof options.static === \"object\" &&\n options.static.entries\n ) {\n // Static page with predefined entries\n for (const entry of options.static.entries) {\n const path = buildPathFromParams(\n options.path || \"\",\n entry.params || {},\n );\n const url = `${baseUrl.replace(/\\/$/, \"\")}${path}`;\n urls.push(url);\n }\n }\n }\n\n return buildSitemapXml(urls);\n}\n\nfunction buildPathFromParams(\n pathPattern: string,\n params: Record<string, any>,\n): string {\n let path = pathPattern;\n\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`:${key}`, String(value));\n }\n\n return path || \"/\";\n}\n\nfunction buildSitemapXml(urls: string[]): string {\n const lastMod = new Date().toISOString().split(\"T\")[0];\n const urlEntries = urls\n .map(\n (url) =>\n ` <url>\\n <loc>${escapeXml(url)}</loc>\\n\\t\\t<lastmod>${lastMod}</lastmod>\\n </url>`,\n )\n .join(\"\\n\");\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urlEntries}\n</urlset>`;\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n","import { mkdir, stat, writeFile } from \"node:fs/promises\";\nimport { importVite } from \"../helpers/importVite.ts\";\n\nexport interface GenerateVercelOptions {\n /**\n * The directory where the build output is placed.\n *\n * @default \"dist\"\n */\n distDir?: string;\n\n /**\n * The name of the client directory.\n *\n * @default \"public\"\n */\n clientDir?: string;\n\n /**\n * Vercel configuration options.\n */\n config?: VercelConfig;\n}\n\nexport interface VercelConfig {\n projectName?: string;\n orgId?: string;\n projectId?: string;\n config?: Record<string, any> & {\n crons?: Array<{\n path: string;\n schedule: string;\n }>;\n };\n}\n\nconst WARNING_COMMENT =\n \"// This file was automatically generated. DO NOT MODIFY.\\n\" +\n \"// Changes to this file will be lost when the code is regenerated.\\n\";\n\n/**\n * Generate Vercel deployment configuration.\n *\n * This task creates:\n * - vercel.json with route rewrites\n * - api/index.js entry point for Vercel serverless function\n * - .vercel/project.json if VERCEL_PROJECT_ID and VERCEL_ORG_ID are set\n */\nexport async function generateVercel(\n opts: GenerateVercelOptions = {},\n): Promise<void> {\n const distDir = opts.distDir ?? \"dist\";\n const clientDir = opts.clientDir ?? \"public\";\n const { loadEnv } = await importVite();\n const env = loadEnv(\"production\", process.cwd(), \"\");\n\n await writeApiEntryPoint(distDir);\n await writeVercelConfig(distDir, clientDir, opts.config?.config);\n\n const projectId = env.VERCEL_PROJECT_ID ?? opts.config?.projectId;\n const projectName = env.VERCEL_PROJECT_NAME ?? opts.config?.projectName;\n const orgId = env.VERCEL_ORG_ID ?? opts.config?.orgId;\n\n if (projectId && orgId) {\n await writeProjectConfig(distDir, projectId, projectName, orgId);\n }\n\n await ensureClientDir(distDir, clientDir);\n}\n\n/**\n * Check if a file or directory exists at the given path\n */\nasync function exists(path: string): Promise<boolean> {\n return stat(path)\n .then(() => true)\n .catch(() => false);\n}\n\n/**\n * Create the serverless function entry point that bootstraps Alepha and handles requests\n */\nasync function writeApiEntryPoint(distDir: string): Promise<void> {\n await mkdir(`${distDir}/api`, { recursive: true });\n await writeFile(\n `${distDir}/api/index.js`,\n `${WARNING_COMMENT}\nimport \"../index.js\";\n\nexport default async (req, res) => {\n\\tawait __alepha.start();\n\\tawait __alepha.events.emit(\"node:request\", { req, res });\n}\n`,\n );\n}\n\n/**\n * Generate vercel.json with route rewrites to direct all traffic to the serverless function\n */\nasync function writeVercelConfig(\n distDir: string,\n clientDir: string,\n config?: VercelConfig[\"config\"],\n): Promise<void> {\n await writeFile(\n `${distDir}/vercel.json`,\n JSON.stringify(\n {\n ...config,\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/api/index.js\",\n },\n ],\n buildCommand: \"\",\n installCommand: \"\",\n outputDirectory: clientDir,\n },\n null,\n \" \",\n ),\n );\n}\n\n/**\n * Generate .vercel/project.json to link the deployment to a Vercel project\n */\nasync function writeProjectConfig(\n distDir: string,\n projectId: string,\n projectName: string | undefined,\n orgId: string,\n): Promise<void> {\n await mkdir(`${distDir}/.vercel`, { recursive: true });\n await writeFile(\n `${distDir}/.vercel/project.json`,\n JSON.stringify(\n {\n projectId,\n projectName,\n orgId,\n },\n null,\n \" \",\n ),\n );\n}\n\n/**\n * Create the client directory with a .keep file if it doesn't exist to avoid Vercel errors\n */\nasync function ensureClientDir(\n distDir: string,\n clientDir: string,\n): Promise<void> {\n const path = `${distDir}/${clientDir}`;\n if (!(await exists(path))) {\n await mkdir(path, { recursive: true });\n await writeFile(`${path}/.keep`, \"\");\n }\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport type { Alepha } from \"alepha\";\nimport { importAlepha } from \"../helpers/importAlepha.ts\";\nimport {\n compressFile,\n type ViteCompressOptions,\n} from \"../plugins/viteCompress.ts\";\n\nexport interface PrerenderPagesOptions {\n /**\n * Entry point for the built Alepha application.\n */\n entry: string;\n\n /**\n * Client dist directory for output files.\n */\n dist: string;\n\n /**\n * Optional compression options.\n */\n compress?: ViteCompressOptions | boolean;\n}\n\nexport interface PrerenderPagesResult {\n /**\n * Number of pages pre-rendered.\n */\n count: number;\n}\n\n/**\n * Pre-render static pages defined in the Alepha application.\n *\n * This task loads the built Alepha application, queries all page\n * primitives with `static: true`, and generates static HTML files\n * for each page. Supports pages with parameterized routes via\n * `static.entries` configuration.\n */\nexport async function prerenderPages(\n opts: PrerenderPagesOptions,\n): Promise<PrerenderPagesResult> {\n const alepha = await importAlepha(opts.entry);\n\n const now = Date.now();\n\n if (!alepha.isConfigured()) {\n await alepha.events.emit(\"configure\", alepha);\n (alepha as any).configured = true;\n }\n\n return await prerenderFromAlepha(alepha, opts.dist, opts.compress);\n}\n\nasync function prerenderFromAlepha(\n alepha: Alepha,\n dist: string,\n compress?: ViteCompressOptions | boolean,\n): Promise<PrerenderPagesResult> {\n let count = 0;\n const pages = alepha.primitives(\"page\") as any[];\n\n for (const page of pages) {\n const options = page.options;\n\n if (options.children) {\n continue;\n }\n\n if (!options.static) {\n continue;\n }\n\n const config = typeof options.static === \"object\" ? options.static : {};\n\n if (!options.schema?.params) {\n count += 1;\n await renderFile(page, {}, dist, compress);\n continue;\n }\n\n if (config.entries) {\n for (const entry of config.entries) {\n count += 1;\n await renderFile(page, entry, dist, compress);\n }\n }\n }\n\n return { count };\n}\n\nasync function renderFile(\n page: any,\n options: any,\n dist: string,\n compress?: ViteCompressOptions | boolean,\n) {\n const { html, state } = await page.render({\n html: true,\n ...options,\n });\n\n const pathname = state.url.pathname;\n const filepath = `${dist}${pathname === \"/\" ? \"/index\" : pathname}.html`;\n\n await mkdir(filepath.substring(0, filepath.lastIndexOf(\"/\")), {\n recursive: true,\n });\n\n await writeFile(filepath, html);\n\n if (compress) {\n await compressFile(typeof compress === \"object\" ? compress : {}, filepath);\n }\n}\n","import path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { Alepha, State } from \"alepha\";\nimport type { ResolvedConfig, ViteDevServer } from \"vite\";\nimport { importVite } from \"../helpers/importVite.ts\";\n\nexport interface AlephaRunnerOptions {\n /**\n * Path to the server entry file.\n */\n entry: string;\n\n /**\n * Enable debug logging.\n */\n debug?: boolean;\n}\n\nexport interface AlephaRunnerState {\n root: string;\n started: boolean;\n app?: Alepha;\n config?: ResolvedConfig;\n lock?: PromiseWithResolvers<void>;\n log: (...msg: string[]) => void;\n entry: string;\n onReload?: () => void;\n}\n\n/**\n * Create an Alepha runner for development.\n *\n * The runner manages the lifecycle of an Alepha application during\n * Vite dev server operation, handling start/stop/restart and HMR.\n */\nexport function createAlephaRunner(opts: AlephaRunnerOptions): AlephaRunner {\n const state: AlephaRunnerState = {\n root: process.cwd().replace(/\\\\/g, \"/\"),\n started: false,\n log: opts.debug ? (...msg: string[]) => console.log(...msg) : () => {},\n entry: opts.entry,\n onReload: () => {},\n };\n\n return new AlephaRunner(state);\n}\n\nexport class AlephaRunner {\n protected state: AlephaRunnerState;\n\n constructor(state: AlephaRunnerState) {\n this.state = state;\n }\n\n /**\n * Set resolved Vite config.\n */\n setConfig(config: ResolvedConfig): void {\n this.state.config = config;\n }\n\n /**\n * Check if SSR is enabled for the running app.\n */\n isSsrEnabled(): boolean {\n if (!this.state.app) return false;\n return (\n (this.state.app.store.get(\"alepha.react.server.ssr\" as keyof State) as\n | boolean\n | undefined) ?? false\n );\n }\n\n /**\n * Check if app is started.\n */\n get isStarted(): boolean {\n return this.state.started;\n }\n\n /**\n * Get the running Alepha app instance.\n */\n get app(): Alepha | undefined {\n return this.state.app;\n }\n\n /**\n * Start the Alepha application.\n */\n async start(server: ViteDevServer): Promise<void> {\n const { loadEnv } = await importVite();\n\n // unfortunately, vite SSR loader does not fix stack traces automatically\n // for now, we make a global helper and alepha/logger will use it before logging errors\n // that's not ideal but works for now\n (global as any).ssrFixStacktrace = (e: Error) => {\n server.ssrFixStacktrace(e);\n let it: any = e;\n do {\n server.ssrFixStacktrace(it);\n it = it.cause;\n } while (it instanceof Error);\n };\n\n if (this.state.started) {\n await this.restart(server, true);\n return;\n }\n\n if (!this.state.config) {\n this.state.log(\"[DEBUG] No config - skip starting\");\n return;\n }\n\n this.state.onReload?.();\n\n this.state.log(\"[DEBUG] Starting Alepha app...\");\n\n this.state.started = false;\n this.state.app = undefined;\n\n const serverEntryPath = path.resolve(\n this.state.config.root,\n this.state.entry,\n );\n const fileUrl = pathToFileURL(`${serverEntryPath}`).href;\n const env = loadEnv(\"development\", this.state.config.root, \"\");\n const before = { ...process.env };\n\n for (const key in env) {\n process.env[key] = env[key];\n }\n\n process.env.NODE_ENV ??= \"development\";\n process.env.VITE_ALEPHA_DEV = \"true\";\n process.env.SERVER_HOST ??=\n typeof server.config.server.host === \"string\"\n ? server.config.server.host\n : \"localhost\";\n process.env.SERVER_PORT ??= String(server.config.server.port || \"5173\");\n\n try {\n const now = Date.now();\n await server.ssrLoadModule(fileUrl, {\n fixStacktrace: true,\n });\n this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);\n await new Promise((r) => setTimeout(r, 10));\n\n this.state.app = (globalThis as any).__alepha;\n if (!this.state.app) {\n this.state.log(\"[DEBUG] No app found - skip starting\");\n return;\n }\n\n this.state.app.store.set(\"alepha.node.server\" as any, server.httpServer);\n\n await this.state.app.start();\n this.state.started = true;\n\n process.env = { ...before };\n\n this.state.log(\"[DEBUG] Starting Done!\");\n } catch (e) {\n if (e instanceof Error) {\n let it: any = e;\n do {\n server.ssrFixStacktrace(it);\n it = it.cause;\n } while (it instanceof Error);\n\n server.ssrFixStacktrace(e);\n if (e.cause instanceof Error) {\n server.ssrFixStacktrace(e.cause);\n }\n\n this.state.app?.log?.error(\"App failed to start:\", e);\n this.state.app?.log?.info(\"Waiting for changes to restart...\");\n }\n this.state.log(\"[DEBUG] Alepha app start error\");\n this.state.started = false;\n }\n }\n\n /**\n * Stop the Alepha application.\n */\n async stop(): Promise<void> {\n if (this.state.app?.stop && this.state.started) {\n this.state.log(\"[DEBUG] Stopping Alepha app...\");\n await this.state.app.stop();\n this.state.started = false;\n this.state.log(\"[DEBUG] Stopping Done!\");\n } else {\n this.state.log(\"[DEBUG] Alepha app not started - skip stop\");\n }\n }\n\n /**\n * Restart the Alepha application.\n *\n * @returns true if the restart was skipped due to locking\n */\n async restart(server: ViteDevServer, invalidate?: boolean): Promise<boolean> {\n if (this.state.lock) {\n this.state.log(\"[DEBUG] STILL LOCKING\");\n return true;\n }\n\n this.state.log(\"[DEBUG] LOCK RESTART\");\n this.state.lock = Promise.withResolvers();\n\n const now = Date.now();\n this.state.log(\"[DEBUG] RESTART\");\n await this.stop();\n this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);\n\n if (invalidate) {\n server.moduleGraph.invalidateAll();\n }\n\n await this.start(server);\n this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);\n\n setTimeout(() => {\n this.state.log(\"[DEBUG] UNLOCK RESTART\");\n this.state.lock?.resolve();\n this.state.lock = undefined;\n }, 500);\n\n return false;\n }\n\n /**\n * Send reload event to client.\n */\n sendReload(server: ViteDevServer): void {\n server.ws.send({\n type: \"custom\",\n event: \"alepha:reload\",\n data: {},\n });\n }\n}\n\n/**\n * Check if a URL path is a Vite internal file.\n */\nexport function isViteInternalPath(pathname: string): boolean {\n const [path] = pathname.split(\"?\");\n\n // Vite internal files\n if (\n path.startsWith(\"/@\") ||\n path.startsWith(\"/src\") ||\n path.includes(\"/node_modules/\")\n ) {\n return true;\n }\n\n return false;\n}\n","import { readFile, unlink, writeFile } from \"node:fs/promises\";\nimport type { Plugin, UserConfig } from \"vite\";\nimport { boot } from \"../helpers/boot.ts\";\nimport { fileExists } from \"../helpers/fileExists.ts\";\nimport {\n type BuildClientOptions,\n buildClient,\n buildServer,\n copyAssets,\n type GenerateDockerOptions,\n generateCloudflare,\n generateDocker,\n generateSitemap,\n generateVercel,\n prerenderPages,\n type VercelConfig,\n} from \"../tasks/index.ts\";\n\nexport interface ViteAlephaBuildOptions {\n /**\n * Path to the entry file for the server build.\n * If empty, SSR build will be skipped.\n */\n serverEntry?: string | false;\n\n /**\n * Set false to skip the client build.\n * This is useful if you only want to build the server-side application.\n */\n client?: false | Partial<BuildClientOptions>;\n\n /**\n * If true, the build will be optimized for Vercel deployment.\n *\n * If `VERCEL_PROJECT_ID` and `VERCEL_ORG_ID` environment variables are set, .vercel will be generated with the correct configuration.\n *\n * @default false\n */\n vercel?: boolean | VercelConfig;\n\n /**\n * If true, the build will generate Cloudflare Workers configuration.\n *\n * @default false\n */\n cloudflare?: boolean;\n\n /**\n * If true, the build will be optimized for Docker deployment.\n * Additionally, it will generate a Dockerfile in the dist directory.\n */\n docker?: boolean | Omit<GenerateDockerOptions, \"distDir\">;\n\n /**\n * If true, build statistics will be printed after the build completes.\n */\n stats?: boolean;\n}\n\n/**\n * Build modes controlled by ALEPHA_BUILD_MODE environment variable:\n * - \"cli\": Skip plugin entirely, CLI handles all tasks\n * - \"client\": Only build client bundle\n * - \"server\": Only build server bundle\n * - undefined/other: Full build (default behavior)\n */\nexport type AlephaBuildMode = \"cli\" | \"client\" | \"server\";\n\n/**\n * Alepha build plugin for Vite.\n *\n * This plugin orchestrates the complete build process:\n * 1. Build client (if index.html exists)\n * 2. Build server (SSR)\n * 3. Copy assets from packages\n * 4. Pre-render static pages (if enabled)\n * 5. Generate sitemap (if enabled)\n * 6. Generate deployment config (Vercel/Cloudflare/Docker)\n *\n * Build mode can be controlled via ALEPHA_BUILD_MODE env var for CLI integration.\n */\nexport async function viteAlephaBuild(\n options: ViteAlephaBuildOptions = {},\n): Promise<Plugin> {\n const entry = options.serverEntry ?? (await boot.getServerEntry());\n const distDir = \"dist\";\n const clientDir = \"public\";\n\n let rootConfig: UserConfig = {};\n\n return {\n name: \"alepha-build\",\n apply: \"build\",\n config(config, ctx) {\n const buildMode = process.env.ALEPHA_BUILD_MODE as\n | AlephaBuildMode\n | undefined;\n\n // CLI mode: plugin does nothing, CLI handles everything\n if (buildMode === \"cli\") {\n return;\n }\n\n // For now, we run two separate builds: one for the client and one for the server\n // We distinguish them using an environment variable\n if (!process.env.VITE_DOUBLE_BUILD_DONE) {\n rootConfig = config;\n }\n\n if (ctx.isSsrBuild || !process.env.VITE_DOUBLE_BUILD_DONE) {\n // Server build, so we don't need the public directory\n config.publicDir = false;\n } else {\n // Client build, so we need the public directory\n config.publicDir = \"public\";\n }\n },\n async buildStart() {\n const buildMode = process.env.ALEPHA_BUILD_MODE as\n | AlephaBuildMode\n | undefined;\n\n // CLI mode: skip entirely\n if (buildMode === \"cli\") {\n return;\n }\n\n if (process.env.VITE_DOUBLE_BUILD_DONE === \"true\") {\n return;\n }\n\n process.env.VITE_DOUBLE_BUILD_DONE = \"true\";\n\n const hasClient =\n options.client !== false && (await fileExists(\"index.html\"));\n\n const buildClientOptions =\n typeof options.client === \"object\" ? options.client : {};\n\n const stats = options.stats ?? process.env.ALEPHA_BUILD_STATS === \"true\";\n\n // Client-only mode\n if (buildMode === \"client\") {\n if (hasClient) {\n await buildClient({\n ...buildClientOptions,\n config: rootConfig,\n dist: `${distDir}/${clientDir}`,\n stats,\n });\n }\n process.exit(0);\n }\n\n // Server-only mode\n if (buildMode === \"server\") {\n if (entry) {\n // Check if client was already built (template exists)\n let clientBuilt = false;\n try {\n await readFile(`${distDir}/${clientDir}/index.html`, \"utf-8\");\n clientBuilt = true;\n } catch {\n // No client build\n }\n\n await buildServer({\n config: {\n base: rootConfig.base || \"\",\n },\n entry,\n distDir,\n clientDir: clientBuilt ? clientDir : undefined,\n stats,\n });\n }\n process.exit(0);\n }\n\n // Full build mode (default)\n\n // Task 1: Build client\n if (hasClient) {\n await buildClient({\n ...buildClientOptions,\n config: rootConfig,\n dist: `${distDir}/${clientDir}`,\n stats,\n });\n }\n\n let template = \"\";\n if (hasClient) {\n // Load output index.html for template embedding\n template = await readFile(\n `${distDir}/${clientDir}/index.html`,\n \"utf-8\",\n );\n }\n\n // Task 2: Build server\n if (entry) {\n await buildServer({\n config: {\n base: rootConfig.base || \"\",\n },\n entry,\n distDir,\n clientDir: hasClient ? clientDir : undefined,\n stats,\n });\n\n // Server will handle index.html if both client & server are built\n if (hasClient && options.serverEntry !== false) {\n await unlink(`${distDir}/${clientDir}/index.html`);\n }\n\n // Task 3: Copy assets (swagger ui & others)\n await copyAssets({\n entry: `${distDir}/index.js`,\n distDir,\n });\n }\n\n // Task 4: Generate sitemap\n if (buildClientOptions.sitemap && entry) {\n await writeFile(\n `${distDir}/${clientDir}/sitemap.xml`,\n await generateSitemap({\n entry: `${distDir}/index.js`,\n baseUrl: buildClientOptions.sitemap.hostname,\n }),\n );\n }\n\n // Task 5: Pre-render static pages\n if (buildClientOptions.prerender && template) {\n await prerenderPages({\n dist: `${distDir}/${clientDir}`,\n entry: `${distDir}/index.js`,\n compress: buildClientOptions.precompress,\n });\n }\n\n // Task 6: Generate deployment configurations\n if (options.vercel) {\n const config =\n typeof options.vercel === \"boolean\" ? {} : options.vercel;\n await generateVercel({\n distDir,\n clientDir,\n config,\n });\n }\n\n if (options.cloudflare) {\n await generateCloudflare({\n distDir,\n });\n }\n\n if (options.docker) {\n const dockerOpts =\n typeof options.docker === \"boolean\" ? {} : options.docker;\n await generateDocker({\n distDir,\n ...dockerOpts,\n });\n }\n\n // Prevent the default build from running again\n process.exit(0);\n },\n };\n}\n","import type { Plugin, ResolvedConfig } from \"vite\";\nimport { boot } from \"../helpers/boot.ts\";\nimport { createAlephaRunner, isViteInternalPath } from \"../tasks/runAlepha.ts\";\n\nexport interface ViteAlephaDevOptions {\n /**\n * Path to the entry file for the server build.\n * If empty, plugin will be disabled.\n */\n serverEntry?: string | false;\n\n /**\n * If true, enables debug logging.\n *\n * @default false\n */\n debug?: boolean;\n}\n\n/**\n * Plug Alepha into Vite development server.\n *\n * This plugin manages the Alepha application lifecycle during development,\n * handling hot module replacement and request forwarding.\n */\nexport async function viteAlephaDev(\n options: ViteAlephaDevOptions = {},\n): Promise<Plugin> {\n let entry = options.serverEntry;\n if (!entry) {\n entry = await boot.getServerEntry();\n if (!entry) {\n return {\n name: \"alepha-dev\",\n apply: \"serve\",\n config() {},\n };\n }\n }\n\n const runner = createAlephaRunner({\n entry,\n debug: options.debug,\n });\n\n return {\n name: \"alepha-dev\",\n apply: \"serve\",\n configResolved(resolvedConfig: ResolvedConfig) {\n runner.setConfig(resolvedConfig);\n },\n async handleHotUpdate(ctx) {\n if (options.debug) {\n console.log(\"[DEBUG] HMR\", ctx.file);\n }\n\n if (ctx.file.includes(\"/.idea/\")) {\n return [];\n }\n\n const isServerOnly = !ctx.modules[0]?._clientModule;\n const isBrowserOnly = !ctx.modules[0]?._ssrModule;\n const isSsrEnabled = runner.isSsrEnabled();\n\n if (isBrowserOnly) {\n if (options.debug) {\n console.log(\n \"[DEBUG] HMR - browser only - no reason to reload server\",\n );\n }\n return;\n }\n\n const root = process.cwd().replace(/\\\\/g, \"/\");\n const invalidate = !ctx.file.startsWith(root);\n if (invalidate && options.debug) {\n console.log(\"[DEBUG] HMR - outside root - invalidate all\");\n }\n\n if (!isSsrEnabled && isServerOnly) {\n await runner.restart(ctx.server, invalidate);\n return [];\n }\n\n if (isSsrEnabled && ctx.modules[0]) {\n const skip = await runner.restart(ctx.server, invalidate);\n if (skip) {\n return [];\n }\n\n if (!runner.isStarted) {\n if (options.debug) {\n console.log(\"[DEBUG] HMR - abort due to app not started\");\n }\n return [];\n }\n\n if (isServerOnly && runner.isStarted) {\n runner.sendReload(ctx.server);\n return [];\n }\n }\n },\n async configureServer(server) {\n // Forward vite request to alepha server\n server.middlewares.use((req, res, next) => {\n if (\n runner.isStarted &&\n runner.app &&\n req.url &&\n !isViteInternalPath(req.url)\n ) {\n // Patch res.end to detect if alepha handled the request\n // If not, we call next() to let vite handle it (e.g. for static files)\n let ended = false;\n\n const writeHead = res.writeHead.bind(res);\n res.writeHead = (...args: any[]) => {\n ended = true;\n return writeHead(args[0], args[1], args[2]);\n };\n\n return runner.app.events\n .emit(\"node:request\" as any, { req, res })\n .then(() => {\n if (!ended) {\n next();\n }\n });\n }\n next();\n });\n\n server.config.logger.info = (msg: string) => {\n runner.app?.log?.info(msg.trim());\n };\n\n server.config.logger.clearScreen = () => {};\n\n await runner.start(server);\n },\n async closeBundle() {\n // Cleanup handled by runner\n },\n };\n}\n","import { createRequire } from \"node:module\";\nimport { OPTIONS } from \"alepha\";\nimport type { Plugin } from \"vite\";\nimport {\n type ViteAlephaBuildOptions,\n viteAlephaBuild,\n} from \"./viteAlephaBuild.ts\";\nimport { type ViteAlephaDevOptions, viteAlephaDev } from \"./viteAlephaDev.ts\";\n\nexport type ViteAlephaOptions = ViteAlephaDevOptions &\n ViteAlephaBuildOptions & {\n react?: false;\n };\n\nexport function viteAlepha(\n options: ViteAlephaOptions = {},\n): (Plugin | Promise<Plugin>)[] {\n if (process.env.NODE_ENV === \"test\") {\n return [];\n }\n\n const plugins: (Plugin | Promise<Plugin>)[] & { [OPTIONS]?: any } = [];\n\n if (options.react !== false) {\n try {\n const { default: viteReact } = createRequire(import.meta.url)(\n \"@vitejs/plugin-react\",\n );\n plugins.push(viteReact());\n } catch (e) {}\n }\n\n plugins.push(viteAlephaDev(options), viteAlephaBuild(options));\n plugins[OPTIONS] = options;\n\n return plugins;\n}\n","import type { Alepha } from \"alepha\";\n\n// Helpers (for advanced use)\nexport * from \"./helpers/boot.ts\";\nexport * from \"./helpers/createBufferedLogger.ts\";\n// Plugins (public API)\nexport * from \"./plugins/viteAlepha.ts\";\nexport * from \"./plugins/viteAlephaBuild.ts\";\nexport * from \"./plugins/viteAlephaDev.ts\";\nexport * from \"./plugins/viteCompress.ts\";\n// Tasks (for CLI integration)\nexport * from \"./tasks/index.ts\";\n\ndeclare global {\n var __cli_alepha: Alepha;\n}\n\n/**\n * Plugin vite for Alepha framework.\n *\n * This module provides Vite plugins and configurations to integrate Alepha applications with Vite's build and development processes.\n *\n * @example\n * ```ts\n * import { defineConfig } from \"vite\";\n * import { viteAlepha } from \"alepha/vite\";\n *\n * export default defineConfig({\n * plugins: [viteAlepha()],\n * // other Vite configurations...\n * });\n * ```\n *\n * @module alepha.vite\n */\n"],"mappings":"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"}