alepha 0.14.3 → 0.14.4

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 (114) hide show
  1. package/README.md +1 -1
  2. package/dist/api/audits/index.d.ts +338 -417
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/files/index.d.ts +1 -80
  5. package/dist/api/files/index.d.ts.map +1 -1
  6. package/dist/api/jobs/index.d.ts +156 -235
  7. package/dist/api/jobs/index.d.ts.map +1 -1
  8. package/dist/api/notifications/index.d.ts +170 -249
  9. package/dist/api/notifications/index.d.ts.map +1 -1
  10. package/dist/api/parameters/index.d.ts +266 -345
  11. package/dist/api/parameters/index.d.ts.map +1 -1
  12. package/dist/api/users/index.d.ts +755 -834
  13. package/dist/api/users/index.d.ts.map +1 -1
  14. package/dist/api/verifications/index.d.ts +125 -125
  15. package/dist/api/verifications/index.d.ts.map +1 -1
  16. package/dist/cli/index.d.ts +116 -20
  17. package/dist/cli/index.d.ts.map +1 -1
  18. package/dist/cli/index.js +212 -124
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/command/index.d.ts +6 -11
  21. package/dist/command/index.d.ts.map +1 -1
  22. package/dist/command/index.js +2 -2
  23. package/dist/command/index.js.map +1 -1
  24. package/dist/core/index.browser.js +26 -4
  25. package/dist/core/index.browser.js.map +1 -1
  26. package/dist/core/index.d.ts +16 -1
  27. package/dist/core/index.d.ts.map +1 -1
  28. package/dist/core/index.js +26 -4
  29. package/dist/core/index.js.map +1 -1
  30. package/dist/core/index.native.js +26 -4
  31. package/dist/core/index.native.js.map +1 -1
  32. package/dist/logger/index.d.ts +1 -1
  33. package/dist/logger/index.d.ts.map +1 -1
  34. package/dist/logger/index.js +12 -2
  35. package/dist/logger/index.js.map +1 -1
  36. package/dist/mcp/index.d.ts.map +1 -1
  37. package/dist/mcp/index.js +1 -1
  38. package/dist/mcp/index.js.map +1 -1
  39. package/dist/orm/index.d.ts +37 -173
  40. package/dist/orm/index.d.ts.map +1 -1
  41. package/dist/orm/index.js +193 -422
  42. package/dist/orm/index.js.map +1 -1
  43. package/dist/server/auth/index.d.ts +167 -167
  44. package/dist/server/cache/index.d.ts +12 -0
  45. package/dist/server/cache/index.d.ts.map +1 -1
  46. package/dist/server/cache/index.js +55 -2
  47. package/dist/server/cache/index.js.map +1 -1
  48. package/dist/server/compress/index.d.ts +6 -0
  49. package/dist/server/compress/index.d.ts.map +1 -1
  50. package/dist/server/compress/index.js +36 -1
  51. package/dist/server/compress/index.js.map +1 -1
  52. package/dist/server/core/index.browser.js +2 -2
  53. package/dist/server/core/index.browser.js.map +1 -1
  54. package/dist/server/core/index.d.ts +10 -10
  55. package/dist/server/core/index.d.ts.map +1 -1
  56. package/dist/server/core/index.js +6 -3
  57. package/dist/server/core/index.js.map +1 -1
  58. package/dist/server/links/index.d.ts +39 -39
  59. package/dist/server/links/index.d.ts.map +1 -1
  60. package/dist/server/security/index.d.ts +9 -9
  61. package/dist/server/static/index.d.ts.map +1 -1
  62. package/dist/server/static/index.js +4 -0
  63. package/dist/server/static/index.js.map +1 -1
  64. package/dist/server/swagger/index.d.ts.map +1 -1
  65. package/dist/server/swagger/index.js +2 -3
  66. package/dist/server/swagger/index.js.map +1 -1
  67. package/dist/vite/index.d.ts +101 -106
  68. package/dist/vite/index.d.ts.map +1 -1
  69. package/dist/vite/index.js +571 -508
  70. package/dist/vite/index.js.map +1 -1
  71. package/package.json +1 -1
  72. package/src/cli/apps/AlephaCli.ts +0 -2
  73. package/src/cli/atoms/buildOptions.ts +88 -0
  74. package/src/cli/commands/build.ts +32 -69
  75. package/src/cli/commands/db.ts +0 -4
  76. package/src/cli/commands/dev.ts +16 -4
  77. package/src/cli/commands/gen/env.ts +53 -0
  78. package/src/cli/commands/gen/openapi.ts +1 -1
  79. package/src/cli/commands/gen/resource.ts +15 -0
  80. package/src/cli/commands/gen.ts +7 -1
  81. package/src/cli/commands/init.ts +0 -1
  82. package/src/cli/commands/test.ts +0 -1
  83. package/src/cli/commands/verify.ts +1 -1
  84. package/src/cli/defineConfig.ts +49 -7
  85. package/src/cli/index.ts +0 -1
  86. package/src/cli/services/AlephaCliUtils.ts +36 -25
  87. package/src/command/helpers/Runner.spec.ts +2 -2
  88. package/src/command/helpers/Runner.ts +1 -1
  89. package/src/command/primitives/$command.ts +0 -6
  90. package/src/command/providers/CliProvider.ts +1 -3
  91. package/src/core/Alepha.ts +42 -0
  92. package/src/logger/index.ts +15 -3
  93. package/src/mcp/transports/StdioMcpTransport.ts +1 -1
  94. package/src/orm/index.ts +2 -8
  95. package/src/queue/core/providers/WorkerProvider.spec.ts +48 -32
  96. package/src/server/cache/providers/ServerCacheProvider.spec.ts +183 -0
  97. package/src/server/cache/providers/ServerCacheProvider.ts +94 -9
  98. package/src/server/compress/providers/ServerCompressProvider.ts +61 -2
  99. package/src/server/core/helpers/ServerReply.ts +2 -2
  100. package/src/server/core/providers/ServerProvider.ts +11 -1
  101. package/src/server/static/providers/ServerStaticProvider.ts +10 -0
  102. package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -8
  103. package/src/vite/helpers/importViteReact.ts +13 -0
  104. package/src/vite/index.ts +1 -21
  105. package/src/vite/plugins/viteAlephaDev.ts +16 -1
  106. package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
  107. package/src/vite/tasks/buildClient.ts +11 -0
  108. package/src/vite/tasks/buildServer.ts +47 -3
  109. package/src/vite/tasks/devServer.ts +69 -0
  110. package/src/vite/tasks/index.ts +2 -1
  111. package/src/cli/assets/viteConfigTs.ts +0 -14
  112. package/src/cli/commands/run.ts +0 -24
  113. package/src/vite/plugins/viteAlepha.ts +0 -37
  114. package/src/vite/plugins/viteAlephaBuild.ts +0 -281
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["path","path","_error","gzipCb","brotliCompress","brotliCompressCb","fs","gzip","viteAnalyzer","viteAnalyzer","WARNING_COMMENT","name","path","path","path"],"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 external: [\"bun\"],\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}';\\n\\n${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 * @default process.cwd()\n */\n root?: string;\n\n /**\n * Add Runner for logging (@see Alepha CLI)\n */\n run?: (opts: {\n name: string;\n handler: () => Promise<void>;\n }) => Promise<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 = opts.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 fn = async () => {\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\n if (opts.run) {\n await opts.run({\n name: \"copy assets\",\n handler: fn,\n });\n } else {\n await fn();\n }\n}\n","import { access, 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 /**\n * Additional Wrangler configuration options to merge into wrangler.jsonc.\n */\n config?: WranglerConfig;\n}\n\nexport interface WranglerConfig {\n [key: string]: any;\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 const hasAssets = await access(join(root, distDir, \"public\"))\n .then(() => true)\n .catch(() => false);\n\n const wrangler: WranglerConfig = {\n name,\n main: \"./main.cloudflare.js\",\n compatibility_flags: [\"nodejs_compat\"],\n compatibility_date: \"2025-11-17\",\n ...opts.config,\n };\n\n if (hasAssets) {\n wrangler.assets ??= {\n directory: \"./public\",\n binding: \"ASSETS\",\n };\n }\n\n const url = process.env.DATABASE_URL;\n if (url?.startsWith(\"cloudflare-d1:\")) {\n const [name, id] = url\n .replace(\"cloudflare-d1://\", \"\")\n .replace(\"cloudflare-d1:\", \"\")\n .split(\":\");\n wrangler.d1_databases = wrangler.d1_databases || [];\n wrangler.d1_databases.push({\n binding: name,\n database_name: name,\n database_id: id,\n });\n wrangler.vars ??= {};\n wrangler.vars.DATABASE_URL = `cloudflare-d1://${name}:${id}`;\n }\n\n await writeFile(\n join(root, distDir, \"wrangler.jsonc\"),\n JSON.stringify(wrangler, null, 2),\n );\n\n await writeWorkerEntryPoint(root, distDir);\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, env) => {\n const ctx = { req: request, res: undefined };\n\n __alepha.set(\"cloudflare.env\", env);\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 let port = 5173;\n const address = server.httpServer?.address();\n if (typeof address === \"object\" && address?.port) {\n port = address.port;\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(port);\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 console.log(\"\");\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 { OPTIONS } from \"alepha\";\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 type WranglerConfig,\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 | WranglerConfig;\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 [OPTIONS as any]: options,\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 const config =\n typeof options.cloudflare === \"boolean\" ? {} : options.cloudflare;\n await generateCloudflare({\n distDir,\n config,\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 { IncomingMessage, ServerResponse } from \"node:http\";\nimport 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 const middleware = (\n req: IncomingMessage,\n res: ServerResponse,\n next: any,\n ) => {\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 // Forward vite request to alepha server\n server.middlewares.use((req, res, next) => {\n // TODO: wait if restarting ?\n middleware(req, res, next);\n });\n\n server.config.logger.info = (msg: string) => {\n console.log(msg);\n };\n\n server.config.logger.clearScreen = () => {};\n\n // Return a function - it runs AFTER internal middlewares are set up\n // and after buildStart has been called\n return () => {\n server.httpServer?.once(\"listening\", () => {\n runner.start(server);\n });\n };\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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"}
1
+ {"version":3,"file":"index.js","names":["path","_error","path","gzipCb","brotliCompress","brotliCompressCb","fs","gzip","viteAnalyzer","viteAnalyzer","path","WARNING_COMMENT","name","path","path","path"],"sources":["../../src/vite/helpers/boot.ts","../../src/vite/helpers/createBufferedLogger.ts","../../src/vite/helpers/importVite.ts","../../src/vite/tasks/runAlepha.ts","../../src/vite/plugins/viteAlephaDev.ts","../../src/vite/plugins/viteAlephaSsrPreload.ts","../../src/vite/plugins/viteCompress.ts","../../src/vite/helpers/importViteReact.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/devServer.ts","../../src/vite/tasks/generateCloudflare.ts","../../src/vite/helpers/fileExists.ts","../../src/vite/tasks/generateDocker.ts","../../src/vite/tasks/generateSitemap.ts","../../src/vite/tasks/generateVercel.ts","../../src/vite/tasks/prerenderPages.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 { 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 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 let port = 5173;\n const address = server.httpServer?.address();\n if (typeof address === \"object\" && address?.port) {\n port = address.port;\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(port);\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 console.log(\"\");\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 type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { Plugin, ResolvedConfig, UserConfig } from \"vite\";\nimport { boot } from \"../helpers/boot.ts\";\nimport { importVite } from \"../helpers/importVite.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 const { loadEnv } = await importVite();\n const env = loadEnv(\"development\", process.cwd(), \"SERVER\");\n\n const config: UserConfig = {};\n if (env.SERVER_PORT) {\n config.server = {\n port: parseInt(env.SERVER_PORT, 10),\n };\n }\n\n return {\n name: \"alepha-dev\",\n apply: \"serve\",\n config: () => config,\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 if (env.SERVER_PORT) {\n server.config.server.port = parseInt(env.SERVER_PORT, 10);\n }\n const middleware = (\n req: IncomingMessage,\n res: ServerResponse,\n next: any,\n ) => {\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 // Forward vite request to alepha server\n server.middlewares.use((req, res, next) => {\n // TODO: wait if restarting ?\n middleware(req, res, next);\n });\n\n server.config.logger.info = (msg: string) => {\n console.log(msg);\n };\n\n server.config.logger.clearScreen = () => {};\n\n // Return a function - it runs AFTER internal middlewares are set up\n // and after buildStart has been called\n return () => {\n server.httpServer?.once(\"listening\", () => {\n runner.start(server);\n });\n };\n },\n async closeBundle() {\n // Cleanup handled by runner\n },\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport type { Plugin } from \"vite\";\n\n/**\n * Preload manifest mapping short keys to source paths.\n * Generated at build time, consumed by SSRManifestProvider at runtime.\n */\nexport interface PreloadManifest {\n [key: string]: string;\n}\n\n/**\n * Vite plugin that generates a preload manifest for SSR module preloading.\n *\n * Instead of injecting source paths directly into $page definitions (which would\n * leak component paths in the browser bundle), this plugin:\n *\n * 1. Collects all lazy import paths from $page definitions during transform\n * 2. Generates a manifest file mapping short keys to resolved source paths\n * 3. Injects only the short key into $page definitions\n *\n * The manifest is written to `.vite/preload-manifest.json` alongside Vite's\n * other manifests. The CLI build command moves all manifests to\n * `dist/server/.ssr/` where SSRManifestProvider loads them at runtime.\n *\n * Before:\n * ```typescript\n * $page({\n * path: '/users/:id',\n * lazy: () => import('./UserDetail.tsx'),\n * })\n * ```\n *\n * After:\n * ```typescript\n * $page({\n * path: '/users/:id',\n * lazy: () => import('./UserDetail.tsx'),\n * [Symbol.for(\"alepha.page.preload\")]: \"a1b2c3\",\n * })\n * ```\n *\n * Manifest (.alepha/preload-manifest.json):\n * ```json\n * {\n * \"a1b2c3\": \"src/pages/UserDetail.tsx\"\n * }\n * ```\n */\nexport function viteAlephaSsrPreload(): Plugin {\n let root = \"\";\n const preloadMap = new Map<string, string>(); // key -> sourcePath\n\n /**\n * Generate a short hash key for a source path.\n * Uses first 8 chars of MD5 hash for brevity while avoiding collisions.\n */\n function generateKey(sourcePath: string): string {\n return createHash(\"md5\").update(sourcePath).digest(\"hex\").slice(0, 8);\n }\n\n return {\n name: \"alepha-preload\",\n configResolved(config) {\n root = config.root;\n },\n transform(code, id) {\n // Only process TypeScript/JavaScript files\n if (!id.match(/\\.[tj]sx?$/)) {\n return null;\n }\n\n // Skip node_modules\n if (id.includes(\"node_modules\")) {\n return null;\n }\n\n // Quick check if file contains $page with lazy\n if (!code.includes(\"$page\") || !code.includes(\"lazy\")) {\n return null;\n }\n\n // Collect all insertions first, then apply in reverse order\n const insertions: Array<{ position: number; text: string }> = [];\n\n // Find all $page({ occurrences\n const pageStartRegex = /\\$page\\s*\\(\\s*\\{/g;\n let pageMatch: RegExpExecArray | null = pageStartRegex.exec(code);\n\n while (pageMatch !== null) {\n const startIndex = pageMatch.index;\n const objectStartIndex = startIndex + pageMatch[0].length - 1; // Position of '{'\n\n // Find the matching closing brace using brace counting\n let braceCount = 1;\n let i = objectStartIndex + 1;\n while (i < code.length && braceCount > 0) {\n if (code[i] === \"{\") braceCount++;\n else if (code[i] === \"}\") braceCount--;\n i++;\n }\n\n // Malformed, skip\n if (braceCount !== 0) {\n pageMatch = pageStartRegex.exec(code);\n continue;\n }\n\n const objectEndIndex = i - 1; // Position of matching '}'\n const pageContent = code.slice(objectStartIndex, objectEndIndex + 1);\n\n // Skip if already has preload symbol\n if (pageContent.includes(\"alepha.page.preload\")) {\n pageMatch = pageStartRegex.exec(code);\n continue;\n }\n\n // Find lazy: () => import('...') within this $page block\n const lazyRegex =\n /lazy\\s*:\\s*\\(\\s*\\)\\s*=>\\s*import\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/;\n const lazyMatch = lazyRegex.exec(pageContent);\n\n if (!lazyMatch) {\n pageMatch = pageStartRegex.exec(code);\n continue;\n }\n\n const importPath = lazyMatch[1];\n\n // Resolve the import path relative to the current file\n const currentDir = dirname(id);\n let resolvedPath: string;\n\n if (importPath.startsWith(\".\")) {\n // Relative import\n resolvedPath = resolve(currentDir, importPath);\n } else if (importPath.startsWith(\"/\")) {\n // Absolute import from root\n resolvedPath = resolve(root, importPath.slice(1));\n } else {\n // Package import - skip preloading for external packages\n pageMatch = pageStartRegex.exec(code);\n continue;\n }\n\n // Make path relative to root for SSR manifest lookup\n let relativePath = relative(root, resolvedPath);\n\n // Normalize path separators for cross-platform compatibility\n relativePath = relativePath.replace(/\\\\/g, \"/\");\n\n // Handle extension - Vite resolves .jsx imports to .tsx files\n // Try to use .tsx when the source has .jsx since TypeScript is more common\n if (!relativePath.match(/\\.[tj]sx?$/)) {\n relativePath = `${relativePath}.tsx`;\n } else if (relativePath.endsWith(\".jsx\")) {\n // Import said .jsx but actual file is likely .tsx\n relativePath = relativePath.replace(/\\.jsx$/, \".tsx\");\n } else if (relativePath.endsWith(\".js\")) {\n // Import said .js but actual file is likely .ts\n relativePath = relativePath.replace(/\\.js$/, \".ts\");\n }\n\n // Generate short key and store mapping\n const key = generateKey(relativePath);\n preloadMap.set(key, relativePath);\n\n // Check if we need a comma (look at character before closing brace)\n const beforeBrace = code.slice(0, objectEndIndex).trimEnd();\n const needsComma = !beforeBrace.endsWith(\",\");\n // Use Symbol.for() so it can be looked up at runtime without importing\n // Only inject the short key, not the full path\n const preloadProperty = `${needsComma ? \",\" : \"\"} [Symbol.for(\"alepha.page.preload\")]: \"${key}\"`;\n\n insertions.push({ position: objectEndIndex, text: preloadProperty });\n\n pageMatch = pageStartRegex.exec(code);\n }\n\n if (insertions.length === 0) {\n return null;\n }\n\n // Apply insertions in reverse order to preserve positions\n let result = code;\n for (let j = insertions.length - 1; j >= 0; j--) {\n const { position, text } = insertions[j];\n result = result.slice(0, position) + text + result.slice(position);\n }\n\n return {\n code: result,\n map: null,\n };\n },\n writeBundle(options) {\n // Only process client build (outputs to dist/public or similar)\n // Skip server build which outputs to dist/server\n const outDir = options.dir || \"\";\n if (outDir.includes(\"server\")) {\n return;\n }\n\n // Write the preload manifest to the same .vite directory Vite uses\n // The CLI build command will move all manifests to dist/server/.ssr/\n if (preloadMap.size > 0) {\n const viteDir = join(outDir, \".vite\");\n\n // Ensure .vite directory exists\n if (!existsSync(viteDir)) {\n mkdirSync(viteDir, { recursive: true });\n }\n\n const manifest: PreloadManifest = Object.fromEntries(preloadMap);\n const manifestPath = join(viteDir, \"preload-manifest.json\");\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));\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 { createRequire } from \"node:module\";\n\nexport const importViteReact = async (): Promise<any> => {\n // Add React plugin for JSX/TSX compilation\n try {\n const { default: viteReact } = createRequire(import.meta.url)(\n \"@vitejs/plugin-react\",\n );\n return viteReact;\n } catch {\n // @vitejs/plugin-react not installed, skip\n }\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 { importViteReact } from \"../helpers/importViteReact.ts\";\nimport { viteAlephaSsrPreload } from \"../plugins/viteAlephaSsrPreload.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 viteReact = await importViteReact();\n if (viteReact) plugins.push(viteReact());\n\n // Add preload plugin for SSR module preloading\n plugins.push(viteAlephaSsrPreload());\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 // Generate manifest for SSR module preloading\n manifest: true,\n ssrManifest: true,\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, rm, 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 { importViteReact } from \"../helpers/importViteReact.ts\";\nimport { viteAlephaSsrPreload } from \"../plugins/viteAlephaSsrPreload.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 const viteReact = await importViteReact();\n if (viteReact && opts.clientDir) {\n plugins.push(viteReact());\n }\n\n plugins.push(viteAlephaSsrPreload());\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,\n ssr: opts.entry,\n outDir: `${opts.distDir}/server`,\n minify: true,\n chunkSizeWarningLimit: 10000,\n rollupOptions: {\n external: [\"bun\"],\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 // Embed SSR manifests if client was built\n // This bundles all manifest data into index.js for serverless deployments\n let manifest = \"\";\n if (opts.clientDir) {\n const viteDir = `${opts.distDir}/${opts.clientDir}/.vite`;\n const ssrManifest = await loadJsonFile(`${viteDir}/ssr-manifest.json`);\n const clientManifest = await loadJsonFile(`${viteDir}/manifest.json`);\n const preloadManifest = await loadJsonFile(\n `${viteDir}/preload-manifest.json`,\n );\n\n const combined = {\n ssr: ssrManifest,\n client: clientManifest,\n preload: preloadManifest,\n };\n\n manifest = `__alepha.set(\"alepha.react.ssr.manifest\", ${JSON.stringify(combined)});\\n`;\n\n // Remove .vite directory - no longer needed at runtime\n await rm(viteDir, { recursive: true, force: true });\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}\\n${template}${manifest}import './server/${entryFile}';\\n`.trim(),\n );\n\n return { entryFile };\n}\n\n/**\n * Load a JSON file, returning undefined if it doesn't exist.\n */\nasync function loadJsonFile(path: string): Promise<any> {\n try {\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content);\n } catch {\n return undefined;\n }\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 * @default process.cwd()\n */\n root?: string;\n\n /**\n * Add Runner for logging (@see Alepha CLI)\n */\n run?: (opts: {\n name: string;\n handler: () => Promise<void>;\n }) => Promise<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 = opts.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 fn = async () => {\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\n if (opts.run) {\n await opts.run({\n name: \"copy assets\",\n handler: fn,\n });\n } else {\n await fn();\n }\n}\n","import type { InlineConfig } from \"vite\";\nimport { importVite } from \"../helpers/importVite.ts\";\nimport { importViteReact } from \"../helpers/importViteReact.ts\";\nimport { viteAlephaDev } from \"../plugins/viteAlephaDev.ts\";\nimport { viteAlephaSsrPreload } from \"../plugins/viteAlephaSsrPreload.ts\";\n\nexport interface DevServerOptions {\n /**\n * Path to the server entry file.\n * If not provided, will auto-detect.\n */\n entry?: string;\n\n /**\n * Port to run the dev server on.\n */\n port?: number;\n\n /**\n * Host to bind the dev server to.\n */\n host?: string | boolean;\n\n /**\n * Enable debug logging.\n */\n debug?: boolean;\n}\n\n/**\n * Start Vite development server with Alepha plugins.\n *\n * This task starts the Vite dev server with all required plugins:\n * - @vitejs/plugin-react (JSX/TSX compilation)\n * - viteAlephaDev (Alepha server integration)\n * - viteAlephaSsrPreload (SSR module preloading)\n */\nexport async function devServer(opts: DevServerOptions = {}): Promise<void> {\n const { createServer, mergeConfig } = await importVite();\n const plugins: any[] = [];\n\n // Add React plugin for JSX/TSX compilation\n const viteReact = await importViteReact();\n if (viteReact) plugins.push(viteReact());\n\n // Add SSR preload plugin\n plugins.push(viteAlephaSsrPreload());\n\n // Add Alepha dev plugin\n plugins.push(\n await viteAlephaDev({\n serverEntry: opts.entry,\n debug: opts.debug,\n }),\n );\n\n const config: InlineConfig = {\n plugins,\n server: {\n port: opts.port,\n host: opts.host,\n },\n };\n\n const server = await createServer(mergeConfig(config, {}));\n await server.listen();\n\n // server.printUrls();\n}\n","import { access, 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 /**\n * Additional Wrangler configuration options to merge into wrangler.jsonc.\n */\n config?: WranglerConfig;\n}\n\nexport interface WranglerConfig {\n [key: string]: any;\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 const hasAssets = await access(join(root, distDir, \"public\"))\n .then(() => true)\n .catch(() => false);\n\n const wrangler: WranglerConfig = {\n name,\n main: \"./main.cloudflare.js\",\n compatibility_flags: [\"nodejs_compat\"],\n compatibility_date: \"2025-11-17\",\n ...opts.config,\n };\n\n if (hasAssets) {\n wrangler.assets ??= {\n directory: \"./public\",\n binding: \"ASSETS\",\n };\n }\n\n const url = process.env.DATABASE_URL;\n if (url?.startsWith(\"cloudflare-d1:\")) {\n const [name, id] = url\n .replace(\"cloudflare-d1://\", \"\")\n .replace(\"cloudflare-d1:\", \"\")\n .split(\":\");\n wrangler.d1_databases = wrangler.d1_databases || [];\n wrangler.d1_databases.push({\n binding: name,\n database_name: name,\n database_id: id,\n });\n wrangler.vars ??= {};\n wrangler.vars.DATABASE_URL = `cloudflare-d1://${name}:${id}`;\n }\n\n await writeFile(\n join(root, distDir, \"wrangler.jsonc\"),\n JSON.stringify(wrangler, null, 2),\n );\n\n await writeWorkerEntryPoint(root, distDir);\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, env) => {\n const ctx = { req: request, res: undefined };\n\n __alepha.set(\"cloudflare.env\", env);\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 { 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 { 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"],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "alepha",
3
3
  "description": "Easy-to-use modern TypeScript framework for building many kind of applications.",
4
4
  "author": "Nicolas Foures",
5
- "version": "0.14.3",
5
+ "version": "0.14.4",
6
6
  "type": "module",
7
7
  "engines": {
8
8
  "node": ">=22.0.0"
@@ -11,7 +11,6 @@ import { GenCommand } from "../commands/gen.ts";
11
11
  import { InitCommand } from "../commands/init.ts";
12
12
  import { LintCommand } from "../commands/lint.ts";
13
13
  import { RootCommand } from "../commands/root.ts";
14
- import { RunCommand } from "../commands/run.ts";
15
14
  import { TestCommand } from "../commands/test.ts";
16
15
  import { TypecheckCommand } from "../commands/typecheck.ts";
17
16
  import { VerifyCommand } from "../commands/verify.ts";
@@ -78,7 +77,6 @@ export const AlephaCli = $module({
78
77
  InitCommand,
79
78
  LintCommand,
80
79
  RootCommand,
81
- RunCommand,
82
80
  TestCommand,
83
81
  TypecheckCommand,
84
82
  VerifyCommand,
@@ -0,0 +1,88 @@
1
+ import { type Static, t } from "alepha";
2
+ import { $atom } from "../../core/primitives/$atom.ts";
3
+
4
+ /**
5
+ * Build options atom for CLI build command.
6
+ *
7
+ * Defines the available build configuration options with their defaults.
8
+ * Options can be overridden via vite.config.ts or CLI flags.
9
+ */
10
+ export const buildOptions = $atom({
11
+ name: "alepha.build.options",
12
+ description: "Build configuration options",
13
+ schema: t.object({
14
+ /**
15
+ * Generate build stats report.
16
+ */
17
+ stats: t.optional(t.boolean({ default: false })),
18
+
19
+ /**
20
+ * Vercel deployment configuration.
21
+ */
22
+ vercel: t.optional(
23
+ t.object({
24
+ projectName: t.optional(t.string()),
25
+ orgId: t.optional(t.string()),
26
+ projectId: t.optional(t.string()),
27
+ config: t.optional(
28
+ t.object({
29
+ crons: t.optional(
30
+ t.array(
31
+ t.object({
32
+ path: t.string(),
33
+ schedule: t.string(),
34
+ }),
35
+ ),
36
+ ),
37
+ }),
38
+ ),
39
+ }),
40
+ ),
41
+
42
+ /**
43
+ * Cloudflare Workers deployment configuration.
44
+ */
45
+ cloudflare: t.optional(
46
+ t.object({
47
+ config: t.optional(t.json()),
48
+ }),
49
+ ),
50
+
51
+ /**
52
+ * Docker deployment configuration.
53
+ */
54
+ docker: t.optional(
55
+ t.object({
56
+ /**
57
+ * Docker image name to use in the Dockerfile.
58
+ * @default "node:24-alpine"
59
+ */
60
+ image: t.optional(t.string({ default: "node:24-alpine" })),
61
+
62
+ /**
63
+ * Command to run in the Docker container.
64
+ * @default "node"
65
+ */
66
+ command: t.optional(t.string({ default: "node" })),
67
+ }),
68
+ ),
69
+
70
+ /**
71
+ * Sitemap generation configuration.
72
+ */
73
+ sitemap: t.optional(
74
+ t.object({
75
+ /**
76
+ * Base URL for sitemap entries.
77
+ */
78
+ hostname: t.string(),
79
+ }),
80
+ ),
81
+ }),
82
+ default: {},
83
+ });
84
+
85
+ /**
86
+ * Type for build options.
87
+ */
88
+ export type BuildOptions = Static<typeof buildOptions.schema>;