alepha 0.15.4 → 0.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -11
- package/dist/api/audits/index.d.ts +3 -3
- package/dist/api/audits/index.js +3 -3
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +3 -3
- package/dist/api/files/index.js +3 -3
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +47 -4
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +100 -5
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +3 -3
- package/dist/api/keys/index.js +3 -3
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.d.ts +3 -3
- package/dist/api/notifications/index.js +3 -3
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +263 -263
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +31 -30
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +373 -67
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +273 -72
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +3 -3
- package/dist/api/verifications/index.js +3 -3
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.d.ts +7 -7
- package/dist/batch/index.js +3 -3
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +3 -3
- package/dist/bucket/index.js +6 -6
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/core/index.d.ts +3 -3
- package/dist/cache/core/index.js +3 -3
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +5607 -20
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +103 -89
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +11 -4
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +8 -6
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +4 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +3 -3
- package/dist/datetime/index.js +3 -3
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +3 -3
- package/dist/email/index.js +8 -8
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +3 -3
- package/dist/fake/index.js +3 -3
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +3 -3
- package/dist/lock/core/index.js +3 -3
- package/dist/lock/core/index.js.map +1 -1
- package/dist/logger/index.d.ts +3 -3
- package/dist/logger/index.js +6 -3
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +3 -3
- package/dist/mcp/index.js +3 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.d.ts +12 -12
- package/dist/orm/index.js +4 -4
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +3 -3
- package/dist/queue/core/index.js +3 -3
- package/dist/queue/core/index.js.map +1 -1
- package/dist/react/auth/index.d.ts +3 -3
- package/dist/react/auth/index.js +3 -3
- package/dist/react/auth/index.js.map +1 -1
- package/dist/react/core/index.d.ts +3 -3
- package/dist/react/core/index.js +3 -3
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +3 -3
- package/dist/react/form/index.js +3 -3
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.d.ts +3 -3
- package/dist/react/head/index.js +3 -3
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +3 -3
- package/dist/react/i18n/index.js +3 -3
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.css +337 -0
- package/dist/react/intro/index.css.map +1 -0
- package/dist/react/intro/index.d.ts +10 -0
- package/dist/react/intro/index.d.ts.map +1 -0
- package/dist/react/intro/index.js +222 -0
- package/dist/react/intro/index.js.map +1 -0
- package/dist/react/router/index.browser.js +2 -2
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +1 -1
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +5 -5
- package/dist/react/router/index.js.map +1 -1
- package/dist/redis/index.d.ts +17 -17
- package/dist/redis/index.js +3 -3
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +3 -3
- package/dist/retry/index.js +3 -3
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +3 -3
- package/dist/scheduler/index.js +3 -3
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/security/index.js +5 -5
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +3 -3
- package/dist/server/auth/index.js +3 -3
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +3 -3
- package/dist/server/cache/index.js +3 -3
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +3 -3
- package/dist/server/compress/index.js +3 -3
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +3 -3
- package/dist/server/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +5 -16
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +13 -29
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +3 -3
- package/dist/server/cors/index.js +3 -3
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/health/index.d.ts +20 -20
- package/dist/server/health/index.js +3 -3
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/helmet/index.d.ts +3 -3
- package/dist/server/helmet/index.js +3 -3
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.d.ts +42 -42
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +3 -3
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +3 -3
- package/dist/server/metrics/index.js +3 -3
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts +3 -3
- package/dist/server/multipart/index.js +3 -3
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts +3 -3
- package/dist/server/proxy/index.js +3 -3
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts +3 -3
- package/dist/server/rate-limit/index.js +3 -3
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +3 -3
- package/dist/server/static/index.js +6 -6
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +3 -3
- package/dist/server/swagger/index.js +6 -6
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +3 -3
- package/dist/sms/index.js +6 -6
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.d.ts +3 -3
- package/dist/system/index.js +3 -3
- package/dist/system/index.js.map +1 -1
- package/dist/thread/index.d.ts +3 -3
- package/dist/thread/index.js +3 -3
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts +3 -3
- package/dist/topic/core/index.js +3 -3
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.d.ts +6284 -3
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/websocket/index.d.ts +3 -3
- package/dist/websocket/index.js +3 -3
- package/dist/websocket/index.js.map +1 -1
- package/package.json +7 -2
- package/src/api/audits/index.ts +3 -3
- package/src/api/files/index.ts +3 -3
- package/src/api/jobs/controllers/AdminJobController.ts +15 -2
- package/src/api/jobs/index.ts +4 -3
- package/src/api/jobs/services/JobAudits.spec.ts +89 -0
- package/src/api/jobs/services/JobAudits.ts +101 -0
- package/src/api/keys/index.ts +3 -3
- package/src/api/notifications/index.ts +3 -3
- package/src/api/parameters/index.ts +5 -3
- package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1 -1
- package/src/api/users/__tests__/ApiKeys.spec.ts +1 -1
- package/src/api/users/__tests__/EmailVerification.spec.ts +16 -1
- package/src/api/users/__tests__/PasswordReset.spec.ts +11 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -0
- package/src/api/users/index.ts +8 -9
- package/src/api/users/primitives/$realm.ts +117 -19
- package/src/api/users/providers/RealmProvider.ts +15 -7
- package/src/api/users/services/CredentialService.spec.ts +11 -0
- package/src/api/users/services/CredentialService.ts +47 -24
- package/src/api/users/services/IdentityService.ts +12 -4
- package/src/api/users/services/RegistrationService.spec.ts +11 -0
- package/src/api/users/services/RegistrationService.ts +33 -12
- package/src/api/users/services/SessionService.ts +83 -12
- package/src/api/users/services/UserAudits.ts +47 -0
- package/src/api/users/services/UserFiles.ts +19 -0
- package/src/api/users/services/UserJobs.spec.ts +107 -0
- package/src/api/users/services/UserJobs.ts +62 -0
- package/src/api/users/services/UserParameters.ts +23 -0
- package/src/api/users/services/UserService.ts +34 -17
- package/src/api/verifications/index.ts +3 -3
- package/src/batch/index.ts +3 -3
- package/src/bucket/index.ts +3 -3
- package/src/cache/core/index.ts +3 -3
- package/src/cli/commands/db.ts +9 -0
- package/src/cli/commands/init.spec.ts +2 -17
- package/src/cli/commands/init.ts +37 -1
- package/src/cli/providers/ViteDevServerProvider.ts +5 -2
- package/src/cli/services/AlephaCliUtils.ts +17 -0
- package/src/cli/services/PackageManagerUtils.ts +15 -1
- package/src/cli/services/ProjectScaffolder.ts +8 -13
- package/src/cli/templates/agentMd.ts +2 -25
- package/src/cli/templates/apiAppSecurityTs.ts +37 -2
- package/src/cli/templates/mainCss.ts +2 -32
- package/src/cli/templates/webAppRouterTs.ts +5 -5
- package/src/cli/templates/webHomeComponentTsx.ts +10 -0
- package/src/command/helpers/Runner.ts +14 -1
- package/src/command/index.ts +3 -3
- package/src/core/helpers/primitive.ts +0 -5
- package/src/core/index.ts +3 -3
- package/src/datetime/index.ts +3 -3
- package/src/email/index.ts +3 -3
- package/src/email/providers/LocalEmailProvider.ts +2 -2
- package/src/fake/index.ts +3 -3
- package/src/lock/core/index.ts +3 -3
- package/src/logger/index.ts +3 -3
- package/src/logger/providers/PrettyFormatterProvider.ts +7 -0
- package/src/mcp/index.ts +3 -3
- package/src/orm/index.ts +3 -3
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
- package/src/queue/core/index.ts +3 -3
- package/src/react/auth/index.ts +3 -3
- package/src/react/core/index.ts +3 -3
- package/src/react/form/index.ts +3 -3
- package/src/react/head/index.ts +3 -3
- package/src/react/i18n/index.ts +3 -3
- package/src/react/intro/components/GettingStarted.css +334 -0
- package/src/react/intro/components/GettingStarted.tsx +276 -0
- package/src/react/intro/index.ts +1 -0
- package/src/react/router/index.browser.ts +2 -0
- package/src/react/router/index.ts +2 -0
- package/src/redis/index.ts +3 -3
- package/src/retry/index.ts +3 -3
- package/src/router/index.ts +3 -3
- package/src/scheduler/index.ts +3 -3
- package/src/security/index.ts +3 -3
- package/src/security/providers/JwtProvider.ts +2 -2
- package/src/server/auth/index.ts +3 -3
- package/src/server/cache/index.ts +3 -3
- package/src/server/compress/index.ts +3 -3
- package/src/server/cookies/index.ts +3 -3
- package/src/server/core/index.ts +3 -3
- package/src/server/core/primitives/$action.spec.ts +3 -2
- package/src/server/core/primitives/$action.ts +6 -2
- package/src/server/core/providers/NodeHttpServerProvider.ts +2 -15
- package/src/server/core/providers/ServerProvider.ts +4 -2
- package/src/server/core/providers/ServerRouterProvider.ts +5 -27
- package/src/server/cors/index.ts +3 -3
- package/src/server/health/index.ts +3 -3
- package/src/server/helmet/index.ts +3 -3
- package/src/server/links/index.ts +3 -3
- package/src/server/metrics/index.ts +3 -3
- package/src/server/multipart/index.ts +3 -3
- package/src/server/proxy/index.ts +3 -3
- package/src/server/rate-limit/index.ts +3 -3
- package/src/server/static/index.ts +3 -3
- package/src/server/swagger/index.ts +3 -3
- package/src/sms/index.ts +3 -3
- package/src/system/index.ts +3 -3
- package/src/thread/index.ts +3 -3
- package/src/topic/core/index.ts +3 -3
- package/src/websocket/index.ts +3 -3
- package/src/cli/templates/webHelloComponentTsx.ts +0 -30
- /package/src/api/users/{notifications → services}/UserNotifications.ts +0 -0
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["nodeJoin","fsRm","fsCp","fsMkdir","fsReadFile","fsWriteFile","$atom","$atom","alephaPackageJson.devDependencies","devDependencies"],"sources":["../../src/system/providers/FileSystemProvider.ts","../../src/system/providers/MemoryFileSystemProvider.ts","../../src/system/providers/MemoryShellProvider.ts","../../src/system/services/FileDetector.ts","../../src/system/providers/NodeFileSystemProvider.ts","../../src/system/providers/NodeShellProvider.ts","../../src/system/providers/ShellProvider.ts","../../src/system/index.ts","../../src/core/constants/KIND.ts","../../src/core/primitives/$atom.ts","../../src/cli/atoms/buildOptions.ts","../../src/cli/atoms/appEntryOptions.ts","../../src/cli/providers/AppEntryProvider.ts","../../src/cli/services/ViteUtils.ts","../../src/cli/providers/ViteBuildProvider.ts","../../src/cli/services/AlephaCliUtils.ts","../../package.json","../../src/cli/version.ts","../../src/cli/services/PackageManagerUtils.ts","../../src/cli/templates/agentMd.ts","../../src/cli/templates/apiAppSecurityTs.ts","../../src/cli/templates/apiHelloControllerTs.ts","../../src/cli/templates/apiIndexTs.ts","../../src/cli/templates/biomeJson.ts","../../src/cli/templates/dummySpecTs.ts","../../src/cli/templates/editorconfig.ts","../../src/cli/templates/gitignore.ts","../../src/cli/templates/mainBrowserTs.ts","../../src/cli/templates/mainCss.ts","../../src/cli/templates/mainServerTs.ts","../../src/cli/templates/tsconfigJson.ts","../../src/cli/templates/webAppRouterTs.ts","../../src/cli/templates/webHelloComponentTsx.ts","../../src/cli/templates/webIndexTs.ts","../../src/cli/services/ProjectScaffolder.ts","../../src/cli/commands/build.ts","../../src/cli/commands/clean.ts","../../src/cli/commands/db.ts","../../src/cli/commands/deploy.ts","../../src/cli/providers/ViteDevServerProvider.ts","../../src/cli/commands/dev.ts","../../src/cli/atoms/changelogOptions.ts","../../src/cli/services/GitMessageParser.ts","../../src/cli/commands/gen/changelog.ts","../../src/cli/commands/gen/env.ts","../../src/cli/commands/gen/openapi.ts","../../src/cli/commands/gen.ts","../../src/cli/commands/init.ts","../../src/cli/commands/lint.ts","../../src/cli/commands/root.ts","../../src/cli/commands/test.ts","../../src/cli/commands/typecheck.ts","../../src/cli/commands/verify.ts","../../src/cli/apps/AlephaCli.ts","../../src/cli/apps/AlephaPackageBuilderCli.ts","../../src/cli/defineConfig.ts"],"sourcesContent":["import type { FileLike, StreamLike } from \"alepha\";\n\n/**\n * Options for creating a file from a URL\n */\nexport interface CreateFileFromUrlOptions {\n /**\n * The URL to load the file from (file://, http://, or https://)\n */\n url: string;\n /**\n * The MIME type of the file (optional, will be detected from filename if not provided)\n */\n type?: string;\n /**\n * The name of the file (optional, will be extracted from URL if not provided)\n */\n name?: string;\n}\n\n/**\n * Options for creating a file from a path (URL with file:// scheme)\n */\nexport interface CreateFileFromPathOptions {\n /**\n * The path to the file on the local filesystem\n */\n path: string;\n /**\n * The MIME type of the file (optional, will be detected from filename if not provided)\n */\n type?: string;\n /**\n * The name of the file (optional, will be extracted from URL if not provided)\n */\n name?: string;\n}\n\n/**\n * Options for creating a file from a Buffer\n */\nexport interface CreateFileFromBufferOptions {\n /**\n * The Buffer containing the file data\n */\n buffer: Buffer;\n /**\n * The MIME type of the file (optional, will be detected from name if not provided)\n */\n type?: string;\n /**\n * The name of the file (required for proper content type detection)\n */\n name?: string;\n}\n\n/**\n * Options for creating a file from a stream\n */\nexport interface CreateFileFromStreamOptions {\n /**\n * The readable stream containing the file data\n */\n stream: StreamLike;\n /**\n * The MIME type of the file (optional, will be detected from name if not provided)\n */\n type?: string;\n /**\n * The name of the file (required for proper content type detection)\n */\n name?: string;\n /**\n * The size of the file in bytes (optional)\n */\n size?: number;\n}\n\n/**\n * Options for creating a file from text content\n */\nexport interface CreateFileFromTextOptions {\n /**\n * The text content to create the file from\n */\n text: string;\n /**\n * The MIME type of the file (default: text/plain)\n */\n type?: string;\n /**\n * The name of the file (default: \"file.txt\")\n */\n name?: string;\n}\n\nexport interface CreateFileFromResponseOptions {\n /**\n * The Response object containing the file data\n */\n response: Response;\n /**\n * Override the name (optional, uses filename from Content-Disposition header if not provided)\n */\n name?: string;\n /**\n * Override the MIME type (optional, uses file.type if not provided)\n */\n type?: string;\n}\n\n/**\n * Options for creating a file from a Web File object\n */\nexport interface CreateFileFromWebFileOptions {\n /**\n * The Web File object\n */\n file: File;\n /**\n * Override the MIME type (optional, uses file.type if not provided)\n */\n type?: string;\n /**\n * Override the name (optional, uses file.name if not provided)\n */\n name?: string;\n /**\n * Override the size (optional, uses file.size if not provided)\n */\n size?: number;\n}\n\n/**\n * Options for creating a file from an ArrayBuffer\n */\nexport interface CreateFileFromArrayBufferOptions {\n /**\n * The ArrayBuffer containing the file data\n */\n arrayBuffer: ArrayBuffer;\n /**\n * The MIME type of the file (optional, will be detected from name if not provided)\n */\n type?: string;\n /**\n * The name of the file (required for proper content type detection)\n */\n name?: string;\n}\n\n/**\n * Union type for all createFile options\n */\nexport type CreateFileOptions =\n | CreateFileFromUrlOptions\n | CreateFileFromPathOptions\n | CreateFileFromBufferOptions\n | CreateFileFromStreamOptions\n | CreateFileFromTextOptions\n | CreateFileFromWebFileOptions\n | CreateFileFromResponseOptions\n | CreateFileFromArrayBufferOptions;\n\n/**\n * Options for rm (remove) operation\n */\nexport interface RmOptions {\n /**\n * If true, removes directories and their contents recursively\n */\n recursive?: boolean;\n /**\n * If true, no error will be thrown if the path does not exist\n */\n force?: boolean;\n}\n\n/**\n * Options for cp (copy) operation\n */\nexport interface CpOptions {\n /**\n * If true, copy directories recursively\n */\n recursive?: boolean;\n /**\n * If true, overwrite existing destination\n */\n force?: boolean;\n}\n\n/**\n * Options for mkdir operation\n */\nexport interface MkdirOptions {\n /**\n * If true, creates parent directories as needed\n *\n * @default true\n */\n recursive?: boolean;\n /**\n * If true, does not throw an error if the directory already exists\n *\n * @default true\n */\n force?: boolean;\n /**\n * File mode (permission and sticky bits)\n */\n mode?: number;\n}\n\n/**\n * Options for ls (list) operation\n */\nexport interface LsOptions {\n /**\n * If true, list contents of directories recursively\n */\n recursive?: boolean;\n /**\n * If true, include hidden files (starting with .)\n */\n hidden?: boolean;\n}\n\n/**\n * FileSystem interface providing utilities for working with files.\n */\nexport abstract class FileSystemProvider {\n /**\n * Joins multiple path segments into a single path.\n *\n * @param paths - The path segments to join\n * @returns The joined path\n */\n abstract join(...paths: string[]): string;\n\n /**\n * Creates a FileLike object from various sources.\n *\n * @param options - Options for creating the file\n * @returns A FileLike object\n */\n abstract createFile(options: CreateFileOptions): FileLike;\n\n /**\n * Removes a file or directory.\n *\n * @param path - The path to remove\n * @param options - Remove options\n */\n abstract rm(path: string, options?: RmOptions): Promise<void>;\n\n /**\n * Copies a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n * @param options - Copy options\n */\n abstract cp(src: string, dest: string, options?: CpOptions): Promise<void>;\n\n /**\n * Moves/renames a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n */\n abstract mv(src: string, dest: string): Promise<void>;\n\n /**\n * Creates a directory.\n *\n * @param path - The directory path to create\n * @param options - Mkdir options\n */\n abstract mkdir(path: string, options?: MkdirOptions): Promise<void>;\n\n /**\n * Lists files in a directory.\n *\n * @param path - The directory path to list\n * @param options - List options\n * @returns Array of filenames\n */\n abstract ls(path: string, options?: LsOptions): Promise<string[]>;\n\n /**\n * Checks if a file or directory exists.\n *\n * @param path - The path to check\n * @returns True if the path exists, false otherwise\n */\n abstract exists(path: string): Promise<boolean>;\n\n /**\n * Reads the content of a file.\n *\n * @param path - The file path to read\n * @returns The file content as a Buffer\n */\n abstract readFile(path: string): Promise<Buffer>;\n\n /**\n * Writes data to a file.\n *\n * @param path - The file path to write to\n * @param data - The data to write (Buffer or string)\n */\n abstract writeFile(\n path: string,\n data: Uint8Array | Buffer | string | FileLike,\n ): Promise<void>;\n\n /**\n * Reads the content of a file as a string.\n *\n * @param path - The file path to read\n * @returns The file content as a string\n */\n abstract readTextFile(path: string): Promise<string>;\n\n /**\n * Reads the content of a file as JSON.\n *\n * @param path - The file path to read\n * @returns The parsed JSON content\n */\n abstract readJsonFile<T = unknown>(path: string): Promise<T>;\n}\n","import { join as nodeJoin } from \"node:path\";\nimport { $inject, type FileLike, Json } from \"alepha\";\nimport type {\n CpOptions,\n CreateFileOptions,\n FileSystemProvider,\n LsOptions,\n MkdirOptions,\n RmOptions,\n} from \"./FileSystemProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface MemoryFileSystemProviderOptions {\n /**\n * Error to throw on mkdir operations (for testing error handling)\n */\n mkdirError?: Error | null;\n /**\n * Error to throw on writeFile operations (for testing error handling)\n */\n writeFileError?: Error | null;\n /**\n * Error to throw on readFile operations (for testing error handling)\n */\n readFileError?: Error | null;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * In-memory implementation of FileSystemProvider for testing.\n *\n * This provider stores all files and directories in memory, making it ideal for\n * unit tests that need to verify file operations without touching the real file system.\n *\n * @example\n * ```typescript\n * // In tests, substitute the real FileSystemProvider with MemoryFileSystemProvider\n * const alepha = Alepha.create().with({\n * provide: FileSystemProvider,\n * use: MemoryFileSystemProvider,\n * });\n *\n * // Run code that uses FileSystemProvider\n * const service = alepha.inject(MyService);\n * await service.saveFile(\"test.txt\", \"Hello World\");\n *\n * // Verify the file was written\n * const memoryFs = alepha.inject(MemoryFileSystemProvider);\n * expect(memoryFs.files.get(\"test.txt\")?.toString()).toBe(\"Hello World\");\n * ```\n */\nexport class MemoryFileSystemProvider implements FileSystemProvider {\n protected json = $inject(Json);\n\n /**\n * In-memory storage for files (path -> content)\n */\n public files = new Map<string, Buffer>();\n\n /**\n * In-memory storage for directories\n */\n public directories = new Set<string>();\n\n /**\n * Track mkdir calls for test assertions\n */\n public mkdirCalls: Array<{ path: string; options?: MkdirOptions }> = [];\n\n /**\n * Track writeFile calls for test assertions\n */\n public writeFileCalls: Array<{ path: string; data: string }> = [];\n\n /**\n * Track readFile calls for test assertions\n */\n public readFileCalls: Array<string> = [];\n\n /**\n * Track rm calls for test assertions\n */\n public rmCalls: Array<{ path: string; options?: RmOptions }> = [];\n\n /**\n * Track join calls for test assertions\n */\n public joinCalls: Array<string[]> = [];\n\n /**\n * Error to throw on mkdir (for testing error handling)\n */\n public mkdirError: Error | null = null;\n\n /**\n * Error to throw on writeFile (for testing error handling)\n */\n public writeFileError: Error | null = null;\n\n /**\n * Error to throw on readFile (for testing error handling)\n */\n public readFileError: Error | null = null;\n\n constructor(options: MemoryFileSystemProviderOptions = {}) {\n this.mkdirError = options.mkdirError ?? null;\n this.writeFileError = options.writeFileError ?? null;\n this.readFileError = options.readFileError ?? null;\n }\n\n /**\n * Join path segments using forward slashes.\n * Uses Node's path.join for proper normalization (handles .. and .)\n */\n public join(...paths: string[]): string {\n this.joinCalls.push(paths);\n return nodeJoin(...paths);\n }\n\n /**\n * Create a FileLike object from various sources.\n */\n public createFile(options: CreateFileOptions): FileLike {\n if (\"path\" in options) {\n const filePath = options.path;\n const buffer = this.files.get(filePath);\n if (buffer === undefined) {\n throw new Error(\n `ENOENT: no such file or directory, open '${filePath}'`,\n );\n }\n return {\n name: options.name ?? filePath.split(\"/\").pop() ?? \"file\",\n type: options.type ?? \"application/octet-stream\",\n size: buffer.byteLength,\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Stream not implemented in MemoryFileSystemProvider\");\n },\n arrayBuffer: async (): Promise<ArrayBuffer> =>\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer,\n text: async () => buffer.toString(\"utf-8\"),\n };\n }\n\n if (\"buffer\" in options) {\n const buffer = options.buffer;\n return {\n name: options.name ?? \"file\",\n type: options.type ?? \"application/octet-stream\",\n size: buffer.byteLength,\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Stream not implemented in MemoryFileSystemProvider\");\n },\n arrayBuffer: async (): Promise<ArrayBuffer> =>\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer,\n text: async () => buffer.toString(\"utf-8\"),\n };\n }\n\n if (\"text\" in options) {\n const buffer = Buffer.from(options.text, \"utf-8\");\n return {\n name: options.name ?? \"file.txt\",\n type: options.type ?? \"text/plain\",\n size: buffer.byteLength,\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Stream not implemented in MemoryFileSystemProvider\");\n },\n arrayBuffer: async (): Promise<ArrayBuffer> =>\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer,\n text: async () => options.text,\n };\n }\n\n throw new Error(\n \"MemoryFileSystemProvider.createFile: unsupported options. Only buffer and text are supported.\",\n );\n }\n\n /**\n * Remove a file or directory from memory.\n */\n public async rm(path: string, options?: RmOptions): Promise<void> {\n this.rmCalls.push({ path, options });\n\n const exists = this.files.has(path) || this.directories.has(path);\n\n if (!exists && !options?.force) {\n throw new Error(`ENOENT: no such file or directory, rm '${path}'`);\n }\n\n if (this.directories.has(path)) {\n if (options?.recursive) {\n // Remove directory and all contents\n this.directories.delete(path);\n for (const filePath of this.files.keys()) {\n if (filePath.startsWith(`${path}/`)) {\n this.files.delete(filePath);\n }\n }\n for (const dirPath of this.directories) {\n if (dirPath.startsWith(`${path}/`)) {\n this.directories.delete(dirPath);\n }\n }\n } else {\n throw new Error(\n `EISDIR: illegal operation on a directory, rm '${path}'`,\n );\n }\n } else {\n this.files.delete(path);\n }\n }\n\n /**\n * Copy a file or directory in memory.\n */\n public async cp(\n src: string,\n dest: string,\n options?: CpOptions,\n ): Promise<void> {\n if (this.directories.has(src)) {\n if (!options?.recursive) {\n throw new Error(\n `Cannot copy directory without recursive option: ${src}`,\n );\n }\n // Copy directory and contents\n this.directories.add(dest);\n for (const [filePath, content] of this.files) {\n if (filePath.startsWith(`${src}/`)) {\n const newPath = filePath.replace(src, dest);\n this.files.set(newPath, Buffer.from(content));\n }\n }\n } else if (this.files.has(src)) {\n const content = this.files.get(src)!;\n this.files.set(dest, Buffer.from(content));\n } else {\n throw new Error(`ENOENT: no such file or directory, cp '${src}'`);\n }\n }\n\n /**\n * Move/rename a file or directory in memory.\n */\n public async mv(src: string, dest: string): Promise<void> {\n if (this.directories.has(src)) {\n // Move directory and contents\n this.directories.delete(src);\n this.directories.add(dest);\n for (const [filePath, content] of this.files) {\n if (filePath.startsWith(`${src}/`)) {\n const newPath = filePath.replace(src, dest);\n this.files.delete(filePath);\n this.files.set(newPath, content);\n }\n }\n } else if (this.files.has(src)) {\n const content = this.files.get(src)!;\n this.files.delete(src);\n this.files.set(dest, content);\n } else {\n throw new Error(`ENOENT: no such file or directory, mv '${src}'`);\n }\n }\n\n /**\n * Create a directory in memory.\n */\n public async mkdir(path: string, options?: MkdirOptions): Promise<void> {\n this.mkdirCalls.push({ path, options });\n\n if (this.mkdirError) {\n throw this.mkdirError;\n }\n\n if (this.directories.has(path) && !options?.recursive) {\n throw new Error(`EEXIST: file already exists, mkdir '${path}'`);\n }\n\n this.directories.add(path);\n\n // If recursive, create parent directories\n if (options?.recursive) {\n const parts = path.split(\"/\").filter(Boolean);\n let current = \"\";\n for (const part of parts) {\n current = current ? `${current}/${part}` : part;\n this.directories.add(current);\n }\n }\n }\n\n /**\n * List files in a directory.\n */\n public async ls(path: string, options?: LsOptions): Promise<string[]> {\n const normalizedPath = path.replace(/\\/$/, \"\");\n const entries = new Set<string>();\n\n // Find files in the directory\n for (const filePath of this.files.keys()) {\n if (filePath.startsWith(`${normalizedPath}/`)) {\n const relativePath = filePath.slice(normalizedPath.length + 1);\n const parts = relativePath.split(\"/\");\n\n if (options?.recursive) {\n entries.add(relativePath);\n } else {\n entries.add(parts[0]);\n }\n }\n }\n\n // Find subdirectories\n for (const dirPath of this.directories) {\n if (\n dirPath.startsWith(`${normalizedPath}/`) &&\n dirPath !== normalizedPath\n ) {\n const relativePath = dirPath.slice(normalizedPath.length + 1);\n const parts = relativePath.split(\"/\");\n\n if (options?.recursive) {\n entries.add(relativePath);\n } else if (parts.length === 1) {\n entries.add(parts[0]);\n }\n }\n }\n\n let result = Array.from(entries);\n\n // Filter hidden files unless requested\n if (!options?.hidden) {\n result = result.filter((entry) => !entry.startsWith(\".\"));\n }\n\n return result.sort();\n }\n\n /**\n * Check if a file or directory exists in memory.\n */\n public async exists(path: string): Promise<boolean> {\n return this.files.has(path) || this.directories.has(path);\n }\n\n /**\n * Read a file from memory.\n */\n public async readFile(path: string): Promise<Buffer> {\n this.readFileCalls.push(path);\n\n if (this.readFileError) {\n throw this.readFileError;\n }\n\n const content = this.files.get(path);\n if (!content) {\n throw new Error(`ENOENT: no such file or directory, open '${path}'`);\n }\n return content;\n }\n\n /**\n * Read a file from memory as text.\n */\n public async readTextFile(path: string): Promise<string> {\n const buffer = await this.readFile(path);\n return buffer.toString(\"utf-8\");\n }\n\n /**\n * Read a file from memory as JSON.\n */\n public async readJsonFile<T = unknown>(path: string): Promise<T> {\n const text = await this.readTextFile(path);\n return this.json.parse(text) as T;\n }\n\n /**\n * Write a file to memory.\n */\n public async writeFile(\n path: string,\n data: Uint8Array | Buffer | string | FileLike,\n ): Promise<void> {\n const dataStr =\n typeof data === \"string\"\n ? data\n : data instanceof Buffer || data instanceof Uint8Array\n ? data.toString(\"utf-8\")\n : await data.text();\n\n this.writeFileCalls.push({ path, data: dataStr });\n\n if (this.writeFileError) {\n throw this.writeFileError;\n }\n\n const buffer =\n typeof data === \"string\"\n ? Buffer.from(data, \"utf-8\")\n : data instanceof Buffer\n ? data\n : data instanceof Uint8Array\n ? Buffer.from(data)\n : Buffer.from(await data.text(), \"utf-8\");\n\n this.files.set(path, buffer);\n }\n\n /**\n * Reset all in-memory state (useful between tests).\n */\n public reset(): void {\n this.files.clear();\n this.directories.clear();\n this.mkdirCalls = [];\n this.writeFileCalls = [];\n this.readFileCalls = [];\n this.rmCalls = [];\n this.joinCalls = [];\n this.mkdirError = null;\n this.writeFileError = null;\n this.readFileError = null;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Test assertion helpers\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Check if a file was written during the test.\n *\n * @example\n * ```typescript\n * expect(fs.wasWritten(\"/project/tsconfig.json\")).toBe(true);\n * ```\n */\n public wasWritten(path: string): boolean {\n return this.writeFileCalls.some((call) => call.path === path);\n }\n\n /**\n * Check if a file was written with content matching a pattern.\n *\n * @example\n * ```typescript\n * expect(fs.wasWrittenMatching(\"/project/tsconfig.json\", /extends/)).toBe(true);\n * ```\n */\n public wasWrittenMatching(path: string, pattern: RegExp): boolean {\n const call = this.writeFileCalls.find((c) => c.path === path);\n return call ? pattern.test(call.data) : false;\n }\n\n /**\n * Check if a file was read during the test.\n *\n * @example\n * ```typescript\n * expect(fs.wasRead(\"/project/package.json\")).toBe(true);\n * ```\n */\n public wasRead(path: string): boolean {\n return this.readFileCalls.includes(path);\n }\n\n /**\n * Check if a file was deleted during the test.\n *\n * @example\n * ```typescript\n * expect(fs.wasDeleted(\"/project/old-file.txt\")).toBe(true);\n * ```\n */\n public wasDeleted(path: string): boolean {\n return this.rmCalls.some((call) => call.path === path);\n }\n\n /**\n * Get the content of a file as a string (convenience method for testing).\n */\n public getFileContent(path: string): string | undefined {\n return this.files.get(path)?.toString(\"utf-8\");\n }\n}\n","import type { ShellProvider, ShellRunOptions } from \"./ShellProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface MemoryShellCall {\n command: string;\n options: ShellRunOptions;\n}\n\nexport interface MemoryShellProviderOptions {\n /**\n * Simulated outputs for specific commands.\n * Key is the command string, value is the stdout to return.\n */\n outputs?: Record<string, string>;\n\n /**\n * Commands that should throw an error.\n * Key is the command string, value is the error message.\n */\n errors?: Record<string, string>;\n\n /**\n * Commands that are considered \"installed\" in the system PATH.\n */\n installedCommands?: string[];\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * In-memory implementation of ShellProvider for testing.\n *\n * Records all commands that would be executed without actually running them.\n * Can be configured to return specific outputs or throw errors for testing.\n *\n * @example\n * ```typescript\n * // In tests, substitute the real ShellProvider with MemoryShellProvider\n * const alepha = Alepha.create().with({\n * provide: ShellProvider,\n * use: MemoryShellProvider,\n * });\n *\n * // Configure mock behavior\n * const shell = alepha.inject(MemoryShellProvider);\n * shell.configure({\n * outputs: { \"echo hello\": \"hello\\n\" },\n * errors: { \"failing-cmd\": \"Command failed\" },\n * });\n *\n * // Or use the fluent API\n * shell.outputs.set(\"another-cmd\", \"output\");\n * shell.errors.set(\"another-error\", \"Error message\");\n *\n * // Run code that uses ShellProvider\n * const service = alepha.inject(MyService);\n * await service.doSomething();\n *\n * // Verify commands were called\n * expect(shell.calls).toHaveLength(2);\n * expect(shell.calls[0].command).toBe(\"yarn install\");\n * ```\n */\nexport class MemoryShellProvider implements ShellProvider {\n /**\n * All recorded shell calls.\n */\n public calls: MemoryShellCall[] = [];\n\n /**\n * Simulated outputs for specific commands.\n */\n public outputs = new Map<string, string>();\n\n /**\n * Commands that should throw an error.\n */\n public errors = new Map<string, string>();\n\n /**\n * Commands considered installed in the system PATH.\n */\n public installedCommands = new Set<string>();\n\n /**\n * Configure the mock with predefined outputs, errors, and installed commands.\n */\n public configure(options: MemoryShellProviderOptions): this {\n if (options.outputs) {\n for (const [cmd, output] of Object.entries(options.outputs)) {\n this.outputs.set(cmd, output);\n }\n }\n if (options.errors) {\n for (const [cmd, error] of Object.entries(options.errors)) {\n this.errors.set(cmd, error);\n }\n }\n if (options.installedCommands) {\n for (const cmd of options.installedCommands) {\n this.installedCommands.add(cmd);\n }\n }\n return this;\n }\n\n /**\n * Record command and return simulated output.\n */\n public async run(\n command: string,\n options: ShellRunOptions = {},\n ): Promise<string> {\n this.calls.push({ command, options });\n\n // Check for configured error\n const errorMsg = this.errors.get(command);\n if (errorMsg) {\n throw new Error(errorMsg);\n }\n\n // Return configured output or empty string\n return this.outputs.get(command) ?? \"\";\n }\n\n /**\n * Check if a specific command was called.\n */\n public wasCalled(command: string): boolean {\n return this.calls.some((call) => call.command === command);\n }\n\n /**\n * Check if a command matching a pattern was called.\n */\n public wasCalledMatching(pattern: RegExp): boolean {\n return this.calls.some((call) => pattern.test(call.command));\n }\n\n /**\n * Get all calls matching a pattern.\n */\n public getCallsMatching(pattern: RegExp): MemoryShellCall[] {\n return this.calls.filter((call) => pattern.test(call.command));\n }\n\n /**\n * Check if a command is installed.\n */\n public async isInstalled(command: string): Promise<boolean> {\n return this.installedCommands.has(command);\n }\n\n /**\n * Reset all recorded state.\n */\n public reset(): void {\n this.calls = [];\n this.outputs.clear();\n this.errors.clear();\n this.installedCommands.clear();\n }\n}\n","import { Readable } from \"node:stream\";\n\nexport interface FileTypeResult {\n /**\n * The detected MIME type\n */\n mimeType: string;\n /**\n * The detected file extension\n */\n extension: string;\n /**\n * Whether the file type was verified by magic bytes\n */\n verified: boolean;\n /**\n * The stream (potentially wrapped to allow re-reading)\n */\n stream: Readable;\n}\n\n/**\n * Service for detecting file types and getting content types.\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n *\n * // Get content type from filename\n * const mimeType = detector.getContentType(\"image.png\"); // \"image/png\"\n *\n * // Detect file type by magic bytes\n * const stream = createReadStream('image.png');\n * const result = await detector.detectFileType(stream, 'image.png');\n * console.log(result.mimeType); // 'image/png'\n * console.log(result.verified); // true if magic bytes match\n * ```\n */\nexport class FileDetector {\n /**\n * Magic byte signatures for common file formats.\n * Each signature is represented as an array of bytes or null (wildcard).\n */\n protected static readonly MAGIC_BYTES: Record<\n string,\n { signature: (number | null)[]; mimeType: string }[]\n > = {\n // Images\n png: [\n {\n signature: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],\n mimeType: \"image/png\",\n },\n ],\n jpg: [\n { signature: [0xff, 0xd8, 0xff, 0xe0], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe1], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe2], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe3], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe8], mimeType: \"image/jpeg\" },\n ],\n jpeg: [\n { signature: [0xff, 0xd8, 0xff, 0xe0], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe1], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe2], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe3], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe8], mimeType: \"image/jpeg\" },\n ],\n gif: [\n {\n signature: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61],\n mimeType: \"image/gif\",\n }, // GIF87a\n {\n signature: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61],\n mimeType: \"image/gif\",\n }, // GIF89a\n ],\n webp: [\n {\n signature: [\n 0x52,\n 0x49,\n 0x46,\n 0x46,\n null,\n null,\n null,\n null,\n 0x57,\n 0x45,\n 0x42,\n 0x50,\n ],\n mimeType: \"image/webp\",\n },\n ],\n bmp: [{ signature: [0x42, 0x4d], mimeType: \"image/bmp\" }],\n ico: [{ signature: [0x00, 0x00, 0x01, 0x00], mimeType: \"image/x-icon\" }],\n tiff: [\n { signature: [0x49, 0x49, 0x2a, 0x00], mimeType: \"image/tiff\" }, // Little-endian\n { signature: [0x4d, 0x4d, 0x00, 0x2a], mimeType: \"image/tiff\" }, // Big-endian\n ],\n tif: [\n { signature: [0x49, 0x49, 0x2a, 0x00], mimeType: \"image/tiff\" },\n { signature: [0x4d, 0x4d, 0x00, 0x2a], mimeType: \"image/tiff\" },\n ],\n\n // Documents\n pdf: [\n {\n signature: [0x25, 0x50, 0x44, 0x46, 0x2d],\n mimeType: \"application/pdf\",\n },\n ], // %PDF-\n zip: [\n { signature: [0x50, 0x4b, 0x03, 0x04], mimeType: \"application/zip\" },\n { signature: [0x50, 0x4b, 0x05, 0x06], mimeType: \"application/zip\" },\n { signature: [0x50, 0x4b, 0x07, 0x08], mimeType: \"application/zip\" },\n ],\n\n // Archives\n rar: [\n {\n signature: [0x52, 0x61, 0x72, 0x21, 0x1a, 0x07],\n mimeType: \"application/vnd.rar\",\n },\n ],\n \"7z\": [\n {\n signature: [0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c],\n mimeType: \"application/x-7z-compressed\",\n },\n ],\n tar: [\n {\n signature: [0x75, 0x73, 0x74, 0x61, 0x72],\n mimeType: \"application/x-tar\",\n },\n ],\n gz: [{ signature: [0x1f, 0x8b], mimeType: \"application/gzip\" }],\n tgz: [{ signature: [0x1f, 0x8b], mimeType: \"application/gzip\" }],\n\n // Audio\n mp3: [\n { signature: [0xff, 0xfb], mimeType: \"audio/mpeg\" },\n { signature: [0xff, 0xf3], mimeType: \"audio/mpeg\" },\n { signature: [0xff, 0xf2], mimeType: \"audio/mpeg\" },\n { signature: [0x49, 0x44, 0x33], mimeType: \"audio/mpeg\" }, // ID3\n ],\n wav: [\n {\n signature: [\n 0x52,\n 0x49,\n 0x46,\n 0x46,\n null,\n null,\n null,\n null,\n 0x57,\n 0x41,\n 0x56,\n 0x45,\n ],\n mimeType: \"audio/wav\",\n },\n ],\n ogg: [{ signature: [0x4f, 0x67, 0x67, 0x53], mimeType: \"audio/ogg\" }],\n flac: [{ signature: [0x66, 0x4c, 0x61, 0x43], mimeType: \"audio/flac\" }], // fLaC\n\n // Video\n mp4: [\n {\n signature: [null, null, null, null, 0x66, 0x74, 0x79, 0x70],\n mimeType: \"video/mp4\",\n }, // ftyp\n {\n signature: [\n null,\n null,\n null,\n null,\n 0x66,\n 0x74,\n 0x79,\n 0x70,\n 0x69,\n 0x73,\n 0x6f,\n 0x6d,\n ],\n mimeType: \"video/mp4\",\n }, // ftypisom\n {\n signature: [\n null,\n null,\n null,\n null,\n 0x66,\n 0x74,\n 0x79,\n 0x70,\n 0x6d,\n 0x70,\n 0x34,\n 0x32,\n ],\n mimeType: \"video/mp4\",\n }, // ftypmp42\n ],\n webm: [{ signature: [0x1a, 0x45, 0xdf, 0xa3], mimeType: \"video/webm\" }],\n avi: [\n {\n signature: [\n 0x52,\n 0x49,\n 0x46,\n 0x46,\n null,\n null,\n null,\n null,\n 0x41,\n 0x56,\n 0x49,\n 0x20,\n ],\n mimeType: \"video/x-msvideo\",\n },\n ],\n mov: [\n {\n signature: [\n null,\n null,\n null,\n null,\n 0x66,\n 0x74,\n 0x79,\n 0x70,\n 0x71,\n 0x74,\n 0x20,\n 0x20,\n ],\n mimeType: \"video/quicktime\",\n },\n ],\n mkv: [\n { signature: [0x1a, 0x45, 0xdf, 0xa3], mimeType: \"video/x-matroska\" },\n ],\n\n // Office (DOCX, XLSX, PPTX are all ZIP-based)\n docx: [\n {\n signature: [0x50, 0x4b, 0x03, 0x04],\n mimeType:\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n },\n ],\n xlsx: [\n {\n signature: [0x50, 0x4b, 0x03, 0x04],\n mimeType:\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n },\n ],\n pptx: [\n {\n signature: [0x50, 0x4b, 0x03, 0x04],\n mimeType:\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n },\n ],\n doc: [\n {\n signature: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1],\n mimeType: \"application/msword\",\n },\n ],\n xls: [\n {\n signature: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1],\n mimeType: \"application/vnd.ms-excel\",\n },\n ],\n ppt: [\n {\n signature: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1],\n mimeType: \"application/vnd.ms-powerpoint\",\n },\n ],\n };\n\n /**\n * All possible format signatures for checking against actual file content\n */\n protected static readonly ALL_SIGNATURES = Object.entries(\n FileDetector.MAGIC_BYTES,\n ).flatMap(([ext, signatures]) => signatures.map((sig) => ({ ext, ...sig })));\n\n /**\n * MIME type map for file extensions.\n *\n * Can be used to get the content type of file based on its extension.\n * Feel free to add more mime types in your project!\n */\n public static readonly mimeMap: Record<string, string> = {\n // Documents\n json: \"application/json\",\n txt: \"text/plain\",\n html: \"text/html\",\n htm: \"text/html\",\n xml: \"application/xml\",\n csv: \"text/csv\",\n pdf: \"application/pdf\",\n md: \"text/markdown\",\n markdown: \"text/markdown\",\n rtf: \"application/rtf\",\n\n // Styles and scripts\n css: \"text/css\",\n js: \"application/javascript\",\n mjs: \"application/javascript\",\n ts: \"application/typescript\",\n jsx: \"text/jsx\",\n tsx: \"text/tsx\",\n\n // Archives\n zip: \"application/zip\",\n rar: \"application/vnd.rar\",\n \"7z\": \"application/x-7z-compressed\",\n tar: \"application/x-tar\",\n gz: \"application/gzip\",\n tgz: \"application/gzip\",\n\n // Images\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n tiff: \"image/tiff\",\n tif: \"image/tiff\",\n\n // Audio\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n ogg: \"audio/ogg\",\n m4a: \"audio/mp4\",\n aac: \"audio/aac\",\n flac: \"audio/flac\",\n\n // Video\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n avi: \"video/x-msvideo\",\n mov: \"video/quicktime\",\n wmv: \"video/x-ms-wmv\",\n flv: \"video/x-flv\",\n mkv: \"video/x-matroska\",\n\n // Office\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xls: \"application/vnd.ms-excel\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n ppt: \"application/vnd.ms-powerpoint\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n\n // Fonts\n woff: \"font/woff\",\n woff2: \"font/woff2\",\n ttf: \"font/ttf\",\n otf: \"font/otf\",\n eot: \"application/vnd.ms-fontobject\",\n };\n\n /**\n * Reverse MIME type map for looking up extensions from MIME types.\n * Prefers shorter, more common extensions when multiple exist.\n */\n protected static readonly reverseMimeMap: Record<string, string> = (() => {\n const reverse: Record<string, string> = {};\n // Process in order so common extensions come first\n for (const [ext, mimeType] of Object.entries(FileDetector.mimeMap)) {\n // Only set if not already set (prefer first/shorter extension)\n if (!reverse[mimeType]) {\n reverse[mimeType] = ext;\n }\n }\n return reverse;\n })();\n\n /**\n * Returns the file extension for a given MIME type.\n *\n * @param mimeType - The MIME type to look up\n * @returns The file extension (without dot), or \"bin\" if not found\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n * const ext = detector.getExtensionFromMimeType(\"image/png\"); // \"png\"\n * const ext2 = detector.getExtensionFromMimeType(\"application/octet-stream\"); // \"bin\"\n * ```\n */\n getExtensionFromMimeType(mimeType: string): string {\n return FileDetector.reverseMimeMap[mimeType] || \"bin\";\n }\n /**\n * Returns the content type of file based on its filename.\n *\n * @param filename - The filename to check\n * @returns The MIME type\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n * const mimeType = detector.getContentType(\"image.png\"); // \"image/png\"\n * ```\n */\n getContentType(filename: string): string {\n const ext = filename.toLowerCase().split(\".\").pop() || \"\";\n return FileDetector.mimeMap[ext] || \"application/octet-stream\";\n }\n\n /**\n * Detects the file type by checking magic bytes against the stream content.\n *\n * @param stream - The readable stream to check\n * @param filename - The filename (used to get the extension)\n * @returns File type information including MIME type, extension, and verification status\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n * const stream = createReadStream('image.png');\n * const result = await detector.detectFileType(stream, 'image.png');\n * console.log(result.mimeType); // 'image/png'\n * console.log(result.verified); // true if magic bytes match\n * ```\n */\n async detectFileType(\n stream: Readable,\n filename: string,\n ): Promise<FileTypeResult> {\n // Get the expected MIME type from the filename extension\n const expectedMimeType = this.getContentType(filename);\n\n // Extract extension - only if filename contains a dot\n const lastDotIndex = filename.lastIndexOf(\".\");\n const ext =\n lastDotIndex > 0\n ? filename.substring(lastDotIndex + 1).toLowerCase()\n : \"\";\n\n // Read the first 16 bytes (enough for most magic byte checks)\n const { buffer, stream: newStream } = await this.peekBytes(stream, 16);\n\n // First, check if the extension's expected signature matches\n const expectedSignatures = FileDetector.MAGIC_BYTES[ext];\n if (expectedSignatures) {\n for (const { signature, mimeType } of expectedSignatures) {\n if (this.matchesSignature(buffer, signature)) {\n return {\n mimeType,\n extension: ext,\n verified: true,\n stream: newStream,\n };\n }\n }\n }\n\n // If the expected signature didn't match, try all other signatures\n for (const {\n ext: detectedExt,\n signature,\n mimeType,\n } of FileDetector.ALL_SIGNATURES) {\n if (detectedExt !== ext && this.matchesSignature(buffer, signature)) {\n return {\n mimeType,\n extension: detectedExt,\n verified: true,\n stream: newStream,\n };\n }\n }\n\n // If no magic bytes matched, fall back to extension-based detection\n // or return binary if extension is not recognized\n return {\n mimeType: expectedMimeType,\n extension: ext,\n verified: false,\n stream: newStream,\n };\n }\n\n /**\n * Reads all bytes from a stream and returns the first N bytes along with a new stream containing all data.\n * This approach reads the entire stream upfront to avoid complex async handling issues.\n *\n * @protected\n */\n protected async peekBytes(\n stream: Readable,\n numBytes: number,\n ): Promise<{ buffer: Buffer; stream: Readable }> {\n const chunks: Buffer[] = [];\n\n // Read the entire stream\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n const allData = Buffer.concat(chunks);\n const buffer = allData.subarray(0, numBytes);\n\n // Create a new stream with all the data\n const newStream = Readable.from(allData);\n\n return { buffer, stream: newStream };\n }\n\n /**\n * Checks if a buffer matches a magic byte signature.\n *\n * @protected\n */\n protected matchesSignature(\n buffer: Buffer,\n signature: (number | null)[],\n ): boolean {\n if (buffer.length < signature.length) {\n return false;\n }\n\n for (let i = 0; i < signature.length; i++) {\n if (signature[i] !== null && buffer[i] !== signature[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n","import { createReadStream } from \"node:fs\";\nimport {\n access,\n copyFile,\n cp as fsCp,\n mkdir as fsMkdir,\n readFile as fsReadFile,\n rm as fsRm,\n writeFile as fsWriteFile,\n readdir,\n rename,\n stat,\n} from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { PassThrough, Readable } from \"node:stream\";\nimport type { ReadableStream as NodeWebStream } from \"node:stream/web\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n $inject,\n AlephaError,\n type FileLike,\n isFileLike,\n Json,\n type StreamLike,\n} from \"alepha\";\nimport { FileDetector } from \"../services/FileDetector.ts\";\nimport type {\n CpOptions,\n CreateFileOptions,\n FileSystemProvider,\n LsOptions,\n MkdirOptions,\n RmOptions,\n} from \"./FileSystemProvider.ts\";\n\n/**\n * Node.js implementation of FileSystem interface.\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Create from URL\n * const file1 = fs.createFile({ url: \"file:///path/to/file.png\" });\n *\n * // Create from Buffer\n * const file2 = fs.createFile({ buffer: Buffer.from(\"hello\"), name: \"hello.txt\" });\n *\n * // Create from text\n * const file3 = fs.createFile({ text: \"Hello, world!\", name: \"greeting.txt\" });\n *\n * // File operations\n * await fs.mkdir(\"/tmp/mydir\", { recursive: true });\n * await fs.cp(\"/src/file.txt\", \"/dest/file.txt\");\n * await fs.mv(\"/old/path.txt\", \"/new/path.txt\");\n * const files = await fs.ls(\"/tmp\");\n * await fs.rm(\"/tmp/file.txt\");\n * ```\n */\nexport class NodeFileSystemProvider implements FileSystemProvider {\n protected detector = $inject(FileDetector);\n protected json = $inject(Json);\n\n public join(...paths: string[]): string {\n return join(...paths);\n }\n\n /**\n * Creates a FileLike object from various sources.\n *\n * @param options - Options for creating the file\n * @returns A FileLike object\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // From URL\n * const file1 = fs.createFile({ url: \"https://example.com/image.png\" });\n *\n * // From Buffer\n * const file2 = fs.createFile({\n * buffer: Buffer.from(\"hello\"),\n * name: \"hello.txt\",\n * type: \"text/plain\"\n * });\n *\n * // From text\n * const file3 = fs.createFile({ text: \"Hello!\", name: \"greeting.txt\" });\n *\n * // From stream with detection\n * const stream = createReadStream(\"/path/to/file.png\");\n * const file4 = fs.createFile({ stream, name: \"image.png\" });\n * ```\n */\n createFile(options: CreateFileOptions): FileLike {\n if (\"path\" in options) {\n const path = options.path;\n const filename = path.split(\"/\").pop() || \"file\";\n return this.createFileFromUrl(`file://${path}`, {\n type: options.type,\n name: options.name || filename,\n });\n }\n\n // Handle URL\n if (\"url\" in options) {\n return this.createFileFromUrl(options.url, {\n type: options.type,\n name: options.name,\n });\n }\n\n if (\"response\" in options) {\n if (!options.response.body) {\n throw new AlephaError(\"Response has no body stream\");\n }\n const res = options.response;\n // guess size from content-length header if available\n const sizeHeader = res.headers.get(\"content-length\");\n const size = sizeHeader ? parseInt(sizeHeader, 10) : undefined;\n // guess name from content-disposition header if available\n let name = options.name;\n const contentDisposition = res.headers.get(\"content-disposition\");\n if (contentDisposition && !name) {\n const match = contentDisposition.match(/filename=\"?([^\"]+)\"?/);\n if (match) {\n name = match[1];\n }\n }\n // guess type from content-type header if available\n const type = options.type || res.headers.get(\"content-type\") || undefined;\n return this.createFileFromStream(options.response.body, {\n type,\n name,\n size,\n });\n }\n\n // Handle Web File\n if (\"file\" in options) {\n return this.createFileFromWebFile(options.file, {\n type: options.type,\n name: options.name,\n size: options.size,\n });\n }\n\n // Handle Buffer\n if (\"buffer\" in options) {\n return this.createFileFromBuffer(options.buffer, {\n type: options.type,\n name: options.name,\n });\n }\n\n // Handle ArrayBuffer\n if (\"arrayBuffer\" in options) {\n return this.createFileFromBuffer(Buffer.from(options.arrayBuffer), {\n type: options.type,\n name: options.name,\n });\n }\n\n // Handle text\n if (\"text\" in options) {\n return this.createFileFromBuffer(Buffer.from(options.text, \"utf-8\"), {\n type: options.type || \"text/plain\",\n name: options.name || \"file.txt\",\n });\n }\n\n // Handle stream\n if (\"stream\" in options) {\n return this.createFileFromStream(options.stream, {\n type: options.type,\n name: options.name,\n size: options.size,\n });\n }\n\n throw new AlephaError(\n \"Invalid createFile options: no valid source provided\",\n );\n }\n\n /**\n * Removes a file or directory.\n *\n * @param path - The path to remove\n * @param options - Remove options\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Remove a file\n * await fs.rm(\"/tmp/file.txt\");\n *\n * // Remove a directory recursively\n * await fs.rm(\"/tmp/mydir\", { recursive: true });\n *\n * // Remove with force (no error if doesn't exist)\n * await fs.rm(\"/tmp/maybe-exists.txt\", { force: true });\n * ```\n */\n async rm(path: string, options?: RmOptions): Promise<void> {\n await fsRm(path, options);\n }\n\n /**\n * Copies a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n * @param options - Copy options\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Copy a file\n * await fs.cp(\"/src/file.txt\", \"/dest/file.txt\");\n *\n * // Copy a directory recursively\n * await fs.cp(\"/src/dir\", \"/dest/dir\", { recursive: true });\n *\n * // Copy with force (overwrite existing)\n * await fs.cp(\"/src/file.txt\", \"/dest/file.txt\", { force: true });\n * ```\n */\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n // Check if source is a directory\n const srcStat = await stat(src);\n\n if (srcStat.isDirectory()) {\n if (!options?.recursive) {\n throw new Error(\n `Cannot copy directory without recursive option: ${src}`,\n );\n }\n // Use Node.js cp function for recursive directory copy\n await fsCp(src, dest, {\n recursive: true,\n force: options?.force ?? false,\n });\n } else {\n // For files, use copyFile\n await copyFile(src, dest);\n }\n }\n\n /**\n * Moves/renames a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Move/rename a file\n * await fs.mv(\"/old/path.txt\", \"/new/path.txt\");\n *\n * // Move a directory\n * await fs.mv(\"/old/dir\", \"/new/dir\");\n * ```\n */\n async mv(src: string, dest: string): Promise<void> {\n await rename(src, dest);\n }\n\n /**\n * Creates a directory.\n *\n * @param path - The directory path to create\n * @param options - Mkdir options\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Create a directory\n * await fs.mkdir(\"/tmp/mydir\");\n *\n * // Create nested directories\n * await fs.mkdir(\"/tmp/path/to/dir\", { recursive: true });\n *\n * // Create with specific permissions\n * await fs.mkdir(\"/tmp/mydir\", { mode: 0o755 });\n * ```\n */\n async mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n const p = fsMkdir(path, {\n recursive: options.recursive ?? true,\n mode: options.mode,\n });\n\n if (options.force === false) {\n await p;\n } else {\n await p.catch(() => {});\n }\n }\n\n /**\n * Lists files in a directory.\n *\n * @param path - The directory path to list\n * @param options - List options\n * @returns Array of filenames\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // List files in a directory\n * const files = await fs.ls(\"/tmp\");\n * console.log(files); // [\"file1.txt\", \"file2.txt\", \"subdir\"]\n *\n * // List with hidden files\n * const allFiles = await fs.ls(\"/tmp\", { hidden: true });\n *\n * // List recursively\n * const allFilesRecursive = await fs.ls(\"/tmp\", { recursive: true });\n * ```\n */\n async ls(path: string, options?: LsOptions): Promise<string[]> {\n const entries = await readdir(path);\n\n // Filter out hidden files if not requested\n const filteredEntries = options?.hidden\n ? entries\n : entries.filter((e) => !e.startsWith(\".\"));\n\n // If recursive, get all nested files\n if (options?.recursive) {\n const allFiles: string[] = [];\n\n for (const entry of filteredEntries) {\n const fullPath = join(path, entry);\n const entryStat = await stat(fullPath);\n\n if (entryStat.isDirectory()) {\n // Add directory entry\n allFiles.push(entry);\n // Recursively get files from subdirectory\n const subFiles = await this.ls(fullPath, options);\n allFiles.push(...subFiles.map((f) => join(entry, f)));\n } else {\n allFiles.push(entry);\n }\n }\n\n return allFiles;\n }\n\n return filteredEntries;\n }\n\n /**\n * Checks if a file or directory exists.\n *\n * @param path - The path to check\n * @returns True if the path exists, false otherwise\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * if (await fs.exists(\"/tmp/file.txt\")) {\n * console.log(\"File exists\");\n * }\n * ```\n */\n async exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Reads the content of a file.\n *\n * @param path - The file path to read\n * @returns The file content as a Buffer\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * const buffer = await fs.readFile(\"/tmp/file.txt\");\n * console.log(buffer.toString(\"utf-8\"));\n * ```\n */\n async readFile(path: string): Promise<Buffer> {\n return await fsReadFile(path);\n }\n\n /**\n * Writes data to a file.\n *\n * @param path - The file path to write to\n * @param data - The data to write (Buffer or string)\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Write string\n * await fs.writeFile(\"/tmp/file.txt\", \"Hello, world!\");\n *\n * // Write Buffer\n * await fs.writeFile(\"/tmp/file.bin\", Buffer.from([0x01, 0x02, 0x03]));\n * ```\n */\n async writeFile(\n path: string,\n data: Uint8Array | Buffer | string | FileLike,\n ): Promise<void> {\n if (isFileLike(data)) {\n await fsWriteFile(path, Readable.from(data.stream()));\n return;\n }\n await fsWriteFile(path, data);\n }\n\n /**\n * Reads the content of a file as a string.\n *\n * @param path - The file path to read\n * @returns The file content as a string\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n * const content = await fs.readTextFile(\"/tmp/file.txt\");\n * ```\n */\n async readTextFile(path: string): Promise<string> {\n const buffer = await this.readFile(path);\n return buffer.toString(\"utf-8\");\n }\n\n /**\n * Reads the content of a file as JSON.\n *\n * @param path - The file path to read\n * @returns The parsed JSON content\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n * const config = await fs.readJsonFile<{ name: string }>(\"/tmp/config.json\");\n * ```\n */\n async readJsonFile<T = unknown>(path: string): Promise<T> {\n const text = await this.readTextFile(path);\n return this.json.parse(text) as T;\n }\n\n /**\n * Creates a FileLike object from a Web File.\n *\n * @protected\n */\n protected createFileFromWebFile(\n source: File,\n options: {\n type?: string;\n name?: string;\n size?: number;\n } = {},\n ): FileLike {\n const name = options.name ?? source.name;\n return {\n name,\n type: options.type ?? (source.type || this.detector.getContentType(name)),\n size: options.size ?? source.size ?? 0,\n lastModified: source.lastModified || Date.now(),\n stream: () => source.stream(),\n arrayBuffer: async (): Promise<ArrayBuffer> => {\n return await source.arrayBuffer();\n },\n text: async (): Promise<string> => {\n return await source.text();\n },\n };\n }\n\n /**\n * Creates a FileLike object from a Buffer.\n *\n * @protected\n */\n protected createFileFromBuffer(\n source: Buffer,\n options: {\n type?: string;\n name?: string;\n } = {},\n ): FileLike {\n const name: string = options.name ?? \"file\";\n return {\n name,\n type: options.type ?? this.detector.getContentType(options.name ?? name),\n size: source.byteLength,\n lastModified: Date.now(),\n stream: (): Readable => Readable.from(source),\n arrayBuffer: async (): Promise<ArrayBuffer> => {\n return this.bufferToArrayBuffer(source);\n },\n text: async (): Promise<string> => {\n return source.toString(\"utf-8\");\n },\n };\n }\n\n /**\n * Creates a FileLike object from a stream.\n *\n * @protected\n */\n protected createFileFromStream(\n source: StreamLike,\n options: {\n type?: string;\n name?: string;\n size?: number;\n } = {},\n ): FileLike & { _buffer: null | Buffer } {\n let buffer: Buffer | null = null;\n\n return {\n name: options.name ?? \"file\",\n type:\n options.type ?? this.detector.getContentType(options.name ?? \"file\"),\n size: options.size ?? 0,\n lastModified: Date.now(),\n stream: () => source,\n _buffer: null as Buffer | null,\n arrayBuffer: async () => {\n buffer ??= await this.streamToBuffer(source);\n return this.bufferToArrayBuffer(buffer);\n },\n text: async () => {\n buffer ??= await this.streamToBuffer(source);\n return buffer.toString(\"utf-8\");\n },\n };\n }\n\n /**\n * Creates a FileLike object from a URL.\n *\n * @protected\n */\n protected createFileFromUrl(\n url: string,\n options: {\n type?: string;\n name?: string;\n } = {},\n ): FileLike {\n const parsedUrl = new URL(url);\n const filename =\n options.name || parsedUrl.pathname.split(\"/\").pop() || \"file\";\n let buffer: Buffer | null = null;\n\n return {\n name: filename,\n type: options.type ?? this.detector.getContentType(filename),\n size: 0, // Unknown size until loaded\n lastModified: Date.now(),\n stream: () => this.createStreamFromUrl(url),\n arrayBuffer: async () => {\n buffer ??= await this.loadFromUrl(url);\n return this.bufferToArrayBuffer(buffer);\n },\n text: async () => {\n buffer ??= await this.loadFromUrl(url);\n return buffer.toString(\"utf-8\");\n },\n filepath: url,\n };\n }\n\n /**\n * Gets a streaming response from a URL.\n *\n * @protected\n */\n protected getStreamingResponse(url: string): Readable {\n const stream = new PassThrough();\n\n fetch(url)\n .then((res) =>\n Readable.fromWeb(res.body as unknown as NodeWebStream).pipe(stream),\n )\n .catch((err) => stream.destroy(err));\n\n return stream;\n }\n\n /**\n * Loads data from a URL.\n *\n * @protected\n */\n protected async loadFromUrl(url: string): Promise<Buffer> {\n const parsedUrl = new URL(url);\n\n if (parsedUrl.protocol === \"file:\") {\n // Handle file:// URLs\n const filePath = fileURLToPath(url);\n return await fsReadFile(filePath);\n } else if (\n parsedUrl.protocol === \"http:\" ||\n parsedUrl.protocol === \"https:\"\n ) {\n // Handle HTTP/HTTPS URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(\n `Failed to fetch ${url}: ${response.status} ${response.statusText}`,\n );\n }\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n } else {\n throw new Error(`Unsupported protocol: ${parsedUrl.protocol}`);\n }\n }\n\n /**\n * Creates a stream from a URL.\n *\n * @protected\n */\n protected createStreamFromUrl(url: string): Readable {\n const parsedUrl = new URL(url);\n\n if (parsedUrl.protocol === \"file:\") {\n // For file:// URLs, create a stream that reads the file\n return createReadStream(fileURLToPath(url));\n } else if (\n parsedUrl.protocol === \"http:\" ||\n parsedUrl.protocol === \"https:\"\n ) {\n // For HTTP/HTTPS URLs, create a stream that fetches the content\n return this.getStreamingResponse(url);\n } else {\n throw new AlephaError(`Unsupported protocol: ${parsedUrl.protocol}`);\n }\n }\n\n /**\n * Converts a stream-like object to a Buffer.\n *\n * @protected\n */\n protected async streamToBuffer(streamLike: StreamLike): Promise<Buffer> {\n const stream =\n streamLike instanceof Readable\n ? streamLike\n : Readable.fromWeb(streamLike as NodeWebStream);\n\n return new Promise<Buffer>((resolve, reject) => {\n const buffer: any[] = [];\n stream.on(\"data\", (chunk) => buffer.push(Buffer.from(chunk)));\n stream.on(\"end\", () => resolve(Buffer.concat(buffer)));\n stream.on(\"error\", (err) =>\n reject(new AlephaError(\"Error converting stream\", { cause: err })),\n );\n });\n }\n\n /**\n * Converts a Node.js Buffer to an ArrayBuffer.\n *\n * @protected\n */\n protected bufferToArrayBuffer(buffer: Buffer): ArrayBuffer {\n return buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer;\n }\n}\n","import { exec, spawn } from \"node:child_process\";\nimport { $inject, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"./FileSystemProvider.ts\";\nimport type { ShellProvider, ShellRunOptions } from \"./ShellProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Node.js implementation of ShellProvider.\n *\n * Executes shell commands using Node.js child_process module.\n * Supports binary resolution from node_modules/.bin for local packages.\n */\nexport class NodeShellProvider implements ShellProvider {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Run a shell command or binary.\n */\n public async run(\n command: string,\n options: ShellRunOptions = {},\n ): Promise<string> {\n const { resolve = false, capture = false, root, env } = options;\n const cwd = root ?? process.cwd();\n\n this.log.debug(`Shell: ${command}`, { cwd, resolve, capture });\n\n let executable: string;\n let args: string[];\n\n if (resolve) {\n const [bin, ...rest] = command.split(\" \");\n executable = await this.resolveExecutable(bin, cwd);\n args = rest;\n } else {\n [executable, ...args] = command.split(\" \");\n }\n\n if (capture) {\n return this.execCapture(command, { cwd, env });\n }\n\n return this.execInherit(executable, args, { cwd, env });\n }\n\n /**\n * Execute command with inherited stdio (streams to terminal).\n */\n protected async execInherit(\n executable: string,\n args: string[],\n options: { cwd: string; env?: Record<string, string> },\n ): Promise<string> {\n const proc = spawn(executable, args, {\n stdio: \"inherit\",\n cwd: options.cwd,\n env: {\n ...process.env,\n ...options.env,\n },\n });\n\n return new Promise<string>((resolve, reject) => {\n proc.on(\"exit\", (code) => {\n if (code === 0 || code === null) {\n resolve(\"\");\n } else {\n reject(new AlephaError(`Command exited with code ${code}`));\n }\n });\n proc.on(\"error\", reject);\n });\n }\n\n /**\n * Execute command and capture stdout.\n */\n protected execCapture(\n command: string,\n options: { cwd: string; env?: Record<string, string> },\n ): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n exec(\n command,\n {\n cwd: options.cwd,\n env: {\n ...process.env,\n LOG_FORMAT: \"pretty\",\n ...options.env,\n },\n },\n (err, stdout) => {\n if (err) {\n (err as any).stdout = stdout;\n reject(err);\n } else {\n resolve(stdout);\n }\n },\n );\n });\n }\n\n /**\n * Resolve executable path from node_modules/.bin.\n *\n * Search order:\n * 1. Local: node_modules/.bin/\n * 2. Pnpm nested: node_modules/alepha/node_modules/.bin/\n * 3. Monorepo: Walk up to 3 parent directories\n */\n protected async resolveExecutable(\n name: string,\n root: string,\n ): Promise<string> {\n const suffix = process.platform === \"win32\" ? \".cmd\" : \"\";\n\n // 1. Local node_modules\n let execPath = await this.findExecutable(\n root,\n `node_modules/.bin/${name}${suffix}`,\n );\n\n // 2. Pnpm nested (alepha's own node_modules)\n if (!execPath) {\n execPath = await this.findExecutable(\n root,\n `node_modules/alepha/node_modules/.bin/${name}${suffix}`,\n );\n }\n\n // 3. Monorepo: check parent directories (up to 3 levels)\n if (!execPath) {\n let parentDir = this.fs.join(root, \"..\");\n for (let i = 0; i < 3; i++) {\n execPath = await this.findExecutable(\n parentDir,\n `node_modules/.bin/${name}${suffix}`,\n );\n if (execPath) break;\n parentDir = this.fs.join(parentDir, \"..\");\n }\n }\n\n if (!execPath) {\n throw new AlephaError(\n `Could not find executable for '${name}'. Make sure the package is installed.`,\n );\n }\n\n return execPath;\n }\n\n /**\n * Check if executable exists at path.\n */\n protected async findExecutable(\n root: string,\n relativePath: string,\n ): Promise<string | undefined> {\n const fullPath = this.fs.join(root, relativePath);\n if (await this.fs.exists(fullPath)) {\n return fullPath;\n }\n return undefined;\n }\n\n /**\n * Check if a command is installed and available in the system PATH.\n */\n public isInstalled(command: string): Promise<boolean> {\n return new Promise((resolve) => {\n const check =\n process.platform === \"win32\"\n ? `where ${command}`\n : `command -v ${command}`;\n exec(check, (error) => resolve(!error));\n });\n }\n}\n","// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface ShellRunOptions {\n /**\n * Working directory for the command.\n */\n root?: string;\n\n /**\n * Additional environment variables.\n */\n env?: Record<string, string>;\n\n /**\n * Resolve the executable from node_modules/.bin.\n * Supports local project, pnpm nested, and monorepo structures.\n * @default false\n */\n resolve?: boolean;\n\n /**\n * Capture stdout instead of inheriting stdio.\n * When true, returns stdout as string.\n * When false, streams output to terminal.\n * @default false\n */\n capture?: boolean;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Abstract provider for executing shell commands and binaries.\n *\n * Implementations:\n * - `NodeShellProvider` - Real shell execution using Node.js child_process\n * - `MemoryShellProvider` - In-memory mock for testing\n *\n * @example\n * ```typescript\n * class MyService {\n * protected readonly shell = $inject(ShellProvider);\n *\n * async build() {\n * // Run shell command directly\n * await this.shell.run(\"yarn install\");\n *\n * // Run local binary with resolution\n * await this.shell.run(\"vite build\", { resolve: true });\n *\n * // Capture output\n * const output = await this.shell.run(\"echo hello\", { capture: true });\n * }\n * }\n * ```\n */\nexport abstract class ShellProvider {\n /**\n * Run a shell command or binary.\n *\n * @param command - The command to run\n * @param options - Execution options\n * @returns stdout if capture is true, empty string otherwise\n */\n abstract run(command: string, options?: ShellRunOptions): Promise<string>;\n\n /**\n * Check if a command is installed and available in the system PATH.\n *\n * @param command - The command name to check\n * @returns true if the command is available\n */\n abstract isInstalled(command: string): Promise<boolean>;\n}\n","import { $module } from \"alepha\";\nimport { FileSystemProvider } from \"./providers/FileSystemProvider.ts\";\nimport { MemoryFileSystemProvider } from \"./providers/MemoryFileSystemProvider.ts\";\nimport { MemoryShellProvider } from \"./providers/MemoryShellProvider.ts\";\nimport { NodeFileSystemProvider } from \"./providers/NodeFileSystemProvider.ts\";\nimport { NodeShellProvider } from \"./providers/NodeShellProvider.ts\";\nimport { ShellProvider } from \"./providers/ShellProvider.ts\";\nimport { FileDetector } from \"./services/FileDetector.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./errors/FileError.ts\";\nexport * from \"./providers/FileSystemProvider.ts\";\nexport * from \"./providers/MemoryFileSystemProvider.ts\";\nexport * from \"./providers/MemoryShellProvider.ts\";\nexport * from \"./providers/NodeFileSystemProvider.ts\";\nexport * from \"./providers/NodeShellProvider.ts\";\nexport * from \"./providers/ShellProvider.ts\";\nexport * from \"./services/FileDetector.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * | type | quality | stability |\n * |------|---------|-----------|\n * | tooling | standard | stable |\n *\n * System-level abstractions for portable code across runtimes.\n *\n * **Features:**\n * - File system operations (read, write, exists, etc.)\n * - Shell command execution\n * - File type detection and MIME utilities\n * - Memory implementations for testing\n *\n * @module alepha.system\n */\nexport const AlephaSystem = $module({\n name: \"alepha.system\",\n primitives: [],\n services: [\n FileDetector,\n FileSystemProvider,\n MemoryFileSystemProvider,\n NodeFileSystemProvider,\n ShellProvider,\n MemoryShellProvider,\n NodeShellProvider,\n ],\n register: (alepha) =>\n alepha\n .with({\n optional: true,\n provide: FileSystemProvider,\n use: NodeFileSystemProvider,\n })\n .with({\n optional: true,\n provide: ShellProvider,\n use: alepha.isTest() ? MemoryShellProvider : NodeShellProvider,\n }),\n});\n","/**\n * Used for identifying primitives.\n *\n * @internal\n */\nexport const KIND: unique symbol = Symbol.for(\"Alepha.Kind\");\n","import type { TArray } from \"typebox\";\nimport { KIND } from \"../constants/KIND.ts\";\nimport type {\n Static,\n TObject,\n TOptionalAdd,\n} from \"../providers/TypeProvider.ts\";\n\n/**\n * Define an atom for state management.\n *\n * Atom lets you define a piece of state with a name, schema, and default value.\n *\n * By default, Alepha state is just a simple key-value store.\n * Using atoms allows you to have type safety, validation, and default values for your state.\n *\n * You control how state is structured and validated.\n *\n * Features:\n * - Set a schema for validation\n * - Set a default value for initial state\n * - Rules, like read-only, custom validation, etc.\n * - Automatic getter access in services with {@link $use}\n * - SSR support (server state automatically serialized and hydrated on client)\n * - React integration (useAtom hook for automatic component re-renders)\n * - Middleware\n * - Persistence adapters (localStorage, Redis, database, file system, cookie, etc.)\n * - State migrations (version upgrades when schema changes)\n * - Documentation generation & devtools integration\n *\n * Common use cases:\n * - user preferences\n * - feature flags\n * - configuration options\n * - session data\n *\n * Atom must contain only serializable data.\n * Avoid storing complex objects like class instances, functions, or DOM elements.\n * If you need to store complex data, consider using identifiers or references instead.\n */\nexport const $atom = <\n T extends TObject<TProperties> | TArray,\n N extends string,\n>(\n options: AtomOptions<T, N>,\n): Atom<T, N> => {\n return new Atom<T, N>(options);\n};\n\nexport type AtomOptions<T extends TAtomObject, N extends string> = {\n name: N;\n schema: T;\n description?: string;\n} & (T extends TOptionalAdd<T>\n ? {\n default?: Static<T>;\n }\n : {\n default: Static<T>;\n });\n\nexport class Atom<T extends TAtomObject = TObject, N extends string = string> {\n public readonly options: AtomOptions<T, N>;\n\n public get schema(): T {\n return this.options.schema;\n }\n\n public get key(): N {\n return this.options.name;\n }\n\n constructor(options: AtomOptions<T, N>) {\n this.options = options;\n }\n}\n\n$atom[KIND] = \"atom\";\n\ntype TProperties = any; // it's required to avoid required [ string ] error, ...\n\nexport type TAtomObject = TObject<any> | TArray;\nexport type AtomStatic<T extends TAtomObject> =\n T extends TOptionalAdd<T> ? Static<T> | undefined : Static<T>;\n","import { type Static, t } from \"alepha\";\nimport { $atom } from \"../../core/primitives/$atom.ts\";\n\n/**\n * Deployment target for the build output.\n *\n * - `docker` - Generate Dockerfile for containerized deployment\n * - `vercel` - Generate Vercel deployment configuration (forces node runtime)\n * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime)\n */\nexport type BuildTarget = \"bare\" | \"docker\" | \"vercel\" | \"cloudflare\";\n\n/**\n * JavaScript runtime for the build output.\n *\n * - `node` - Node.js runtime (default)\n * - `bun` - Bun runtime (uses bun export conditions)\n * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target)\n */\nexport type BuildRuntime = \"node\" | \"bun\" | \"workerd\";\n\n/**\n * Build options atom for CLI build command.\n *\n * Defines the available build configuration options with their defaults.\n * Options can be overridden via alepha.config.ts or CLI flags.\n */\nexport const buildOptions = $atom({\n name: \"alepha.cli.build.options\",\n description: \"Build configuration options\",\n schema: t.object({\n /**\n * Generate build stats report.\n */\n stats: t.optional(t.boolean({ default: false })),\n\n /**\n * Deployment target for the build output.\n *\n * - `docker` - Generate Dockerfile for containerized deployment\n * - `vercel` - Generate Vercel deployment configuration (forces node runtime)\n * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime)\n */\n target: t.optional(t.enum([\"bare\", \"docker\", \"vercel\", \"cloudflare\"])),\n\n /**\n * JavaScript runtime for the build output.\n *\n * - `node` - Node.js runtime (default)\n * - `bun` - Bun runtime (uses bun export conditions)\n * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target)\n *\n * Note: Some targets force a specific runtime:\n * - `cloudflare` always uses `workerd`\n * - `vercel` always uses `node`\n */\n runtime: t.optional(t.enum([\"node\", \"bun\", \"workerd\"])),\n\n /**\n * Vercel-specific deployment configuration.\n *\n * Note: Set `target: \"vercel\"` to enable Vercel deployment.\n * This object is only for additional configuration.\n */\n vercel: t.optional(\n t.object({\n projectName: t.optional(t.string()),\n orgId: t.optional(t.string()),\n projectId: t.optional(t.string()),\n config: t.optional(\n t.object({\n crons: t.optional(\n t.array(\n t.object({\n path: t.string(),\n schedule: t.string(),\n }),\n ),\n ),\n }),\n ),\n }),\n ),\n\n /**\n * Cloudflare-specific deployment configuration.\n *\n * Note: Set `target: \"cloudflare\"` to enable Cloudflare deployment.\n * This object is only for additional configuration.\n */\n cloudflare: t.optional(\n t.object({\n config: t.optional(t.json()),\n }),\n ),\n\n /**\n * Docker-specific deployment configuration.\n *\n * Note: Set `target: \"docker\"` to enable Docker deployment.\n * This object is only for additional configuration.\n */\n docker: t.optional(\n t.object({\n /**\n * Base image for the Dockerfile (FROM instruction).\n *\n * @default \"node:24-alpine\" for node runtime\n * @default \"oven/bun:alpine\" for bun runtime\n */\n from: t.optional(t.string()),\n\n /**\n * Command to run in the Docker container.\n *\n * @default \"node\" for node runtime\n * @default \"bun\" for bun runtime\n */\n command: t.optional(t.string()),\n\n /**\n * Docker build options (used when --image flag is passed).\n */\n image: t.optional(\n t.object({\n /**\n * Default image tag (name without version).\n *\n * Used when --image is provided without a full override:\n * - `--image` → `tag:latest`\n * - `--image=1.3.4` → `tag:1.3.4`\n * - `--image=other/img:v1` → `other/img:v1` (full override)\n *\n * @example \"myproject/myapp\"\n * @example \"ghcr.io/myorg/myapp\"\n */\n tag: t.string(),\n\n /**\n * Additional arguments to pass to `docker build`.\n *\n * @example '--platform linux/amd64 --no-cache'\n */\n args: t.optional(t.string()),\n\n /**\n * Auto-add OCI standard labels (revision, created, version).\n *\n * Adds:\n * - org.opencontainers.image.revision (git commit SHA)\n * - org.opencontainers.image.created (build timestamp)\n * - org.opencontainers.image.version (from image tag)\n */\n oci: t.optional(t.boolean()),\n }),\n ),\n }),\n ),\n\n /**\n * Sitemap generation configuration.\n */\n sitemap: t.optional(\n t.object({\n /**\n * Base URL for sitemap entries.\n */\n hostname: t.string(),\n }),\n ),\n }),\n default: {},\n});\n\n/**\n * Type for build options.\n */\nexport type BuildOptions = Static<typeof buildOptions.schema>;\n","import { $atom, type Static, t } from \"alepha\";\n\nexport const appEntryOptions = $atom({\n name: \"alepha.cli.appEntry.options\",\n schema: t.object({\n server: t.optional(t.text()),\n browser: t.optional(t.text()),\n style: t.optional(t.text()),\n }),\n default: {},\n});\n\nexport type AppEntryOptions = Static<typeof appEntryOptions.schema>;\n","import { $inject, $use, AlephaError } from \"alepha\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { appEntryOptions } from \"../atoms/appEntryOptions.ts\";\n\n/**\n * Service for locating entry files in Alepha projects.\n *\n * Originally in alepha/vite, moved to CLI to avoid cli -> vite dependency.\n */\nexport class AppEntryProvider {\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly options = $use(appEntryOptions);\n\n protected readonly serverEntries = [\n \"main.server.ts\",\n \"main.server.tsx\",\n \"main.ts\",\n \"main.tsx\",\n ] as const;\n\n protected readonly browserEntries = [\n \"main.browser.ts\",\n \"main.browser.tsx\",\n \"main.ts\",\n \"main.tsx\",\n ] as const;\n\n protected readonly styleEntries = [\n \"main.css\",\n \"styles.css\",\n \"style.css\",\n ] as const;\n\n /**\n * Get application entry points.\n *\n * Server entry is required, an error is thrown if not found.\n * Browser entry is optional.\n *\n * It will first check for custom entries in options, see appEntryOptions.\n */\n public async getAppEntry(root: string): Promise<AppEntry> {\n const appEntry: AppEntry = {\n root,\n server: \"\",\n };\n\n if (this.options.server) {\n const serverExists = await this.fs.exists(\n this.fs.join(root, this.options.server),\n );\n if (!serverExists) {\n throw new AlephaError(\n `Custom server entry \"${this.options.server}\" not found.`,\n );\n }\n appEntry.server = this.options.server;\n }\n\n if (this.options.browser) {\n const browserExists = await this.fs.exists(\n this.fs.join(root, this.options.browser),\n );\n if (!browserExists) {\n throw new AlephaError(\n `Custom browser entry \"${this.options.browser}\" not found.`,\n );\n }\n appEntry.browser = this.options.browser;\n }\n\n if (this.options.style) {\n const styleExists = await this.fs.exists(\n this.fs.join(root, this.options.style),\n );\n if (!styleExists) {\n throw new AlephaError(\n `Custom style entry \"${this.options.style}\" not found.`,\n );\n }\n appEntry.style = this.options.style;\n }\n\n const srcFiles = await this.fs.ls(this.fs.join(root, \"src\"));\n\n if (!appEntry.server) {\n // find in conventional locations\n for (const entry of this.serverEntries) {\n if (srcFiles.includes(entry)) {\n appEntry.server = this.fs.join(\"src\", entry);\n break;\n }\n }\n }\n\n if (!appEntry.server) {\n throw new AlephaError(\n \"No server entry found. Please, add a main.server.ts file in the src/ directory or configure a custom entry in alepha.config.ts.\",\n );\n }\n\n if (!appEntry.browser) {\n // find in conventional locations\n for (const entry of this.browserEntries) {\n if (srcFiles.includes(entry)) {\n appEntry.browser = this.fs.join(\"src\", entry);\n break;\n }\n }\n }\n\n if (!appEntry.style) {\n // find in conventional locations\n for (const entry of this.styleEntries) {\n if (srcFiles.includes(entry)) {\n appEntry.style = this.fs.join(\"src\", entry);\n break;\n }\n }\n }\n\n return appEntry;\n }\n}\n\nexport interface AppEntry {\n root: string;\n server: string;\n browser?: string;\n style?: string;\n}\n","import { $hook, $inject, type Alepha, AlephaError } from \"alepha\";\nimport { importVite } from \"alepha/vite\";\nimport type { InlineConfig, ViteDevServer } from \"vite\";\nimport { FileSystemProvider } from \"../../system/index.ts\";\nimport type { AppEntry } from \"../providers/AppEntryProvider.ts\";\n\nexport class ViteUtils {\n protected readonly fs = $inject(FileSystemProvider);\n protected viteDevServer?: ViteDevServer;\n\n public generateIndexHtml(entry: AppEntry): string {\n const style = entry.style;\n const browser = entry.browser ?? entry.server;\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\" />\n<title>App</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n${style ? `<link rel=\"stylesheet\" href=\"/${style}\" />` : \"\"}\n</head>\n<body>\n<div id=\"root\"></div>\n<script type=\"module\" src=\"/${browser}\"></script>\n</body>\n</html>\n`.trim();\n }\n\n /**\n * We need to close the Vite dev server after build is done.\n */\n protected onReady = $hook({\n on: \"ready\",\n priority: \"last\",\n handler: async () => {\n await this.viteDevServer?.close();\n },\n });\n\n protected onStop = $hook({\n on: \"stop\",\n handler: async () => {\n await this.viteDevServer?.close();\n },\n });\n\n public async runAlepha(opts: {\n entry: AppEntry;\n mode: \"production\" | \"development\";\n }): Promise<Alepha> {\n const { createServer } = await importVite();\n\n process.env.NODE_ENV = opts.mode;\n process.env.ALEPHA_CLI_IMPORT = \"true\"; // signal Alepha App about CLI import, run(alepha) won't start server\n process.env.LOG_LEVEL ??= \"warn\"; // reduce log noise\n\n /**\n * 01/26 Vite 7\n * \"runnerImport\" doesn't work as expected here. (e.g. build docs fail)\n * -> We still use devServer and ssrLoadModule for now.\n * -> This is clearly a bad stuff, we need to find better way.\n */\n this.viteDevServer = await createServer({\n server: { middlewareMode: true },\n appType: \"custom\",\n logLevel: \"silent\",\n } satisfies InlineConfig);\n\n await this.viteDevServer.ssrLoadModule(opts.entry.server);\n\n const alepha: Alepha = (globalThis as any).__alepha;\n if (!alepha) {\n throw new AlephaError(\n \"Alepha instance not found after loading entry module\",\n );\n }\n\n return alepha;\n }\n}\n","import { $inject, type Alepha, AlephaError } from \"alepha\";\nimport { ViteUtils } from \"../services/ViteUtils.ts\";\nimport type { AppEntry } from \"./AppEntryProvider.ts\";\n\nexport class ViteBuildProvider {\n protected alepha?: Alepha;\n protected appEntry?: AppEntry;\n protected readonly viteUtils = $inject(ViteUtils);\n\n public async init(opts: { entry: AppEntry }) {\n const alepha = await this.viteUtils.runAlepha({\n entry: opts.entry,\n mode: \"production\",\n });\n\n this.alepha = alepha;\n this.appEntry = opts.entry;\n\n return alepha;\n }\n\n public hasClient(): boolean {\n if (!this.alepha) {\n throw new AlephaError(\"ViteBuildProvider not initialized\");\n }\n try {\n this.alepha.inject(\"ReactServerProvider\");\n return true;\n } catch {\n return false;\n }\n }\n\n public generateIndexHtml(): string {\n if (!this.appEntry) {\n throw new AlephaError(\"ViteBuildProvider not initialized\");\n }\n return this.viteUtils.generateIndexHtml(this.appEntry);\n }\n}\n","import { $inject, type Alepha } from \"alepha\";\nimport { EnvUtils } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\nimport {\n type AppEntry,\n AppEntryProvider,\n} from \"../providers/AppEntryProvider.ts\";\nimport { ViteUtils } from \"./ViteUtils.ts\";\n\n/**\n * Core utility service for CLI commands.\n *\n * Provides:\n * - Command execution\n * - File editing helpers\n * - Drizzle/ORM utilities\n * - Environment loading\n */\nexport class AlephaCliUtils {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly boot = $inject(AppEntryProvider);\n protected readonly shell = $inject(ShellProvider);\n protected readonly viteUtils = $inject(ViteUtils);\n\n // ===========================================\n // Command Execution\n // ===========================================\n\n /**\n * Execute a command with inherited stdio.\n *\n * @param command - The command to execute\n * @param options.root - Working directory\n * @param options.env - Additional environment variables\n * @param options.global - If true, run command directly without resolving from node_modules\n */\n public async exec(\n command: string,\n options: {\n root?: string;\n env?: Record<string, string>;\n global?: boolean;\n } = {},\n ): Promise<void> {\n await this.shell.run(command, {\n root: options.root,\n env: options.env,\n resolve: !options.global,\n capture: false,\n });\n }\n\n /**\n * Write a configuration file to node_modules/.alepha directory.\n */\n public async writeConfigFile(\n name: string,\n content: string,\n root = process.cwd(),\n ): Promise<string> {\n const dir = this.fs.join(root, \"node_modules\", \".alepha\");\n\n await this.fs.mkdir(dir, { recursive: true }).catch(() => null);\n\n const path = this.fs.join(dir, name);\n await this.fs.writeFile(path, content);\n\n this.log.debug(`Config file written: ${path}`);\n\n return path;\n }\n\n public async loadAlephaFromServerEntryFile(\n opts: {\n mode: \"production\" | \"development\";\n } & ({ entry: AppEntry } | { root: string }),\n ): Promise<Alepha> {\n let entry: AppEntry;\n if (\"root\" in opts) {\n entry = await this.boot.getAppEntry(opts.root);\n } else {\n entry = opts.entry;\n }\n\n return await this.viteUtils.runAlepha({\n entry,\n mode: opts.mode,\n });\n }\n\n // ===========================================\n // Drizzle ORM & Kit Utilities\n // ===========================================\n\n /**\n * Generate JavaScript code for Drizzle entities export.\n */\n public generateEntitiesJs(\n entry: string,\n provider: string,\n models: string[] = [],\n ): string {\n return `\nimport \"${entry}\";\nimport { DrizzleKitProvider, Repository } from \"alepha/orm\";\n\nconst alepha = globalThis.__alepha;\nconst kit = alepha.inject(DrizzleKitProvider);\nconst provider = alepha.services(Repository).find((it) => it.provider.name === \"${provider}\").provider;\nconst models = kit.getModels(provider);\n\n${models.map((it: string) => `export const ${it} = models[\"${it}\"];`).join(\"\\n\")}\n\n`.trim();\n }\n\n // ===========================================\n // Environment\n // ===========================================\n\n /**\n * Load environment variables from a .env file.\n */\n public async loadEnv(\n root: string,\n files: string[] = [\".env\"],\n ): Promise<void> {\n await this.envUtils.loadEnv(root, files);\n }\n\n // ===========================================\n // Helpers\n // ===========================================\n\n public async exists(root: string, path: string): Promise<boolean> {\n return this.fs.exists(this.fs.join(root, path));\n }\n\n /**\n * Check if a command is installed and available in the system PATH.\n */\n public isInstalledAsync(cmd: string): Promise<boolean> {\n return this.shell.isInstalled(cmd);\n }\n\n /**\n * Get the current git revision (commit SHA).\n *\n * @returns The short commit SHA or \"unknown\" if not in a git repo\n */\n public async getGitRevision(): Promise<string> {\n try {\n const result = await this.shell.run(\"git rev-parse --short HEAD\", {\n capture: true,\n });\n return result.trim();\n } catch {\n return \"unknown\";\n }\n }\n}\n","","import { readFileSync } from \"node:fs\";\n\nconst packageJson = JSON.parse(\n readFileSync(new URL(\"../../package.json\", import.meta.url), \"utf-8\"),\n);\n\nexport const version = packageJson.version;\n","import { $inject, Alepha } from \"alepha\";\nimport type { RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport alephaPackageJson from \"alepha/package.json\" with { type: \"json\" };\nimport { FileSystemProvider } from \"alepha/system\";\nimport { version } from \"../version.ts\";\n\n/**\n * Context information about a workspace root.\n * Used when initializing a package inside a monorepo.\n */\nexport interface WorkspaceContext {\n /**\n * Whether we're inside a workspace package.\n */\n isPackage: boolean;\n /**\n * The workspace root directory (e.g., ../.. from packages/my-pkg).\n */\n workspaceRoot: string | null;\n /**\n * Package manager detected at workspace root.\n */\n packageManager: \"yarn\" | \"pnpm\" | \"npm\" | \"bun\" | null;\n /**\n * Config files present at workspace root.\n */\n config: {\n biomeJson: boolean;\n editorconfig: boolean;\n tsconfigJson: boolean;\n };\n}\n\n/**\n * Utility service for package manager operations.\n *\n * Handles detection, installation, and cleanup for:\n * - Yarn\n * - npm\n * - pnpm\n * - Bun\n */\nexport class PackageManagerUtils {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly alepha = $inject(Alepha);\n\n /**\n * Detect the package manager used in the project.\n */\n public async getPackageManager(\n root: string,\n pm?: \"yarn\" | \"pnpm\" | \"npm\" | \"bun\",\n ): Promise<\"yarn\" | \"pnpm\" | \"npm\" | \"bun\"> {\n if (pm) return pm;\n if (this.alepha.isBun()) return \"bun\";\n if (await this.fs.exists(this.fs.join(root, \"bun.lock\"))) return \"bun\";\n if (await this.fs.exists(this.fs.join(root, \"yarn.lock\"))) return \"yarn\";\n if (await this.fs.exists(this.fs.join(root, \"pnpm-lock.yaml\")))\n return \"pnpm\";\n return \"npm\";\n }\n\n /**\n * Detect workspace context when inside a monorepo package.\n *\n * Checks if we're inside a workspace package (e.g., packages/my-pkg or apps/my-app)\n * by looking 2 levels up for workspace indicators like lockfiles and config files.\n *\n * @param root - The current package directory\n * @returns Workspace context with root path, PM, and config presence\n */\n public async getWorkspaceContext(root: string): Promise<WorkspaceContext> {\n // Workspace root is 2 levels up (e.g., packages/my-pkg → ..)\n const workspaceRoot = this.fs.join(root, \"..\", \"..\");\n\n // Check for lockfiles to detect PM\n const [hasYarnLock, hasPnpmLock, hasNpmLock, hasBunLock] =\n await Promise.all([\n this.fs.exists(this.fs.join(workspaceRoot, \"yarn.lock\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"pnpm-lock.yaml\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"package-lock.json\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"bun.lock\")),\n ]);\n\n // Check for config files\n const [hasBiome, hasEditorConfig, hasTsConfig, hasWorkspacePackageJson] =\n await Promise.all([\n this.fs.exists(this.fs.join(workspaceRoot, \"biome.json\")),\n this.fs.exists(this.fs.join(workspaceRoot, \".editorconfig\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"tsconfig.json\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"package.json\")),\n ]);\n\n // Determine if this looks like a workspace root\n const hasLockfile = hasYarnLock || hasPnpmLock || hasNpmLock || hasBunLock;\n const isPackage = hasLockfile && hasWorkspacePackageJson;\n\n // Detect package manager from lockfile\n let packageManager: \"yarn\" | \"pnpm\" | \"npm\" | \"bun\" | null = null;\n if (hasYarnLock) packageManager = \"yarn\";\n else if (hasPnpmLock) packageManager = \"pnpm\";\n else if (hasBunLock) packageManager = \"bun\";\n else if (hasNpmLock) packageManager = \"npm\";\n\n return {\n isPackage,\n workspaceRoot: isPackage ? workspaceRoot : null,\n packageManager,\n config: {\n biomeJson: hasBiome,\n editorconfig: hasEditorConfig,\n tsconfigJson: hasTsConfig,\n },\n };\n }\n\n /**\n * Get the install command for a package.\n */\n public async getInstallCommand(\n root: string,\n packageName: string,\n dev = true,\n ): Promise<string> {\n const pm = await this.getPackageManager(root);\n let cmd: string;\n\n switch (pm) {\n case \"yarn\":\n cmd = `yarn add ${dev ? \"-D\" : \"\"} ${packageName}`;\n break;\n case \"pnpm\":\n cmd = `pnpm add ${dev ? \"-D\" : \"\"} ${packageName}`;\n break;\n case \"bun\":\n cmd = `bun add ${dev ? \"-d\" : \"\"} ${packageName}`;\n break;\n default:\n cmd = `npm install ${dev ? \"--save-dev\" : \"\"} ${packageName}`;\n }\n\n return cmd.replace(/\\s+/g, \" \").trim();\n }\n\n /**\n * Check if a dependency is installed in the project.\n */\n public async hasDependency(\n root: string,\n packageName: string,\n ): Promise<boolean> {\n try {\n const pkg = await this.readPackageJson(root);\n return !!(\n pkg.dependencies?.[packageName] || pkg.devDependencies?.[packageName]\n );\n } catch {\n return false;\n }\n }\n\n /**\n * Check if Expo is present in the project.\n */\n public async hasExpo(root: string): Promise<boolean> {\n return this.hasDependency(root, \"expo\");\n }\n\n /**\n * Check if React is present in the project.\n */\n public async hasReact(root: string): Promise<boolean> {\n return this.hasDependency(root, \"react\");\n }\n\n /**\n * Install a dependency if it's missing from the project.\n * Optionally checks workspace root for the dependency in monorepo setups.\n */\n public async ensureDependency(\n root: string,\n packageName: string,\n options: {\n dev?: boolean;\n /**\n * Also check workspace root for the dependency (for monorepo setups).\n */\n checkWorkspace?: boolean;\n run?: RunnerMethod;\n exec?: (\n cmd: string,\n opts?: { global?: boolean; root?: string },\n ) => Promise<void>;\n } = {},\n ): Promise<void> {\n const { dev = true, checkWorkspace = false } = options;\n\n // Check current package\n if (await this.hasDependency(root, packageName)) {\n this.log.debug(`Dependency '${packageName}' is already installed`);\n return;\n }\n\n // Check workspace root (for monorepo setups)\n if (checkWorkspace) {\n const workspace = await this.getWorkspaceContext(root);\n if (workspace.workspaceRoot) {\n if (await this.hasDependency(workspace.workspaceRoot, packageName)) {\n this.log.debug(\n `Dependency '${packageName}' is already installed in workspace root`,\n );\n return;\n }\n }\n }\n\n const cmd = await this.getInstallCommand(root, packageName, dev);\n\n if (options.run) {\n await options.run(cmd, { alias: `add ${packageName}`, root });\n } else if (options.exec) {\n this.log.debug(`Installing ${packageName}`);\n await options.exec(cmd, { global: true, root });\n }\n }\n\n // ===========================================\n // Package Manager Setup & Cleanup\n // ===========================================\n\n public async ensureYarn(root: string): Promise<void> {\n const yarnrcPath = this.fs.join(root, \".yarnrc.yml\");\n if (!(await this.fs.exists(yarnrcPath))) {\n await this.fs.writeFile(yarnrcPath, \"nodeLinker: node-modules\");\n }\n await this.removeAllPmFilesExcept(root, \"yarn\");\n }\n\n public async ensureBun(root: string): Promise<void> {\n await this.removeAllPmFilesExcept(root, \"bun\");\n }\n\n public async ensurePnpm(root: string): Promise<void> {\n await this.removeAllPmFilesExcept(root, \"pnpm\");\n }\n\n public async ensureNpm(root: string): Promise<void> {\n await this.removeAllPmFilesExcept(root, \"npm\");\n }\n\n public async removeAllPmFilesExcept(\n root: string,\n except: string,\n ): Promise<void> {\n if (except !== \"yarn\") await this.removeYarn(root);\n if (except !== \"pnpm\") await this.removePnpm(root);\n if (except !== \"npm\") await this.removeNpm(root);\n if (except !== \"bun\") await this.removeBun(root);\n }\n\n public async removeYarn(root: string): Promise<void> {\n await this.removeFiles(root, [\".yarn\", \".yarnrc.yml\", \"yarn.lock\"]);\n await this.editPackageJson(root, (pkg) => {\n delete pkg.packageManager;\n return pkg;\n });\n }\n\n public async removePnpm(root: string): Promise<void> {\n await this.removeFiles(root, [\"pnpm-lock.yaml\", \"pnpm-workspace.yaml\"]);\n await this.editPackageJson(root, (pkg) => {\n delete pkg.packageManager;\n return pkg;\n });\n }\n\n public async removeNpm(root: string): Promise<void> {\n await this.removeFiles(root, [\"package-lock.json\"]);\n }\n\n public async removeBun(root: string): Promise<void> {\n await this.removeFiles(root, [\"bun.lockb\", \"bun.lock\"]);\n }\n\n // ===========================================\n // Package.json utilities\n // ===========================================\n\n public async readPackageJson(root: string): Promise<Record<string, any>> {\n const content = await this.fs\n .createFile({ path: this.fs.join(root, \"package.json\") })\n .text();\n return JSON.parse(content);\n }\n\n public async writePackageJson(\n root: string,\n content: Record<string, any>,\n ): Promise<void> {\n await this.fs.writeFile(\n this.fs.join(root, \"package.json\"),\n JSON.stringify(content, null, 2),\n );\n }\n\n public async editPackageJson(\n root: string,\n editFn: (pkg: Record<string, any>) => Record<string, any>,\n ): Promise<void> {\n try {\n const pkg = await this.readPackageJson(root);\n const updated = editFn(pkg);\n await this.writePackageJson(root, updated);\n } catch {\n // package.json doesn't exist, skip\n }\n }\n\n public async ensurePackageJson(\n root: string,\n modes: DependencyModes,\n ): Promise<Record<string, any>> {\n const packageJsonPath = this.fs.join(root, \"package.json\");\n\n if (!(await this.fs.exists(packageJsonPath))) {\n const content = this.generatePackageJsonContent(modes);\n await this.writePackageJson(root, content);\n return content;\n }\n\n const packageJson = await this.readPackageJson(root);\n const newContent = this.generatePackageJsonContent(modes);\n\n packageJson.type = \"module\";\n packageJson.dependencies ??= {};\n packageJson.devDependencies ??= {};\n packageJson.scripts ??= {};\n\n Object.assign(packageJson.dependencies, newContent.dependencies);\n Object.assign(packageJson.devDependencies, newContent.devDependencies);\n Object.assign(packageJson.scripts, newContent.scripts);\n\n await this.writePackageJson(root, packageJson);\n return packageJson;\n }\n\n public generatePackageJsonContent(modes: DependencyModes): {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n scripts: Record<string, string>;\n type: \"module\";\n } {\n const alephaDeps = alephaPackageJson.devDependencies;\n\n const dependencies: Record<string, string> = {\n alepha: `^${version}`,\n };\n\n const devDependencies: Record<string, string> = {};\n\n // Add biome/vitest only if not a workspace package (workspace root has them)\n if (!modes.isPackage) {\n devDependencies[\"@biomejs/biome\"] = alephaDeps[\"@biomejs/biome\"];\n if (modes.test) {\n devDependencies.vitest = alephaDeps.vitest;\n }\n }\n\n const scripts: Record<string, string> = {\n dev: \"alepha dev\",\n build: \"alepha build\",\n lint: \"alepha lint\",\n typecheck: \"alepha typecheck\",\n verify: \"alepha verify\",\n };\n\n if (modes.test) {\n scripts.test = \"vitest run\";\n }\n\n if (modes.ui) {\n dependencies[\"@alepha/ui\"] = `^${version}`;\n modes.react = true;\n }\n\n if (modes.react) {\n dependencies.react = alephaDeps.react;\n dependencies[\"react-dom\"] = alephaDeps[\"react-dom\"];\n devDependencies[\"@vitejs/plugin-react\"] =\n alephaDeps[\"@vitejs/plugin-react\"];\n devDependencies[\"@types/react\"] = alephaDeps[\"@types/react\"];\n }\n\n return {\n type: \"module\",\n dependencies,\n devDependencies,\n scripts,\n };\n }\n\n // ===========================================\n // Helper methods\n // ===========================================\n\n protected async removeFiles(root: string, files: string[]): Promise<void> {\n await Promise.all(\n files.map((file) =>\n this.fs.rm(this.fs.join(root, file), { force: true, recursive: true }),\n ),\n );\n }\n}\n\nexport interface DependencyModes {\n react?: boolean;\n ui?: boolean;\n expo?: boolean;\n test?: boolean;\n /**\n * Skip biome/vitest when inside a workspace package (they're at root).\n */\n isPackage?: boolean;\n}\n","export interface AgentMdOptions {\n react?: boolean;\n ui?: boolean;\n projectName?: string;\n}\n\nexport type AgentMdType = \"claude\" | \"agents\";\n\nexport const agentMd = (\n type: AgentMdType,\n options: AgentMdOptions = {},\n): string => {\n const { react = false, projectName = \"my-app\" } = options;\n\n const header =\n type === \"claude\"\n ? `# CLAUDE.md\n\nThis file provides guidance to Claude Code when working with this Alepha project.`\n : `# AGENTS.md\n\nThis file provides guidance to AI coding assistants when working with this Alepha project.`;\n\n const reactSection = react\n ? `\n## React & Frontend\n\n### Pages with \\`$page\\`\n\\`\\`\\`tsx\nimport { $page } from \"alepha/react/router\";\nimport { $client } from \"alepha/server/links\";\nimport type { UserController } from \"./UserController.ts\";\n\nclass AppRouter {\n api = $client<UserController>();\n\n users = $page({\n path: \"/users\",\n loader: async () => ({ users: await this.api.listUsers() }),\n component: ({ users }) => (\n <ul>{users.map(u => <li key={u.id}>{u.email}</li>)}</ul>\n ),\n });\n\n userDetail = $page({\n path: \"/users/:id\",\n schema: { params: t.object({ id: t.uuid() }) },\n loader: async ({ params }) => ({ user: await this.api.getUser({ params }) }),\n lazy: () => import(\"./UserDetail.tsx\"), // Code splitting\n });\n}\n\\`\\`\\`\n\n### React Hooks\n\\`\\`\\`typescript\nimport { useAlepha, useClient, useStore, useAction, useInject } from \"alepha/react\";\nimport { useRouter, useActive } from \"alepha/react/router\";\nimport { useForm } from \"alepha/react/form\";\n\\`\\`\\`\n\n- \\`useClient<Controller>()\\` - Type-safe API calls\n- \\`useStore(atom)\\` - Global state (returns \\`[value, setValue]\\`)\n- \\`useAction({ handler })\\` - Async operations with loading/error state\n- \\`useRouter<AppRouter>()\\` - Type-safe navigation\n- \\`useForm({ schema, handler })\\` - Type-safe forms with validation\n`\n : \"\";\n\n const projectStructure = react\n ? `\n\\`\\`\\`\n${projectName}/\n├── src/\n│ ├── api/ # Backend\n│ │ ├── controllers/ # API controllers with $action\n│ │ ├── services/ # Business logic\n│ │ ├── entities/ # Database entities with $entity\n│ │ ├── providers/ # External service wrappers\n│ │ └── index.ts # API module definition with $module\n│ ├── web/ # Frontend (React only)\n│ │ ├── components/ # React components\n│ │ ├── atoms/ # State atoms with $atom\n│ │ ├── AppRouter.ts # Routes with $page\n│ │ └── index.ts # Web module definition with $module\n│ ├── main.server.ts # Server entry\n│ ├── main.browser.ts # Browser entry (React only)\n│ └── main.css # CSS entry (React only)\n├── package.json\n└── tsconfig.json\n\\`\\`\\`\n`\n : `\n\\`\\`\\`\n${projectName}/\n├── src/\n│ ├── api/ # Backend\n│ │ ├── controllers/ # API controllers with $action\n│ │ ├── services/ # Business logic\n│ │ ├── entities/ # Database entities with $entity\n│ │ ├── providers/ # External service wrappers\n│ │ └── index.ts # API module definition with $module\n│ └── main.server.ts # Server entry (always use main.server.ts)\n├── package.json\n└── tsconfig.json\n\\`\\`\\`\n`;\n\n return `${header}\n\n## Overview\n\nThis is an **Alepha** project - a convention-driven TypeScript framework for type-safe full-stack applications.\n\n**Key Concepts:**\n- **Primitives**: Features defined with \\`$\\`-prefixed functions (\\`$action\\`, \\`$entity\\`, \\`$page\\`)\n- **Class-Based**: Services are classes, primitives are class properties\n- **Zero-Config**: Code structure IS the configuration\n- **End-to-End Types**: Types flow from database → API → ${react ? \"React\" : \"client\"}\n\n## Rules\n\n- Use TypeScript strict mode, always check types (\\`alepha typecheck\\`)\n- Use Biome for formatting (\\`alepha lint\\`)\n- Use Vitest for testing (\\`alepha test\\`)\n- One file = one class, multiple interfaces/types allowed\n- Primitives are class properties (except \\`$entity\\`, \\`$atom\\`)\n- No decorators, no Express/Fastify patterns\n- No manual instantiation - use dependency injection\n- Use \\`protected\\` instead of \\`private\\` for class members\n- Import with file extensions: \\`import { User } from \"./User.ts\"\\`\n- Use \\`t\\` from Alepha for schemas (not Zod)\n- Prefer \\`t.text()\\` over \\`t.string()\\` for user input (has default max length, auto-trim, supports lowercase option)\n- One file = one schema (schemas/createUserSchema.ts)\n\n## Project Structure\n${projectStructure}\n## Core Primitives\n\n### API with \\`$action\\`\n\\`\\`\\`typescript\nimport { t } from \"alepha\";\nimport { $action } from \"alepha/server\";\n\nclass UserController {\n getUser = $action({\n path: \"/users/:id\", // → GET /api/users/:id\n schema: {\n params: t.object({ id: t.uuid() }),\n response: t.object({ id: t.uuid(), email: t.email() }),\n },\n handler: async ({ params }) => this.userRepo.findById(params.id),\n });\n\n createUser = $action({\n // POST inferred from body schema\n schema: {\n body: t.object({ email: t.email() }),\n response: userEntity.schema,\n },\n handler: async ({ body }) => this.userRepo.create(body),\n });\n}\n\\`\\`\\`\n\n### Database with \\`$entity\\` and \\`$repository\\`\n\\`\\`\\`typescript\nimport { $entity, $repository, db } from \"alepha/orm\";\n\n// Entity defined at module level (for drizzle-kit compatibility)\nexport const userEntity = $entity({\n name: \"users\",\n schema: t.object({\n id: db.primaryKey(),\n email: t.email(),\n createdAt: db.createdAt(),\n }),\n indexes: [{ column: \"email\", unique: true }],\n});\n\nclass UserService {\n userRepository = $repository(userEntity);\n}\n\\`\\`\\`\n\n### Dependency Injection\n\\`\\`\\`typescript\nimport { $inject } from \"alepha\";\n\nclass OrderService {\n userService = $inject(UserService); // Within same module\n}\n\n// Cross-module: use $client instead of $inject\nclass AppRouter {\n api = $client<OrderController>(); // Type-safe HTTP client\n}\n\\`\\`\\`\n\n### Modules with \\`$module\\`\n\\`\\`\\`typescript\n// src/api/index.ts - Groups all API services\nimport { $module } from \"alepha\";\n\nexport const ApiModule = $module({\n name: \"app.api\",\n services: [\n UserController,\n OrderController,\n UserService,\n ],\n});\n\n// src/web/index.ts - Groups all web services (React only)\nexport const WebModule = $module({\n name: \"app.web\",\n services: [AppRouter, Toaster],\n register(alepha) {\n // Optional: configure additional services\n alepha.with(SomeLibrary);\n },\n});\n\\`\\`\\`\n\n### Environment Variables\n\\`\\`\\`typescript\nimport { $env, t } from \"alepha\";\n\nclass AppConfig {\n env = $env(t.object({\n DATABASE_URL: t.string(),\n API_KEY: t.optional(t.string()),\n }));\n}\n\\`\\`\\`\n${reactSection}\n## Quick Reference\n\n| Primitive | Import | Purpose |\n|-----------|--------|---------|\n| \\`$inject\\` | \\`alepha\\` | Dependency injection |\n| \\`$env\\` | \\`alepha\\` | Environment variables |\n| \\`$hook\\` | \\`alepha\\` | Lifecycle hooks |\n| \\`$logger\\` | \\`alepha/logger\\` | Structured logging |\n| \\`$action\\` | \\`alepha/server\\` | REST API endpoints |\n| \\`$route\\` | \\`alepha/server\\` | Low-level HTTP routes |\n| \\`$entity\\` | \\`alepha/orm\\` | Database tables |\n| \\`$repository\\` | \\`alepha/orm\\` | Type-safe data access |\n| \\`$queue\\` | \\`alepha/queue\\` | Background jobs |\n| \\`$scheduler\\` | \\`alepha/scheduler\\` | Cron tasks |\n| \\`$cache\\` | \\`alepha/cache\\` | Cached computations |\n| \\`$bucket\\` | \\`alepha/bucket\\` | File storage |\n| \\`$issuer\\` | \\`alepha/security\\` | JWT tokens |\n| \\`$command\\` | \\`alepha/command\\` | CLI commands |${\n react\n ? `\n| \\`$page\\` | \\`alepha/react/router\\` | React pages with SSR |\n| \\`$atom\\` | \\`alepha\\` | Global state |`\n : \"\"\n }\n\n## Testing\n\n\\`\\`\\`typescript\nimport { describe, it, expect } from \"vitest\";\nimport { Alepha } from \"alepha\";\n\ndescribe(\"UserService\", () => {\n it(\"should create user\", async () => {\n const alepha = Alepha.create().with(UserService);\n const service = alepha.inject(UserService);\n\n const user = await service.create({ email: \"test@example.com\" });\n expect(user.email).toBe(\"test@example.com\");\n });\n\n it(\"should mock dependencies\", async () => {\n const alepha = Alepha.create()\n .with(OrderService)\n .with({ provide: PaymentGateway, use: MockPaymentGateway });\n\n const service = alepha.inject(OrderService);\n // PaymentGateway is now mocked\n });\n});\n\\`\\`\\`\n\n## Common Mistakes\n\n1. **DON'T use decorators** - Use primitives (\\`$action\\`, not \\`@Get()\\`)\n2. **DON'T use Zod** - Use TypeBox via \\`t\\` from Alepha\n3. **DON'T use Express patterns** - No \\`app.get()\\`, \\`router.use()\\`\n4. **DON'T inject across modules** - Use \\`$client\\` for cross-module calls\n5. **DON'T use async constructors** - Use \\`$hook({ on: \"start\" })\\`\n6. **DON'T instantiate manually** - Let DI container manage instances\n\n## After Code Changes\n\nAlways run:\n\\`\\`\\`bash\nalepha lint # Format and lint\nalepha typecheck # Type checking\nalepha test # Run tests (if applicable)\nalepha build # Build the project\n\\`\\`\\`\n\n## Documentation\n\n- Full docs: https://alepha.dev/llms.txt\n- Detailed docs: https://alepha.dev/llms-full.txt\n\n## Source Code Access\n\nFull framework source available at \\`node_modules/alepha/src/\\`.\n\n**IMPORTANT:** When answering questions about Alepha primitives, APIs, or internals:\n1. ALWAYS read the local source code first at \\`node_modules/alepha/src/\\` or \\`node_modules/@alepha/ui/src/\\` for UI-related questions\n2. Use \\`Glob\\` to find relevant files: \\`node_modules/alepha/src/**/primitives/$<name>.ts\\`\n3. Read the implementation AND the \\`.spec.ts\\` test files for usage examples\n4. Use external documentation as a fallback if source code is insufficient\n`.trim();\n};\n","export const apiAppSecurityTs = () => {\n return `\nimport { $realm } from \"alepha/api/users\";\n\nexport class AppSecurity {\n users = $realm({\n // configure your realm here\n });\n}\n`.trim();\n};\n","export const apiHelloControllerTs = () =>\n `\nimport { t } from \"alepha\";\nimport { $action } from \"alepha/server\";\n\nexport class HelloController {\n hello = $action({\n path: \"/hello\",\n schema: {\n response: t.object({\n message: t.string(),\n }),\n },\n handler: () => ({\n message: \"Hello, Alepha!\",\n }),\n });\n}\n`.trim();\n","export interface ApiIndexTsOptions {\n appName?: string;\n auth?: boolean;\n}\n\nexport const apiIndexTs = (options: ApiIndexTsOptions = {}) => {\n const { appName = \"app\", auth = false } = options;\n\n const imports: string[] = ['import { $module } from \"alepha\";'];\n const services: string[] = [];\n\n if (auth) {\n imports.push('import { AppSecurity } from \"./AppSecurity.ts\";');\n services.push(\"AppSecurity\");\n }\n\n imports.push(\n 'import { HelloController } from \"./controllers/HelloController.ts\";',\n );\n services.push(\"HelloController\");\n\n return `\n${imports.join(\"\\n\")}\n\nexport const ApiModule = $module({\n name: \"${appName}.api\",\n services: [${services.join(\", \")}],\n});\n`.trim();\n};\n","export const biomeJson = () =>\n `\n{\n \"$schema\": \"https://biomejs.dev/schemas/latest/schema.json\",\n \"vcs\": {\n \"enabled\": true,\n \"clientKind\": \"git\"\n },\n \"files\": {\n \"ignoreUnknown\": true,\n \"includes\": [\"**\", \"!node_modules\", \"!dist\"]\n },\n \"formatter\": {\n \"enabled\": true,\n \"useEditorconfig\": true\n },\n \"linter\": {\n \"enabled\": true,\n \"rules\": {\n \"recommended\": true\n },\n \"domains\": {\n \"react\": \"recommended\"\n }\n },\n \"assist\": {\n \"actions\": {\n \"source\": {\n \"organizeImports\": \"on\"\n }\n }\n }\n}\n`.trim();\n","export const dummySpecTs = () =>\n `\nimport { test, expect } from \"vitest\";\n\ntest(\"dummy test\", () => {\n expect(1 + 1).toBe(2);\n});\n`.trim();\n","export const editorconfig = () =>\n `\n# https://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = space\nindent_size = 2\n`.trim();\n","export const gitignore = () =>\n `\n# Dependencies\nnode_modules/\n\n# Build outputs\ndist/\n.vite/\n\n# Environment files\n.env\n.env.*\n!.env.example\n\n# IDE\n.idea/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nlogs/\n\n# Test coverage\ncoverage/\n\n# Yarn\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/sdks\n!.yarn/versions\n.pnp.*\n`.trim();\n","export const mainBrowserTs = () =>\n `\nimport { Alepha, run } from \"alepha\";\nimport { WebModule } from \"./web/index.ts\";\n\nconst alepha = Alepha.create();\n\nalepha.with(WebModule);\n\nrun(alepha);\n`.trim();\n","export interface MainCssOptions {\n ui?: boolean;\n}\n\nexport const mainCss = (options: MainCssOptions = {}) => {\n if (options.ui) {\n return `@import \"@alepha/ui/styles\";`;\n }\n\n return `\n* {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\nhtml,\nbody {\n height: 100%;\n}\n\nbody {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n \"Helvetica Neue\", Arial, sans-serif;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n}\n\n#root {\n height: 100%;\n}\n`.trim();\n};\n","export interface MainServerTsOptions {\n api?: boolean;\n react?: boolean;\n}\n\nexport const mainServerTs = (options: MainServerTsOptions = {}) => {\n const { api = false, react = false } = options;\n\n const imports: string[] = [];\n const withs: string[] = [];\n\n if (api) {\n imports.push(`import { ApiModule } from \"./api/index.ts\";`);\n withs.push(`alepha.with(ApiModule);`);\n }\n\n if (react) {\n imports.push(`import { WebModule } from \"./web/index.ts\";`);\n withs.push(`alepha.with(WebModule);`);\n }\n\n const importsBlock = imports.length > 0 ? `${imports.join(\"\\n\")}\\n` : \"\";\n const withsBlock = withs.length > 0 ? `\\n${withs.join(\"\\n\")}` : \"\";\n\n return `\nimport { Alepha, run } from \"alepha\";\n${importsBlock}\nconst alepha = Alepha.create();\n${withsBlock}\n\nrun(alepha);\n`.trim();\n};\n","export const tsconfigJson = () =>\n `\n{\n \"extends\": \"alepha/tsconfig.base\"\n}\n`.trim();\n","export const webAppRouterTs = (options: {\n api?: boolean;\n ui?: boolean;\n auth?: boolean;\n admin?: boolean;\n}) => {\n const imports: string[] = [];\n const classMembers: string[] = [];\n\n // UI import and setup\n if (options.ui) {\n imports.push('import { $ui } from \"@alepha/ui\";');\n }\n\n // Auth import\n if (options.auth) {\n imports.push('import { $uiAuth } from \"@alepha/ui/auth\";');\n }\n\n // Admin import\n if (options.admin) {\n imports.push('import { $uiAdmin } from \"@alepha/ui/admin\";');\n }\n\n // Page import\n imports.push('import { $page } from \"alepha/react/router\";');\n\n // API imports (only if api flag is set)\n if (options.api) {\n imports.push('import { $client } from \"alepha/server/links\";');\n imports.push(\n 'import type { HelloController } from \"../api/controllers/HelloController.ts\";',\n );\n classMembers.push(\" api = $client<HelloController>();\");\n }\n\n // UI layout setup\n if (options.ui) {\n classMembers.push(\" ui = $ui();\");\n\n if (options.auth) {\n classMembers.push(\" uiAuth = $uiAuth();\");\n }\n\n if (options.admin) {\n classMembers.push(\" uiAdmin = $uiAdmin();\");\n }\n\n classMembers.push(` layout = $page({\n parent: this.ui.root,\n children: () => [this.home],\n });`);\n }\n\n // Home page - with or without loader\n if (options.api) {\n classMembers.push(` home = $page({\n path: \"/\",\n lazy: () => import(\"./components/Hello.tsx\"),\n loader: () => this.api.hello(),\n });`);\n } else {\n classMembers.push(` home = $page({\n path: \"/\",\n lazy: () => import(\"./components/Hello.tsx\"),\n });`);\n }\n\n return `${imports.join(\"\\n\")}\n\nexport class AppRouter {\n${classMembers.join(\"\\n\\n\")}\n}`;\n};\n","export const webHelloComponentTsx = (options: { auth?: boolean } = {}) => {\n const imports: string[] = [];\n\n if (options.auth) {\n imports.push('import { UserButton } from \"@alepha/ui/auth\";');\n }\n imports.push('import { useState } from \"react\";');\n\n const userButton = options.auth ? \"\\n <UserButton />\" : \"\";\n\n return `${imports.join(\"\\n\")}\n\ninterface Props {\n message?: string;\n}\n\nconst Hello = (props: Props) => {\n const [message, setMessage] = useState(props.message ?? \"\");\n return (\n <div>\n <h1>{message}</h1>\n <input value={message} onChange={(e) => setMessage(e.target.value)} />\n <p>Edit this component in src/web/components/Hello.tsx</p>${userButton}\n </div>\n );\n};\n\nexport default Hello;\n`;\n};\n","export interface WebIndexTsOptions {\n appName?: string;\n}\n\nexport const webIndexTs = (options: WebIndexTsOptions = {}) => {\n const { appName = \"app\" } = options;\n return `\nimport { $module } from \"alepha\";\nimport { AppRouter } from \"./AppRouter.ts\";\n\nexport const WebModule = $module({\n name: \"${appName}.web\",\n services: [AppRouter],\n});\n`.trim();\n};\n","import { basename, dirname } from \"node:path\";\nimport { $inject } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport {\n type AgentMdOptions,\n type AgentMdType,\n agentMd,\n} from \"../templates/agentMd.ts\";\nimport { apiAppSecurityTs } from \"../templates/apiAppSecurityTs.ts\";\nimport { apiHelloControllerTs } from \"../templates/apiHelloControllerTs.ts\";\nimport { apiIndexTs } from \"../templates/apiIndexTs.ts\";\nimport { biomeJson } from \"../templates/biomeJson.ts\";\nimport { dummySpecTs } from \"../templates/dummySpecTs.ts\";\nimport { editorconfig } from \"../templates/editorconfig.ts\";\nimport { gitignore } from \"../templates/gitignore.ts\";\nimport { mainBrowserTs } from \"../templates/mainBrowserTs.ts\";\nimport { mainCss } from \"../templates/mainCss.ts\";\nimport { mainServerTs } from \"../templates/mainServerTs.ts\";\nimport { tsconfigJson } from \"../templates/tsconfigJson.ts\";\nimport { webAppRouterTs } from \"../templates/webAppRouterTs.ts\";\nimport { webHelloComponentTsx } from \"../templates/webHelloComponentTsx.ts\";\nimport { webIndexTs } from \"../templates/webIndexTs.ts\";\nimport { AlephaCliUtils } from \"./AlephaCliUtils.ts\";\nimport {\n type DependencyModes,\n PackageManagerUtils,\n} from \"./PackageManagerUtils.ts\";\n\n/**\n * Service for scaffolding new Alepha projects.\n *\n * Handles creation of:\n * - Project structure (src/api, src/web)\n * - Configuration files (tsconfig, biome, editorconfig)\n * - Entry points (main.server.ts, main.browser.ts)\n * - Example code (HelloController, Hello component)\n */\nexport class ProjectScaffolder {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly utils = $inject(AlephaCliUtils);\n\n /**\n * Get the app name from the directory name.\n *\n * Converts the directory name to a valid module name:\n * - Converts to lowercase\n * - Replaces spaces, dashes, underscores with nothing\n * - Falls back to \"app\" if empty\n */\n public getAppName(root: string): string {\n const dirName = basename(root);\n const appName = dirName.toLowerCase().replace(/[\\s\\-_.\\d]/g, \"\");\n return appName || \"app\";\n }\n\n /**\n * Ensure all configuration files exist.\n */\n public async ensureConfig(\n root: string,\n opts: {\n force?: boolean;\n /**\n * Check workspace root for existing config files.\n */\n checkWorkspace?: boolean;\n packageJson?: boolean | DependencyModes;\n tsconfigJson?: boolean;\n biomeJson?: boolean;\n editorconfig?: boolean;\n agentMd?: false | (AgentMdOptions & { type: AgentMdType });\n },\n ): Promise<void> {\n const tasks: Promise<void>[] = [];\n const force = opts.force ?? false;\n const checkWorkspace = opts.checkWorkspace ?? false;\n\n if (opts.packageJson) {\n tasks.push(\n this.pm\n .ensurePackageJson(\n root,\n typeof opts.packageJson === \"boolean\" ? {} : opts.packageJson,\n )\n .then(() => {}),\n );\n }\n if (opts.tsconfigJson) {\n tasks.push(this.ensureTsConfig(root, { force }));\n }\n if (opts.biomeJson) {\n tasks.push(this.ensureBiomeConfig(root, { force, checkWorkspace }));\n }\n if (opts.editorconfig) {\n tasks.push(this.ensureEditorConfig(root, { force, checkWorkspace }));\n }\n if (opts.agentMd) {\n tasks.push(this.ensureAgentMd(root, { ...opts.agentMd, force }));\n }\n\n await Promise.all(tasks);\n }\n\n // ===========================================\n // Config Files\n // ===========================================\n\n public async ensureTsConfig(\n root: string,\n opts: { force?: boolean } = {},\n ): Promise<void> {\n // Check if tsconfig.json exists in current or parent directories\n if (!opts.force && (await this.existsInParents(root, \"tsconfig.json\"))) {\n return;\n }\n await this.fs.writeFile(\n this.fs.join(root, \"tsconfig.json\"),\n tsconfigJson(),\n );\n }\n\n public async ensureBiomeConfig(\n root: string,\n opts: { force?: boolean; checkWorkspace?: boolean } = {},\n ): Promise<void> {\n if (\n !opts.force &&\n opts.checkWorkspace &&\n (await this.existsInParents(root, \"biome.json\"))\n ) {\n return;\n }\n await this.ensureFile(root, \"biome.json\", biomeJson(), opts.force);\n }\n\n public async ensureEditorConfig(\n root: string,\n opts: { force?: boolean; checkWorkspace?: boolean } = {},\n ): Promise<void> {\n if (\n !opts.force &&\n opts.checkWorkspace &&\n (await this.existsInParents(root, \".editorconfig\"))\n ) {\n return;\n }\n await this.ensureFile(root, \".editorconfig\", editorconfig(), opts.force);\n }\n\n /**\n * Ensure git repository is initialized with .gitignore.\n *\n * @returns true if git was initialized, false if already exists or git unavailable\n */\n public async ensureGitRepo(\n root: string,\n opts: { force?: boolean } = {},\n ): Promise<boolean> {\n const gitDir = this.fs.join(root, \".git\");\n\n // Skip if .git already exists\n if (!opts.force && (await this.fs.exists(gitDir))) {\n return false;\n }\n\n // Check if git is available\n const hasGit = await this.utils.isInstalledAsync(\"git\");\n if (!hasGit) {\n return false;\n }\n\n // Initialize git repository\n await this.utils.exec(\"git init\", { root, global: true });\n\n // Write .gitignore\n await this.ensureFile(root, \".gitignore\", gitignore(), opts.force);\n\n return true;\n }\n\n public async ensureAgentMd(\n root: string,\n options: AgentMdOptions & { type: AgentMdType; force?: boolean },\n ): Promise<void> {\n const filename = options.type === \"claude\" ? \"CLAUDE.md\" : \"AGENTS.md\";\n await this.ensureFile(\n root,\n filename,\n agentMd(options.type, options),\n options.force,\n );\n }\n\n // ===========================================\n // Minimal Project Structure\n // ===========================================\n\n /**\n * Ensure src/main.server.ts exists with correct module imports.\n */\n public async ensureMainServerTs(\n root: string,\n opts: { api?: boolean; react?: boolean; force?: boolean } = {},\n ): Promise<void> {\n const srcDir = this.fs.join(root, \"src\");\n await this.fs.mkdir(srcDir, { recursive: true });\n await this.ensureFile(\n srcDir,\n \"main.server.ts\",\n mainServerTs({ api: opts.api, react: opts.react }),\n opts.force,\n );\n }\n\n // ===========================================\n // API Project Structure\n // ===========================================\n\n /**\n * Ensure API module structure exists.\n *\n * Creates:\n * - src/api/index.ts (API module)\n * - src/api/controllers/HelloController.ts (example controller)\n */\n public async ensureApiProject(\n root: string,\n opts: { auth?: boolean; force?: boolean } = {},\n ): Promise<void> {\n const appName = this.getAppName(root);\n\n // Create directories\n await this.fs.mkdir(this.fs.join(root, \"src/api/controllers\"), {\n recursive: true,\n });\n\n // Create files\n await this.ensureFile(\n root,\n \"src/api/index.ts\",\n apiIndexTs({ appName, auth: opts.auth }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/api/controllers/HelloController.ts\",\n apiHelloControllerTs(),\n opts.force,\n );\n\n // Create AppSecurity if auth is enabled\n if (opts.auth) {\n await this.ensureFile(\n root,\n \"src/api/AppSecurity.ts\",\n apiAppSecurityTs(),\n opts.force,\n );\n }\n }\n\n // ===========================================\n // Web Project Structure\n // ===========================================\n\n /**\n * Ensure web/React project structure exists.\n *\n * Creates:\n * - src/main.browser.ts\n * - src/main.css\n * - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Hello.tsx\n */\n public async ensureWebProject(\n root: string,\n opts: {\n api?: boolean;\n ui?: boolean;\n auth?: boolean;\n admin?: boolean;\n force?: boolean;\n } = {},\n ): Promise<void> {\n const appName = this.getAppName(root);\n\n // Create directories\n await this.fs.mkdir(this.fs.join(root, \"src/web/components\"), {\n recursive: true,\n });\n\n // src/main.css\n await this.ensureFile(\n root,\n \"src/main.css\",\n mainCss({ ui: opts.ui }),\n opts.force,\n );\n\n // Web structure\n await this.ensureFile(\n root,\n \"src/web/index.ts\",\n webIndexTs({ appName }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/web/AppRouter.ts\",\n webAppRouterTs({\n api: opts.api,\n ui: opts.ui,\n auth: opts.auth,\n admin: opts.admin,\n }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/web/components/Hello.tsx\",\n webHelloComponentTsx({ auth: opts.auth }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/main.browser.ts\",\n mainBrowserTs(),\n opts.force,\n );\n }\n\n // ===========================================\n // Test Directory\n // ===========================================\n\n /**\n * Ensure test directory exists with a dummy test file.\n */\n public async ensureTestDir(root: string): Promise<void> {\n const testDir = this.fs.join(root, \"test\");\n const dummyPath = this.fs.join(testDir, \"dummy.spec.ts\");\n\n if (!(await this.fs.exists(testDir))) {\n await this.fs.mkdir(testDir, { recursive: true });\n await this.fs.writeFile(dummyPath, dummySpecTs());\n return;\n }\n\n const files = await this.fs.ls(testDir);\n if (files.length === 0) {\n await this.fs.writeFile(dummyPath, dummySpecTs());\n }\n }\n\n // ===========================================\n // Helpers\n // ===========================================\n\n /**\n * Write a file, optionally overriding if it exists.\n */\n protected async ensureFile(\n root: string,\n relativePath: string,\n content: string,\n force?: boolean,\n ): Promise<void> {\n const fullPath = this.fs.join(root, relativePath);\n if (force || !(await this.fs.exists(fullPath))) {\n await this.fs.writeFile(fullPath, content);\n }\n }\n\n /**\n * Check if a file exists in the given directory or any parent directory.\n */\n protected async existsInParents(\n root: string,\n filename: string,\n ): Promise<boolean> {\n let current = root;\n while (true) {\n if (await this.fs.exists(this.fs.join(current, filename))) {\n return true;\n }\n const parent = dirname(current);\n if (parent === current) {\n // Reached filesystem root\n return false;\n }\n current = parent;\n }\n }\n}\n","import { $inject, $use, type Alepha, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport {\n buildClient,\n buildServer,\n copyAssets,\n generateCloudflare,\n generateDocker,\n generateSitemap,\n generateVercel,\n prerenderPages,\n} from \"alepha/vite\";\nimport {\n type BuildRuntime,\n type BuildTarget,\n buildOptions,\n} from \"../atoms/buildOptions.ts\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\nimport { ViteBuildProvider } from \"../providers/ViteBuildProvider.ts\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class BuildCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n protected readonly boot = $inject(AppEntryProvider);\n protected readonly viteBuildProvider = $inject(ViteBuildProvider);\n protected readonly options = $use(buildOptions);\n\n /**\n * Resolve the effective runtime based on target and explicit runtime flag.\n *\n * Some targets force a specific runtime:\n * - `cloudflare` always uses `workerd`\n * - `vercel` always uses `node`\n * - `docker` and bare deployments respect the runtime flag\n *\n * @throws {AlephaError} If an incompatible runtime is specified for a target\n */\n protected resolveRuntime(\n target: BuildTarget | undefined,\n runtime: BuildRuntime | undefined,\n ): BuildRuntime {\n if (target === \"cloudflare\") {\n if (runtime && runtime !== \"workerd\") {\n throw new AlephaError(\n `Target 'cloudflare' requires 'workerd' runtime, got '${runtime}'`,\n );\n }\n return \"workerd\";\n }\n\n if (target === \"vercel\") {\n if (runtime && runtime !== \"node\") {\n throw new AlephaError(\n `Target 'vercel' requires 'node' runtime, got '${runtime}'`,\n );\n }\n return \"node\";\n }\n\n return runtime ?? \"node\";\n }\n\n public readonly build = $command({\n name: \"build\",\n mode: \"production\",\n description: \"Build the project for production\",\n flags: t.object({\n stats: t.optional(\n t.boolean({\n description: \"Generate build stats report\",\n }),\n ),\n target: t.optional(\n t.enum([\"bare\", \"docker\", \"vercel\", \"cloudflare\"], {\n aliases: [\"t\"],\n description: \"Deployment target\",\n }),\n ),\n runtime: t.optional(\n t.enum([\"node\", \"bun\", \"workerd\"], {\n aliases: [\"r\"],\n description: \"JavaScript runtime\",\n }),\n ),\n image: t.optional(\n t.union([t.boolean(), t.text()], {\n aliases: [\"i\"],\n description:\n \"Build Docker image. Use -i for latest, -i=<version> for specific version\",\n }),\n ),\n sitemap: t.optional(\n t.text({\n description: \"Generate sitemap.xml with base URL\",\n }),\n ),\n }),\n handler: async ({ flags, run, root }) => {\n process.env.NODE_ENV = \"production\";\n\n if (await this.pm.hasExpo(root)) {\n // will come soon\n return;\n }\n\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n });\n\n const entry = await this.boot.getAppEntry(root);\n this.log.trace(\"Entry file found\", { entry });\n\n const distDir = \"dist\";\n const publicDir = \"public\";\n\n await run.rm(\"dist\", { alias: \"clean dist\" });\n\n const options = this.options;\n await this.utils.loadEnv(root, [\".env\", \".env.production\"]);\n\n // Resolve target and runtime\n const target = flags.target ?? options.target;\n const runtime = this.resolveRuntime(\n target,\n flags.runtime ?? options.runtime,\n );\n\n // Validate --image requires --target=docker\n if (flags.image && target !== \"docker\") {\n throw new AlephaError(\n `Flag '--image' requires '--target=docker', got '${target ?? \"bare\"}'`,\n );\n }\n\n this.log.trace(\"Build configuration\", { target, runtime });\n\n const stats = flags.stats ?? options.stats ?? false;\n let template = \"\";\n let hasClient = false;\n let alepha: Alepha | undefined;\n\n await run({\n name: \"analyze app\",\n handler: async () => {\n alepha = await this.viteBuildProvider.init({ entry });\n hasClient = this.viteBuildProvider.hasClient();\n if (hasClient) {\n template = this.viteBuildProvider.generateIndexHtml();\n }\n },\n });\n\n if (!alepha) {\n throw new AlephaError(\"Alepha instance not found\");\n }\n\n // Build client (precompress always enabled)\n if (hasClient) {\n // TODO: find a way to avoid writing index.html to disk\n const indexHtmlPath = this.fs.join(root, \"index.html\");\n await this.fs.writeFile(indexHtmlPath, template);\n try {\n await run({\n name: \"vite build client\",\n handler: () =>\n buildClient({\n silent: true,\n dist: `${distDir}/${publicDir}`,\n stats,\n precompress: true,\n }),\n });\n } finally {\n await this.fs.rm(indexHtmlPath);\n }\n }\n\n // Build server\n await run({\n name: \"vite build server\",\n handler: async () => {\n if (!alepha) {\n throw new AlephaError(\"Alepha instance not found\");\n }\n\n const clientIndexPath = `${distDir}/${publicDir}/index.html`;\n const clientBuilt = await this.fs.exists(clientIndexPath);\n\n // Set export conditions based on runtime\n const conditions: string[] = [];\n if (runtime === \"bun\") {\n conditions.push(\"bun\");\n } else if (runtime === \"workerd\") {\n conditions.push(\"workerd\");\n }\n\n await buildServer({\n silent: true,\n entry: entry.server,\n distDir,\n clientDir: clientBuilt ? publicDir : undefined,\n stats,\n conditions,\n alepha,\n });\n\n // Server will handle index.html if both client & server are built\n if (clientBuilt) {\n await this.fs.rm(clientIndexPath);\n }\n },\n });\n\n // Copy assets\n await copyAssets({\n alepha,\n root,\n entry: `${distDir}/index.js`,\n distDir,\n run,\n });\n\n if (hasClient) {\n // Generate sitemap\n const sitemapHostname = flags.sitemap ?? options.sitemap?.hostname;\n if (sitemapHostname) {\n await generateSitemap({\n alepha,\n baseUrl: sitemapHostname,\n output: `${distDir}/${publicDir}/sitemap.xml`,\n run,\n });\n }\n\n // Pre-render static pages (always enabled)\n await prerenderPages({\n alepha,\n dist: `${distDir}/${publicDir}`,\n compress: true,\n run,\n });\n }\n\n // Generate deployment configuration based on target\n if (target === \"vercel\") {\n await run({\n name: \"add Vercel config\",\n handler: () =>\n generateVercel({\n distDir,\n clientDir: publicDir,\n config: options.vercel,\n }),\n });\n }\n\n if (target === \"cloudflare\") {\n await run({\n name: \"add Cloudflare config\",\n handler: () =>\n generateCloudflare({\n distDir,\n config: options.cloudflare?.config,\n alepha: alepha!,\n }),\n });\n }\n\n if (target === \"docker\") {\n // Auto-configure Docker based on runtime\n const dockerFrom =\n options.docker?.from ??\n (runtime === \"bun\" ? \"oven/bun:alpine\" : \"node:24-alpine\");\n const dockerCommand =\n options.docker?.command ?? (runtime === \"bun\" ? \"bun\" : \"node\");\n\n await run({\n name: \"add Docker config\",\n handler: () =>\n generateDocker({\n distDir,\n image: dockerFrom,\n command: dockerCommand,\n }),\n });\n\n // Build Docker image if --image flag is provided\n if (flags.image) {\n const imageConfig = options.docker?.image;\n const flagValue =\n typeof flags.image === \"string\" ? flags.image : null;\n\n let imageTag: string;\n let version: string;\n\n if (!flagValue) {\n // -i (no value) → use config tag:latest\n if (!imageConfig?.tag) {\n throw new AlephaError(\n \"Flag '--image' requires 'build.docker.image.tag' in config\",\n );\n }\n version = \"latest\";\n imageTag = `${imageConfig.tag}:${version}`;\n } else if (flagValue.startsWith(\":\")) {\n // -i=:1.3.4 → version only, prepend config tag\n if (!imageConfig?.tag) {\n throw new AlephaError(\n \"Flag '--image=:version' requires 'build.docker.image.tag' in config\",\n );\n }\n version = flagValue.slice(1); // remove leading \":\"\n imageTag = `${imageConfig.tag}:${version}`;\n } else if (flagValue.includes(\":\")) {\n // -i=toto:1.3.4 → full image with version\n imageTag = flagValue;\n version = flagValue.split(\":\")[1];\n } else {\n // -i=toto → image name without version → add :latest\n imageTag = `${flagValue}:latest`;\n version = \"latest\";\n }\n\n const args: string[] = [];\n\n // Add custom args\n if (imageConfig?.args) {\n args.push(imageConfig.args);\n }\n\n // Add OCI labels if enabled\n if (imageConfig?.oci) {\n const revision = await this.utils.getGitRevision();\n const created = new Date().toISOString();\n\n args.push(\n `--label \"org.opencontainers.image.revision=${revision}\"`,\n );\n args.push(`--label \"org.opencontainers.image.created=${created}\"`);\n args.push(`--label \"org.opencontainers.image.version=${version}\"`);\n }\n\n const argsStr = args.length > 0 ? `${args.join(\" \")} ` : \"\";\n const dockerCmd = `docker build ${argsStr}-t ${imageTag} ${distDir}`;\n\n await run(dockerCmd, {\n alias: `docker build ${imageTag}`,\n });\n }\n }\n },\n });\n}\n","import { $command } from \"alepha/command\";\n\nexport class CleanCommand {\n /**\n * Clean the project, removing the \"dist\" directory\n */\n public readonly clean = $command({\n name: \"clean\",\n description: \"Clean the project\",\n handler: async ({ run }) => {\n await run.rm(\"./dist\");\n },\n });\n}\n","import { $inject, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport type {\n DatabaseProvider,\n DrizzleKitProvider,\n RepositoryProvider,\n} from \"alepha/orm\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\n\nconst drizzleCommandFlags = t.object({\n provider: t.optional(\n t.text({\n description:\n \"Database provider name to target (e.g., 'postgres', 'sqlite')\",\n }),\n ),\n mode: t.optional(\n t.text({\n description:\n \"Environment variable file(s) to load (e.g., 'production' to load .env.production) https://vite.dev/guide/env-and-mode\",\n }),\n ),\n});\n\nexport class DbCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly entryProvider = $inject(AppEntryProvider);\n\n /**\n * Check if database migrations are up to date.\n */\n protected readonly check = $command({\n name: \"check-migrations\",\n description: \"Check if database migration files are up to date\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ args, root }) => {\n const rootDir = root;\n this.log.debug(`Using project root: ${rootDir}`);\n\n const entry = await this.entryProvider.getAppEntry(root);\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n mode: \"development\",\n entry,\n });\n\n const repositoryProvider =\n alepha.inject<RepositoryProvider>(\"RepositoryProvider\");\n const drizzleKitProvider =\n alepha.inject<DrizzleKitProvider>(\"DrizzleKitProvider\");\n const accepted = new Set<string>([]);\n\n for (const primitive of repositoryProvider.getRepositories()) {\n const provider = primitive.provider;\n const providerName = provider.name;\n if (accepted.has(providerName)) {\n continue;\n }\n\n accepted.add(providerName);\n\n const migrationDir = this.fs.join(rootDir, \"migrations\", providerName);\n\n const journalBuffer = await this.fs\n .readFile(`${migrationDir}/meta/_journal.json`)\n .catch(() => null);\n\n if (!journalBuffer) {\n this.log.info(\"No migration journal found.\");\n return;\n }\n\n const journal = JSON.parse(journalBuffer.toString(\"utf-8\"));\n const lastMigration = journal.entries[journal.entries.length - 1];\n const snapshotBuffer = await this.fs.readFile(\n `${migrationDir}/meta/${String(lastMigration.idx).padStart(4, \"0\")}_snapshot.json`,\n );\n const lastSnapshot = JSON.parse(snapshotBuffer.toString(\"utf-8\"));\n\n const models = drizzleKitProvider.getModels(provider);\n const kit = drizzleKitProvider.importDrizzleKit();\n const now = kit.generateDrizzleJson(models, lastSnapshot.id);\n\n const migrationStatements = await new Promise<Array<any>>((resolve) => {\n (async () => {\n const timer = setTimeout(() => {\n resolve([{ message: \"Migration generation timed out.\" }]);\n }, 5000);\n const statements = await kit.generateMigration(lastSnapshot, now);\n clearTimeout(timer);\n resolve(statements);\n })();\n });\n\n if (migrationStatements.length === 0) {\n this.log.info(\"No changes detected.\");\n return;\n }\n\n this.log.info(\"\");\n this.log.info(\"Detected migration statements:\");\n this.log.info(\"\");\n for (const stmt of migrationStatements) {\n this.log.info(stmt);\n }\n this.log.info(\"\");\n\n this.log.info(\n `At least ${migrationStatements.length} change(s) detected.`,\n );\n this.log.info(\n \"Please, run 'alepha db:generate' to update the migration files.\",\n );\n this.log.info(\"\");\n\n throw new AlephaError(\"Database migrations are not up to date.\");\n }\n },\n });\n\n /**\n * Generate database migration files\n */\n protected readonly generate = $command({\n name: \"generate\",\n description: \"Generate migration files based on current database schema\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: t.extend(drizzleCommandFlags, {\n custom: t.optional(\n t.text({\n description:\n \"Custom migration name for drizzle-kit generate --custom\",\n }),\n ),\n }),\n handler: async ({ args, flags, root }) => {\n const commandFlags = flags.custom\n ? `--custom=${flags.custom}`\n : undefined;\n\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"generate\",\n commandFlags,\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Generate '${providerName}' migrations (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Push database schema changes directly to the database\n */\n protected readonly push = $command({\n name: \"push\",\n description: \"Push database schema changes directly to the database\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ root, args, flags }) => {\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"push\",\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Push '${providerName}' schema (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Apply pending database migrations\n */\n protected readonly migrate = $command({\n name: \"migrate\",\n description: \"Apply pending database migrations\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ root, args, flags }) => {\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"migrate\",\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Migrate '${providerName}' database (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Launch Drizzle Studio database browser\n */\n protected readonly studio = $command({\n name: \"studio\",\n description: \"Launch Drizzle Studio database browser\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ root, args, flags }) => {\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"studio\",\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Launch Studio for '${providerName}' (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Parent command for database operations.\n */\n public readonly db = $command({\n name: \"db\",\n description: \"Database management commands\",\n children: [this.check, this.generate, this.push, this.migrate, this.studio],\n handler: async ({ help }) => {\n help();\n },\n });\n\n /**\n * Run a drizzle-kit command for all database providers in an Alepha instance.\n */\n public async runDrizzleKitCommand(options: {\n root: string;\n args?: string;\n command: string;\n commandFlags?: string;\n provider?: string;\n logMessage: (providerName: string, dialect: string) => string;\n env?: string;\n }): Promise<void> {\n const rootDir = options.root;\n\n const envFiles = [\".env\"];\n if (options.env) {\n envFiles.push(`.env.${options.env}`);\n }\n\n await this.utils.loadEnv(rootDir, envFiles);\n\n this.log.debug(`Using project root: ${rootDir}`);\n\n const entry = await this.entryProvider.getAppEntry(rootDir);\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n mode: \"development\",\n entry,\n });\n\n const drizzleKitProvider =\n alepha.inject<DrizzleKitProvider>(\"DrizzleKitProvider\");\n const repositoryProvider =\n alepha.inject<RepositoryProvider>(\"RepositoryProvider\");\n const accepted = new Set<string>([]);\n\n for (const primitive of repositoryProvider.getRepositories()) {\n const provider = primitive.provider;\n const providerName = provider.name;\n const dialect = provider.dialect;\n\n if (providerName === \"\") {\n continue;\n }\n\n if (accepted.has(providerName)) {\n continue;\n }\n accepted.add(providerName);\n\n // Skip if provider filter is set and doesn't match\n if (options.provider && options.provider !== providerName) {\n this.log.debug(\n `Skipping provider '${providerName}' (filter: ${options.provider})`,\n );\n continue;\n }\n\n this.log.info(\"\");\n this.log.info(options.logMessage(providerName, dialect));\n\n const drizzleConfigJsPath = await this.prepareDrizzleConfig({\n kit: drizzleKitProvider,\n provider,\n providerName,\n providerUrl: provider.url,\n providerDriver: provider.driver,\n dialect,\n entry: this.fs.join(rootDir, entry.server),\n rootDir,\n });\n\n const flags = options.commandFlags ? ` ${options.commandFlags}` : \"\";\n await this.utils.exec(\n `drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`,\n {\n env: {\n NODE_OPTIONS: [process.env.NODE_OPTIONS, \"--import tsx\"]\n .filter(Boolean)\n .join(\" \"),\n },\n },\n );\n }\n }\n\n /**\n * Prepare Drizzle configuration files for a database provider.\n */\n public async prepareDrizzleConfig(options: {\n kit: any;\n provider: DatabaseProvider;\n providerName: string;\n providerUrl: string;\n providerDriver: string;\n dialect: string;\n entry: string;\n rootDir: string;\n }): Promise<string> {\n const models = Object.keys(options.kit.getModels(options.provider));\n const entitiesJs = this.utils.generateEntitiesJs(\n options.entry,\n options.providerName,\n models,\n );\n\n const entitiesJsPath = await this.utils.writeConfigFile(\n \"entities.js\",\n entitiesJs,\n options.rootDir,\n );\n\n const config: Record<string, any> = {\n schema: entitiesJsPath,\n out: `./migrations/${options.providerName}`,\n dialect: options.dialect,\n dbCredentials: {\n url: options.providerUrl,\n },\n };\n\n if (options.provider.schema) {\n config.schemaFilter = options.provider.schema;\n }\n\n if (options.providerDriver === \"d1\") {\n config.driver = \"d1-http\";\n }\n\n if (options.providerDriver === \"pglite\") {\n config.driver = \"pglite\";\n }\n\n if (options.dialect === \"sqlite\") {\n if (options.providerDriver === \"d1\") {\n const token = process.env.CLOUDFLARE_API_TOKEN;\n if (!token) {\n throw new AlephaError(\n \"CLOUDFLARE_API_TOKEN environment variable is not set. https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit\",\n );\n }\n\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n if (!accountId) {\n throw new AlephaError(\n \"CLOUDFLARE_ACCOUNT_ID environment variable is not set. https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit\",\n );\n }\n\n const url = options.providerUrl;\n if (!url.startsWith(\"d1://\")) {\n throw new AlephaError(\"D1 provider URL must start with 'd1://'.\");\n }\n\n const [, databaseId] = url\n .replace(\"d1://\", \"\")\n .replace(\"d1:\", \"\")\n .split(\":\");\n\n if (!databaseId) {\n throw new AlephaError(\n \"Database ID is missing in the D1 provider URL. Cloudflare D1 URL format: d1://<database_name>:<database_id>\",\n );\n }\n\n config.dbCredentials = {\n accountId,\n databaseId,\n token,\n };\n } else {\n let url = options.providerUrl;\n url = url.replace(\"sqlite://\", \"\").replace(\"file://\", \"\");\n url = this.fs.join(options.rootDir, url);\n\n config.dbCredentials = {\n url,\n };\n }\n }\n\n const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;\n\n return await this.utils.writeConfigFile(\n \"drizzle.config.js\",\n drizzleConfigJs,\n options.rootDir,\n );\n }\n}\n","import { $inject, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\n\nexport class DeployCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n\n /**\n * Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)\n *\n * Deploy command can be overridden by creating a alepha.config.ts in the project root:\n *\n * ```ts\n * import { defineConfig } from \"alepha/cli\";\n *\n * export default defineConfig({\n * commands: {\n * deploy: {\n * handler: async ({ root, mode, flags }) => {\n * // Custom deployment logic here\n * },\n * },\n * },\n * });\n * ```\n */\n public readonly deploy = $command({\n name: \"deploy\",\n description:\n \"Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)\",\n mode: true,\n flags: t.object({\n build: t.boolean({\n description: \"Build the project before deployment\",\n default: false,\n }),\n migrate: t.boolean({\n description:\n \"Run database migrations before deployment (if applicable)\",\n default: false,\n }),\n }),\n env: t.object({\n VERCEL_TOKEN: t.optional(\n t.text({\n description: \"Vercel API token (e.g., xxxxxxxxxxxxxxxxxxxx)\",\n }),\n ),\n VERCEL_ORG_ID: t.optional(\n t.text({\n description: \"Vercel organization ID (e.g., team_abc123...)\",\n }),\n ),\n VERCEL_PROJECT_ID: t.optional(\n t.text({ description: \"Vercel project ID (e.g., prj_abc123...)\" }),\n ),\n CLOUDFLARE_API_TOKEN: t.optional(\n t.text({\n description: \"Cloudflare API token (e.g., xxxx-xxxx-xxxx-xxxx)\",\n }),\n ),\n CLOUDFLARE_ACCOUNT_ID: t.optional(\n t.text({\n description: \"Cloudflare account ID (e.g., abc123def456...)\",\n }),\n ),\n }),\n handler: async ({ root, mode, flags }) => {\n if (flags.build) {\n await this.utils.exec(\"alepha build\");\n }\n\n // Vercel deployment\n if (await this.utils.exists(root, \"dist/vercel.json\")) {\n if (flags.migrate) {\n this.log.debug(\"Running database migrations before deployment...\");\n await this.utils.exec(`alepha db migrate --mode=${mode}`);\n }\n await this.pm.ensureDependency(root, \"vercel\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n const command =\n `vercel . --cwd=dist ${mode === \"production\" ? \"--prod\" : \"\"}`.trim();\n this.log.debug(`Deploying to Vercel with command: ${command}`);\n await this.utils.exec(command);\n return;\n }\n\n // Cloudflare deployment\n if (await this.utils.exists(root, \"dist/wrangler.jsonc\")) {\n if (flags.migrate) {\n this.log.debug(\"Running database migrations before deployment...\");\n await this.utils.exec(`alepha db migrate --mode=${mode}`);\n }\n await this.pm.ensureDependency(root, \"wrangler\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n const command =\n `wrangler deploy ${mode === \"production\" ? \"\" : \"--env preview\"} --config=dist/wrangler.jsonc`.trim();\n this.log.info(`Deploying to Cloudflare with command: ${command}`);\n await this.utils.exec(command);\n return;\n }\n\n // Surge deployment\n if (await this.utils.exists(root, \"dist/public/404.html\")) {\n await this.pm.ensureDependency(root, \"surge\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n const distPath = this.fs.join(root, \"dist/public\");\n this.log.debug(`Deploying to Surge from directory: ${distPath}`);\n await this.utils.exec(`surge ${distPath}`);\n return;\n }\n\n throw new AlephaError(\n \"No deployment configuration found in the dist folder.\",\n );\n },\n });\n}\n","import { $inject, type Alepha, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { importVite, importViteReact, viteAlephaSsrPreload } from \"alepha/vite\";\nimport type { InlineConfig, Plugin, ViteDevServer } from \"vite\";\nimport type { AppEntry } from \"./AppEntryProvider.ts\";\n\nexport interface ViteDevServerOptions {\n /**\n * Root directory of the project.\n */\n root: string;\n\n /**\n * Path to the server entry file.\n */\n entry: AppEntry;\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/**\n * Vite development server with Alepha integration.\n *\n * Architecture:\n * - Vite runs in middleware mode (no HTTP server)\n * - Alepha is the HTTP server via server:onRequest event\n * - Request flow: Page requests → Alepha SSR, Assets → Vite middleware\n *\n * HMR Strategy:\n * - Browser-only changes (CSS, client components) → Vite HMR (React Fast Refresh)\n * - Server-only changes → Restart Alepha → Full browser reload\n * - Shared changes → Restart Alepha → Let Vite HMR propagate\n *\n * Features:\n * - Automatic .env reload detection\n * - Error recovery on next file change\n * - Optimized module invalidation (only changed files + importers)\n */\nexport class ViteDevServerProvider {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected server!: ViteDevServer;\n protected options!: ViteDevServerOptions;\n protected alepha: Alepha | null = null;\n protected hasError = false;\n protected changedFiles = new Set<string>();\n\n public async init(options: ViteDevServerOptions): Promise<Alepha> {\n this.options = options;\n await this.createViteServer();\n return await this.loadAlepha(true);\n }\n\n public async start(): Promise<void> {\n await this.alepha?.start();\n }\n\n /**\n * Create the Vite server in middleware mode.\n */\n protected async createViteServer(): Promise<void> {\n const { createServer } = await importVite();\n const viteReact = await importViteReact();\n\n const plugins: Plugin[] = [];\n if (viteReact) plugins.push(viteReact());\n plugins.push(viteAlephaSsrPreload());\n plugins.push(this.createHmrPlugin());\n\n this.server = await createServer({\n root: this.options.root,\n plugins,\n server: { middlewareMode: true },\n appType: \"custom\",\n customLogger: {\n info: () => {},\n warn: this.log.warn.bind(this.log),\n error: this.log.error.bind(this.log),\n warnOnce: this.log.warn.bind(this.log),\n clearScreen: () => {},\n hasWarned: false,\n hasErrorLogged: () => false,\n },\n } satisfies InlineConfig);\n\n // Intercept .env changes (Vite calls restart() for .env files)\n this.server.restart = async () => {\n const startTime = Date.now();\n try {\n this.hasError = true; // Force full invalidation for env changes\n await this.loadAlepha(false);\n await this.alepha?.start();\n this.log.debug(`Env reloaded in ${Date.now() - startTime}ms`);\n this.sendBrowserReload();\n } catch (err) {\n this.hasError = true;\n this.log.error(\"Reload failed\", err);\n this.log.warn(\"Waiting for file changes to retry...\");\n this.alepha = null;\n }\n };\n }\n\n /**\n * Vite plugin to handle HMR for Alepha.\n */\n protected createHmrPlugin(): Plugin {\n return {\n name: \"alepha-hmr\",\n handleHotUpdate: async (ctx) => {\n if (ctx.file.includes(\"/.idea/\")) return [];\n\n const firstModule = ctx.modules[0] as any;\n const isBrowserOnly = firstModule && !firstModule._ssrModule;\n const isServerOnly = firstModule && !firstModule._clientModule;\n\n // Browser-only: let Vite HMR handle it (React Fast Refresh)\n if (isBrowserOnly) return;\n\n // Server or shared change: restart Alepha\n const startTime = Date.now();\n\n try {\n this.changedFiles.add(ctx.file);\n await this.loadAlepha(false);\n await this.alepha?.start();\n this.log.debug(`Reloaded in ${Date.now() - startTime}ms`);\n\n // Server-only: full browser reload\n if (isServerOnly) {\n this.sendBrowserReload();\n return [];\n }\n\n // Shared: let HMR propagate to browser\n return;\n } catch (err) {\n this.hasError = true;\n this.log.error(\"Reload failed\", err);\n this.log.warn(\"Waiting for file changes to retry...\");\n this.alepha = null;\n return [];\n }\n },\n };\n }\n\n /**\n * Send browser reload signal via custom event.\n * Browser listens for 'alepha:reload' and does window.location.reload()\n */\n protected sendBrowserReload(): void {\n this.server.ws.send({\n type: \"custom\",\n event: \"alepha:reload\",\n data: {},\n });\n }\n\n /**\n * Setup environment variables for dev mode.\n */\n protected async setupEnvironment(): Promise<void> {\n const { loadEnv } = await importVite();\n const mode = process.env.NODE_ENV || \"development\";\n const env = loadEnv(mode, this.options.root, \"\");\n\n // Merge into process.env (only set if not already defined)\n for (const [key, value] of Object.entries(env)) {\n process.env[key] ??= value;\n }\n\n process.env.NODE_ENV ??= \"development\";\n process.env.VITE_ALEPHA_DEV = \"true\";\n process.env.SERVER_HOST ??= this.options.host?.toString() ?? \"localhost\";\n process.env.SERVER_PORT ??= String(\n this.options.port ??\n (process.env.SERVER_PORT ? Number(process.env.SERVER_PORT) : 3000),\n );\n }\n\n /**\n * Load or reload the Alepha instance.\n */\n protected async loadAlepha(isInitialLoad = false): Promise<Alepha> {\n if (this.alepha) {\n await this.alepha\n .stop()\n .catch((err) => this.log.warn(\"Error stopping Alepha\", err));\n this.alepha = null;\n }\n\n if (isInitialLoad || this.hasError) {\n this.server.moduleGraph.invalidateAll();\n } else {\n this.invalidateModulesWithImporters();\n }\n this.changedFiles.clear();\n\n // Snapshot and restore process.env to isolate each reload\n const envSnapshot = { ...process.env };\n await this.setupEnvironment();\n\n await this.server.ssrLoadModule(this.options.entry.server);\n\n const alepha: Alepha = (globalThis as any).__alepha;\n if (!alepha) {\n throw new AlephaError(\n \"Alepha instance not found after loading entry module\",\n );\n }\n\n this.alepha = alepha;\n await this.setupAlepha();\n\n this.hasError = false;\n process.env = envSnapshot;\n\n return alepha;\n }\n\n public hasReact(): boolean {\n try {\n this.alepha?.inject(\"ReactServerProvider\");\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Setup Alepha instance with Vite middleware.\n */\n protected async setupAlepha(): Promise<void> {\n if (!this.alepha || !this.hasReact()) {\n return;\n }\n\n // Generate dev head content using Vite's transformIndexHtml\n // This lets Vite and all plugins (React, etc.) inject their scripts\n const devHead = await this.generateDevHead();\n this.alepha.store.set(\"alepha.react.ssr.manifest\" as any, { devHead });\n\n this.alepha.events.on(\"server:onRequest\", {\n priority: \"first\",\n callback: async ({ request }) => {\n const node = request.raw.node;\n if (!node || this.isPageRequest(node.req)) return;\n\n const handled = await this.runViteMiddleware(\n node.req,\n node.res,\n request,\n );\n if (handled) {\n request.reply.status = node.res.statusCode || 200;\n request.reply.body = null;\n }\n },\n });\n }\n\n /**\n * Generate dev head content by transforming a minimal HTML through Vite.\n * This lets Vite and all plugins inject their scripts (HMR client, React Fast Refresh, etc.).\n */\n protected async generateDevHead(): Promise<string> {\n const { browser, style } = this.options.entry;\n\n // Build minimal HTML with entry points\n const scripts: string[] = [];\n if (style) {\n scripts.push(`<link rel=\"stylesheet\" href=\"/${style}\">`);\n }\n if (browser) {\n scripts.push(`<script type=\"module\" src=\"/${browser}\"></script>`);\n }\n\n const minimalHtml = `<!DOCTYPE html><html><head>${scripts.join(\"\\n\")}</head><body></body></html>`;\n\n // Transform through Vite to inject all plugin scripts\n const transformed = await this.server.transformIndexHtml(\"/\", minimalHtml);\n\n // Extract head content\n const headMatch = transformed.match(/<head>([\\s\\S]*?)<\\/head>/i);\n return headMatch?.[1]?.trim() ?? \"\";\n }\n\n /**\n * Check if request is for an HTML page (not an asset).\n */\n protected isPageRequest(req: any): boolean {\n const url = req.url || \"/\";\n\n // Root and index.html are page requests\n if (url === \"/\" || url === \"/index.html\") return true;\n\n // Vite internal routes\n if (url.startsWith(\"/@\") || url.startsWith(\"/__vite\")) return false;\n\n // Files with extensions are assets\n if (/\\.\\w+$/.test(url.split(\"?\")[0])) return false;\n\n return true;\n }\n\n /**\n * Run Vite middleware and detect if it handled the request.\n */\n protected async runViteMiddleware(\n req: any,\n res: any,\n ctx: { metadata: any },\n ): Promise<boolean> {\n // Skip if response already started\n if (res.headersSent || res.writableEnded) {\n return false;\n }\n\n return new Promise((resolve) => {\n let resolved = false;\n\n const done = (handled: boolean) => {\n if (resolved) return;\n resolved = true;\n if (handled) ctx.metadata.vite = true;\n resolve(handled);\n };\n\n // Wrap response to prevent writes after we've resolved\n const originalSetHeader = res.setHeader.bind(res);\n const originalWriteHead = res.writeHead?.bind(res);\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n\n const guardedCall = <T>(fn: (...args: any[]) => T, ...args: any[]): T => {\n if (resolved && !ctx.metadata.vite) {\n // Vite didn't handle this request, silently ignore late writes\n return undefined as T;\n }\n return fn(...args);\n };\n\n res.setHeader = (...args: any[]) =>\n guardedCall(originalSetHeader, ...args);\n if (originalWriteHead) {\n res.writeHead = (...args: any[]) =>\n guardedCall(originalWriteHead, ...args);\n }\n res.write = (...args: any[]) => guardedCall(originalWrite, ...args);\n res.end = (...args: any[]) => guardedCall(originalEnd, ...args);\n\n res.on(\"finish\", () => done(true));\n res.on(\"close\", () => res.headersSent && done(true));\n\n this.server.middlewares(req, res, () => done(false));\n\n // Check after microtask if Vite started writing (for async handlers)\n setImmediate(() => {\n if (res.headersSent || res.writableEnded) {\n done(true);\n }\n });\n });\n }\n\n /**\n * Invalidate modules and all their importers.\n */\n protected invalidateModulesWithImporters(): void {\n const invalidated = new Set<string>();\n const queue: string[] = [...this.changedFiles];\n\n while (queue.length > 0) {\n const file = queue.pop()!;\n if (invalidated.has(file)) continue;\n\n const mod = this.server.moduleGraph.getModuleById(file);\n if (!mod) continue;\n\n this.server.moduleGraph.invalidateModule(mod);\n invalidated.add(file);\n\n for (const importer of mod.importers) {\n if (importer.id && !invalidated.has(importer.id)) {\n queue.push(importer.id);\n }\n }\n }\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\nimport { ViteDevServerProvider } from \"../providers/ViteDevServerProvider.ts\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class DevCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n protected readonly alepha = $inject(Alepha);\n protected readonly viteDevServer = $inject(ViteDevServerProvider);\n protected readonly boot = $inject(AppEntryProvider);\n\n /**\n * Will run the project in watch mode.\n */\n public readonly dev = $command({\n name: \"dev\",\n description: \"Run the project in development mode\",\n handler: async ({ root }) => {\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n });\n\n const entry = await this.boot.getAppEntry(root);\n this.log.debug(\"Entry file found\", { entry });\n\n // -> here, we assume we use Vite as runner (api or fullstack)\n // but it's planned to support Bun runner in the future as well\n await this.viteDevServer.init({ root, entry });\n await this.viteDevServer.start();\n },\n });\n}\n","import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Default scopes to ignore in changelog generation.\n * Commits with these scopes won't appear in release notes.\n */\nexport const DEFAULT_IGNORE = [\n \"project\",\n \"release\",\n \"starter\",\n \"example\",\n \"chore\",\n \"ci\",\n \"build\",\n \"test\",\n \"style\",\n];\n\n/**\n * Changelog configuration atom.\n *\n * Configure in `alepha.config.ts`:\n * ```ts\n * import { changelogOptions } from \"alepha/cli\";\n *\n * alepha.set(changelogOptions, {\n * ignore: [\"project\", \"release\", \"chore\", \"docs\"],\n * });\n * ```\n */\nexport const changelogOptions = $atom({\n name: \"alepha.cli.changelog.options\",\n schema: t.object({\n /**\n * Scopes to ignore (e.g., \"project\", \"release\", \"chore\").\n * Commits like `feat(chore): ...` will be excluded from changelog.\n */\n ignore: t.optional(t.array(t.string())),\n }),\n default: {\n ignore: DEFAULT_IGNORE,\n },\n});\n\nexport type ChangelogOptions = Static<typeof changelogOptions.schema>;\n","import { $logger } from \"alepha/logger\";\nimport {\n type ChangelogOptions,\n DEFAULT_IGNORE,\n} from \"../atoms/changelogOptions.ts\";\nimport type { Commit } from \"../commands/gen/changelog.ts\";\n\n/**\n * Service for parsing git commit messages into structured format.\n *\n * Only parses **conventional commits with a scope**:\n * - `feat(scope): description` → feature\n * - `fix(scope): description` → bug fix\n * - `feat(scope)!: description` → breaking change\n *\n * Commits without scope are ignored, allowing developers to commit\n * work-in-progress changes without polluting release notes:\n * - `cli: work in progress` → ignored (no type)\n * - `fix: quick patch` → ignored (no scope)\n * - `feat(cli): add command` → included\n */\nexport class GitMessageParser {\n protected readonly log = $logger();\n\n /**\n * Parse a git commit line into a structured Commit object.\n *\n * **Format:** `type(scope): description` or `type(scope)!: description`\n *\n * **Supported types:** feat, fix, docs, refactor, perf, revert\n *\n * **Breaking changes:** Use `!` before `:` (e.g., `feat(api)!: remove endpoint`)\n *\n * @returns Commit object or null if not matching/ignored\n */\n parseCommit(line: string, config: ChangelogOptions): Commit | null {\n // Extract hash and message from git log --oneline format\n const match = line.match(/^([a-f0-9]+)\\s+(.+)$/);\n if (!match) return null;\n\n const [, hash, message] = match;\n const ignore = config.ignore ?? DEFAULT_IGNORE;\n\n // Conventional commit with REQUIRED scope: type(scope): description\n // The `!` before `:` marks a breaking change\n const conventionalMatch = message.match(\n /^(feat|fix|docs|refactor|perf|revert)\\(([^)]+)\\)(!)?:\\s*(.+)$/i,\n );\n\n if (!conventionalMatch) {\n // No match - commit doesn't follow required format\n return null;\n }\n\n const [, type, scope, breakingMark, description] = conventionalMatch;\n\n // Check if scope should be ignored\n const baseScope = scope.split(\"/\")[0];\n if (ignore.includes(baseScope) || ignore.includes(scope)) {\n return null;\n }\n\n // Breaking change detection:\n // 1. Explicit `!` marker: feat(api)!: change\n // 2. Word \"breaking\" in description: feat(api): breaking change to auth\n const breaking =\n breakingMark === \"!\" || description.toLowerCase().includes(\"breaking\");\n\n return {\n hash: hash.substring(0, 8),\n type: type.toLowerCase(),\n scope,\n description: description.trim(),\n breaking,\n };\n }\n}\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { $inject, $use, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { changelogOptions } from \"../../atoms/changelogOptions.ts\";\nimport { GitMessageParser } from \"../../services/GitMessageParser.ts\";\n\nexport {\n type ChangelogOptions,\n changelogOptions,\n DEFAULT_IGNORE,\n} from \"../../atoms/changelogOptions.ts\";\nexport { GitMessageParser } from \"../../services/GitMessageParser.ts\";\n\nconst execAsync = promisify(exec);\n\n// =============================================================================\n// GIT PROVIDER\n// =============================================================================\n\n/**\n * Git provider for executing git commands.\n * Can be substituted in tests with a mock implementation.\n */\nexport class GitProvider {\n async exec(cmd: string, cwd: string): Promise<string> {\n const { stdout } = await execAsync(`git ${cmd}`, { cwd });\n return stdout;\n }\n}\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface Commit {\n hash: string;\n type: string;\n scope: string | null;\n description: string;\n breaking: boolean;\n}\n\ninterface ChangelogEntry {\n features: Commit[];\n fixes: Commit[];\n}\n\n// =============================================================================\n// CHANGELOG COMMAND\n// =============================================================================\n\n/**\n * Changelog command for generating release notes from git commits.\n *\n * Usage:\n * - `alepha gen changelog` - Show unreleased changes since latest tag to HEAD\n * - `alepha gen changelog --from=1.0.0` - Show changes from version to HEAD\n * - `alepha gen changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs\n * - `alepha gen changelog | tee -a CHANGELOG.md` - Append to file\n */\nexport class ChangelogCommand {\n protected readonly log = $logger();\n protected readonly git = $inject(GitProvider);\n protected readonly parser = $inject(GitMessageParser);\n protected readonly config = $use(changelogOptions);\n\n // ---------------------------------------------------------------------------\n // FORMATTING\n // ---------------------------------------------------------------------------\n\n /**\n * Format a single commit line.\n * Example: `- **cli**: add new command (\\`abc1234\\`)`\n * Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\\`abc1234\\`)`\n */\n protected formatCommit(commit: Commit): string {\n const breaking = commit.breaking ? \" [BREAKING]\" : \"\";\n return `- **${commit.scope}**: ${commit.description}${breaking} (\\`${commit.hash}\\`)`;\n }\n\n /**\n * Format the changelog entry with sections.\n */\n protected formatEntry(entry: ChangelogEntry): string {\n const sections: string[] = [];\n\n if (entry.features.length > 0) {\n sections.push(\"### Features\\n\");\n for (const commit of entry.features) {\n sections.push(this.formatCommit(commit));\n }\n sections.push(\"\");\n }\n\n if (entry.fixes.length > 0) {\n sections.push(\"### Bug Fixes\\n\");\n for (const commit of entry.fixes) {\n sections.push(this.formatCommit(commit));\n }\n sections.push(\"\");\n }\n\n return sections.join(\"\\n\");\n }\n\n // ---------------------------------------------------------------------------\n // PARSING\n // ---------------------------------------------------------------------------\n\n /**\n * Parse git log output into a changelog entry.\n */\n protected parseCommits(commitsOutput: string): ChangelogEntry {\n const entry: ChangelogEntry = {\n features: [],\n fixes: [],\n };\n\n for (const line of commitsOutput.trim().split(\"\\n\")) {\n if (!line.trim()) continue;\n\n const commit = this.parser.parseCommit(line, this.config);\n if (!commit) {\n this.log.trace(\"Skipping commit\", { line });\n continue;\n }\n\n this.log.trace(\"Parsed commit\", { commit });\n\n // Categorize commit (breaking flag is preserved on the commit itself)\n if (commit.type === \"feat\") {\n entry.features.push(commit);\n } else if (commit.type === \"fix\") {\n entry.fixes.push(commit);\n }\n }\n\n return entry;\n }\n\n /**\n * Check if entry has any public commits.\n */\n protected hasChanges(entry: ChangelogEntry): boolean {\n return entry.features.length > 0 || entry.fixes.length > 0;\n }\n\n /**\n * Get the latest version tag.\n */\n protected async getLatestTag(\n git: (cmd: string) => Promise<string>,\n ): Promise<string | null> {\n const tagsOutput = await git(\"tag --sort=-version:refname\");\n const tags = tagsOutput\n .trim()\n .split(\"\\n\")\n .filter((tag) => tag.match(/^\\d+\\.\\d+\\.\\d+$/));\n\n return tags[0] || null;\n }\n\n // ---------------------------------------------------------------------------\n // COMMAND\n // ---------------------------------------------------------------------------\n\n public readonly command = $command({\n name: \"changelog\",\n description:\n \"Generate changelog from conventional commits (outputs to stdout)\",\n flags: t.object({\n /**\n * Show changes from this ref (tag, commit, branch).\n * Defaults to the latest version tag.\n * Example: --from=1.0.0\n */\n from: t.optional(\n t.string({\n aliases: [\"f\"],\n description: \"Starting ref (default: latest tag)\",\n }),\n ),\n /**\n * Show changes up to this ref (tag, commit, branch).\n * Defaults to HEAD.\n * Example: --to=main\n */\n to: t.optional(\n t.string({\n aliases: [\"t\"],\n description: \"Ending ref (default: HEAD)\",\n }),\n ),\n }),\n handler: async ({ flags, root }) => {\n const git = (cmd: string) => this.git.exec(cmd, root);\n\n // Determine the starting point\n let fromRef: string;\n\n if (flags.from) {\n // User specified a ref\n fromRef = flags.from;\n this.log.debug(\"Using specified from ref\", { from: fromRef });\n } else {\n // Use latest tag\n const latestTag = await this.getLatestTag(git);\n if (!latestTag) {\n process.stdout.write(\"No version tags found in repository\\n\");\n return;\n }\n fromRef = latestTag;\n this.log.debug(\"Using latest tag\", { from: fromRef });\n }\n\n // Determine the ending point\n const toRef = flags.to || \"HEAD\";\n this.log.debug(\"Using to ref\", { to: toRef });\n\n // Get commits in range\n const commitsOutput = await git(`log ${fromRef}..${toRef} --oneline`);\n\n if (!commitsOutput.trim()) {\n process.stdout.write(`No changes in range ${fromRef}..${toRef}\\n`);\n return;\n }\n\n // Parse and format\n const entry = this.parseCommits(commitsOutput);\n\n if (!this.hasChanges(entry)) {\n process.stdout.write(\n `No public changes in range ${fromRef}..${toRef}\\n`,\n );\n return;\n }\n\n // Output the formatted changelog (no header - caller adds it if needed)\n process.stdout.write(this.formatEntry(entry));\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../../services/AlephaCliUtils.ts\";\n\nexport class GenEnvCommand {\n protected readonly log = $logger();\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly fs = $inject(FileSystemProvider);\n\n public readonly command = $command({\n name: \"env\",\n description: \"Extract environment variables from server entry file\",\n flags: t.object({\n out: t.optional(\n t.text({\n aliases: [\"o\"],\n description: \"Output file path (e.g., .env)\",\n }),\n ),\n }),\n handler: async ({ root, flags }) => {\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n root,\n mode: \"development\",\n });\n\n try {\n const { env } = alepha.dump();\n\n let dotEnvFile = \"\";\n for (const [key, value] of Object.entries(env)) {\n if (value.description) {\n dotEnvFile += `# ${value.description.split(\"\\n\").join(\"\\n# \")}\\n`;\n }\n if (value.required && !value.default) {\n dotEnvFile += `# (required)\\n`;\n }\n if (value.enum) {\n dotEnvFile += `# Possible values: ${value.enum.join(\", \")}\\n`;\n }\n dotEnvFile += `#${key}=${value.default || \"\"}\\n\\n`;\n }\n\n if (flags.out) {\n await this.fs.writeFile(this.fs.join(root, flags.out), dotEnvFile);\n } else {\n this.log.info(dotEnvFile);\n }\n } catch (err) {\n this.log.error(\"Failed to extract environment variables\", err);\n }\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ServerSwaggerProvider } from \"alepha/server/swagger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../../services/AlephaCliUtils.ts\";\n\nexport class OpenApiCommand {\n protected readonly log = $logger();\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly fs = $inject(FileSystemProvider);\n\n public readonly command = $command({\n name: \"openapi\",\n description: \"Generate OpenAPI specification from actions\",\n flags: t.object({\n out: t.optional(\n t.text({\n aliases: [\"o\"],\n description: \"Output file path\",\n }),\n ),\n }),\n handler: async ({ root, flags }) => {\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n root,\n mode: \"development\",\n });\n\n try {\n const openapiProvider = alepha.inject(\n ServerSwaggerProvider,\n ) as ServerSwaggerProvider;\n\n await alepha.events.emit(\"configure\", alepha);\n\n let json: any = openapiProvider.json;\n\n if (!json) {\n json = openapiProvider.generateSwaggerDoc({\n info: {\n title: \"API Documentation\",\n version: \"1.0.0\",\n },\n });\n }\n\n if (!json) {\n this.log.error(\"No actions found to generate OpenAPI specification.\");\n return;\n }\n\n if (flags.out) {\n await this.fs.writeFile(\n this.fs.join(root, flags.out),\n JSON.stringify(json, null, 2),\n );\n } else {\n this.log.info(JSON.stringify(json, null, 2));\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"Service not found\")) {\n this.log.error(\n \"Missing $swagger() primitive in your server configuration.\",\n );\n return;\n }\n\n this.log.error(`OpenAPI generation failed - ${message}`, err);\n }\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { ChangelogCommand } from \"./gen/changelog.ts\";\nimport { GenEnvCommand } from \"./gen/env.ts\";\nimport { OpenApiCommand } from \"./gen/openapi.ts\";\n\nexport class GenCommand {\n protected readonly changelog = $inject(ChangelogCommand);\n protected readonly openapi = $inject(OpenApiCommand);\n protected readonly genEnv = $inject(GenEnvCommand);\n\n public readonly gen = $command({\n name: \"gen\",\n description: \"Generate code, documentation, ...\",\n children: [\n this.changelog.command,\n this.openapi.command,\n this.genEnv.command,\n ],\n handler: async ({ help }) => {\n help();\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class InitCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Ensure the project has the necessary Alepha configuration files.\n * Add the correct dependencies to package.json and install them.\n */\n public readonly init = $command({\n name: \"init\",\n description: \"Add missing Alepha configuration files to the project\",\n args: t.optional(\n t.text({\n title: \"path\",\n trim: true,\n lowercase: true,\n }),\n ),\n flags: t.object({\n ai: t.optional(\n t.boolean({\n description:\n \"Add AI agent instructions (CLAUDE.md if claude CLI installed, else AGENTS.md)\",\n }),\n ),\n pm: t.optional(\n t.enum([\"yarn\", \"npm\", \"pnpm\", \"bun\"], {\n description: \"Package manager to use\",\n }),\n ),\n // choose which modules to scaffold\n api: t.optional(\n t.boolean({\n description: \"Include API module structure (src/api/)\",\n }),\n ),\n react: t.optional(\n t.boolean({\n aliases: [\"r\"],\n description: \"Include React dependencies and web module (src/web/)\",\n }),\n ),\n ui: t.optional(\n t.boolean({\n description:\n \"Include @alepha/ui (components, auth portal, admin portal)\",\n }),\n ),\n auth: t.optional(\n t.boolean({\n description:\n \"Include authentication (AppSecurity, $uiAuth). Implies --api --ui --react\",\n }),\n ),\n admin: t.optional(\n t.boolean({\n description: \"Include admin portal ($uiAdmin). Implies --auth\",\n }),\n ),\n test: t.optional(\n t.boolean({ description: \"Include Vitest and create test directory\" }),\n ),\n force: t.optional(\n t.boolean({\n aliases: [\"f\"],\n description: \"Override existing files\",\n }),\n ),\n }),\n handler: async ({ run, flags, root, args }) => {\n if (args) {\n root = this.fs.join(root, args);\n await this.fs.mkdir(root, { force: true });\n }\n\n // Flag cascading: --admin → --auth → --ui → --react, --api\n if (flags.admin) {\n flags.auth = true;\n }\n if (flags.auth) {\n flags.api = true;\n flags.ui = true;\n }\n if (flags.ui) {\n flags.react = true;\n }\n\n // Detect workspace context (are we inside packages/ or apps/ of a monorepo?)\n const workspace = await this.pm.getWorkspaceContext(root);\n\n // Detect agent type: claude CLI → CLAUDE.md, else → AGENTS.md\n let agentType: \"claude\" | \"agents\" | false = false;\n if (flags.ai) {\n const hasClaudeCli = await this.utils.isInstalledAsync(\"claude\");\n agentType = hasClaudeCli ? \"claude\" : \"agents\";\n }\n\n const isExpo = await this.pm.hasExpo(root);\n\n const force = !!flags.force;\n\n await run({\n name: \"ensuring configuration files\",\n handler: async () => {\n await this.scaffolder.ensureConfig(root, {\n force,\n tsconfigJson: !workspace.config.tsconfigJson,\n packageJson: { ...flags, isPackage: workspace.isPackage },\n // Skip workspace-level configs if they exist at workspace root\n biomeJson: !workspace.config.biomeJson,\n editorconfig: !workspace.config.editorconfig,\n agentMd: agentType\n ? { type: agentType, react: !!flags.react, ui: !!flags.ui }\n : false,\n });\n\n // Create project structure based on flags\n await this.scaffolder.ensureMainServerTs(root, {\n api: !!flags.api,\n react: !!flags.react && !isExpo,\n force,\n });\n if (flags.api) {\n await this.scaffolder.ensureApiProject(root, {\n auth: !!flags.auth,\n force,\n });\n }\n if (flags.react && !isExpo) {\n await this.scaffolder.ensureWebProject(root, {\n api: !!flags.api,\n ui: !!flags.ui,\n auth: !!flags.auth,\n admin: !!flags.admin,\n force,\n });\n }\n },\n });\n\n // Use workspace PM if detected, otherwise detect from current root\n const pmName = await this.pm.getPackageManager(\n workspace.workspaceRoot ?? root,\n flags.pm ?? workspace.packageManager ?? undefined,\n );\n\n // Only setup PM files if not in a workspace package\n if (!workspace.isPackage) {\n if (pmName === \"yarn\") {\n await this.pm.ensureYarn(root);\n await run(\"yarn set version stable\", { root });\n } else if (pmName === \"bun\") {\n await this.pm.ensureBun(root);\n } else if (pmName === \"pnpm\") {\n await this.pm.ensurePnpm(root);\n } else {\n await this.pm.ensureNpm(root);\n }\n }\n\n // Run install from workspace root if in a package, otherwise from current root\n const installRoot = workspace.workspaceRoot ?? root;\n await run(`${pmName} install`, {\n alias: `installing dependencies with ${pmName}`,\n root: installRoot,\n });\n\n // Create test directory if --test flag is set (vitest is in package.json)\n if (flags.test) {\n await this.scaffolder.ensureTestDir(root);\n }\n\n await run(`${pmName} run lint`, {\n alias: \"running linter\",\n root: installRoot,\n });\n\n // Initialize git repository if not in a workspace package\n if (!workspace.isPackage) {\n const gitInitialized = await this.scaffolder.ensureGitRepo(root, {\n force,\n });\n if (gitInitialized) {\n await run(\"git add .\", {\n alias: \"staging generated files\",\n root,\n });\n }\n }\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class LintCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n\n public readonly lint = $command({\n name: \"lint\",\n description: \"Run linter across the codebase using Biome\",\n handler: async ({ root }) => {\n await this.scaffolder.ensureConfig(root, {\n biomeJson: true,\n checkWorkspace: true,\n });\n\n await this.pm.ensureDependency(root, \"@biomejs/biome\", {\n checkWorkspace: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n\n await this.utils.exec(\"biome check --fix\");\n },\n });\n}\n","import { $inject, Alepha, t } from \"alepha\";\nimport { $command, CliProvider } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { version } from \"../version.ts\";\n\nexport class RootCommand {\n protected readonly log = $logger();\n protected readonly cli = $inject(CliProvider);\n protected readonly alepha = $inject(Alepha);\n protected readonly color = $inject(ConsoleColorProvider);\n\n /**\n * Called when no command is provided\n */\n public readonly root = $command({\n root: true,\n flags: t.object({\n version: t.optional(\n t.boolean({\n description: \"Show Alepha CLI version\",\n aliases: [\"v\"],\n }),\n ),\n }),\n handler: async ({ flags }) => {\n if (flags.version) {\n this.log.info(this.color.set(\"WHITE_BOLD\", `Alepha v${version}`));\n if (this.alepha.isBun()) {\n this.log.info(this.color.set(\"GREY_DARK\", `└─ Bun v${Bun.version}`));\n } else {\n this.log.info(\n this.color.set(\"GREY_DARK\", `└─ Node ${process.version}`),\n );\n }\n return;\n }\n\n this.cli.printHelp();\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class TestCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n\n public readonly test = $command({\n name: \"test\",\n description: \"Run tests using Vitest\",\n flags: t.object({\n config: t.optional(\n t.string({\n description: \"Path to Vitest config file\",\n alias: \"c\",\n }),\n ),\n }),\n env: t.object({\n VITEST_ARGS: t.optional(\n t.string({\n default: \"\",\n description:\n \"Additional arguments to pass to Vitest. E.g., --coverage\",\n }),\n ),\n }),\n handler: async ({ root, flags, env }) => {\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n });\n\n // Ensure vitest is installed before running\n await this.pm.ensureDependency(root, \"vitest\", {\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n\n const config = flags.config ? `--config=${flags.config}` : \"\";\n\n await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class TypecheckCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly log = $logger();\n protected readonly scaffolder = $inject(ProjectScaffolder);\n\n /**\n * Run TypeScript type checking across the codebase with no emit.\n */\n public readonly typecheck = $command({\n name: \"typecheck\",\n aliases: [\"tc\"],\n description: \"Check TypeScript types across the codebase\",\n handler: async ({ root }) => {\n this.log.info(\"Starting TypeScript type checking...\");\n\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n checkWorkspace: true,\n });\n\n await this.pm.ensureDependency(root, \"typescript\", {\n checkWorkspace: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n\n await this.utils.exec(\"tsc --noEmit\");\n\n this.log.info(\"TypeScript type checking completed successfully.\");\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\n\nexport class VerifyCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n\n /**\n * Run a series of verification commands to ensure code quality and correctness.\n *\n * This command runs the following checks in order:\n * - Clean the project\n * - Format the code\n * - Lint the code\n * - Run tests (if Vitest is a dev dependency)\n * - Check database migrations (if a migrations directory exists)\n * - Type check the code\n * - Build the project\n * - Clean the project again\n */\n public readonly verify = $command({\n name: \"verify\",\n description: \"Verify the Alepha project\",\n handler: async ({ root, run }) => {\n await run(\"alepha clean\");\n await run(\"alepha format\");\n await run(\"alepha lint\");\n\n await run(\"alepha typecheck\");\n\n const pkg = await this.pm.readPackageJson(root);\n if (pkg.devDependencies?.vitest) {\n await run(\"alepha test\");\n }\n\n if (await this.utils.exists(root, \"migrations\")) {\n await run(\"alepha db check-migrations\");\n }\n\n const isExpo = await this.pm.hasExpo(root);\n if (!isExpo) {\n await run(\"alepha build\");\n }\n await run(\"alepha clean\");\n },\n });\n}\n","import { $hook, $inject, $module, Alepha } from \"alepha\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { BuildCommand } from \"../commands/build.ts\";\nimport { CleanCommand } from \"../commands/clean.ts\";\nimport { DbCommand } from \"../commands/db.ts\";\nimport { DeployCommand } from \"../commands/deploy.ts\";\nimport { DevCommand } from \"../commands/dev.ts\";\nimport { GitProvider } from \"../commands/gen/changelog.ts\";\nimport { GenCommand } from \"../commands/gen.ts\";\nimport { InitCommand } from \"../commands/init.ts\";\nimport { LintCommand } from \"../commands/lint.ts\";\nimport { RootCommand } from \"../commands/root.ts\";\nimport { TestCommand } from \"../commands/test.ts\";\nimport { TypecheckCommand } from \"../commands/typecheck.ts\";\nimport { VerifyCommand } from \"../commands/verify.ts\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Allow to extend Alepha CLI via `alepha.config.ts` file located in the project root.\n */\n\nclass AlephaCliExtension {\n protected readonly alepha = $inject(Alepha);\n protected readonly fs = $inject(FileSystemProvider);\n\n protected readonly onConfigure = $hook({\n on: \"configure\",\n handler: async () => {\n const root = process.cwd();\n const extensionPath = this.fs.join(root, \"alepha.config.ts\");\n const hasExtension = await this.fs.exists(extensionPath);\n if (!hasExtension) {\n return;\n }\n\n // import\n const { default: Extension } = await import(extensionPath);\n if (typeof Extension !== \"function\") {\n return;\n }\n\n this.alepha.inject(Extension, {\n args: [this.alepha],\n });\n },\n });\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaCli = $module({\n name: \"alepha.cli\",\n services: [\n AlephaCliExtension,\n // Commands (one per file)\n BuildCommand,\n CleanCommand,\n DbCommand,\n DeployCommand,\n DevCommand,\n InitCommand,\n LintCommand,\n RootCommand,\n TestCommand,\n TypecheckCommand,\n VerifyCommand,\n GenCommand,\n // Support services\n AppEntryProvider,\n GitProvider,\n ],\n});\n","import { access, readdir, readFile } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { join } from \"node:path\";\nimport { $inject, AlephaError } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport type { InlineConfig } from \"tsdown\";\n\ninterface Module {\n name: string;\n dependencies: string[];\n native?: boolean;\n browser?: boolean;\n workerd?: boolean;\n bun?: boolean;\n node?: boolean;\n}\n\nexport class AlephaPackageBuilderCli {\n src = \"src\";\n dist = \"dist\";\n fs = $inject(FileSystemProvider);\n\n make = $command({\n root: true,\n handler: async ({ run, root }) => {\n const modules: Array<Module> = [];\n\n const pkgBuffer = await this.fs.readFile(\"package.json\");\n const pkgData = JSON.parse(pkgBuffer.toString(\"utf-8\"));\n const packageName = pkgData.name as string;\n\n await run(\"analyze modules\", async () => {\n modules.push(\n ...(await analyzeModules(this.fs.join(root, this.src), packageName)),\n );\n });\n\n pkgData.exports = {};\n\n for (const item of modules) {\n let m = `./${item.name.replace(\"core\", \"\")}`;\n if (m.endsWith(\"/\")) m = m.slice(0, -1);\n const path = m;\n\n pkgData.exports[path] = {};\n // order is important here for compatibility\n pkgData.exports[path].types = `./src/${item.name}/index.ts`;\n if (item.native) {\n pkgData.exports[path][\"react-native\"] =\n `./src/${item.name}/index.native.ts`;\n } else if (item.browser) {\n pkgData.exports[path][\"react-native\"] =\n `./src/${item.name}/index.browser.ts`;\n }\n\n if (item.workerd) {\n pkgData.exports[path].workerd = `./src/${item.name}/index.workerd.ts`;\n }\n\n if (item.browser) {\n pkgData.exports[path].browser = `./src/${item.name}/index.browser.ts`;\n }\n\n if (item.bun) {\n pkgData.exports[path].bun = `./src/${item.name}/index.bun.ts`;\n }\n\n pkgData.exports[path].import = `./src/${item.name}/index.ts`;\n pkgData.exports[path].default = `./src/${item.name}/index.ts`;\n }\n\n if (packageName === \"alepha\") {\n pkgData.exports[\"./tsconfig.base\"] = \"./tsconfig.base.json\";\n pkgData.exports[\"./package.json\"] = \"./package.json\";\n }\n\n if (packageName === \"@alepha/ui\") {\n pkgData.exports[\"./styles\"] = \"./src/core/styles.css\";\n pkgData.exports[\"./json/styles\"] = \"./src/json/styles.css\";\n }\n\n await this.fs.writeFile(\"package.json\", JSON.stringify(pkgData, null, 2));\n\n const tmpDir = this.fs.join(root, \"node_modules/.alepha\");\n await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});\n\n await this.fs.writeFile(\n this.fs.join(tmpDir, \"module-dependencies.json\"),\n JSON.stringify(modules, null, 2),\n );\n\n const tsconfigBuffer = await this.fs.readFile(\n this.fs.join(root, \"../../tsconfig.json\"),\n );\n\n const external: string[] = Object.keys(\n JSON.parse(tsconfigBuffer.toString(\"utf-8\")).compilerOptions.paths,\n );\n\n external.push(\"bun\");\n external.push(\"bun:sqlite\");\n\n await run.rm(this.dist);\n\n const build = async (item: Module) => {\n const entries: InlineConfig[] = [];\n const src = this.fs.join(root, this.src, item.name);\n const dest = this.fs.join(root, this.dist, item.name);\n\n entries.push({\n entry: this.fs.join(src, \"index.ts\"),\n outDir: dest,\n format: [\"esm\"],\n sourcemap: true,\n fixedExtension: false,\n platform: \"node\", // TODO: node must be enabled only if index.node.ts exists\n inlineOnly: false,\n external,\n dts: {\n sourcemap: true,\n },\n });\n\n if (item.native) {\n entries.push({\n entry: this.fs.join(src, \"index.native.ts\"),\n outDir: dest,\n platform: \"neutral\",\n sourcemap: true,\n dts: false,\n inlineOnly: false,\n external,\n });\n }\n\n if (item.browser) {\n entries.push({\n entry: this.fs.join(src, \"index.browser.ts\"),\n outDir: dest,\n platform: \"browser\",\n sourcemap: true,\n dts: false,\n inlineOnly: false,\n external,\n });\n }\n\n if (item.bun) {\n entries.push({\n entry: this.fs.join(src, \"index.bun.ts\"),\n outDir: dest,\n platform: \"node\",\n sourcemap: true,\n fixedExtension: false,\n dts: false,\n inlineOnly: false,\n external,\n });\n }\n\n const config = this.fs.join(\n tmpDir,\n `tsdown-${item.name.replace(\"/\", \"-\")}.config.js`,\n );\n await this.fs.writeFile(\n config,\n `export default ${JSON.stringify(entries, null, 2)};`,\n );\n\n // /!\\ Warning /!\\\n // avoid to call tsdown programmatically, when we spawn 8 processes at once it 'JavaScript heap out of memory' :---)\n await run(`npx tsdown -c=${config}`);\n };\n\n const concurrency = Math.ceil(os.cpus().length / 2);\n const queue = modules.slice();\n const workers: Promise<void>[] = [];\n for (let i = 0; i < concurrency; i++) {\n const worker = (async () => {\n while (queue.length > 0) {\n const item = queue.shift();\n if (item) {\n await build(item);\n } else {\n await new Promise((r) => setTimeout(r, 100));\n }\n }\n })();\n workers.push(worker);\n }\n await Promise.all(workers);\n },\n });\n}\n\nexport default AlephaPackageBuilderCli;\n\nasync function getAllFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n async function scan(currentDir: string) {\n const entries = await readdir(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n\n if (entry.isDirectory()) {\n await scan(fullPath);\n } else if (entry.isFile() && /\\.(ts|tsx)$/.test(entry.name)) {\n files.push(fullPath);\n }\n }\n }\n\n await scan(dir);\n return files;\n}\n\nfunction removeComments(content: string): string {\n // Remove single-line comments\n let cleaned = content.replace(/\\/\\/.*$/gm, \"\");\n\n // Remove multi-line comments\n cleaned = cleaned.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n\n return cleaned;\n}\n\nfunction extractAlephaDependencies(\n content: string,\n packageName: string,\n moduleName: string,\n): string[] {\n const deps = new Set<string>();\n const cleanedContent = removeComments(content);\n\n // Match: from \"alepha/xxx\" or from 'alepha/xxx'\n const importRegex = new RegExp(\n `from \"${packageName}/([a-zA-Z0-9_/]+)\";`,\n \"g\",\n );\n\n const matches = cleanedContent.matchAll(importRegex);\n for (const match of matches) {\n deps.add(match[1]);\n }\n\n return Array.from(deps);\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction detectCircularDependencies(modules: Module[]): void {\n const moduleMap = new Map(modules.map((m) => [m.name, m.dependencies]));\n\n function hasCycle(\n moduleName: string,\n visited: Set<string> = new Set(),\n path: string[] = [],\n ): string[] | null {\n if (visited.has(moduleName)) {\n // Found a cycle, return the path\n const cycleStart = path.indexOf(moduleName);\n return [...path.slice(cycleStart), moduleName];\n }\n\n const deps = moduleMap.get(moduleName);\n if (!deps) return null;\n\n visited.add(moduleName);\n path.push(moduleName);\n\n for (const dep of deps) {\n const cycle = hasCycle(dep, new Set(visited), [...path]);\n if (cycle) return cycle;\n }\n\n return null;\n }\n\n for (const module of modules) {\n const cycle = hasCycle(module.name);\n if (cycle) {\n throw new AlephaError(\n `Circular dependency detected: ${cycle.join(\" -> \")}`,\n );\n }\n }\n}\n\nexport async function analyzeModules(\n srcDir: string,\n packageName: string,\n): Promise<Module[]> {\n const modules: Module[] = [];\n\n async function scanDirectory(dir: string, prefix: string): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const moduleName = prefix ? `${prefix}/${entry.name}` : entry.name;\n const modulePath = join(dir, entry.name);\n\n // Check if this directory has an index.ts (is a module)\n const hasIndex = await fileExists(join(modulePath, \"index.ts\"));\n\n if (hasIndex) {\n // This is a module\n const dependencies = new Set<string>();\n\n // Check for browser/node/bun entry points\n const hasBrowser = await fileExists(\n join(modulePath, \"index.browser.ts\"),\n );\n const hasNative = await fileExists(\n join(modulePath, \"index.native.ts\"),\n );\n const hasBun = await fileExists(join(modulePath, \"index.bun.ts\"));\n const hasNode = await fileExists(join(modulePath, \"index.node.ts\"));\n const hasEdge = await fileExists(\n join(modulePath, \"index.workerd.ts\"),\n );\n\n // Get all .ts/.tsx files in this module\n const files = await getAllFiles(modulePath);\n\n for (const file of files) {\n const content = await readFile(file, \"utf-8\");\n const deps = extractAlephaDependencies(\n content,\n packageName,\n moduleName,\n );\n for (const dep of deps) {\n if (dep.endsWith(\".ts\")) {\n throw new Error(\n `Invalid dependency '${dep}' in module '${moduleName}'. Do not include file extensions in Alepha module imports.`,\n );\n }\n if (dep.includes(\"-\")) {\n throw new Error(\n `Invalid dependency '${dep}' in module '${moduleName}'. Use '/' instead of '-' in Alepha module imports.`,\n );\n }\n dependencies.add(dep);\n }\n }\n\n const module: Module = {\n name: moduleName,\n dependencies: Array.from(dependencies),\n };\n\n if (hasNative) module.native = true;\n if (hasEdge) module.workerd = true;\n if (hasBrowser) module.browser = true;\n if (hasBun) module.bun = true;\n if (hasNode) module.node = true;\n\n modules.push(module);\n } else {\n // No index.ts, check subdirectories for modules\n await scanDirectory(modulePath, moduleName);\n }\n }\n }\n }\n\n await scanDirectory(srcDir, \"\");\n\n // Check for circular dependencies\n detectCircularDependencies(modules);\n\n return modules;\n}\n","import type { Alepha } from \"alepha\";\nimport type { CommandPrimitive } from \"alepha/command\";\nimport {\n type AppEntryOptions,\n appEntryOptions,\n} from \"./atoms/appEntryOptions.ts\";\nimport { type BuildOptions, buildOptions } from \"./atoms/buildOptions.ts\";\n\nexport interface AlephaCliConfig {\n entry?: AppEntryOptions;\n /**\n * Add custom commands to the Alepha CLI.\n *\n * You can override 'deploy', 'build', 'dev', 'start' commands this way.\n * But you can also add your own commands and run them via `alepha <command>`.\n */\n commands?: Record<string, CommandPrimitive>;\n\n /**\n * Register more services to the Alepha CLI (enhancements, commands, etc.).\n */\n services?: Array<any>;\n\n /**\n * Configure Alepha build command.\n */\n build?: BuildOptions;\n\n /**\n * Environment variables to set before running commands.\n *\n * Always use .env files by default, this is only for dynamic values.\n */\n env?: Record<string, unknown>;\n}\n\nexport type AlephaCliConfigFn = (alepha: Alepha) => AlephaCliConfig;\n\nexport const defineConfig = (\n runConfig: AlephaCliConfig | AlephaCliConfigFn,\n) => {\n return (alepha: Alepha) => {\n const config =\n typeof runConfig === \"function\" ? runConfig(alepha) : runConfig;\n\n if (config.services) {\n for (const it of config.services) {\n alepha.with(it);\n }\n }\n\n if (config.env) {\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = String(value);\n }\n }\n\n if (config.build) {\n alepha.set(buildOptions, config.build);\n }\n\n if (config.entry) {\n alepha.set(appEntryOptions, config.entry);\n }\n\n return {\n ...config.commands,\n };\n };\n};\n\n/**\n * @alias defineConfig\n */\nexport const defineAlephaConfig = defineConfig;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["nodeJoin","fsRm","fsCp","fsMkdir","fsReadFile","fsWriteFile","$atom","$atom","alephaPackageJson.devDependencies","devDependencies"],"sources":["../../src/system/providers/FileSystemProvider.ts","../../src/system/providers/MemoryFileSystemProvider.ts","../../src/system/providers/MemoryShellProvider.ts","../../src/system/services/FileDetector.ts","../../src/system/providers/NodeFileSystemProvider.ts","../../src/system/providers/NodeShellProvider.ts","../../src/system/providers/ShellProvider.ts","../../src/system/index.ts","../../src/core/constants/KIND.ts","../../src/core/primitives/$atom.ts","../../src/cli/atoms/buildOptions.ts","../../src/cli/atoms/appEntryOptions.ts","../../src/cli/providers/AppEntryProvider.ts","../../src/cli/services/ViteUtils.ts","../../src/cli/providers/ViteBuildProvider.ts","../../src/cli/services/AlephaCliUtils.ts","../../package.json","../../src/cli/version.ts","../../src/cli/services/PackageManagerUtils.ts","../../src/cli/templates/agentMd.ts","../../src/cli/templates/apiAppSecurityTs.ts","../../src/cli/templates/apiHelloControllerTs.ts","../../src/cli/templates/apiIndexTs.ts","../../src/cli/templates/biomeJson.ts","../../src/cli/templates/dummySpecTs.ts","../../src/cli/templates/editorconfig.ts","../../src/cli/templates/gitignore.ts","../../src/cli/templates/mainBrowserTs.ts","../../src/cli/templates/mainCss.ts","../../src/cli/templates/mainServerTs.ts","../../src/cli/templates/tsconfigJson.ts","../../src/cli/templates/webAppRouterTs.ts","../../src/cli/templates/webHomeComponentTsx.ts","../../src/cli/templates/webIndexTs.ts","../../src/cli/services/ProjectScaffolder.ts","../../src/cli/commands/build.ts","../../src/cli/commands/clean.ts","../../src/cli/commands/db.ts","../../src/cli/commands/deploy.ts","../../src/cli/providers/ViteDevServerProvider.ts","../../src/cli/commands/dev.ts","../../src/cli/atoms/changelogOptions.ts","../../src/cli/services/GitMessageParser.ts","../../src/cli/commands/gen/changelog.ts","../../src/cli/commands/gen/env.ts","../../src/cli/commands/gen/openapi.ts","../../src/cli/commands/gen.ts","../../src/cli/commands/init.ts","../../src/cli/commands/lint.ts","../../src/cli/commands/root.ts","../../src/cli/commands/test.ts","../../src/cli/commands/typecheck.ts","../../src/cli/commands/verify.ts","../../src/cli/apps/AlephaCli.ts","../../src/cli/apps/AlephaPackageBuilderCli.ts","../../src/cli/defineConfig.ts"],"sourcesContent":["import type { FileLike, StreamLike } from \"alepha\";\n\n/**\n * Options for creating a file from a URL\n */\nexport interface CreateFileFromUrlOptions {\n /**\n * The URL to load the file from (file://, http://, or https://)\n */\n url: string;\n /**\n * The MIME type of the file (optional, will be detected from filename if not provided)\n */\n type?: string;\n /**\n * The name of the file (optional, will be extracted from URL if not provided)\n */\n name?: string;\n}\n\n/**\n * Options for creating a file from a path (URL with file:// scheme)\n */\nexport interface CreateFileFromPathOptions {\n /**\n * The path to the file on the local filesystem\n */\n path: string;\n /**\n * The MIME type of the file (optional, will be detected from filename if not provided)\n */\n type?: string;\n /**\n * The name of the file (optional, will be extracted from URL if not provided)\n */\n name?: string;\n}\n\n/**\n * Options for creating a file from a Buffer\n */\nexport interface CreateFileFromBufferOptions {\n /**\n * The Buffer containing the file data\n */\n buffer: Buffer;\n /**\n * The MIME type of the file (optional, will be detected from name if not provided)\n */\n type?: string;\n /**\n * The name of the file (required for proper content type detection)\n */\n name?: string;\n}\n\n/**\n * Options for creating a file from a stream\n */\nexport interface CreateFileFromStreamOptions {\n /**\n * The readable stream containing the file data\n */\n stream: StreamLike;\n /**\n * The MIME type of the file (optional, will be detected from name if not provided)\n */\n type?: string;\n /**\n * The name of the file (required for proper content type detection)\n */\n name?: string;\n /**\n * The size of the file in bytes (optional)\n */\n size?: number;\n}\n\n/**\n * Options for creating a file from text content\n */\nexport interface CreateFileFromTextOptions {\n /**\n * The text content to create the file from\n */\n text: string;\n /**\n * The MIME type of the file (default: text/plain)\n */\n type?: string;\n /**\n * The name of the file (default: \"file.txt\")\n */\n name?: string;\n}\n\nexport interface CreateFileFromResponseOptions {\n /**\n * The Response object containing the file data\n */\n response: Response;\n /**\n * Override the name (optional, uses filename from Content-Disposition header if not provided)\n */\n name?: string;\n /**\n * Override the MIME type (optional, uses file.type if not provided)\n */\n type?: string;\n}\n\n/**\n * Options for creating a file from a Web File object\n */\nexport interface CreateFileFromWebFileOptions {\n /**\n * The Web File object\n */\n file: File;\n /**\n * Override the MIME type (optional, uses file.type if not provided)\n */\n type?: string;\n /**\n * Override the name (optional, uses file.name if not provided)\n */\n name?: string;\n /**\n * Override the size (optional, uses file.size if not provided)\n */\n size?: number;\n}\n\n/**\n * Options for creating a file from an ArrayBuffer\n */\nexport interface CreateFileFromArrayBufferOptions {\n /**\n * The ArrayBuffer containing the file data\n */\n arrayBuffer: ArrayBuffer;\n /**\n * The MIME type of the file (optional, will be detected from name if not provided)\n */\n type?: string;\n /**\n * The name of the file (required for proper content type detection)\n */\n name?: string;\n}\n\n/**\n * Union type for all createFile options\n */\nexport type CreateFileOptions =\n | CreateFileFromUrlOptions\n | CreateFileFromPathOptions\n | CreateFileFromBufferOptions\n | CreateFileFromStreamOptions\n | CreateFileFromTextOptions\n | CreateFileFromWebFileOptions\n | CreateFileFromResponseOptions\n | CreateFileFromArrayBufferOptions;\n\n/**\n * Options for rm (remove) operation\n */\nexport interface RmOptions {\n /**\n * If true, removes directories and their contents recursively\n */\n recursive?: boolean;\n /**\n * If true, no error will be thrown if the path does not exist\n */\n force?: boolean;\n}\n\n/**\n * Options for cp (copy) operation\n */\nexport interface CpOptions {\n /**\n * If true, copy directories recursively\n */\n recursive?: boolean;\n /**\n * If true, overwrite existing destination\n */\n force?: boolean;\n}\n\n/**\n * Options for mkdir operation\n */\nexport interface MkdirOptions {\n /**\n * If true, creates parent directories as needed\n *\n * @default true\n */\n recursive?: boolean;\n /**\n * If true, does not throw an error if the directory already exists\n *\n * @default true\n */\n force?: boolean;\n /**\n * File mode (permission and sticky bits)\n */\n mode?: number;\n}\n\n/**\n * Options for ls (list) operation\n */\nexport interface LsOptions {\n /**\n * If true, list contents of directories recursively\n */\n recursive?: boolean;\n /**\n * If true, include hidden files (starting with .)\n */\n hidden?: boolean;\n}\n\n/**\n * FileSystem interface providing utilities for working with files.\n */\nexport abstract class FileSystemProvider {\n /**\n * Joins multiple path segments into a single path.\n *\n * @param paths - The path segments to join\n * @returns The joined path\n */\n abstract join(...paths: string[]): string;\n\n /**\n * Creates a FileLike object from various sources.\n *\n * @param options - Options for creating the file\n * @returns A FileLike object\n */\n abstract createFile(options: CreateFileOptions): FileLike;\n\n /**\n * Removes a file or directory.\n *\n * @param path - The path to remove\n * @param options - Remove options\n */\n abstract rm(path: string, options?: RmOptions): Promise<void>;\n\n /**\n * Copies a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n * @param options - Copy options\n */\n abstract cp(src: string, dest: string, options?: CpOptions): Promise<void>;\n\n /**\n * Moves/renames a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n */\n abstract mv(src: string, dest: string): Promise<void>;\n\n /**\n * Creates a directory.\n *\n * @param path - The directory path to create\n * @param options - Mkdir options\n */\n abstract mkdir(path: string, options?: MkdirOptions): Promise<void>;\n\n /**\n * Lists files in a directory.\n *\n * @param path - The directory path to list\n * @param options - List options\n * @returns Array of filenames\n */\n abstract ls(path: string, options?: LsOptions): Promise<string[]>;\n\n /**\n * Checks if a file or directory exists.\n *\n * @param path - The path to check\n * @returns True if the path exists, false otherwise\n */\n abstract exists(path: string): Promise<boolean>;\n\n /**\n * Reads the content of a file.\n *\n * @param path - The file path to read\n * @returns The file content as a Buffer\n */\n abstract readFile(path: string): Promise<Buffer>;\n\n /**\n * Writes data to a file.\n *\n * @param path - The file path to write to\n * @param data - The data to write (Buffer or string)\n */\n abstract writeFile(\n path: string,\n data: Uint8Array | Buffer | string | FileLike,\n ): Promise<void>;\n\n /**\n * Reads the content of a file as a string.\n *\n * @param path - The file path to read\n * @returns The file content as a string\n */\n abstract readTextFile(path: string): Promise<string>;\n\n /**\n * Reads the content of a file as JSON.\n *\n * @param path - The file path to read\n * @returns The parsed JSON content\n */\n abstract readJsonFile<T = unknown>(path: string): Promise<T>;\n}\n","import { join as nodeJoin } from \"node:path\";\nimport { $inject, type FileLike, Json } from \"alepha\";\nimport type {\n CpOptions,\n CreateFileOptions,\n FileSystemProvider,\n LsOptions,\n MkdirOptions,\n RmOptions,\n} from \"./FileSystemProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface MemoryFileSystemProviderOptions {\n /**\n * Error to throw on mkdir operations (for testing error handling)\n */\n mkdirError?: Error | null;\n /**\n * Error to throw on writeFile operations (for testing error handling)\n */\n writeFileError?: Error | null;\n /**\n * Error to throw on readFile operations (for testing error handling)\n */\n readFileError?: Error | null;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * In-memory implementation of FileSystemProvider for testing.\n *\n * This provider stores all files and directories in memory, making it ideal for\n * unit tests that need to verify file operations without touching the real file system.\n *\n * @example\n * ```typescript\n * // In tests, substitute the real FileSystemProvider with MemoryFileSystemProvider\n * const alepha = Alepha.create().with({\n * provide: FileSystemProvider,\n * use: MemoryFileSystemProvider,\n * });\n *\n * // Run code that uses FileSystemProvider\n * const service = alepha.inject(MyService);\n * await service.saveFile(\"test.txt\", \"Hello World\");\n *\n * // Verify the file was written\n * const memoryFs = alepha.inject(MemoryFileSystemProvider);\n * expect(memoryFs.files.get(\"test.txt\")?.toString()).toBe(\"Hello World\");\n * ```\n */\nexport class MemoryFileSystemProvider implements FileSystemProvider {\n protected json = $inject(Json);\n\n /**\n * In-memory storage for files (path -> content)\n */\n public files = new Map<string, Buffer>();\n\n /**\n * In-memory storage for directories\n */\n public directories = new Set<string>();\n\n /**\n * Track mkdir calls for test assertions\n */\n public mkdirCalls: Array<{ path: string; options?: MkdirOptions }> = [];\n\n /**\n * Track writeFile calls for test assertions\n */\n public writeFileCalls: Array<{ path: string; data: string }> = [];\n\n /**\n * Track readFile calls for test assertions\n */\n public readFileCalls: Array<string> = [];\n\n /**\n * Track rm calls for test assertions\n */\n public rmCalls: Array<{ path: string; options?: RmOptions }> = [];\n\n /**\n * Track join calls for test assertions\n */\n public joinCalls: Array<string[]> = [];\n\n /**\n * Error to throw on mkdir (for testing error handling)\n */\n public mkdirError: Error | null = null;\n\n /**\n * Error to throw on writeFile (for testing error handling)\n */\n public writeFileError: Error | null = null;\n\n /**\n * Error to throw on readFile (for testing error handling)\n */\n public readFileError: Error | null = null;\n\n constructor(options: MemoryFileSystemProviderOptions = {}) {\n this.mkdirError = options.mkdirError ?? null;\n this.writeFileError = options.writeFileError ?? null;\n this.readFileError = options.readFileError ?? null;\n }\n\n /**\n * Join path segments using forward slashes.\n * Uses Node's path.join for proper normalization (handles .. and .)\n */\n public join(...paths: string[]): string {\n this.joinCalls.push(paths);\n return nodeJoin(...paths);\n }\n\n /**\n * Create a FileLike object from various sources.\n */\n public createFile(options: CreateFileOptions): FileLike {\n if (\"path\" in options) {\n const filePath = options.path;\n const buffer = this.files.get(filePath);\n if (buffer === undefined) {\n throw new Error(\n `ENOENT: no such file or directory, open '${filePath}'`,\n );\n }\n return {\n name: options.name ?? filePath.split(\"/\").pop() ?? \"file\",\n type: options.type ?? \"application/octet-stream\",\n size: buffer.byteLength,\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Stream not implemented in MemoryFileSystemProvider\");\n },\n arrayBuffer: async (): Promise<ArrayBuffer> =>\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer,\n text: async () => buffer.toString(\"utf-8\"),\n };\n }\n\n if (\"buffer\" in options) {\n const buffer = options.buffer;\n return {\n name: options.name ?? \"file\",\n type: options.type ?? \"application/octet-stream\",\n size: buffer.byteLength,\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Stream not implemented in MemoryFileSystemProvider\");\n },\n arrayBuffer: async (): Promise<ArrayBuffer> =>\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer,\n text: async () => buffer.toString(\"utf-8\"),\n };\n }\n\n if (\"text\" in options) {\n const buffer = Buffer.from(options.text, \"utf-8\");\n return {\n name: options.name ?? \"file.txt\",\n type: options.type ?? \"text/plain\",\n size: buffer.byteLength,\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Stream not implemented in MemoryFileSystemProvider\");\n },\n arrayBuffer: async (): Promise<ArrayBuffer> =>\n buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer,\n text: async () => options.text,\n };\n }\n\n throw new Error(\n \"MemoryFileSystemProvider.createFile: unsupported options. Only buffer and text are supported.\",\n );\n }\n\n /**\n * Remove a file or directory from memory.\n */\n public async rm(path: string, options?: RmOptions): Promise<void> {\n this.rmCalls.push({ path, options });\n\n const exists = this.files.has(path) || this.directories.has(path);\n\n if (!exists && !options?.force) {\n throw new Error(`ENOENT: no such file or directory, rm '${path}'`);\n }\n\n if (this.directories.has(path)) {\n if (options?.recursive) {\n // Remove directory and all contents\n this.directories.delete(path);\n for (const filePath of this.files.keys()) {\n if (filePath.startsWith(`${path}/`)) {\n this.files.delete(filePath);\n }\n }\n for (const dirPath of this.directories) {\n if (dirPath.startsWith(`${path}/`)) {\n this.directories.delete(dirPath);\n }\n }\n } else {\n throw new Error(\n `EISDIR: illegal operation on a directory, rm '${path}'`,\n );\n }\n } else {\n this.files.delete(path);\n }\n }\n\n /**\n * Copy a file or directory in memory.\n */\n public async cp(\n src: string,\n dest: string,\n options?: CpOptions,\n ): Promise<void> {\n if (this.directories.has(src)) {\n if (!options?.recursive) {\n throw new Error(\n `Cannot copy directory without recursive option: ${src}`,\n );\n }\n // Copy directory and contents\n this.directories.add(dest);\n for (const [filePath, content] of this.files) {\n if (filePath.startsWith(`${src}/`)) {\n const newPath = filePath.replace(src, dest);\n this.files.set(newPath, Buffer.from(content));\n }\n }\n } else if (this.files.has(src)) {\n const content = this.files.get(src)!;\n this.files.set(dest, Buffer.from(content));\n } else {\n throw new Error(`ENOENT: no such file or directory, cp '${src}'`);\n }\n }\n\n /**\n * Move/rename a file or directory in memory.\n */\n public async mv(src: string, dest: string): Promise<void> {\n if (this.directories.has(src)) {\n // Move directory and contents\n this.directories.delete(src);\n this.directories.add(dest);\n for (const [filePath, content] of this.files) {\n if (filePath.startsWith(`${src}/`)) {\n const newPath = filePath.replace(src, dest);\n this.files.delete(filePath);\n this.files.set(newPath, content);\n }\n }\n } else if (this.files.has(src)) {\n const content = this.files.get(src)!;\n this.files.delete(src);\n this.files.set(dest, content);\n } else {\n throw new Error(`ENOENT: no such file or directory, mv '${src}'`);\n }\n }\n\n /**\n * Create a directory in memory.\n */\n public async mkdir(path: string, options?: MkdirOptions): Promise<void> {\n this.mkdirCalls.push({ path, options });\n\n if (this.mkdirError) {\n throw this.mkdirError;\n }\n\n if (this.directories.has(path) && !options?.recursive) {\n throw new Error(`EEXIST: file already exists, mkdir '${path}'`);\n }\n\n this.directories.add(path);\n\n // If recursive, create parent directories\n if (options?.recursive) {\n const parts = path.split(\"/\").filter(Boolean);\n let current = \"\";\n for (const part of parts) {\n current = current ? `${current}/${part}` : part;\n this.directories.add(current);\n }\n }\n }\n\n /**\n * List files in a directory.\n */\n public async ls(path: string, options?: LsOptions): Promise<string[]> {\n const normalizedPath = path.replace(/\\/$/, \"\");\n const entries = new Set<string>();\n\n // Find files in the directory\n for (const filePath of this.files.keys()) {\n if (filePath.startsWith(`${normalizedPath}/`)) {\n const relativePath = filePath.slice(normalizedPath.length + 1);\n const parts = relativePath.split(\"/\");\n\n if (options?.recursive) {\n entries.add(relativePath);\n } else {\n entries.add(parts[0]);\n }\n }\n }\n\n // Find subdirectories\n for (const dirPath of this.directories) {\n if (\n dirPath.startsWith(`${normalizedPath}/`) &&\n dirPath !== normalizedPath\n ) {\n const relativePath = dirPath.slice(normalizedPath.length + 1);\n const parts = relativePath.split(\"/\");\n\n if (options?.recursive) {\n entries.add(relativePath);\n } else if (parts.length === 1) {\n entries.add(parts[0]);\n }\n }\n }\n\n let result = Array.from(entries);\n\n // Filter hidden files unless requested\n if (!options?.hidden) {\n result = result.filter((entry) => !entry.startsWith(\".\"));\n }\n\n return result.sort();\n }\n\n /**\n * Check if a file or directory exists in memory.\n */\n public async exists(path: string): Promise<boolean> {\n return this.files.has(path) || this.directories.has(path);\n }\n\n /**\n * Read a file from memory.\n */\n public async readFile(path: string): Promise<Buffer> {\n this.readFileCalls.push(path);\n\n if (this.readFileError) {\n throw this.readFileError;\n }\n\n const content = this.files.get(path);\n if (!content) {\n throw new Error(`ENOENT: no such file or directory, open '${path}'`);\n }\n return content;\n }\n\n /**\n * Read a file from memory as text.\n */\n public async readTextFile(path: string): Promise<string> {\n const buffer = await this.readFile(path);\n return buffer.toString(\"utf-8\");\n }\n\n /**\n * Read a file from memory as JSON.\n */\n public async readJsonFile<T = unknown>(path: string): Promise<T> {\n const text = await this.readTextFile(path);\n return this.json.parse(text) as T;\n }\n\n /**\n * Write a file to memory.\n */\n public async writeFile(\n path: string,\n data: Uint8Array | Buffer | string | FileLike,\n ): Promise<void> {\n const dataStr =\n typeof data === \"string\"\n ? data\n : data instanceof Buffer || data instanceof Uint8Array\n ? data.toString(\"utf-8\")\n : await data.text();\n\n this.writeFileCalls.push({ path, data: dataStr });\n\n if (this.writeFileError) {\n throw this.writeFileError;\n }\n\n const buffer =\n typeof data === \"string\"\n ? Buffer.from(data, \"utf-8\")\n : data instanceof Buffer\n ? data\n : data instanceof Uint8Array\n ? Buffer.from(data)\n : Buffer.from(await data.text(), \"utf-8\");\n\n this.files.set(path, buffer);\n }\n\n /**\n * Reset all in-memory state (useful between tests).\n */\n public reset(): void {\n this.files.clear();\n this.directories.clear();\n this.mkdirCalls = [];\n this.writeFileCalls = [];\n this.readFileCalls = [];\n this.rmCalls = [];\n this.joinCalls = [];\n this.mkdirError = null;\n this.writeFileError = null;\n this.readFileError = null;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Test assertion helpers\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Check if a file was written during the test.\n *\n * @example\n * ```typescript\n * expect(fs.wasWritten(\"/project/tsconfig.json\")).toBe(true);\n * ```\n */\n public wasWritten(path: string): boolean {\n return this.writeFileCalls.some((call) => call.path === path);\n }\n\n /**\n * Check if a file was written with content matching a pattern.\n *\n * @example\n * ```typescript\n * expect(fs.wasWrittenMatching(\"/project/tsconfig.json\", /extends/)).toBe(true);\n * ```\n */\n public wasWrittenMatching(path: string, pattern: RegExp): boolean {\n const call = this.writeFileCalls.find((c) => c.path === path);\n return call ? pattern.test(call.data) : false;\n }\n\n /**\n * Check if a file was read during the test.\n *\n * @example\n * ```typescript\n * expect(fs.wasRead(\"/project/package.json\")).toBe(true);\n * ```\n */\n public wasRead(path: string): boolean {\n return this.readFileCalls.includes(path);\n }\n\n /**\n * Check if a file was deleted during the test.\n *\n * @example\n * ```typescript\n * expect(fs.wasDeleted(\"/project/old-file.txt\")).toBe(true);\n * ```\n */\n public wasDeleted(path: string): boolean {\n return this.rmCalls.some((call) => call.path === path);\n }\n\n /**\n * Get the content of a file as a string (convenience method for testing).\n */\n public getFileContent(path: string): string | undefined {\n return this.files.get(path)?.toString(\"utf-8\");\n }\n}\n","import type { ShellProvider, ShellRunOptions } from \"./ShellProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface MemoryShellCall {\n command: string;\n options: ShellRunOptions;\n}\n\nexport interface MemoryShellProviderOptions {\n /**\n * Simulated outputs for specific commands.\n * Key is the command string, value is the stdout to return.\n */\n outputs?: Record<string, string>;\n\n /**\n * Commands that should throw an error.\n * Key is the command string, value is the error message.\n */\n errors?: Record<string, string>;\n\n /**\n * Commands that are considered \"installed\" in the system PATH.\n */\n installedCommands?: string[];\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * In-memory implementation of ShellProvider for testing.\n *\n * Records all commands that would be executed without actually running them.\n * Can be configured to return specific outputs or throw errors for testing.\n *\n * @example\n * ```typescript\n * // In tests, substitute the real ShellProvider with MemoryShellProvider\n * const alepha = Alepha.create().with({\n * provide: ShellProvider,\n * use: MemoryShellProvider,\n * });\n *\n * // Configure mock behavior\n * const shell = alepha.inject(MemoryShellProvider);\n * shell.configure({\n * outputs: { \"echo hello\": \"hello\\n\" },\n * errors: { \"failing-cmd\": \"Command failed\" },\n * });\n *\n * // Or use the fluent API\n * shell.outputs.set(\"another-cmd\", \"output\");\n * shell.errors.set(\"another-error\", \"Error message\");\n *\n * // Run code that uses ShellProvider\n * const service = alepha.inject(MyService);\n * await service.doSomething();\n *\n * // Verify commands were called\n * expect(shell.calls).toHaveLength(2);\n * expect(shell.calls[0].command).toBe(\"yarn install\");\n * ```\n */\nexport class MemoryShellProvider implements ShellProvider {\n /**\n * All recorded shell calls.\n */\n public calls: MemoryShellCall[] = [];\n\n /**\n * Simulated outputs for specific commands.\n */\n public outputs = new Map<string, string>();\n\n /**\n * Commands that should throw an error.\n */\n public errors = new Map<string, string>();\n\n /**\n * Commands considered installed in the system PATH.\n */\n public installedCommands = new Set<string>();\n\n /**\n * Configure the mock with predefined outputs, errors, and installed commands.\n */\n public configure(options: MemoryShellProviderOptions): this {\n if (options.outputs) {\n for (const [cmd, output] of Object.entries(options.outputs)) {\n this.outputs.set(cmd, output);\n }\n }\n if (options.errors) {\n for (const [cmd, error] of Object.entries(options.errors)) {\n this.errors.set(cmd, error);\n }\n }\n if (options.installedCommands) {\n for (const cmd of options.installedCommands) {\n this.installedCommands.add(cmd);\n }\n }\n return this;\n }\n\n /**\n * Record command and return simulated output.\n */\n public async run(\n command: string,\n options: ShellRunOptions = {},\n ): Promise<string> {\n this.calls.push({ command, options });\n\n // Check for configured error\n const errorMsg = this.errors.get(command);\n if (errorMsg) {\n throw new Error(errorMsg);\n }\n\n // Return configured output or empty string\n return this.outputs.get(command) ?? \"\";\n }\n\n /**\n * Check if a specific command was called.\n */\n public wasCalled(command: string): boolean {\n return this.calls.some((call) => call.command === command);\n }\n\n /**\n * Check if a command matching a pattern was called.\n */\n public wasCalledMatching(pattern: RegExp): boolean {\n return this.calls.some((call) => pattern.test(call.command));\n }\n\n /**\n * Get all calls matching a pattern.\n */\n public getCallsMatching(pattern: RegExp): MemoryShellCall[] {\n return this.calls.filter((call) => pattern.test(call.command));\n }\n\n /**\n * Check if a command is installed.\n */\n public async isInstalled(command: string): Promise<boolean> {\n return this.installedCommands.has(command);\n }\n\n /**\n * Reset all recorded state.\n */\n public reset(): void {\n this.calls = [];\n this.outputs.clear();\n this.errors.clear();\n this.installedCommands.clear();\n }\n}\n","import { Readable } from \"node:stream\";\n\nexport interface FileTypeResult {\n /**\n * The detected MIME type\n */\n mimeType: string;\n /**\n * The detected file extension\n */\n extension: string;\n /**\n * Whether the file type was verified by magic bytes\n */\n verified: boolean;\n /**\n * The stream (potentially wrapped to allow re-reading)\n */\n stream: Readable;\n}\n\n/**\n * Service for detecting file types and getting content types.\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n *\n * // Get content type from filename\n * const mimeType = detector.getContentType(\"image.png\"); // \"image/png\"\n *\n * // Detect file type by magic bytes\n * const stream = createReadStream('image.png');\n * const result = await detector.detectFileType(stream, 'image.png');\n * console.log(result.mimeType); // 'image/png'\n * console.log(result.verified); // true if magic bytes match\n * ```\n */\nexport class FileDetector {\n /**\n * Magic byte signatures for common file formats.\n * Each signature is represented as an array of bytes or null (wildcard).\n */\n protected static readonly MAGIC_BYTES: Record<\n string,\n { signature: (number | null)[]; mimeType: string }[]\n > = {\n // Images\n png: [\n {\n signature: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],\n mimeType: \"image/png\",\n },\n ],\n jpg: [\n { signature: [0xff, 0xd8, 0xff, 0xe0], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe1], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe2], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe3], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe8], mimeType: \"image/jpeg\" },\n ],\n jpeg: [\n { signature: [0xff, 0xd8, 0xff, 0xe0], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe1], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe2], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe3], mimeType: \"image/jpeg\" },\n { signature: [0xff, 0xd8, 0xff, 0xe8], mimeType: \"image/jpeg\" },\n ],\n gif: [\n {\n signature: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61],\n mimeType: \"image/gif\",\n }, // GIF87a\n {\n signature: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61],\n mimeType: \"image/gif\",\n }, // GIF89a\n ],\n webp: [\n {\n signature: [\n 0x52,\n 0x49,\n 0x46,\n 0x46,\n null,\n null,\n null,\n null,\n 0x57,\n 0x45,\n 0x42,\n 0x50,\n ],\n mimeType: \"image/webp\",\n },\n ],\n bmp: [{ signature: [0x42, 0x4d], mimeType: \"image/bmp\" }],\n ico: [{ signature: [0x00, 0x00, 0x01, 0x00], mimeType: \"image/x-icon\" }],\n tiff: [\n { signature: [0x49, 0x49, 0x2a, 0x00], mimeType: \"image/tiff\" }, // Little-endian\n { signature: [0x4d, 0x4d, 0x00, 0x2a], mimeType: \"image/tiff\" }, // Big-endian\n ],\n tif: [\n { signature: [0x49, 0x49, 0x2a, 0x00], mimeType: \"image/tiff\" },\n { signature: [0x4d, 0x4d, 0x00, 0x2a], mimeType: \"image/tiff\" },\n ],\n\n // Documents\n pdf: [\n {\n signature: [0x25, 0x50, 0x44, 0x46, 0x2d],\n mimeType: \"application/pdf\",\n },\n ], // %PDF-\n zip: [\n { signature: [0x50, 0x4b, 0x03, 0x04], mimeType: \"application/zip\" },\n { signature: [0x50, 0x4b, 0x05, 0x06], mimeType: \"application/zip\" },\n { signature: [0x50, 0x4b, 0x07, 0x08], mimeType: \"application/zip\" },\n ],\n\n // Archives\n rar: [\n {\n signature: [0x52, 0x61, 0x72, 0x21, 0x1a, 0x07],\n mimeType: \"application/vnd.rar\",\n },\n ],\n \"7z\": [\n {\n signature: [0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c],\n mimeType: \"application/x-7z-compressed\",\n },\n ],\n tar: [\n {\n signature: [0x75, 0x73, 0x74, 0x61, 0x72],\n mimeType: \"application/x-tar\",\n },\n ],\n gz: [{ signature: [0x1f, 0x8b], mimeType: \"application/gzip\" }],\n tgz: [{ signature: [0x1f, 0x8b], mimeType: \"application/gzip\" }],\n\n // Audio\n mp3: [\n { signature: [0xff, 0xfb], mimeType: \"audio/mpeg\" },\n { signature: [0xff, 0xf3], mimeType: \"audio/mpeg\" },\n { signature: [0xff, 0xf2], mimeType: \"audio/mpeg\" },\n { signature: [0x49, 0x44, 0x33], mimeType: \"audio/mpeg\" }, // ID3\n ],\n wav: [\n {\n signature: [\n 0x52,\n 0x49,\n 0x46,\n 0x46,\n null,\n null,\n null,\n null,\n 0x57,\n 0x41,\n 0x56,\n 0x45,\n ],\n mimeType: \"audio/wav\",\n },\n ],\n ogg: [{ signature: [0x4f, 0x67, 0x67, 0x53], mimeType: \"audio/ogg\" }],\n flac: [{ signature: [0x66, 0x4c, 0x61, 0x43], mimeType: \"audio/flac\" }], // fLaC\n\n // Video\n mp4: [\n {\n signature: [null, null, null, null, 0x66, 0x74, 0x79, 0x70],\n mimeType: \"video/mp4\",\n }, // ftyp\n {\n signature: [\n null,\n null,\n null,\n null,\n 0x66,\n 0x74,\n 0x79,\n 0x70,\n 0x69,\n 0x73,\n 0x6f,\n 0x6d,\n ],\n mimeType: \"video/mp4\",\n }, // ftypisom\n {\n signature: [\n null,\n null,\n null,\n null,\n 0x66,\n 0x74,\n 0x79,\n 0x70,\n 0x6d,\n 0x70,\n 0x34,\n 0x32,\n ],\n mimeType: \"video/mp4\",\n }, // ftypmp42\n ],\n webm: [{ signature: [0x1a, 0x45, 0xdf, 0xa3], mimeType: \"video/webm\" }],\n avi: [\n {\n signature: [\n 0x52,\n 0x49,\n 0x46,\n 0x46,\n null,\n null,\n null,\n null,\n 0x41,\n 0x56,\n 0x49,\n 0x20,\n ],\n mimeType: \"video/x-msvideo\",\n },\n ],\n mov: [\n {\n signature: [\n null,\n null,\n null,\n null,\n 0x66,\n 0x74,\n 0x79,\n 0x70,\n 0x71,\n 0x74,\n 0x20,\n 0x20,\n ],\n mimeType: \"video/quicktime\",\n },\n ],\n mkv: [\n { signature: [0x1a, 0x45, 0xdf, 0xa3], mimeType: \"video/x-matroska\" },\n ],\n\n // Office (DOCX, XLSX, PPTX are all ZIP-based)\n docx: [\n {\n signature: [0x50, 0x4b, 0x03, 0x04],\n mimeType:\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n },\n ],\n xlsx: [\n {\n signature: [0x50, 0x4b, 0x03, 0x04],\n mimeType:\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n },\n ],\n pptx: [\n {\n signature: [0x50, 0x4b, 0x03, 0x04],\n mimeType:\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n },\n ],\n doc: [\n {\n signature: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1],\n mimeType: \"application/msword\",\n },\n ],\n xls: [\n {\n signature: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1],\n mimeType: \"application/vnd.ms-excel\",\n },\n ],\n ppt: [\n {\n signature: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1],\n mimeType: \"application/vnd.ms-powerpoint\",\n },\n ],\n };\n\n /**\n * All possible format signatures for checking against actual file content\n */\n protected static readonly ALL_SIGNATURES = Object.entries(\n FileDetector.MAGIC_BYTES,\n ).flatMap(([ext, signatures]) => signatures.map((sig) => ({ ext, ...sig })));\n\n /**\n * MIME type map for file extensions.\n *\n * Can be used to get the content type of file based on its extension.\n * Feel free to add more mime types in your project!\n */\n public static readonly mimeMap: Record<string, string> = {\n // Documents\n json: \"application/json\",\n txt: \"text/plain\",\n html: \"text/html\",\n htm: \"text/html\",\n xml: \"application/xml\",\n csv: \"text/csv\",\n pdf: \"application/pdf\",\n md: \"text/markdown\",\n markdown: \"text/markdown\",\n rtf: \"application/rtf\",\n\n // Styles and scripts\n css: \"text/css\",\n js: \"application/javascript\",\n mjs: \"application/javascript\",\n ts: \"application/typescript\",\n jsx: \"text/jsx\",\n tsx: \"text/tsx\",\n\n // Archives\n zip: \"application/zip\",\n rar: \"application/vnd.rar\",\n \"7z\": \"application/x-7z-compressed\",\n tar: \"application/x-tar\",\n gz: \"application/gzip\",\n tgz: \"application/gzip\",\n\n // Images\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n tiff: \"image/tiff\",\n tif: \"image/tiff\",\n\n // Audio\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n ogg: \"audio/ogg\",\n m4a: \"audio/mp4\",\n aac: \"audio/aac\",\n flac: \"audio/flac\",\n\n // Video\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n avi: \"video/x-msvideo\",\n mov: \"video/quicktime\",\n wmv: \"video/x-ms-wmv\",\n flv: \"video/x-flv\",\n mkv: \"video/x-matroska\",\n\n // Office\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xls: \"application/vnd.ms-excel\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n ppt: \"application/vnd.ms-powerpoint\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n\n // Fonts\n woff: \"font/woff\",\n woff2: \"font/woff2\",\n ttf: \"font/ttf\",\n otf: \"font/otf\",\n eot: \"application/vnd.ms-fontobject\",\n };\n\n /**\n * Reverse MIME type map for looking up extensions from MIME types.\n * Prefers shorter, more common extensions when multiple exist.\n */\n protected static readonly reverseMimeMap: Record<string, string> = (() => {\n const reverse: Record<string, string> = {};\n // Process in order so common extensions come first\n for (const [ext, mimeType] of Object.entries(FileDetector.mimeMap)) {\n // Only set if not already set (prefer first/shorter extension)\n if (!reverse[mimeType]) {\n reverse[mimeType] = ext;\n }\n }\n return reverse;\n })();\n\n /**\n * Returns the file extension for a given MIME type.\n *\n * @param mimeType - The MIME type to look up\n * @returns The file extension (without dot), or \"bin\" if not found\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n * const ext = detector.getExtensionFromMimeType(\"image/png\"); // \"png\"\n * const ext2 = detector.getExtensionFromMimeType(\"application/octet-stream\"); // \"bin\"\n * ```\n */\n getExtensionFromMimeType(mimeType: string): string {\n return FileDetector.reverseMimeMap[mimeType] || \"bin\";\n }\n /**\n * Returns the content type of file based on its filename.\n *\n * @param filename - The filename to check\n * @returns The MIME type\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n * const mimeType = detector.getContentType(\"image.png\"); // \"image/png\"\n * ```\n */\n getContentType(filename: string): string {\n const ext = filename.toLowerCase().split(\".\").pop() || \"\";\n return FileDetector.mimeMap[ext] || \"application/octet-stream\";\n }\n\n /**\n * Detects the file type by checking magic bytes against the stream content.\n *\n * @param stream - The readable stream to check\n * @param filename - The filename (used to get the extension)\n * @returns File type information including MIME type, extension, and verification status\n *\n * @example\n * ```typescript\n * const detector = alepha.inject(FileDetector);\n * const stream = createReadStream('image.png');\n * const result = await detector.detectFileType(stream, 'image.png');\n * console.log(result.mimeType); // 'image/png'\n * console.log(result.verified); // true if magic bytes match\n * ```\n */\n async detectFileType(\n stream: Readable,\n filename: string,\n ): Promise<FileTypeResult> {\n // Get the expected MIME type from the filename extension\n const expectedMimeType = this.getContentType(filename);\n\n // Extract extension - only if filename contains a dot\n const lastDotIndex = filename.lastIndexOf(\".\");\n const ext =\n lastDotIndex > 0\n ? filename.substring(lastDotIndex + 1).toLowerCase()\n : \"\";\n\n // Read the first 16 bytes (enough for most magic byte checks)\n const { buffer, stream: newStream } = await this.peekBytes(stream, 16);\n\n // First, check if the extension's expected signature matches\n const expectedSignatures = FileDetector.MAGIC_BYTES[ext];\n if (expectedSignatures) {\n for (const { signature, mimeType } of expectedSignatures) {\n if (this.matchesSignature(buffer, signature)) {\n return {\n mimeType,\n extension: ext,\n verified: true,\n stream: newStream,\n };\n }\n }\n }\n\n // If the expected signature didn't match, try all other signatures\n for (const {\n ext: detectedExt,\n signature,\n mimeType,\n } of FileDetector.ALL_SIGNATURES) {\n if (detectedExt !== ext && this.matchesSignature(buffer, signature)) {\n return {\n mimeType,\n extension: detectedExt,\n verified: true,\n stream: newStream,\n };\n }\n }\n\n // If no magic bytes matched, fall back to extension-based detection\n // or return binary if extension is not recognized\n return {\n mimeType: expectedMimeType,\n extension: ext,\n verified: false,\n stream: newStream,\n };\n }\n\n /**\n * Reads all bytes from a stream and returns the first N bytes along with a new stream containing all data.\n * This approach reads the entire stream upfront to avoid complex async handling issues.\n *\n * @protected\n */\n protected async peekBytes(\n stream: Readable,\n numBytes: number,\n ): Promise<{ buffer: Buffer; stream: Readable }> {\n const chunks: Buffer[] = [];\n\n // Read the entire stream\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n const allData = Buffer.concat(chunks);\n const buffer = allData.subarray(0, numBytes);\n\n // Create a new stream with all the data\n const newStream = Readable.from(allData);\n\n return { buffer, stream: newStream };\n }\n\n /**\n * Checks if a buffer matches a magic byte signature.\n *\n * @protected\n */\n protected matchesSignature(\n buffer: Buffer,\n signature: (number | null)[],\n ): boolean {\n if (buffer.length < signature.length) {\n return false;\n }\n\n for (let i = 0; i < signature.length; i++) {\n if (signature[i] !== null && buffer[i] !== signature[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n","import { createReadStream } from \"node:fs\";\nimport {\n access,\n copyFile,\n cp as fsCp,\n mkdir as fsMkdir,\n readFile as fsReadFile,\n rm as fsRm,\n writeFile as fsWriteFile,\n readdir,\n rename,\n stat,\n} from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { PassThrough, Readable } from \"node:stream\";\nimport type { ReadableStream as NodeWebStream } from \"node:stream/web\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n $inject,\n AlephaError,\n type FileLike,\n isFileLike,\n Json,\n type StreamLike,\n} from \"alepha\";\nimport { FileDetector } from \"../services/FileDetector.ts\";\nimport type {\n CpOptions,\n CreateFileOptions,\n FileSystemProvider,\n LsOptions,\n MkdirOptions,\n RmOptions,\n} from \"./FileSystemProvider.ts\";\n\n/**\n * Node.js implementation of FileSystem interface.\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Create from URL\n * const file1 = fs.createFile({ url: \"file:///path/to/file.png\" });\n *\n * // Create from Buffer\n * const file2 = fs.createFile({ buffer: Buffer.from(\"hello\"), name: \"hello.txt\" });\n *\n * // Create from text\n * const file3 = fs.createFile({ text: \"Hello, world!\", name: \"greeting.txt\" });\n *\n * // File operations\n * await fs.mkdir(\"/tmp/mydir\", { recursive: true });\n * await fs.cp(\"/src/file.txt\", \"/dest/file.txt\");\n * await fs.mv(\"/old/path.txt\", \"/new/path.txt\");\n * const files = await fs.ls(\"/tmp\");\n * await fs.rm(\"/tmp/file.txt\");\n * ```\n */\nexport class NodeFileSystemProvider implements FileSystemProvider {\n protected detector = $inject(FileDetector);\n protected json = $inject(Json);\n\n public join(...paths: string[]): string {\n return join(...paths);\n }\n\n /**\n * Creates a FileLike object from various sources.\n *\n * @param options - Options for creating the file\n * @returns A FileLike object\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // From URL\n * const file1 = fs.createFile({ url: \"https://example.com/image.png\" });\n *\n * // From Buffer\n * const file2 = fs.createFile({\n * buffer: Buffer.from(\"hello\"),\n * name: \"hello.txt\",\n * type: \"text/plain\"\n * });\n *\n * // From text\n * const file3 = fs.createFile({ text: \"Hello!\", name: \"greeting.txt\" });\n *\n * // From stream with detection\n * const stream = createReadStream(\"/path/to/file.png\");\n * const file4 = fs.createFile({ stream, name: \"image.png\" });\n * ```\n */\n createFile(options: CreateFileOptions): FileLike {\n if (\"path\" in options) {\n const path = options.path;\n const filename = path.split(\"/\").pop() || \"file\";\n return this.createFileFromUrl(`file://${path}`, {\n type: options.type,\n name: options.name || filename,\n });\n }\n\n // Handle URL\n if (\"url\" in options) {\n return this.createFileFromUrl(options.url, {\n type: options.type,\n name: options.name,\n });\n }\n\n if (\"response\" in options) {\n if (!options.response.body) {\n throw new AlephaError(\"Response has no body stream\");\n }\n const res = options.response;\n // guess size from content-length header if available\n const sizeHeader = res.headers.get(\"content-length\");\n const size = sizeHeader ? parseInt(sizeHeader, 10) : undefined;\n // guess name from content-disposition header if available\n let name = options.name;\n const contentDisposition = res.headers.get(\"content-disposition\");\n if (contentDisposition && !name) {\n const match = contentDisposition.match(/filename=\"?([^\"]+)\"?/);\n if (match) {\n name = match[1];\n }\n }\n // guess type from content-type header if available\n const type = options.type || res.headers.get(\"content-type\") || undefined;\n return this.createFileFromStream(options.response.body, {\n type,\n name,\n size,\n });\n }\n\n // Handle Web File\n if (\"file\" in options) {\n return this.createFileFromWebFile(options.file, {\n type: options.type,\n name: options.name,\n size: options.size,\n });\n }\n\n // Handle Buffer\n if (\"buffer\" in options) {\n return this.createFileFromBuffer(options.buffer, {\n type: options.type,\n name: options.name,\n });\n }\n\n // Handle ArrayBuffer\n if (\"arrayBuffer\" in options) {\n return this.createFileFromBuffer(Buffer.from(options.arrayBuffer), {\n type: options.type,\n name: options.name,\n });\n }\n\n // Handle text\n if (\"text\" in options) {\n return this.createFileFromBuffer(Buffer.from(options.text, \"utf-8\"), {\n type: options.type || \"text/plain\",\n name: options.name || \"file.txt\",\n });\n }\n\n // Handle stream\n if (\"stream\" in options) {\n return this.createFileFromStream(options.stream, {\n type: options.type,\n name: options.name,\n size: options.size,\n });\n }\n\n throw new AlephaError(\n \"Invalid createFile options: no valid source provided\",\n );\n }\n\n /**\n * Removes a file or directory.\n *\n * @param path - The path to remove\n * @param options - Remove options\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Remove a file\n * await fs.rm(\"/tmp/file.txt\");\n *\n * // Remove a directory recursively\n * await fs.rm(\"/tmp/mydir\", { recursive: true });\n *\n * // Remove with force (no error if doesn't exist)\n * await fs.rm(\"/tmp/maybe-exists.txt\", { force: true });\n * ```\n */\n async rm(path: string, options?: RmOptions): Promise<void> {\n await fsRm(path, options);\n }\n\n /**\n * Copies a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n * @param options - Copy options\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Copy a file\n * await fs.cp(\"/src/file.txt\", \"/dest/file.txt\");\n *\n * // Copy a directory recursively\n * await fs.cp(\"/src/dir\", \"/dest/dir\", { recursive: true });\n *\n * // Copy with force (overwrite existing)\n * await fs.cp(\"/src/file.txt\", \"/dest/file.txt\", { force: true });\n * ```\n */\n async cp(src: string, dest: string, options?: CpOptions): Promise<void> {\n // Check if source is a directory\n const srcStat = await stat(src);\n\n if (srcStat.isDirectory()) {\n if (!options?.recursive) {\n throw new Error(\n `Cannot copy directory without recursive option: ${src}`,\n );\n }\n // Use Node.js cp function for recursive directory copy\n await fsCp(src, dest, {\n recursive: true,\n force: options?.force ?? false,\n });\n } else {\n // For files, use copyFile\n await copyFile(src, dest);\n }\n }\n\n /**\n * Moves/renames a file or directory.\n *\n * @param src - Source path\n * @param dest - Destination path\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Move/rename a file\n * await fs.mv(\"/old/path.txt\", \"/new/path.txt\");\n *\n * // Move a directory\n * await fs.mv(\"/old/dir\", \"/new/dir\");\n * ```\n */\n async mv(src: string, dest: string): Promise<void> {\n await rename(src, dest);\n }\n\n /**\n * Creates a directory.\n *\n * @param path - The directory path to create\n * @param options - Mkdir options\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Create a directory\n * await fs.mkdir(\"/tmp/mydir\");\n *\n * // Create nested directories\n * await fs.mkdir(\"/tmp/path/to/dir\", { recursive: true });\n *\n * // Create with specific permissions\n * await fs.mkdir(\"/tmp/mydir\", { mode: 0o755 });\n * ```\n */\n async mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n const p = fsMkdir(path, {\n recursive: options.recursive ?? true,\n mode: options.mode,\n });\n\n if (options.force === false) {\n await p;\n } else {\n await p.catch(() => {});\n }\n }\n\n /**\n * Lists files in a directory.\n *\n * @param path - The directory path to list\n * @param options - List options\n * @returns Array of filenames\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // List files in a directory\n * const files = await fs.ls(\"/tmp\");\n * console.log(files); // [\"file1.txt\", \"file2.txt\", \"subdir\"]\n *\n * // List with hidden files\n * const allFiles = await fs.ls(\"/tmp\", { hidden: true });\n *\n * // List recursively\n * const allFilesRecursive = await fs.ls(\"/tmp\", { recursive: true });\n * ```\n */\n async ls(path: string, options?: LsOptions): Promise<string[]> {\n const entries = await readdir(path);\n\n // Filter out hidden files if not requested\n const filteredEntries = options?.hidden\n ? entries\n : entries.filter((e) => !e.startsWith(\".\"));\n\n // If recursive, get all nested files\n if (options?.recursive) {\n const allFiles: string[] = [];\n\n for (const entry of filteredEntries) {\n const fullPath = join(path, entry);\n const entryStat = await stat(fullPath);\n\n if (entryStat.isDirectory()) {\n // Add directory entry\n allFiles.push(entry);\n // Recursively get files from subdirectory\n const subFiles = await this.ls(fullPath, options);\n allFiles.push(...subFiles.map((f) => join(entry, f)));\n } else {\n allFiles.push(entry);\n }\n }\n\n return allFiles;\n }\n\n return filteredEntries;\n }\n\n /**\n * Checks if a file or directory exists.\n *\n * @param path - The path to check\n * @returns True if the path exists, false otherwise\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * if (await fs.exists(\"/tmp/file.txt\")) {\n * console.log(\"File exists\");\n * }\n * ```\n */\n async exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Reads the content of a file.\n *\n * @param path - The file path to read\n * @returns The file content as a Buffer\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * const buffer = await fs.readFile(\"/tmp/file.txt\");\n * console.log(buffer.toString(\"utf-8\"));\n * ```\n */\n async readFile(path: string): Promise<Buffer> {\n return await fsReadFile(path);\n }\n\n /**\n * Writes data to a file.\n *\n * @param path - The file path to write to\n * @param data - The data to write (Buffer or string)\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n *\n * // Write string\n * await fs.writeFile(\"/tmp/file.txt\", \"Hello, world!\");\n *\n * // Write Buffer\n * await fs.writeFile(\"/tmp/file.bin\", Buffer.from([0x01, 0x02, 0x03]));\n * ```\n */\n async writeFile(\n path: string,\n data: Uint8Array | Buffer | string | FileLike,\n ): Promise<void> {\n if (isFileLike(data)) {\n await fsWriteFile(path, Readable.from(data.stream()));\n return;\n }\n await fsWriteFile(path, data);\n }\n\n /**\n * Reads the content of a file as a string.\n *\n * @param path - The file path to read\n * @returns The file content as a string\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n * const content = await fs.readTextFile(\"/tmp/file.txt\");\n * ```\n */\n async readTextFile(path: string): Promise<string> {\n const buffer = await this.readFile(path);\n return buffer.toString(\"utf-8\");\n }\n\n /**\n * Reads the content of a file as JSON.\n *\n * @param path - The file path to read\n * @returns The parsed JSON content\n *\n * @example\n * ```typescript\n * const fs = alepha.inject(NodeFileSystemProvider);\n * const config = await fs.readJsonFile<{ name: string }>(\"/tmp/config.json\");\n * ```\n */\n async readJsonFile<T = unknown>(path: string): Promise<T> {\n const text = await this.readTextFile(path);\n return this.json.parse(text) as T;\n }\n\n /**\n * Creates a FileLike object from a Web File.\n *\n * @protected\n */\n protected createFileFromWebFile(\n source: File,\n options: {\n type?: string;\n name?: string;\n size?: number;\n } = {},\n ): FileLike {\n const name = options.name ?? source.name;\n return {\n name,\n type: options.type ?? (source.type || this.detector.getContentType(name)),\n size: options.size ?? source.size ?? 0,\n lastModified: source.lastModified || Date.now(),\n stream: () => source.stream(),\n arrayBuffer: async (): Promise<ArrayBuffer> => {\n return await source.arrayBuffer();\n },\n text: async (): Promise<string> => {\n return await source.text();\n },\n };\n }\n\n /**\n * Creates a FileLike object from a Buffer.\n *\n * @protected\n */\n protected createFileFromBuffer(\n source: Buffer,\n options: {\n type?: string;\n name?: string;\n } = {},\n ): FileLike {\n const name: string = options.name ?? \"file\";\n return {\n name,\n type: options.type ?? this.detector.getContentType(options.name ?? name),\n size: source.byteLength,\n lastModified: Date.now(),\n stream: (): Readable => Readable.from(source),\n arrayBuffer: async (): Promise<ArrayBuffer> => {\n return this.bufferToArrayBuffer(source);\n },\n text: async (): Promise<string> => {\n return source.toString(\"utf-8\");\n },\n };\n }\n\n /**\n * Creates a FileLike object from a stream.\n *\n * @protected\n */\n protected createFileFromStream(\n source: StreamLike,\n options: {\n type?: string;\n name?: string;\n size?: number;\n } = {},\n ): FileLike & { _buffer: null | Buffer } {\n let buffer: Buffer | null = null;\n\n return {\n name: options.name ?? \"file\",\n type:\n options.type ?? this.detector.getContentType(options.name ?? \"file\"),\n size: options.size ?? 0,\n lastModified: Date.now(),\n stream: () => source,\n _buffer: null as Buffer | null,\n arrayBuffer: async () => {\n buffer ??= await this.streamToBuffer(source);\n return this.bufferToArrayBuffer(buffer);\n },\n text: async () => {\n buffer ??= await this.streamToBuffer(source);\n return buffer.toString(\"utf-8\");\n },\n };\n }\n\n /**\n * Creates a FileLike object from a URL.\n *\n * @protected\n */\n protected createFileFromUrl(\n url: string,\n options: {\n type?: string;\n name?: string;\n } = {},\n ): FileLike {\n const parsedUrl = new URL(url);\n const filename =\n options.name || parsedUrl.pathname.split(\"/\").pop() || \"file\";\n let buffer: Buffer | null = null;\n\n return {\n name: filename,\n type: options.type ?? this.detector.getContentType(filename),\n size: 0, // Unknown size until loaded\n lastModified: Date.now(),\n stream: () => this.createStreamFromUrl(url),\n arrayBuffer: async () => {\n buffer ??= await this.loadFromUrl(url);\n return this.bufferToArrayBuffer(buffer);\n },\n text: async () => {\n buffer ??= await this.loadFromUrl(url);\n return buffer.toString(\"utf-8\");\n },\n filepath: url,\n };\n }\n\n /**\n * Gets a streaming response from a URL.\n *\n * @protected\n */\n protected getStreamingResponse(url: string): Readable {\n const stream = new PassThrough();\n\n fetch(url)\n .then((res) =>\n Readable.fromWeb(res.body as unknown as NodeWebStream).pipe(stream),\n )\n .catch((err) => stream.destroy(err));\n\n return stream;\n }\n\n /**\n * Loads data from a URL.\n *\n * @protected\n */\n protected async loadFromUrl(url: string): Promise<Buffer> {\n const parsedUrl = new URL(url);\n\n if (parsedUrl.protocol === \"file:\") {\n // Handle file:// URLs\n const filePath = fileURLToPath(url);\n return await fsReadFile(filePath);\n } else if (\n parsedUrl.protocol === \"http:\" ||\n parsedUrl.protocol === \"https:\"\n ) {\n // Handle HTTP/HTTPS URLs\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(\n `Failed to fetch ${url}: ${response.status} ${response.statusText}`,\n );\n }\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n } else {\n throw new Error(`Unsupported protocol: ${parsedUrl.protocol}`);\n }\n }\n\n /**\n * Creates a stream from a URL.\n *\n * @protected\n */\n protected createStreamFromUrl(url: string): Readable {\n const parsedUrl = new URL(url);\n\n if (parsedUrl.protocol === \"file:\") {\n // For file:// URLs, create a stream that reads the file\n return createReadStream(fileURLToPath(url));\n } else if (\n parsedUrl.protocol === \"http:\" ||\n parsedUrl.protocol === \"https:\"\n ) {\n // For HTTP/HTTPS URLs, create a stream that fetches the content\n return this.getStreamingResponse(url);\n } else {\n throw new AlephaError(`Unsupported protocol: ${parsedUrl.protocol}`);\n }\n }\n\n /**\n * Converts a stream-like object to a Buffer.\n *\n * @protected\n */\n protected async streamToBuffer(streamLike: StreamLike): Promise<Buffer> {\n const stream =\n streamLike instanceof Readable\n ? streamLike\n : Readable.fromWeb(streamLike as NodeWebStream);\n\n return new Promise<Buffer>((resolve, reject) => {\n const buffer: any[] = [];\n stream.on(\"data\", (chunk) => buffer.push(Buffer.from(chunk)));\n stream.on(\"end\", () => resolve(Buffer.concat(buffer)));\n stream.on(\"error\", (err) =>\n reject(new AlephaError(\"Error converting stream\", { cause: err })),\n );\n });\n }\n\n /**\n * Converts a Node.js Buffer to an ArrayBuffer.\n *\n * @protected\n */\n protected bufferToArrayBuffer(buffer: Buffer): ArrayBuffer {\n return buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer;\n }\n}\n","import { exec, spawn } from \"node:child_process\";\nimport { $inject, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"./FileSystemProvider.ts\";\nimport type { ShellProvider, ShellRunOptions } from \"./ShellProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Node.js implementation of ShellProvider.\n *\n * Executes shell commands using Node.js child_process module.\n * Supports binary resolution from node_modules/.bin for local packages.\n */\nexport class NodeShellProvider implements ShellProvider {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Run a shell command or binary.\n */\n public async run(\n command: string,\n options: ShellRunOptions = {},\n ): Promise<string> {\n const { resolve = false, capture = false, root, env } = options;\n const cwd = root ?? process.cwd();\n\n this.log.debug(`Shell: ${command}`, { cwd, resolve, capture });\n\n let executable: string;\n let args: string[];\n\n if (resolve) {\n const [bin, ...rest] = command.split(\" \");\n executable = await this.resolveExecutable(bin, cwd);\n args = rest;\n } else {\n [executable, ...args] = command.split(\" \");\n }\n\n if (capture) {\n return this.execCapture(command, { cwd, env });\n }\n\n return this.execInherit(executable, args, { cwd, env });\n }\n\n /**\n * Execute command with inherited stdio (streams to terminal).\n */\n protected async execInherit(\n executable: string,\n args: string[],\n options: { cwd: string; env?: Record<string, string> },\n ): Promise<string> {\n const proc = spawn(executable, args, {\n stdio: \"inherit\",\n cwd: options.cwd,\n env: {\n ...process.env,\n ...options.env,\n },\n });\n\n return new Promise<string>((resolve, reject) => {\n proc.on(\"exit\", (code) => {\n if (code === 0 || code === null) {\n resolve(\"\");\n } else {\n reject(new AlephaError(`Command exited with code ${code}`));\n }\n });\n proc.on(\"error\", reject);\n });\n }\n\n /**\n * Execute command and capture stdout.\n */\n protected execCapture(\n command: string,\n options: { cwd: string; env?: Record<string, string> },\n ): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n exec(\n command,\n {\n cwd: options.cwd,\n env: {\n ...process.env,\n LOG_FORMAT: \"pretty\",\n ...options.env,\n },\n },\n (err, stdout) => {\n if (err) {\n (err as any).stdout = stdout;\n reject(err);\n } else {\n resolve(stdout);\n }\n },\n );\n });\n }\n\n /**\n * Resolve executable path from node_modules/.bin.\n *\n * Search order:\n * 1. Local: node_modules/.bin/\n * 2. Pnpm nested: node_modules/alepha/node_modules/.bin/\n * 3. Monorepo: Walk up to 3 parent directories\n */\n protected async resolveExecutable(\n name: string,\n root: string,\n ): Promise<string> {\n const suffix = process.platform === \"win32\" ? \".cmd\" : \"\";\n\n // 1. Local node_modules\n let execPath = await this.findExecutable(\n root,\n `node_modules/.bin/${name}${suffix}`,\n );\n\n // 2. Pnpm nested (alepha's own node_modules)\n if (!execPath) {\n execPath = await this.findExecutable(\n root,\n `node_modules/alepha/node_modules/.bin/${name}${suffix}`,\n );\n }\n\n // 3. Monorepo: check parent directories (up to 3 levels)\n if (!execPath) {\n let parentDir = this.fs.join(root, \"..\");\n for (let i = 0; i < 3; i++) {\n execPath = await this.findExecutable(\n parentDir,\n `node_modules/.bin/${name}${suffix}`,\n );\n if (execPath) break;\n parentDir = this.fs.join(parentDir, \"..\");\n }\n }\n\n if (!execPath) {\n throw new AlephaError(\n `Could not find executable for '${name}'. Make sure the package is installed.`,\n );\n }\n\n return execPath;\n }\n\n /**\n * Check if executable exists at path.\n */\n protected async findExecutable(\n root: string,\n relativePath: string,\n ): Promise<string | undefined> {\n const fullPath = this.fs.join(root, relativePath);\n if (await this.fs.exists(fullPath)) {\n return fullPath;\n }\n return undefined;\n }\n\n /**\n * Check if a command is installed and available in the system PATH.\n */\n public isInstalled(command: string): Promise<boolean> {\n return new Promise((resolve) => {\n const check =\n process.platform === \"win32\"\n ? `where ${command}`\n : `command -v ${command}`;\n exec(check, (error) => resolve(!error));\n });\n }\n}\n","// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface ShellRunOptions {\n /**\n * Working directory for the command.\n */\n root?: string;\n\n /**\n * Additional environment variables.\n */\n env?: Record<string, string>;\n\n /**\n * Resolve the executable from node_modules/.bin.\n * Supports local project, pnpm nested, and monorepo structures.\n * @default false\n */\n resolve?: boolean;\n\n /**\n * Capture stdout instead of inheriting stdio.\n * When true, returns stdout as string.\n * When false, streams output to terminal.\n * @default false\n */\n capture?: boolean;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Abstract provider for executing shell commands and binaries.\n *\n * Implementations:\n * - `NodeShellProvider` - Real shell execution using Node.js child_process\n * - `MemoryShellProvider` - In-memory mock for testing\n *\n * @example\n * ```typescript\n * class MyService {\n * protected readonly shell = $inject(ShellProvider);\n *\n * async build() {\n * // Run shell command directly\n * await this.shell.run(\"yarn install\");\n *\n * // Run local binary with resolution\n * await this.shell.run(\"vite build\", { resolve: true });\n *\n * // Capture output\n * const output = await this.shell.run(\"echo hello\", { capture: true });\n * }\n * }\n * ```\n */\nexport abstract class ShellProvider {\n /**\n * Run a shell command or binary.\n *\n * @param command - The command to run\n * @param options - Execution options\n * @returns stdout if capture is true, empty string otherwise\n */\n abstract run(command: string, options?: ShellRunOptions): Promise<string>;\n\n /**\n * Check if a command is installed and available in the system PATH.\n *\n * @param command - The command name to check\n * @returns true if the command is available\n */\n abstract isInstalled(command: string): Promise<boolean>;\n}\n","import { $module } from \"alepha\";\nimport { FileSystemProvider } from \"./providers/FileSystemProvider.ts\";\nimport { MemoryFileSystemProvider } from \"./providers/MemoryFileSystemProvider.ts\";\nimport { MemoryShellProvider } from \"./providers/MemoryShellProvider.ts\";\nimport { NodeFileSystemProvider } from \"./providers/NodeFileSystemProvider.ts\";\nimport { NodeShellProvider } from \"./providers/NodeShellProvider.ts\";\nimport { ShellProvider } from \"./providers/ShellProvider.ts\";\nimport { FileDetector } from \"./services/FileDetector.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./errors/FileError.ts\";\nexport * from \"./providers/FileSystemProvider.ts\";\nexport * from \"./providers/MemoryFileSystemProvider.ts\";\nexport * from \"./providers/MemoryShellProvider.ts\";\nexport * from \"./providers/NodeFileSystemProvider.ts\";\nexport * from \"./providers/NodeShellProvider.ts\";\nexport * from \"./providers/ShellProvider.ts\";\nexport * from \"./services/FileDetector.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * | Stability | Since | Runtime |\n * |-----------|-------|---------|\n * | 3 - stable | 0.14.0 | node, bun, browser|\n *\n * System-level abstractions for portable code across runtimes.\n *\n * **Features:**\n * - File system operations (read, write, exists, etc.)\n * - Shell command execution\n * - File type detection and MIME utilities\n * - Memory implementations for testing\n *\n * @module alepha.system\n */\nexport const AlephaSystem = $module({\n name: \"alepha.system\",\n primitives: [],\n services: [\n FileDetector,\n FileSystemProvider,\n MemoryFileSystemProvider,\n NodeFileSystemProvider,\n ShellProvider,\n MemoryShellProvider,\n NodeShellProvider,\n ],\n register: (alepha) =>\n alepha\n .with({\n optional: true,\n provide: FileSystemProvider,\n use: NodeFileSystemProvider,\n })\n .with({\n optional: true,\n provide: ShellProvider,\n use: alepha.isTest() ? MemoryShellProvider : NodeShellProvider,\n }),\n});\n","/**\n * Used for identifying primitives.\n *\n * @internal\n */\nexport const KIND: unique symbol = Symbol.for(\"Alepha.Kind\");\n","import type { TArray } from \"typebox\";\nimport { KIND } from \"../constants/KIND.ts\";\nimport type {\n Static,\n TObject,\n TOptionalAdd,\n} from \"../providers/TypeProvider.ts\";\n\n/**\n * Define an atom for state management.\n *\n * Atom lets you define a piece of state with a name, schema, and default value.\n *\n * By default, Alepha state is just a simple key-value store.\n * Using atoms allows you to have type safety, validation, and default values for your state.\n *\n * You control how state is structured and validated.\n *\n * Features:\n * - Set a schema for validation\n * - Set a default value for initial state\n * - Rules, like read-only, custom validation, etc.\n * - Automatic getter access in services with {@link $use}\n * - SSR support (server state automatically serialized and hydrated on client)\n * - React integration (useAtom hook for automatic component re-renders)\n * - Middleware\n * - Persistence adapters (localStorage, Redis, database, file system, cookie, etc.)\n * - State migrations (version upgrades when schema changes)\n * - Documentation generation & devtools integration\n *\n * Common use cases:\n * - user preferences\n * - feature flags\n * - configuration options\n * - session data\n *\n * Atom must contain only serializable data.\n * Avoid storing complex objects like class instances, functions, or DOM elements.\n * If you need to store complex data, consider using identifiers or references instead.\n */\nexport const $atom = <\n T extends TObject<TProperties> | TArray,\n N extends string,\n>(\n options: AtomOptions<T, N>,\n): Atom<T, N> => {\n return new Atom<T, N>(options);\n};\n\nexport type AtomOptions<T extends TAtomObject, N extends string> = {\n name: N;\n schema: T;\n description?: string;\n} & (T extends TOptionalAdd<T>\n ? {\n default?: Static<T>;\n }\n : {\n default: Static<T>;\n });\n\nexport class Atom<T extends TAtomObject = TObject, N extends string = string> {\n public readonly options: AtomOptions<T, N>;\n\n public get schema(): T {\n return this.options.schema;\n }\n\n public get key(): N {\n return this.options.name;\n }\n\n constructor(options: AtomOptions<T, N>) {\n this.options = options;\n }\n}\n\n$atom[KIND] = \"atom\";\n\ntype TProperties = any; // it's required to avoid required [ string ] error, ...\n\nexport type TAtomObject = TObject<any> | TArray;\nexport type AtomStatic<T extends TAtomObject> =\n T extends TOptionalAdd<T> ? Static<T> | undefined : Static<T>;\n","import { type Static, t } from \"alepha\";\nimport { $atom } from \"../../core/primitives/$atom.ts\";\n\n/**\n * Deployment target for the build output.\n *\n * - `docker` - Generate Dockerfile for containerized deployment\n * - `vercel` - Generate Vercel deployment configuration (forces node runtime)\n * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime)\n */\nexport type BuildTarget = \"bare\" | \"docker\" | \"vercel\" | \"cloudflare\";\n\n/**\n * JavaScript runtime for the build output.\n *\n * - `node` - Node.js runtime (default)\n * - `bun` - Bun runtime (uses bun export conditions)\n * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target)\n */\nexport type BuildRuntime = \"node\" | \"bun\" | \"workerd\";\n\n/**\n * Build options atom for CLI build command.\n *\n * Defines the available build configuration options with their defaults.\n * Options can be overridden via alepha.config.ts or CLI flags.\n */\nexport const buildOptions = $atom({\n name: \"alepha.cli.build.options\",\n description: \"Build configuration options\",\n schema: t.object({\n /**\n * Generate build stats report.\n */\n stats: t.optional(t.boolean({ default: false })),\n\n /**\n * Deployment target for the build output.\n *\n * - `docker` - Generate Dockerfile for containerized deployment\n * - `vercel` - Generate Vercel deployment configuration (forces node runtime)\n * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime)\n */\n target: t.optional(t.enum([\"bare\", \"docker\", \"vercel\", \"cloudflare\"])),\n\n /**\n * JavaScript runtime for the build output.\n *\n * - `node` - Node.js runtime (default)\n * - `bun` - Bun runtime (uses bun export conditions)\n * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target)\n *\n * Note: Some targets force a specific runtime:\n * - `cloudflare` always uses `workerd`\n * - `vercel` always uses `node`\n */\n runtime: t.optional(t.enum([\"node\", \"bun\", \"workerd\"])),\n\n /**\n * Vercel-specific deployment configuration.\n *\n * Note: Set `target: \"vercel\"` to enable Vercel deployment.\n * This object is only for additional configuration.\n */\n vercel: t.optional(\n t.object({\n projectName: t.optional(t.string()),\n orgId: t.optional(t.string()),\n projectId: t.optional(t.string()),\n config: t.optional(\n t.object({\n crons: t.optional(\n t.array(\n t.object({\n path: t.string(),\n schedule: t.string(),\n }),\n ),\n ),\n }),\n ),\n }),\n ),\n\n /**\n * Cloudflare-specific deployment configuration.\n *\n * Note: Set `target: \"cloudflare\"` to enable Cloudflare deployment.\n * This object is only for additional configuration.\n */\n cloudflare: t.optional(\n t.object({\n config: t.optional(t.json()),\n }),\n ),\n\n /**\n * Docker-specific deployment configuration.\n *\n * Note: Set `target: \"docker\"` to enable Docker deployment.\n * This object is only for additional configuration.\n */\n docker: t.optional(\n t.object({\n /**\n * Base image for the Dockerfile (FROM instruction).\n *\n * @default \"node:24-alpine\" for node runtime\n * @default \"oven/bun:alpine\" for bun runtime\n */\n from: t.optional(t.string()),\n\n /**\n * Command to run in the Docker container.\n *\n * @default \"node\" for node runtime\n * @default \"bun\" for bun runtime\n */\n command: t.optional(t.string()),\n\n /**\n * Docker build options (used when --image flag is passed).\n */\n image: t.optional(\n t.object({\n /**\n * Default image tag (name without version).\n *\n * Used when --image is provided without a full override:\n * - `--image` → `tag:latest`\n * - `--image=1.3.4` → `tag:1.3.4`\n * - `--image=other/img:v1` → `other/img:v1` (full override)\n *\n * @example \"myproject/myapp\"\n * @example \"ghcr.io/myorg/myapp\"\n */\n tag: t.string(),\n\n /**\n * Additional arguments to pass to `docker build`.\n *\n * @example '--platform linux/amd64 --no-cache'\n */\n args: t.optional(t.string()),\n\n /**\n * Auto-add OCI standard labels (revision, created, version).\n *\n * Adds:\n * - org.opencontainers.image.revision (git commit SHA)\n * - org.opencontainers.image.created (build timestamp)\n * - org.opencontainers.image.version (from image tag)\n */\n oci: t.optional(t.boolean()),\n }),\n ),\n }),\n ),\n\n /**\n * Sitemap generation configuration.\n */\n sitemap: t.optional(\n t.object({\n /**\n * Base URL for sitemap entries.\n */\n hostname: t.string(),\n }),\n ),\n }),\n default: {},\n});\n\n/**\n * Type for build options.\n */\nexport type BuildOptions = Static<typeof buildOptions.schema>;\n","import { $atom, type Static, t } from \"alepha\";\n\nexport const appEntryOptions = $atom({\n name: \"alepha.cli.appEntry.options\",\n schema: t.object({\n server: t.optional(t.text()),\n browser: t.optional(t.text()),\n style: t.optional(t.text()),\n }),\n default: {},\n});\n\nexport type AppEntryOptions = Static<typeof appEntryOptions.schema>;\n","import { $inject, $use, AlephaError } from \"alepha\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { appEntryOptions } from \"../atoms/appEntryOptions.ts\";\n\n/**\n * Service for locating entry files in Alepha projects.\n *\n * Originally in alepha/vite, moved to CLI to avoid cli -> vite dependency.\n */\nexport class AppEntryProvider {\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly options = $use(appEntryOptions);\n\n protected readonly serverEntries = [\n \"main.server.ts\",\n \"main.server.tsx\",\n \"main.ts\",\n \"main.tsx\",\n ] as const;\n\n protected readonly browserEntries = [\n \"main.browser.ts\",\n \"main.browser.tsx\",\n \"main.ts\",\n \"main.tsx\",\n ] as const;\n\n protected readonly styleEntries = [\n \"main.css\",\n \"styles.css\",\n \"style.css\",\n ] as const;\n\n /**\n * Get application entry points.\n *\n * Server entry is required, an error is thrown if not found.\n * Browser entry is optional.\n *\n * It will first check for custom entries in options, see appEntryOptions.\n */\n public async getAppEntry(root: string): Promise<AppEntry> {\n const appEntry: AppEntry = {\n root,\n server: \"\",\n };\n\n if (this.options.server) {\n const serverExists = await this.fs.exists(\n this.fs.join(root, this.options.server),\n );\n if (!serverExists) {\n throw new AlephaError(\n `Custom server entry \"${this.options.server}\" not found.`,\n );\n }\n appEntry.server = this.options.server;\n }\n\n if (this.options.browser) {\n const browserExists = await this.fs.exists(\n this.fs.join(root, this.options.browser),\n );\n if (!browserExists) {\n throw new AlephaError(\n `Custom browser entry \"${this.options.browser}\" not found.`,\n );\n }\n appEntry.browser = this.options.browser;\n }\n\n if (this.options.style) {\n const styleExists = await this.fs.exists(\n this.fs.join(root, this.options.style),\n );\n if (!styleExists) {\n throw new AlephaError(\n `Custom style entry \"${this.options.style}\" not found.`,\n );\n }\n appEntry.style = this.options.style;\n }\n\n const srcFiles = await this.fs.ls(this.fs.join(root, \"src\"));\n\n if (!appEntry.server) {\n // find in conventional locations\n for (const entry of this.serverEntries) {\n if (srcFiles.includes(entry)) {\n appEntry.server = this.fs.join(\"src\", entry);\n break;\n }\n }\n }\n\n if (!appEntry.server) {\n throw new AlephaError(\n \"No server entry found. Please, add a main.server.ts file in the src/ directory or configure a custom entry in alepha.config.ts.\",\n );\n }\n\n if (!appEntry.browser) {\n // find in conventional locations\n for (const entry of this.browserEntries) {\n if (srcFiles.includes(entry)) {\n appEntry.browser = this.fs.join(\"src\", entry);\n break;\n }\n }\n }\n\n if (!appEntry.style) {\n // find in conventional locations\n for (const entry of this.styleEntries) {\n if (srcFiles.includes(entry)) {\n appEntry.style = this.fs.join(\"src\", entry);\n break;\n }\n }\n }\n\n return appEntry;\n }\n}\n\nexport interface AppEntry {\n root: string;\n server: string;\n browser?: string;\n style?: string;\n}\n","import { $hook, $inject, type Alepha, AlephaError } from \"alepha\";\nimport { importVite } from \"alepha/vite\";\nimport type { InlineConfig, ViteDevServer } from \"vite\";\nimport { FileSystemProvider } from \"../../system/index.ts\";\nimport type { AppEntry } from \"../providers/AppEntryProvider.ts\";\n\nexport class ViteUtils {\n protected readonly fs = $inject(FileSystemProvider);\n protected viteDevServer?: ViteDevServer;\n\n public generateIndexHtml(entry: AppEntry): string {\n const style = entry.style;\n const browser = entry.browser ?? entry.server;\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\" />\n<title>App</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n${style ? `<link rel=\"stylesheet\" href=\"/${style}\" />` : \"\"}\n</head>\n<body>\n<div id=\"root\"></div>\n<script type=\"module\" src=\"/${browser}\"></script>\n</body>\n</html>\n`.trim();\n }\n\n /**\n * We need to close the Vite dev server after build is done.\n */\n protected onReady = $hook({\n on: \"ready\",\n priority: \"last\",\n handler: async () => {\n await this.viteDevServer?.close();\n },\n });\n\n protected onStop = $hook({\n on: \"stop\",\n handler: async () => {\n await this.viteDevServer?.close();\n },\n });\n\n public async runAlepha(opts: {\n entry: AppEntry;\n mode: \"production\" | \"development\";\n }): Promise<Alepha> {\n const { createServer } = await importVite();\n\n process.env.NODE_ENV = opts.mode;\n process.env.ALEPHA_CLI_IMPORT = \"true\"; // signal Alepha App about CLI import, run(alepha) won't start server\n process.env.LOG_LEVEL ??= \"warn\"; // reduce log noise\n\n /**\n * 01/26 Vite 7\n * \"runnerImport\" doesn't work as expected here. (e.g. build docs fail)\n * -> We still use devServer and ssrLoadModule for now.\n * -> This is clearly a bad stuff, we need to find better way.\n */\n this.viteDevServer = await createServer({\n server: { middlewareMode: true },\n appType: \"custom\",\n logLevel: \"silent\",\n } satisfies InlineConfig);\n\n await this.viteDevServer.ssrLoadModule(opts.entry.server);\n\n const alepha: Alepha = (globalThis as any).__alepha;\n if (!alepha) {\n throw new AlephaError(\n \"Alepha instance not found after loading entry module\",\n );\n }\n\n return alepha;\n }\n}\n","import { $inject, type Alepha, AlephaError } from \"alepha\";\nimport { ViteUtils } from \"../services/ViteUtils.ts\";\nimport type { AppEntry } from \"./AppEntryProvider.ts\";\n\nexport class ViteBuildProvider {\n protected alepha?: Alepha;\n protected appEntry?: AppEntry;\n protected readonly viteUtils = $inject(ViteUtils);\n\n public async init(opts: { entry: AppEntry }) {\n const alepha = await this.viteUtils.runAlepha({\n entry: opts.entry,\n mode: \"production\",\n });\n\n this.alepha = alepha;\n this.appEntry = opts.entry;\n\n return alepha;\n }\n\n public hasClient(): boolean {\n if (!this.alepha) {\n throw new AlephaError(\"ViteBuildProvider not initialized\");\n }\n try {\n this.alepha.inject(\"ReactServerProvider\");\n return true;\n } catch {\n return false;\n }\n }\n\n public generateIndexHtml(): string {\n if (!this.appEntry) {\n throw new AlephaError(\"ViteBuildProvider not initialized\");\n }\n return this.viteUtils.generateIndexHtml(this.appEntry);\n }\n}\n","import { $inject, type Alepha } from \"alepha\";\nimport { EnvUtils } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider, ShellProvider } from \"alepha/system\";\nimport {\n type AppEntry,\n AppEntryProvider,\n} from \"../providers/AppEntryProvider.ts\";\nimport { ViteUtils } from \"./ViteUtils.ts\";\n\n/**\n * Core utility service for CLI commands.\n *\n * Provides:\n * - Command execution\n * - File editing helpers\n * - Drizzle/ORM utilities\n * - Environment loading\n */\nexport class AlephaCliUtils {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly envUtils = $inject(EnvUtils);\n protected readonly boot = $inject(AppEntryProvider);\n protected readonly shell = $inject(ShellProvider);\n protected readonly viteUtils = $inject(ViteUtils);\n\n // ===========================================\n // Command Execution\n // ===========================================\n\n /**\n * Execute a command with inherited stdio.\n *\n * @param command - The command to execute\n * @param options.root - Working directory\n * @param options.env - Additional environment variables\n * @param options.global - If true, run command directly without resolving from node_modules\n */\n public async exec(\n command: string,\n options: {\n root?: string;\n env?: Record<string, string>;\n global?: boolean;\n } = {},\n ): Promise<void> {\n await this.shell.run(command, {\n root: options.root,\n env: options.env,\n resolve: !options.global,\n capture: false,\n });\n }\n\n /**\n * Write a configuration file to node_modules/.alepha directory.\n */\n public async writeConfigFile(\n name: string,\n content: string,\n root = process.cwd(),\n ): Promise<string> {\n const dir = this.fs.join(root, \"node_modules\", \".alepha\");\n\n await this.fs.mkdir(dir, { recursive: true }).catch(() => null);\n\n const path = this.fs.join(dir, name);\n await this.fs.writeFile(path, content);\n\n this.log.debug(`Config file written: ${path}`);\n\n return path;\n }\n\n public async loadAlephaFromServerEntryFile(\n opts: {\n mode: \"production\" | \"development\";\n } & ({ entry: AppEntry } | { root: string }),\n ): Promise<Alepha> {\n let entry: AppEntry;\n if (\"root\" in opts) {\n entry = await this.boot.getAppEntry(opts.root);\n } else {\n entry = opts.entry;\n }\n\n return await this.viteUtils.runAlepha({\n entry,\n mode: opts.mode,\n });\n }\n\n // ===========================================\n // Drizzle ORM & Kit Utilities\n // ===========================================\n\n /**\n * Generate JavaScript code for Drizzle entities export.\n */\n public generateEntitiesJs(\n entry: string,\n provider: string,\n models: string[] = [],\n ): string {\n return `\nimport \"${entry}\";\nimport { DrizzleKitProvider, Repository } from \"alepha/orm\";\n\nconst alepha = globalThis.__alepha;\nconst kit = alepha.inject(DrizzleKitProvider);\nconst provider = alepha.services(Repository).find((it) => it.provider.name === \"${provider}\").provider;\nconst models = kit.getModels(provider);\n\n${models.map((it: string) => `export const ${it} = models[\"${it}\"];`).join(\"\\n\")}\n\n`.trim();\n }\n\n // ===========================================\n // Environment\n // ===========================================\n\n /**\n * Load environment variables from a .env file.\n */\n public async loadEnv(\n root: string,\n files: string[] = [\".env\"],\n ): Promise<void> {\n await this.envUtils.loadEnv(root, files);\n }\n\n // ===========================================\n // Helpers\n // ===========================================\n\n public async exists(root: string, path: string): Promise<boolean> {\n return this.fs.exists(this.fs.join(root, path));\n }\n\n /**\n * Check if a command is installed and available in the system PATH.\n */\n public isInstalledAsync(cmd: string): Promise<boolean> {\n return this.shell.isInstalled(cmd);\n }\n\n /**\n * Get the current git revision (commit SHA).\n *\n * @returns The short commit SHA or \"unknown\" if not in a git repo\n */\n public async getGitRevision(): Promise<string> {\n try {\n const result = await this.shell.run(\"git rev-parse --short HEAD\", {\n capture: true,\n });\n return result.trim();\n } catch {\n return \"unknown\";\n }\n }\n\n /**\n * Get the user's email from git config.\n *\n * @returns The git user email or undefined if not configured\n */\n public async getGitEmail(): Promise<string | undefined> {\n try {\n const result = await this.shell.run(\"git config user.email\", {\n capture: true,\n });\n const email = result.trim();\n return email || undefined;\n } catch {\n return undefined;\n }\n }\n}\n","","import { readFileSync } from \"node:fs\";\n\nconst packageJson = JSON.parse(\n readFileSync(new URL(\"../../package.json\", import.meta.url), \"utf-8\"),\n);\n\nexport const version = packageJson.version;\n","import { $inject, Alepha } from \"alepha\";\nimport type { RunnerMethod } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport alephaPackageJson from \"alepha/package.json\" with { type: \"json\" };\nimport { FileSystemProvider } from \"alepha/system\";\nimport { version } from \"../version.ts\";\n\n/**\n * Context information about a workspace root.\n * Used when initializing a package inside a monorepo.\n */\nexport interface WorkspaceContext {\n /**\n * Whether we're inside a workspace package.\n */\n isPackage: boolean;\n /**\n * The workspace root directory (e.g., ../.. from packages/my-pkg).\n */\n workspaceRoot: string | null;\n /**\n * Package manager detected at workspace root.\n */\n packageManager: \"yarn\" | \"pnpm\" | \"npm\" | \"bun\" | null;\n /**\n * Config files present at workspace root.\n */\n config: {\n biomeJson: boolean;\n editorconfig: boolean;\n tsconfigJson: boolean;\n };\n}\n\n/**\n * Utility service for package manager operations.\n *\n * Handles detection, installation, and cleanup for:\n * - Yarn\n * - npm\n * - pnpm\n * - Bun\n */\nexport class PackageManagerUtils {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly alepha = $inject(Alepha);\n\n /**\n * Detect the package manager used in the project.\n * Checks current directory first, then workspace root if in a monorepo.\n */\n public async getPackageManager(\n root: string,\n pm?: \"yarn\" | \"pnpm\" | \"npm\" | \"bun\",\n ): Promise<\"yarn\" | \"pnpm\" | \"npm\" | \"bun\"> {\n if (pm) return pm;\n if (this.alepha.isBun()) return \"bun\";\n\n // Check current directory first\n if (await this.fs.exists(this.fs.join(root, \"bun.lock\"))) return \"bun\";\n if (await this.fs.exists(this.fs.join(root, \"yarn.lock\"))) return \"yarn\";\n if (await this.fs.exists(this.fs.join(root, \"pnpm-lock.yaml\")))\n return \"pnpm\";\n if (await this.fs.exists(this.fs.join(root, \"package-lock.json\")))\n return \"npm\";\n\n // Check workspace root (for monorepo packages like apps/blog)\n const workspace = await this.getWorkspaceContext(root);\n if (workspace.packageManager) {\n return workspace.packageManager;\n }\n\n return \"npm\";\n }\n\n /**\n * Detect workspace context when inside a monorepo package.\n *\n * Checks if we're inside a workspace package (e.g., packages/my-pkg or apps/my-app)\n * by looking 2 levels up for workspace indicators like lockfiles and config files.\n *\n * @param root - The current package directory\n * @returns Workspace context with root path, PM, and config presence\n */\n public async getWorkspaceContext(root: string): Promise<WorkspaceContext> {\n // Workspace root is 2 levels up (e.g., packages/my-pkg → ..)\n const workspaceRoot = this.fs.join(root, \"..\", \"..\");\n\n // Check for lockfiles to detect PM\n const [hasYarnLock, hasPnpmLock, hasNpmLock, hasBunLock] =\n await Promise.all([\n this.fs.exists(this.fs.join(workspaceRoot, \"yarn.lock\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"pnpm-lock.yaml\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"package-lock.json\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"bun.lock\")),\n ]);\n\n // Check for config files\n const [hasBiome, hasEditorConfig, hasTsConfig, hasWorkspacePackageJson] =\n await Promise.all([\n this.fs.exists(this.fs.join(workspaceRoot, \"biome.json\")),\n this.fs.exists(this.fs.join(workspaceRoot, \".editorconfig\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"tsconfig.json\")),\n this.fs.exists(this.fs.join(workspaceRoot, \"package.json\")),\n ]);\n\n // Determine if this looks like a workspace root\n const hasLockfile = hasYarnLock || hasPnpmLock || hasNpmLock || hasBunLock;\n const isPackage = hasLockfile && hasWorkspacePackageJson;\n\n // Detect package manager from lockfile\n let packageManager: \"yarn\" | \"pnpm\" | \"npm\" | \"bun\" | null = null;\n if (hasYarnLock) packageManager = \"yarn\";\n else if (hasPnpmLock) packageManager = \"pnpm\";\n else if (hasBunLock) packageManager = \"bun\";\n else if (hasNpmLock) packageManager = \"npm\";\n\n return {\n isPackage,\n workspaceRoot: isPackage ? workspaceRoot : null,\n packageManager,\n config: {\n biomeJson: hasBiome,\n editorconfig: hasEditorConfig,\n tsconfigJson: hasTsConfig,\n },\n };\n }\n\n /**\n * Get the install command for a package.\n */\n public async getInstallCommand(\n root: string,\n packageName: string,\n dev = true,\n ): Promise<string> {\n const pm = await this.getPackageManager(root);\n let cmd: string;\n\n switch (pm) {\n case \"yarn\":\n cmd = `yarn add ${dev ? \"-D\" : \"\"} ${packageName}`;\n break;\n case \"pnpm\":\n cmd = `pnpm add ${dev ? \"-D\" : \"\"} ${packageName}`;\n break;\n case \"bun\":\n cmd = `bun add ${dev ? \"-d\" : \"\"} ${packageName}`;\n break;\n default:\n cmd = `npm install ${dev ? \"--save-dev\" : \"\"} ${packageName}`;\n }\n\n return cmd.replace(/\\s+/g, \" \").trim();\n }\n\n /**\n * Check if a dependency is installed in the project.\n */\n public async hasDependency(\n root: string,\n packageName: string,\n ): Promise<boolean> {\n try {\n const pkg = await this.readPackageJson(root);\n return !!(\n pkg.dependencies?.[packageName] || pkg.devDependencies?.[packageName]\n );\n } catch {\n return false;\n }\n }\n\n /**\n * Check if Expo is present in the project.\n */\n public async hasExpo(root: string): Promise<boolean> {\n return this.hasDependency(root, \"expo\");\n }\n\n /**\n * Check if React is present in the project.\n */\n public async hasReact(root: string): Promise<boolean> {\n return this.hasDependency(root, \"react\");\n }\n\n /**\n * Install a dependency if it's missing from the project.\n * Optionally checks workspace root for the dependency in monorepo setups.\n */\n public async ensureDependency(\n root: string,\n packageName: string,\n options: {\n dev?: boolean;\n /**\n * Also check workspace root for the dependency (for monorepo setups).\n */\n checkWorkspace?: boolean;\n run?: RunnerMethod;\n exec?: (\n cmd: string,\n opts?: { global?: boolean; root?: string },\n ) => Promise<void>;\n } = {},\n ): Promise<void> {\n const { dev = true, checkWorkspace = false } = options;\n\n // Check current package\n if (await this.hasDependency(root, packageName)) {\n this.log.debug(`Dependency '${packageName}' is already installed`);\n return;\n }\n\n // Check workspace root (for monorepo setups)\n if (checkWorkspace) {\n const workspace = await this.getWorkspaceContext(root);\n if (workspace.workspaceRoot) {\n if (await this.hasDependency(workspace.workspaceRoot, packageName)) {\n this.log.debug(\n `Dependency '${packageName}' is already installed in workspace root`,\n );\n return;\n }\n }\n }\n\n const cmd = await this.getInstallCommand(root, packageName, dev);\n\n if (options.run) {\n await options.run(cmd, { alias: `add ${packageName}`, root });\n } else if (options.exec) {\n this.log.debug(`Installing ${packageName}`);\n await options.exec(cmd, { global: true, root });\n }\n }\n\n // ===========================================\n // Package Manager Setup & Cleanup\n // ===========================================\n\n public async ensureYarn(root: string): Promise<void> {\n const yarnrcPath = this.fs.join(root, \".yarnrc.yml\");\n if (!(await this.fs.exists(yarnrcPath))) {\n await this.fs.writeFile(yarnrcPath, \"nodeLinker: node-modules\");\n }\n await this.removeAllPmFilesExcept(root, \"yarn\");\n }\n\n public async ensureBun(root: string): Promise<void> {\n await this.removeAllPmFilesExcept(root, \"bun\");\n }\n\n public async ensurePnpm(root: string): Promise<void> {\n await this.removeAllPmFilesExcept(root, \"pnpm\");\n }\n\n public async ensureNpm(root: string): Promise<void> {\n await this.removeAllPmFilesExcept(root, \"npm\");\n }\n\n public async removeAllPmFilesExcept(\n root: string,\n except: string,\n ): Promise<void> {\n if (except !== \"yarn\") await this.removeYarn(root);\n if (except !== \"pnpm\") await this.removePnpm(root);\n if (except !== \"npm\") await this.removeNpm(root);\n if (except !== \"bun\") await this.removeBun(root);\n }\n\n public async removeYarn(root: string): Promise<void> {\n await this.removeFiles(root, [\".yarn\", \".yarnrc.yml\", \"yarn.lock\"]);\n await this.editPackageJson(root, (pkg) => {\n delete pkg.packageManager;\n return pkg;\n });\n }\n\n public async removePnpm(root: string): Promise<void> {\n await this.removeFiles(root, [\"pnpm-lock.yaml\", \"pnpm-workspace.yaml\"]);\n await this.editPackageJson(root, (pkg) => {\n delete pkg.packageManager;\n return pkg;\n });\n }\n\n public async removeNpm(root: string): Promise<void> {\n await this.removeFiles(root, [\"package-lock.json\"]);\n }\n\n public async removeBun(root: string): Promise<void> {\n await this.removeFiles(root, [\"bun.lockb\", \"bun.lock\"]);\n }\n\n // ===========================================\n // Package.json utilities\n // ===========================================\n\n public async readPackageJson(root: string): Promise<Record<string, any>> {\n const content = await this.fs\n .createFile({ path: this.fs.join(root, \"package.json\") })\n .text();\n return JSON.parse(content);\n }\n\n public async writePackageJson(\n root: string,\n content: Record<string, any>,\n ): Promise<void> {\n await this.fs.writeFile(\n this.fs.join(root, \"package.json\"),\n JSON.stringify(content, null, 2),\n );\n }\n\n public async editPackageJson(\n root: string,\n editFn: (pkg: Record<string, any>) => Record<string, any>,\n ): Promise<void> {\n try {\n const pkg = await this.readPackageJson(root);\n const updated = editFn(pkg);\n await this.writePackageJson(root, updated);\n } catch {\n // package.json doesn't exist, skip\n }\n }\n\n public async ensurePackageJson(\n root: string,\n modes: DependencyModes,\n ): Promise<Record<string, any>> {\n const packageJsonPath = this.fs.join(root, \"package.json\");\n\n if (!(await this.fs.exists(packageJsonPath))) {\n const content = this.generatePackageJsonContent(modes);\n await this.writePackageJson(root, content);\n return content;\n }\n\n const packageJson = await this.readPackageJson(root);\n const newContent = this.generatePackageJsonContent(modes);\n\n packageJson.type = \"module\";\n packageJson.dependencies ??= {};\n packageJson.devDependencies ??= {};\n packageJson.scripts ??= {};\n\n Object.assign(packageJson.dependencies, newContent.dependencies);\n Object.assign(packageJson.devDependencies, newContent.devDependencies);\n Object.assign(packageJson.scripts, newContent.scripts);\n\n await this.writePackageJson(root, packageJson);\n return packageJson;\n }\n\n public generatePackageJsonContent(modes: DependencyModes): {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n scripts: Record<string, string>;\n type: \"module\";\n } {\n const alephaDeps = alephaPackageJson.devDependencies;\n\n const dependencies: Record<string, string> = {\n alepha: `^${version}`,\n };\n\n const devDependencies: Record<string, string> = {\n vite: alephaDeps.vite,\n };\n\n // Add biome/vitest only if not a workspace package (workspace root has them)\n if (!modes.isPackage) {\n devDependencies[\"@biomejs/biome\"] = alephaDeps[\"@biomejs/biome\"];\n if (modes.test) {\n devDependencies.vitest = alephaDeps.vitest;\n }\n }\n\n const scripts: Record<string, string> = {\n dev: \"alepha dev\",\n build: \"alepha build\",\n lint: \"alepha lint\",\n typecheck: \"alepha typecheck\",\n verify: \"alepha verify\",\n };\n\n if (modes.test) {\n scripts.test = \"vitest run\";\n }\n\n if (modes.ui) {\n dependencies[\"@alepha/ui\"] = `^${version}`;\n modes.react = true;\n }\n\n if (modes.react) {\n dependencies.react = alephaDeps.react;\n dependencies[\"react-dom\"] = alephaDeps[\"react-dom\"];\n devDependencies[\"@vitejs/plugin-react\"] =\n alephaDeps[\"@vitejs/plugin-react\"];\n devDependencies[\"@types/react\"] = alephaDeps[\"@types/react\"];\n }\n\n return {\n type: \"module\",\n dependencies,\n devDependencies,\n scripts,\n };\n }\n\n // ===========================================\n // Helper methods\n // ===========================================\n\n protected async removeFiles(root: string, files: string[]): Promise<void> {\n await Promise.all(\n files.map((file) =>\n this.fs.rm(this.fs.join(root, file), { force: true, recursive: true }),\n ),\n );\n }\n}\n\nexport interface DependencyModes {\n react?: boolean;\n ui?: boolean;\n expo?: boolean;\n test?: boolean;\n /**\n * Skip biome/vitest when inside a workspace package (they're at root).\n */\n isPackage?: boolean;\n}\n","export interface AgentMdOptions {\n react?: boolean;\n ui?: boolean;\n projectName?: string;\n}\n\nexport type AgentMdType = \"claude\" | \"agents\";\n\nexport const agentMd = (\n type: AgentMdType,\n options: AgentMdOptions = {},\n): string => {\n const { react = false, projectName = \"my-app\" } = options;\n\n const header =\n type === \"claude\"\n ? `# CLAUDE.md\n\nThis file provides guidance to Claude Code when working with this Alepha project.`\n : `# AGENTS.md\n\nThis file provides guidance to AI coding assistants when working with this Alepha project.`;\n\n const reactSection = react\n ? `\n## React & Frontend\n\n### Pages with \\`$page\\`\n\\`\\`\\`tsx\nimport { t } from \"alepha\";\nimport { $page } from \"alepha/react/router\";\nimport { $client } from \"alepha/server/links\";\nimport type { UserController } from \"./UserController.ts\";\n\nclass AppRouter {\n api = $client<UserController>();\n\n users = $page({\n path: \"/users\",\n loader: async () => ({ users: await this.api.listUsers() }),\n component: ({ users }) => (\n <ul>{users.map(u => <li key={u.id}>{u.email}</li>)}</ul>\n ),\n });\n\n userDetail = $page({\n path: \"/users/:id\",\n schema: { params: t.object({ id: t.uuid() }) },\n loader: async ({ params }) => ({ user: await this.api.getUser({ params }) }),\n lazy: () => import(\"./UserDetail.tsx\"), // Code splitting\n });\n}\n\\`\\`\\`\n\n### React Hooks\n\\`\\`\\`typescript\nimport { useAlepha, useClient, useStore, useAction, useInject } from \"alepha/react\";\nimport { useRouter, useActive } from \"alepha/react/router\";\nimport { useForm } from \"alepha/react/form\";\n\\`\\`\\`\n\n- \\`useClient<Controller>()\\` - Type-safe API calls\n- \\`useStore(atom)\\` - Global state (returns \\`[value, setValue]\\`)\n- \\`useAction({ handler })\\` - Async operations with loading/error state\n- \\`useRouter<AppRouter>()\\` - Type-safe navigation\n- \\`useForm({ schema, handler })\\` - Type-safe forms with validation\n`\n : \"\";\n\n const projectStructure = react\n ? `\n\\`\\`\\`\n${projectName}/\n├── src/\n│ ├── api/ # Backend\n│ │ ├── controllers/ # API controllers with $action\n│ │ ├── services/ # Business logic\n│ │ ├── entities/ # Database entities with $entity\n│ │ ├── providers/ # External service wrappers\n│ │ └── index.ts # API module definition with $module\n│ ├── web/ # Frontend (React only)\n│ │ ├── components/ # React components\n│ │ ├── atoms/ # State atoms with $atom\n│ │ ├── AppRouter.ts # Routes with $page\n│ │ └── index.ts # Web module definition with $module\n│ ├── main.server.ts # Server entry\n│ ├── main.browser.ts # Browser entry (React only)\n│ └── main.css # CSS entry (React only)\n├── package.json\n└── tsconfig.json\n\\`\\`\\`\n`\n : `\n\\`\\`\\`\n${projectName}/\n├── src/\n│ ├── api/ # Backend\n│ │ ├── controllers/ # API controllers with $action\n│ │ ├── services/ # Business logic\n│ │ ├── entities/ # Database entities with $entity\n│ │ ├── providers/ # External service wrappers\n│ │ └── index.ts # API module definition with $module\n│ └── main.server.ts # Server entry (always use main.server.ts)\n├── package.json\n└── tsconfig.json\n\\`\\`\\`\n`;\n\n return `${header}\n\n## Overview\n\nThis is an **Alepha** project - a convention-driven TypeScript framework for type-safe full-stack applications.\n\n**Key Concepts:**\n- **Primitives**: Features defined with \\`$\\`-prefixed functions (\\`$action\\`, \\`$entity\\`, \\`$page\\`)\n- **Class-Based**: Services are classes, primitives are class properties\n- **Zero-Config**: Code structure IS the configuration\n- **End-to-End Types**: Types flow from database → API → ${react ? \"React\" : \"client\"}\n\n## Rules\n\n- Use TypeScript strict mode, always check types (\\`alepha typecheck\\`)\n- Use Biome for formatting (\\`alepha lint\\`)\n- Use Vitest for testing (\\`alepha test\\`)\n- One file = one class, multiple interfaces/types allowed\n- Primitives are class properties (except \\`$entity\\`, \\`$atom\\`)\n- No decorators, no Express/Fastify patterns\n- No manual instantiation - use dependency injection\n- Use \\`protected\\` instead of \\`private\\` for class members\n- Import with file extensions: \\`import { User } from \"./User.ts\"\\`\n- Use \\`t\\` from Alepha for schemas (not Zod)\n- Prefer \\`t.text()\\` over \\`t.string()\\` for user input (has default max length, auto-trim, supports lowercase option)\n- One file = one schema (schemas/createUserSchema.ts)\n\n## Project Structure\n${projectStructure}\n## Core Primitives\n\n### API with \\`$action\\`\n\\`\\`\\`typescript\nimport { t } from \"alepha\";\nimport { $action } from \"alepha/server\";\n\nclass UserController {\n getUser = $action({\n path: \"/users/:id\", // → GET /api/users/:id\n schema: {\n params: t.object({ id: t.uuid() }),\n response: t.object({ id: t.uuid(), email: t.email() }),\n },\n handler: async ({ params }) => this.userRepo.findById(params.id),\n });\n\n createUser = $action({\n // POST inferred from body schema\n schema: {\n body: t.object({ email: t.email() }),\n response: userEntity.schema,\n },\n handler: async ({ body }) => this.userRepo.create(body),\n });\n}\n\\`\\`\\`\n\n### Database with \\`$entity\\` and \\`$repository\\`\n\\`\\`\\`typescript\nimport { $entity, $repository, db } from \"alepha/orm\";\n\n// Entity defined at module level (for drizzle-kit compatibility)\nexport const userEntity = $entity({\n name: \"users\",\n schema: t.object({\n id: db.primaryKey(),\n email: t.email(),\n createdAt: db.createdAt(),\n }),\n indexes: [{ column: \"email\", unique: true }],\n});\n\nclass UserService {\n userRepository = $repository(userEntity);\n}\n\\`\\`\\`\n\n### Dependency Injection\n\\`\\`\\`typescript\nimport { $inject } from \"alepha\";\n\nclass OrderService {\n userService = $inject(UserService); // Within same module\n}\n\n// Cross-module: use $client instead of $inject\nclass AppRouter {\n api = $client<OrderController>(); // Type-safe HTTP client\n}\n\\`\\`\\`\n\n### Environment Variables\n\\`\\`\\`typescript\nimport { $env, t } from \"alepha\";\n\nclass AppConfig {\n env = $env(t.object({\n DATABASE_URL: t.string(),\n API_KEY: t.optional(t.string()),\n }));\n}\n\\`\\`\\`\n${reactSection}\n## Quick Reference\n\n| Primitive | Import | Purpose |\n|-----------|--------|---------|\n| \\`$inject\\` | \\`alepha\\` | Dependency injection |\n| \\`$env\\` | \\`alepha\\` | Environment variables |\n| \\`$hook\\` | \\`alepha\\` | Lifecycle hooks |\n| \\`$logger\\` | \\`alepha/logger\\` | Structured logging |\n| \\`$action\\` | \\`alepha/server\\` | REST API endpoints |\n| \\`$route\\` | \\`alepha/server\\` | Low-level HTTP routes |\n| \\`$entity\\` | \\`alepha/orm\\` | Database tables |\n| \\`$repository\\` | \\`alepha/orm\\` | Type-safe data access |\n| \\`$queue\\` | \\`alepha/queue\\` | Background jobs |\n| \\`$scheduler\\` | \\`alepha/scheduler\\` | Cron tasks |\n| \\`$cache\\` | \\`alepha/cache\\` | Cached computations |\n| \\`$bucket\\` | \\`alepha/bucket\\` | File storage |\n| \\`$issuer\\` | \\`alepha/security\\` | JWT tokens |\n| \\`$command\\` | \\`alepha/command\\` | CLI commands |${\n react\n ? `\n| \\`$page\\` | \\`alepha/react/router\\` | React pages with SSR |\n| \\`$atom\\` | \\`alepha\\` | Global state |`\n : \"\"\n }\n\n## Testing\n\n\\`\\`\\`typescript\nimport { describe, it, expect } from \"vitest\";\nimport { Alepha } from \"alepha\";\n\ndescribe(\"UserService\", () => {\n it(\"should create user\", async () => {\n const alepha = Alepha.create().with(UserService);\n const service = alepha.inject(UserService);\n await alepha.start();\n\n const user = await service.create({ email: \"test@example.com\" });\n expect(user.email).toBe(\"test@example.com\");\n });\n\n it(\"should mock dependencies\", async () => {\n const alepha = Alepha.create()\n .with(OrderService)\n .with({ provide: PaymentGateway, use: MockPaymentGateway });\n\n const service = alepha.inject(OrderService);\n // PaymentGateway is now mocked\n });\n});\n\\`\\`\\`\n\n## Common Mistakes\n\n1. **DON'T use decorators** - Use primitives (\\`$action\\`, not \\`@Get()\\`)\n2. **DON'T use Zod** - Use TypeBox via \\`t\\` from Alepha\n3. **DON'T use Express patterns** - No \\`app.get()\\`, \\`router.use()\\`\n4. **DON'T inject across modules** - Use \\`$client\\` for cross-module calls\n5. **DON'T use async constructors** - Use \\`$hook({ on: \"start\" })\\`\n6. **DON'T instantiate manually** - Let DI container manage instances\n\n## After Code Changes\n\nAlways run:\n\\`\\`\\`bash\nalepha lint # Format and lint\nalepha typecheck # Type checking\nalepha test # Run tests (if applicable)\nalepha build # Build the project\n\\`\\`\\`\n\n## Documentation\n\n- Full docs: https://alepha.dev/llms.txt\n- Detailed docs: https://alepha.dev/llms-full.txt\n\n## Source Code Access\n\nFull framework source available at \\`node_modules/alepha/src/\\`.\n\n**IMPORTANT:** When answering questions about Alepha primitives, APIs, or internals:\n1. ALWAYS read the local source code first at \\`node_modules/alepha/src/\\` or \\`node_modules/@alepha/ui/src/\\` for UI-related questions\n2. Use \\`Glob\\` to find relevant files: \\`node_modules/alepha/src/**/primitives/$<name>.ts\\`\n3. Read the implementation AND the \\`.spec.ts\\` test files for usage examples\n4. Use external documentation as a fallback if source code is insufficient\n`.trim();\n};\n","export const apiAppSecurityTs = (opts: { adminEmail?: string } = {}) => {\n const adminEmailsValue = opts.adminEmail ? `[\"${opts.adminEmail}\"]` : \"[]\";\n\n return `\nimport { $realm } from \"alepha/api/users\";\n\nexport class AppSecurity {\n users = $realm({\n settings: {\n // Auto-promote these users to admin on login\n adminEmails: ${adminEmailsValue},\n adminUsernames: [],\n\n // Registration & login options\n registrationAllowed: true,\n emailEnabled: true,\n emailRequired: true,\n usernameEnabled: false,\n usernameRequired: false,\n phoneEnabled: false,\n phoneRequired: false,\n\n // Verification (requires notifications feature)\n verifyEmailRequired: false,\n verifyPhoneRequired: false,\n resetPasswordAllowed: false,\n },\n features: {\n // Enable additional features\n notifications: false,\n audits: false,\n apiKeys: false,\n jobs: false,\n files: false,\n parameters: false,\n },\n identities: {\n // Enable authentication providers\n credentials: true,\n // google: true,\n // github: true,\n },\n });\n}\n`.trim();\n};\n","export const apiHelloControllerTs = () =>\n `\nimport { t } from \"alepha\";\nimport { $action } from \"alepha/server\";\n\nexport class HelloController {\n hello = $action({\n path: \"/hello\",\n schema: {\n response: t.object({\n message: t.string(),\n }),\n },\n handler: () => ({\n message: \"Hello, Alepha!\",\n }),\n });\n}\n`.trim();\n","export interface ApiIndexTsOptions {\n appName?: string;\n auth?: boolean;\n}\n\nexport const apiIndexTs = (options: ApiIndexTsOptions = {}) => {\n const { appName = \"app\", auth = false } = options;\n\n const imports: string[] = ['import { $module } from \"alepha\";'];\n const services: string[] = [];\n\n if (auth) {\n imports.push('import { AppSecurity } from \"./AppSecurity.ts\";');\n services.push(\"AppSecurity\");\n }\n\n imports.push(\n 'import { HelloController } from \"./controllers/HelloController.ts\";',\n );\n services.push(\"HelloController\");\n\n return `\n${imports.join(\"\\n\")}\n\nexport const ApiModule = $module({\n name: \"${appName}.api\",\n services: [${services.join(\", \")}],\n});\n`.trim();\n};\n","export const biomeJson = () =>\n `\n{\n \"$schema\": \"https://biomejs.dev/schemas/latest/schema.json\",\n \"vcs\": {\n \"enabled\": true,\n \"clientKind\": \"git\"\n },\n \"files\": {\n \"ignoreUnknown\": true,\n \"includes\": [\"**\", \"!node_modules\", \"!dist\"]\n },\n \"formatter\": {\n \"enabled\": true,\n \"useEditorconfig\": true\n },\n \"linter\": {\n \"enabled\": true,\n \"rules\": {\n \"recommended\": true\n },\n \"domains\": {\n \"react\": \"recommended\"\n }\n },\n \"assist\": {\n \"actions\": {\n \"source\": {\n \"organizeImports\": \"on\"\n }\n }\n }\n}\n`.trim();\n","export const dummySpecTs = () =>\n `\nimport { test, expect } from \"vitest\";\n\ntest(\"dummy test\", () => {\n expect(1 + 1).toBe(2);\n});\n`.trim();\n","export const editorconfig = () =>\n `\n# https://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = space\nindent_size = 2\n`.trim();\n","export const gitignore = () =>\n `\n# Dependencies\nnode_modules/\n\n# Build outputs\ndist/\n.vite/\n\n# Environment files\n.env\n.env.*\n!.env.example\n\n# IDE\n.idea/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nlogs/\n\n# Test coverage\ncoverage/\n\n# Yarn\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/sdks\n!.yarn/versions\n.pnp.*\n`.trim();\n","export const mainBrowserTs = () =>\n `\nimport { Alepha, run } from \"alepha\";\nimport { WebModule } from \"./web/index.ts\";\n\nconst alepha = Alepha.create();\n\nalepha.with(WebModule);\n\nrun(alepha);\n`.trim();\n","export const mainCss = () => {\n return `@import \"@alepha/ui/styles\";`;\n};\n","export interface MainServerTsOptions {\n api?: boolean;\n react?: boolean;\n}\n\nexport const mainServerTs = (options: MainServerTsOptions = {}) => {\n const { api = false, react = false } = options;\n\n const imports: string[] = [];\n const withs: string[] = [];\n\n if (api) {\n imports.push(`import { ApiModule } from \"./api/index.ts\";`);\n withs.push(`alepha.with(ApiModule);`);\n }\n\n if (react) {\n imports.push(`import { WebModule } from \"./web/index.ts\";`);\n withs.push(`alepha.with(WebModule);`);\n }\n\n const importsBlock = imports.length > 0 ? `${imports.join(\"\\n\")}\\n` : \"\";\n const withsBlock = withs.length > 0 ? `\\n${withs.join(\"\\n\")}` : \"\";\n\n return `\nimport { Alepha, run } from \"alepha\";\n${importsBlock}\nconst alepha = Alepha.create();\n${withsBlock}\n\nrun(alepha);\n`.trim();\n};\n","export const tsconfigJson = () =>\n `\n{\n \"extends\": \"alepha/tsconfig.base\"\n}\n`.trim();\n","export const webAppRouterTs = (options: {\n api?: boolean;\n ui?: boolean;\n auth?: boolean;\n admin?: boolean;\n}) => {\n const imports: string[] = [];\n const classMembers: string[] = [];\n\n // UI import and setup\n if (options.ui) {\n imports.push('import { $ui } from \"@alepha/ui\";');\n }\n\n // Auth import\n if (options.auth) {\n imports.push('import { $uiAuth } from \"@alepha/ui/auth\";');\n }\n\n // Admin import\n if (options.admin) {\n imports.push('import { $uiAdmin } from \"@alepha/ui/admin\";');\n }\n\n // Page import\n imports.push('import { $page } from \"alepha/react/router\";');\n\n // API imports (only if api flag is set)\n if (options.api) {\n imports.push('import { $client } from \"alepha/server/links\";');\n imports.push(\n 'import type { HelloController } from \"../api/controllers/HelloController.ts\";',\n );\n classMembers.push(\" api = $client<HelloController>();\");\n }\n\n // UI layout setup\n if (options.ui) {\n classMembers.push(\" ui = $ui();\");\n\n if (options.auth) {\n classMembers.push(\" uiAuth = $uiAuth();\");\n }\n\n if (options.admin) {\n classMembers.push(\" uiAdmin = $uiAdmin();\");\n }\n\n classMembers.push(` layout = $page({\n parent: this.ui.root,\n children: () => [this.home],\n });`);\n }\n\n // Home page - with or without loader\n if (options.api) {\n classMembers.push(` home = $page({\n path: \"/\",\n lazy: () => import(\"./components/Home.tsx\"),\n loader: () => this.api.hello(),\n });`);\n } else {\n classMembers.push(` home = $page({\n path: \"/\",\n lazy: () => import(\"./components/Home.tsx\"),\n });`);\n }\n\n return `${imports.join(\"\\n\")}\n\nexport class AppRouter {\n${classMembers.join(\"\\n\\n\")}\n}`;\n};\n","export const webHomeComponentTsx = () => {\n return `import { GettingStarted } from \"alepha/react/intro\";\n\nconst Home = () => {\n return <GettingStarted />;\n};\n\nexport default Home;\n`;\n};\n","export interface WebIndexTsOptions {\n appName?: string;\n}\n\nexport const webIndexTs = (options: WebIndexTsOptions = {}) => {\n const { appName = \"app\" } = options;\n return `\nimport { $module } from \"alepha\";\nimport { AppRouter } from \"./AppRouter.ts\";\n\nexport const WebModule = $module({\n name: \"${appName}.web\",\n services: [AppRouter],\n});\n`.trim();\n};\n","import { basename, dirname } from \"node:path\";\nimport { $inject } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport {\n type AgentMdOptions,\n type AgentMdType,\n agentMd,\n} from \"../templates/agentMd.ts\";\nimport { apiAppSecurityTs } from \"../templates/apiAppSecurityTs.ts\";\nimport { apiHelloControllerTs } from \"../templates/apiHelloControllerTs.ts\";\nimport { apiIndexTs } from \"../templates/apiIndexTs.ts\";\nimport { biomeJson } from \"../templates/biomeJson.ts\";\nimport { dummySpecTs } from \"../templates/dummySpecTs.ts\";\nimport { editorconfig } from \"../templates/editorconfig.ts\";\nimport { gitignore } from \"../templates/gitignore.ts\";\nimport { mainBrowserTs } from \"../templates/mainBrowserTs.ts\";\nimport { mainCss } from \"../templates/mainCss.ts\";\nimport { mainServerTs } from \"../templates/mainServerTs.ts\";\nimport { tsconfigJson } from \"../templates/tsconfigJson.ts\";\nimport { webAppRouterTs } from \"../templates/webAppRouterTs.ts\";\nimport { webHomeComponentTsx } from \"../templates/webHomeComponentTsx.ts\";\nimport { webIndexTs } from \"../templates/webIndexTs.ts\";\nimport { AlephaCliUtils } from \"./AlephaCliUtils.ts\";\nimport {\n type DependencyModes,\n PackageManagerUtils,\n} from \"./PackageManagerUtils.ts\";\n\n/**\n * Service for scaffolding new Alepha projects.\n *\n * Handles creation of:\n * - Project structure (src/api, src/web)\n * - Configuration files (tsconfig, biome, editorconfig)\n * - Entry points (main.server.ts, main.browser.ts)\n * - Example code (HelloController, Home component)\n */\nexport class ProjectScaffolder {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly utils = $inject(AlephaCliUtils);\n\n /**\n * Get the app name from the directory name.\n *\n * Converts the directory name to a valid module name:\n * - Converts to lowercase\n * - Replaces spaces, dashes, underscores with nothing\n * - Falls back to \"app\" if empty\n */\n public getAppName(root: string): string {\n const dirName = basename(root);\n const appName = dirName.toLowerCase().replace(/[\\s\\-_.\\d]/g, \"\");\n return appName || \"app\";\n }\n\n /**\n * Ensure all configuration files exist.\n */\n public async ensureConfig(\n root: string,\n opts: {\n force?: boolean;\n /**\n * Check workspace root for existing config files.\n */\n checkWorkspace?: boolean;\n packageJson?: boolean | DependencyModes;\n tsconfigJson?: boolean;\n biomeJson?: boolean;\n editorconfig?: boolean;\n agentMd?: false | (AgentMdOptions & { type: AgentMdType });\n },\n ): Promise<void> {\n const tasks: Promise<void>[] = [];\n const force = opts.force ?? false;\n const checkWorkspace = opts.checkWorkspace ?? false;\n\n if (opts.packageJson) {\n tasks.push(\n this.pm\n .ensurePackageJson(\n root,\n typeof opts.packageJson === \"boolean\" ? {} : opts.packageJson,\n )\n .then(() => {}),\n );\n }\n if (opts.tsconfigJson) {\n tasks.push(this.ensureTsConfig(root, { force }));\n }\n if (opts.biomeJson) {\n tasks.push(this.ensureBiomeConfig(root, { force, checkWorkspace }));\n }\n if (opts.editorconfig) {\n tasks.push(this.ensureEditorConfig(root, { force, checkWorkspace }));\n }\n if (opts.agentMd) {\n tasks.push(this.ensureAgentMd(root, { ...opts.agentMd, force }));\n }\n\n await Promise.all(tasks);\n }\n\n // ===========================================\n // Config Files\n // ===========================================\n\n public async ensureTsConfig(\n root: string,\n opts: { force?: boolean } = {},\n ): Promise<void> {\n // Check if tsconfig.json exists in current or parent directories\n if (!opts.force && (await this.existsInParents(root, \"tsconfig.json\"))) {\n return;\n }\n await this.fs.writeFile(\n this.fs.join(root, \"tsconfig.json\"),\n tsconfigJson(),\n );\n }\n\n public async ensureBiomeConfig(\n root: string,\n opts: { force?: boolean; checkWorkspace?: boolean } = {},\n ): Promise<void> {\n if (\n !opts.force &&\n opts.checkWorkspace &&\n (await this.existsInParents(root, \"biome.json\"))\n ) {\n return;\n }\n await this.ensureFile(root, \"biome.json\", biomeJson(), opts.force);\n }\n\n public async ensureEditorConfig(\n root: string,\n opts: { force?: boolean; checkWorkspace?: boolean } = {},\n ): Promise<void> {\n if (\n !opts.force &&\n opts.checkWorkspace &&\n (await this.existsInParents(root, \".editorconfig\"))\n ) {\n return;\n }\n await this.ensureFile(root, \".editorconfig\", editorconfig(), opts.force);\n }\n\n /**\n * Ensure git repository is initialized with .gitignore.\n *\n * @returns true if git was initialized, false if already exists or git unavailable\n */\n public async ensureGitRepo(\n root: string,\n opts: { force?: boolean } = {},\n ): Promise<boolean> {\n const gitDir = this.fs.join(root, \".git\");\n\n // Skip if .git already exists\n if (!opts.force && (await this.fs.exists(gitDir))) {\n return false;\n }\n\n // Check if git is available\n const hasGit = await this.utils.isInstalledAsync(\"git\");\n if (!hasGit) {\n return false;\n }\n\n // Initialize git repository\n await this.utils.exec(\"git init\", { root, global: true });\n\n // Write .gitignore\n await this.ensureFile(root, \".gitignore\", gitignore(), opts.force);\n\n return true;\n }\n\n public async ensureAgentMd(\n root: string,\n options: AgentMdOptions & { type: AgentMdType; force?: boolean },\n ): Promise<void> {\n const filename = options.type === \"claude\" ? \"CLAUDE.md\" : \"AGENTS.md\";\n await this.ensureFile(\n root,\n filename,\n agentMd(options.type, options),\n options.force,\n );\n }\n\n // ===========================================\n // Minimal Project Structure\n // ===========================================\n\n /**\n * Ensure src/main.server.ts exists with correct module imports.\n */\n public async ensureMainServerTs(\n root: string,\n opts: { api?: boolean; react?: boolean; force?: boolean } = {},\n ): Promise<void> {\n const srcDir = this.fs.join(root, \"src\");\n await this.fs.mkdir(srcDir, { recursive: true });\n await this.ensureFile(\n srcDir,\n \"main.server.ts\",\n mainServerTs({ api: opts.api, react: opts.react }),\n opts.force,\n );\n }\n\n // ===========================================\n // API Project Structure\n // ===========================================\n\n /**\n * Ensure API module structure exists.\n *\n * Creates:\n * - src/api/index.ts (API module)\n * - src/api/controllers/HelloController.ts (example controller)\n */\n public async ensureApiProject(\n root: string,\n opts: { auth?: boolean; adminEmail?: string; force?: boolean } = {},\n ): Promise<void> {\n const appName = this.getAppName(root);\n\n // Create directories\n await this.fs.mkdir(this.fs.join(root, \"src/api/controllers\"), {\n recursive: true,\n });\n\n // Create files\n await this.ensureFile(\n root,\n \"src/api/index.ts\",\n apiIndexTs({ appName, auth: opts.auth }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/api/controllers/HelloController.ts\",\n apiHelloControllerTs(),\n opts.force,\n );\n\n // Create AppSecurity if auth is enabled\n if (opts.auth) {\n await this.ensureFile(\n root,\n \"src/api/AppSecurity.ts\",\n apiAppSecurityTs({ adminEmail: opts.adminEmail }),\n opts.force,\n );\n }\n }\n\n // ===========================================\n // Web Project Structure\n // ===========================================\n\n /**\n * Ensure web/React project structure exists.\n *\n * Creates:\n * - src/main.browser.ts\n * - src/main.css\n * - src/web/index.ts, src/web/AppRouter.ts, src/web/components/Home.tsx\n */\n public async ensureWebProject(\n root: string,\n opts: {\n api?: boolean;\n ui?: boolean;\n auth?: boolean;\n admin?: boolean;\n force?: boolean;\n } = {},\n ): Promise<void> {\n const appName = this.getAppName(root);\n\n // Create directories\n await this.fs.mkdir(this.fs.join(root, \"src/web/components\"), {\n recursive: true,\n });\n\n // src/main.css\n await this.ensureFile(root, \"src/main.css\", mainCss(), opts.force);\n\n // Web structure\n await this.ensureFile(\n root,\n \"src/web/index.ts\",\n webIndexTs({ appName }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/web/AppRouter.ts\",\n webAppRouterTs({\n api: opts.api,\n ui: opts.ui,\n auth: opts.auth,\n admin: opts.admin,\n }),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/web/components/Home.tsx\",\n webHomeComponentTsx(),\n opts.force,\n );\n await this.ensureFile(\n root,\n \"src/main.browser.ts\",\n mainBrowserTs(),\n opts.force,\n );\n }\n\n // ===========================================\n // Test Directory\n // ===========================================\n\n /**\n * Ensure test directory exists with a dummy test file.\n */\n public async ensureTestDir(root: string): Promise<void> {\n const testDir = this.fs.join(root, \"test\");\n const dummyPath = this.fs.join(testDir, \"dummy.spec.ts\");\n\n if (!(await this.fs.exists(testDir))) {\n await this.fs.mkdir(testDir, { recursive: true });\n await this.fs.writeFile(dummyPath, dummySpecTs());\n return;\n }\n\n const files = await this.fs.ls(testDir);\n if (files.length === 0) {\n await this.fs.writeFile(dummyPath, dummySpecTs());\n }\n }\n\n // ===========================================\n // Helpers\n // ===========================================\n\n /**\n * Write a file, optionally overriding if it exists.\n */\n protected async ensureFile(\n root: string,\n relativePath: string,\n content: string,\n force?: boolean,\n ): Promise<void> {\n const fullPath = this.fs.join(root, relativePath);\n if (force || !(await this.fs.exists(fullPath))) {\n await this.fs.writeFile(fullPath, content);\n }\n }\n\n /**\n * Check if a file exists in the given directory or any parent directory.\n */\n protected async existsInParents(\n root: string,\n filename: string,\n ): Promise<boolean> {\n let current = root;\n while (true) {\n if (await this.fs.exists(this.fs.join(current, filename))) {\n return true;\n }\n const parent = dirname(current);\n if (parent === current) {\n // Reached filesystem root\n return false;\n }\n current = parent;\n }\n }\n}\n","import { $inject, $use, type Alepha, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport {\n buildClient,\n buildServer,\n copyAssets,\n generateCloudflare,\n generateDocker,\n generateSitemap,\n generateVercel,\n prerenderPages,\n} from \"alepha/vite\";\nimport {\n type BuildRuntime,\n type BuildTarget,\n buildOptions,\n} from \"../atoms/buildOptions.ts\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\nimport { ViteBuildProvider } from \"../providers/ViteBuildProvider.ts\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class BuildCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n protected readonly boot = $inject(AppEntryProvider);\n protected readonly viteBuildProvider = $inject(ViteBuildProvider);\n protected readonly options = $use(buildOptions);\n\n /**\n * Resolve the effective runtime based on target and explicit runtime flag.\n *\n * Some targets force a specific runtime:\n * - `cloudflare` always uses `workerd`\n * - `vercel` always uses `node`\n * - `docker` and bare deployments respect the runtime flag\n *\n * @throws {AlephaError} If an incompatible runtime is specified for a target\n */\n protected resolveRuntime(\n target: BuildTarget | undefined,\n runtime: BuildRuntime | undefined,\n ): BuildRuntime {\n if (target === \"cloudflare\") {\n if (runtime && runtime !== \"workerd\") {\n throw new AlephaError(\n `Target 'cloudflare' requires 'workerd' runtime, got '${runtime}'`,\n );\n }\n return \"workerd\";\n }\n\n if (target === \"vercel\") {\n if (runtime && runtime !== \"node\") {\n throw new AlephaError(\n `Target 'vercel' requires 'node' runtime, got '${runtime}'`,\n );\n }\n return \"node\";\n }\n\n return runtime ?? \"node\";\n }\n\n public readonly build = $command({\n name: \"build\",\n mode: \"production\",\n description: \"Build the project for production\",\n flags: t.object({\n stats: t.optional(\n t.boolean({\n description: \"Generate build stats report\",\n }),\n ),\n target: t.optional(\n t.enum([\"bare\", \"docker\", \"vercel\", \"cloudflare\"], {\n aliases: [\"t\"],\n description: \"Deployment target\",\n }),\n ),\n runtime: t.optional(\n t.enum([\"node\", \"bun\", \"workerd\"], {\n aliases: [\"r\"],\n description: \"JavaScript runtime\",\n }),\n ),\n image: t.optional(\n t.union([t.boolean(), t.text()], {\n aliases: [\"i\"],\n description:\n \"Build Docker image. Use -i for latest, -i=<version> for specific version\",\n }),\n ),\n sitemap: t.optional(\n t.text({\n description: \"Generate sitemap.xml with base URL\",\n }),\n ),\n }),\n handler: async ({ flags, run, root }) => {\n process.env.NODE_ENV = \"production\";\n\n if (await this.pm.hasExpo(root)) {\n // will come soon\n return;\n }\n\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n });\n\n const entry = await this.boot.getAppEntry(root);\n this.log.trace(\"Entry file found\", { entry });\n\n const distDir = \"dist\";\n const publicDir = \"public\";\n\n await run.rm(\"dist\", { alias: \"clean dist\" });\n\n const options = this.options;\n await this.utils.loadEnv(root, [\".env\", \".env.production\"]);\n\n // Resolve target and runtime\n const target = flags.target ?? options.target;\n const runtime = this.resolveRuntime(\n target,\n flags.runtime ?? options.runtime,\n );\n\n // Validate --image requires --target=docker\n if (flags.image && target !== \"docker\") {\n throw new AlephaError(\n `Flag '--image' requires '--target=docker', got '${target ?? \"bare\"}'`,\n );\n }\n\n this.log.trace(\"Build configuration\", { target, runtime });\n\n const stats = flags.stats ?? options.stats ?? false;\n let template = \"\";\n let hasClient = false;\n let alepha: Alepha | undefined;\n\n await run({\n name: \"analyze app\",\n handler: async () => {\n alepha = await this.viteBuildProvider.init({ entry });\n hasClient = this.viteBuildProvider.hasClient();\n if (hasClient) {\n template = this.viteBuildProvider.generateIndexHtml();\n }\n },\n });\n\n if (!alepha) {\n throw new AlephaError(\"Alepha instance not found\");\n }\n\n // Build client (precompress always enabled)\n if (hasClient) {\n // TODO: find a way to avoid writing index.html to disk\n const indexHtmlPath = this.fs.join(root, \"index.html\");\n await this.fs.writeFile(indexHtmlPath, template);\n try {\n await run({\n name: \"vite build client\",\n handler: () =>\n buildClient({\n silent: true,\n dist: `${distDir}/${publicDir}`,\n stats,\n precompress: true,\n }),\n });\n } finally {\n await this.fs.rm(indexHtmlPath);\n }\n }\n\n // Build server\n await run({\n name: \"vite build server\",\n handler: async () => {\n if (!alepha) {\n throw new AlephaError(\"Alepha instance not found\");\n }\n\n const clientIndexPath = `${distDir}/${publicDir}/index.html`;\n const clientBuilt = await this.fs.exists(clientIndexPath);\n\n // Set export conditions based on runtime\n const conditions: string[] = [];\n if (runtime === \"bun\") {\n conditions.push(\"bun\");\n } else if (runtime === \"workerd\") {\n conditions.push(\"workerd\");\n }\n\n await buildServer({\n silent: true,\n entry: entry.server,\n distDir,\n clientDir: clientBuilt ? publicDir : undefined,\n stats,\n conditions,\n alepha,\n });\n\n // Server will handle index.html if both client & server are built\n if (clientBuilt) {\n await this.fs.rm(clientIndexPath);\n }\n },\n });\n\n // Copy assets\n await copyAssets({\n alepha,\n root,\n entry: `${distDir}/index.js`,\n distDir,\n run,\n });\n\n if (hasClient) {\n // Generate sitemap\n const sitemapHostname = flags.sitemap ?? options.sitemap?.hostname;\n if (sitemapHostname) {\n await generateSitemap({\n alepha,\n baseUrl: sitemapHostname,\n output: `${distDir}/${publicDir}/sitemap.xml`,\n run,\n });\n }\n\n // Pre-render static pages (always enabled)\n await prerenderPages({\n alepha,\n dist: `${distDir}/${publicDir}`,\n compress: true,\n run,\n });\n }\n\n // Generate deployment configuration based on target\n if (target === \"vercel\") {\n await run({\n name: \"add Vercel config\",\n handler: () =>\n generateVercel({\n distDir,\n clientDir: publicDir,\n config: options.vercel,\n }),\n });\n }\n\n if (target === \"cloudflare\") {\n await run({\n name: \"add Cloudflare config\",\n handler: () =>\n generateCloudflare({\n distDir,\n config: options.cloudflare?.config,\n alepha: alepha!,\n }),\n });\n }\n\n if (target === \"docker\") {\n // Auto-configure Docker based on runtime\n const dockerFrom =\n options.docker?.from ??\n (runtime === \"bun\" ? \"oven/bun:alpine\" : \"node:24-alpine\");\n const dockerCommand =\n options.docker?.command ?? (runtime === \"bun\" ? \"bun\" : \"node\");\n\n await run({\n name: \"add Docker config\",\n handler: () =>\n generateDocker({\n distDir,\n image: dockerFrom,\n command: dockerCommand,\n }),\n });\n\n // Build Docker image if --image flag is provided\n if (flags.image) {\n const imageConfig = options.docker?.image;\n const flagValue =\n typeof flags.image === \"string\" ? flags.image : null;\n\n let imageTag: string;\n let version: string;\n\n if (!flagValue) {\n // -i (no value) → use config tag:latest\n if (!imageConfig?.tag) {\n throw new AlephaError(\n \"Flag '--image' requires 'build.docker.image.tag' in config\",\n );\n }\n version = \"latest\";\n imageTag = `${imageConfig.tag}:${version}`;\n } else if (flagValue.startsWith(\":\")) {\n // -i=:1.3.4 → version only, prepend config tag\n if (!imageConfig?.tag) {\n throw new AlephaError(\n \"Flag '--image=:version' requires 'build.docker.image.tag' in config\",\n );\n }\n version = flagValue.slice(1); // remove leading \":\"\n imageTag = `${imageConfig.tag}:${version}`;\n } else if (flagValue.includes(\":\")) {\n // -i=toto:1.3.4 → full image with version\n imageTag = flagValue;\n version = flagValue.split(\":\")[1];\n } else {\n // -i=toto → image name without version → add :latest\n imageTag = `${flagValue}:latest`;\n version = \"latest\";\n }\n\n const args: string[] = [];\n\n // Add custom args\n if (imageConfig?.args) {\n args.push(imageConfig.args);\n }\n\n // Add OCI labels if enabled\n if (imageConfig?.oci) {\n const revision = await this.utils.getGitRevision();\n const created = new Date().toISOString();\n\n args.push(\n `--label \"org.opencontainers.image.revision=${revision}\"`,\n );\n args.push(`--label \"org.opencontainers.image.created=${created}\"`);\n args.push(`--label \"org.opencontainers.image.version=${version}\"`);\n }\n\n const argsStr = args.length > 0 ? `${args.join(\" \")} ` : \"\";\n const dockerCmd = `docker build ${argsStr}-t ${imageTag} ${distDir}`;\n\n await run(dockerCmd, {\n alias: `docker build ${imageTag}`,\n });\n }\n }\n },\n });\n}\n","import { $command } from \"alepha/command\";\n\nexport class CleanCommand {\n /**\n * Clean the project, removing the \"dist\" directory\n */\n public readonly clean = $command({\n name: \"clean\",\n description: \"Clean the project\",\n handler: async ({ run }) => {\n await run.rm(\"./dist\");\n },\n });\n}\n","import { $inject, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport type {\n DatabaseProvider,\n DrizzleKitProvider,\n RepositoryProvider,\n} from \"alepha/orm\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\n\nconst drizzleCommandFlags = t.object({\n provider: t.optional(\n t.text({\n description:\n \"Database provider name to target (e.g., 'postgres', 'sqlite')\",\n }),\n ),\n mode: t.optional(\n t.text({\n description:\n \"Environment variable file(s) to load (e.g., 'production' to load .env.production) https://vite.dev/guide/env-and-mode\",\n }),\n ),\n});\n\nexport class DbCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly entryProvider = $inject(AppEntryProvider);\n\n /**\n * Check if database migrations are up to date.\n */\n protected readonly check = $command({\n name: \"check-migrations\",\n description: \"Check if database migration files are up to date\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ args, root }) => {\n const rootDir = root;\n this.log.debug(`Using project root: ${rootDir}`);\n\n const entry = await this.entryProvider.getAppEntry(root);\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n mode: \"development\",\n entry,\n });\n\n const repositoryProvider =\n alepha.inject<RepositoryProvider>(\"RepositoryProvider\");\n const drizzleKitProvider =\n alepha.inject<DrizzleKitProvider>(\"DrizzleKitProvider\");\n const accepted = new Set<string>([]);\n\n for (const primitive of repositoryProvider.getRepositories()) {\n const provider = primitive.provider;\n const providerName = provider.name;\n if (accepted.has(providerName)) {\n continue;\n }\n\n accepted.add(providerName);\n\n const migrationDir = this.fs.join(rootDir, \"migrations\", providerName);\n\n const journalBuffer = await this.fs\n .readFile(`${migrationDir}/meta/_journal.json`)\n .catch(() => null);\n\n if (!journalBuffer) {\n this.log.info(\"No migration journal found.\");\n return;\n }\n\n const journal = JSON.parse(journalBuffer.toString(\"utf-8\"));\n const lastMigration = journal.entries[journal.entries.length - 1];\n const snapshotBuffer = await this.fs.readFile(\n `${migrationDir}/meta/${String(lastMigration.idx).padStart(4, \"0\")}_snapshot.json`,\n );\n const lastSnapshot = JSON.parse(snapshotBuffer.toString(\"utf-8\"));\n\n const models = drizzleKitProvider.getModels(provider);\n const kit = drizzleKitProvider.importDrizzleKit();\n const now = kit.generateDrizzleJson(models, lastSnapshot.id);\n\n const migrationStatements = await new Promise<Array<any>>((resolve) => {\n (async () => {\n const timer = setTimeout(() => {\n resolve([{ message: \"Migration generation timed out.\" }]);\n }, 5000);\n const statements = await kit.generateMigration(lastSnapshot, now);\n clearTimeout(timer);\n resolve(statements);\n })();\n });\n\n if (migrationStatements.length === 0) {\n this.log.info(\"No changes detected.\");\n return;\n }\n\n this.log.info(\"\");\n this.log.info(\"Detected migration statements:\");\n this.log.info(\"\");\n for (const stmt of migrationStatements) {\n this.log.info(stmt);\n }\n this.log.info(\"\");\n\n this.log.info(\n `At least ${migrationStatements.length} change(s) detected.`,\n );\n this.log.info(\n \"Please, run 'alepha db:generate' to update the migration files.\",\n );\n this.log.info(\"\");\n\n throw new AlephaError(\"Database migrations are not up to date.\");\n }\n },\n });\n\n /**\n * Generate database migration files\n */\n protected readonly generate = $command({\n name: \"generate\",\n description: \"Generate migration files based on current database schema\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: t.extend(drizzleCommandFlags, {\n custom: t.optional(\n t.text({\n description:\n \"Custom migration name for drizzle-kit generate --custom\",\n }),\n ),\n }),\n handler: async ({ args, flags, root }) => {\n const commandFlags = flags.custom\n ? `--custom=${flags.custom}`\n : undefined;\n\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"generate\",\n commandFlags,\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Generate '${providerName}' migrations (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Push database schema changes directly to the database\n */\n protected readonly push = $command({\n name: \"push\",\n description: \"Push database schema changes directly to the database\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ root, args, flags }) => {\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"push\",\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Push '${providerName}' schema (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Apply pending database migrations\n */\n protected readonly migrate = $command({\n name: \"migrate\",\n description: \"Apply pending database migrations\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ root, args, flags }) => {\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"migrate\",\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Migrate '${providerName}' database (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Launch Drizzle Studio database browser\n */\n protected readonly studio = $command({\n name: \"studio\",\n description: \"Launch Drizzle Studio database browser\",\n args: t.optional(\n t.text({\n title: \"path\",\n description: \"Path to the Alepha server entry file\",\n }),\n ),\n flags: drizzleCommandFlags,\n handler: async ({ root, args, flags }) => {\n await this.runDrizzleKitCommand({\n root,\n args,\n command: \"studio\",\n provider: flags.provider,\n env: flags.mode,\n logMessage: (providerName, dialect) =>\n `Launch Studio for '${providerName}' (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Parent command for database operations.\n */\n public readonly db = $command({\n name: \"db\",\n description: \"Database management commands\",\n children: [this.check, this.generate, this.push, this.migrate, this.studio],\n handler: async ({ help }) => {\n help();\n },\n });\n\n /**\n * Run a drizzle-kit command for all database providers in an Alepha instance.\n */\n public async runDrizzleKitCommand(options: {\n root: string;\n args?: string;\n command: string;\n commandFlags?: string;\n provider?: string;\n logMessage: (providerName: string, dialect: string) => string;\n env?: string;\n }): Promise<void> {\n const rootDir = options.root;\n\n const envFiles = [\".env\"];\n if (options.env) {\n envFiles.push(`.env.${options.env}`);\n }\n\n await this.utils.loadEnv(rootDir, envFiles);\n\n this.log.debug(`Using project root: ${rootDir}`);\n\n const entry = await this.entryProvider.getAppEntry(rootDir);\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n mode: \"development\",\n entry,\n });\n\n const drizzleKitProvider =\n alepha.inject<DrizzleKitProvider>(\"DrizzleKitProvider\");\n const repositoryProvider =\n alepha.inject<RepositoryProvider>(\"RepositoryProvider\");\n const accepted = new Set<string>([]);\n\n for (const primitive of repositoryProvider.getRepositories()) {\n const provider = primitive.provider;\n const providerName = provider.name;\n const dialect = provider.dialect;\n\n if (providerName === \"\") {\n continue;\n }\n\n if (accepted.has(providerName)) {\n continue;\n }\n accepted.add(providerName);\n\n // Skip if provider filter is set and doesn't match\n if (options.provider && options.provider !== providerName) {\n this.log.debug(\n `Skipping provider '${providerName}' (filter: ${options.provider})`,\n );\n continue;\n }\n\n this.log.info(\"\");\n this.log.info(options.logMessage(providerName, dialect));\n\n if (dialect === \"sqlite\") {\n await this.pm.ensureDependency(options.root, \"better-sqlite3\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n }\n\n const drizzleConfigJsPath = await this.prepareDrizzleConfig({\n kit: drizzleKitProvider,\n provider,\n providerName,\n providerUrl: provider.url,\n providerDriver: provider.driver,\n dialect,\n entry: this.fs.join(rootDir, entry.server),\n rootDir,\n });\n\n const flags = options.commandFlags ? ` ${options.commandFlags}` : \"\";\n await this.utils.exec(\n `drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`,\n {\n env: {\n NODE_OPTIONS: [process.env.NODE_OPTIONS, \"--import tsx\"]\n .filter(Boolean)\n .join(\" \"),\n },\n },\n );\n }\n }\n\n /**\n * Prepare Drizzle configuration files for a database provider.\n */\n public async prepareDrizzleConfig(options: {\n kit: any;\n provider: DatabaseProvider;\n providerName: string;\n providerUrl: string;\n providerDriver: string;\n dialect: string;\n entry: string;\n rootDir: string;\n }): Promise<string> {\n const models = Object.keys(options.kit.getModels(options.provider));\n const entitiesJs = this.utils.generateEntitiesJs(\n options.entry,\n options.providerName,\n models,\n );\n\n const entitiesJsPath = await this.utils.writeConfigFile(\n \"entities.js\",\n entitiesJs,\n options.rootDir,\n );\n\n const config: Record<string, any> = {\n schema: entitiesJsPath,\n out: `./migrations/${options.providerName}`,\n dialect: options.dialect,\n dbCredentials: {\n url: options.providerUrl,\n },\n };\n\n if (options.provider.schema) {\n config.schemaFilter = options.provider.schema;\n }\n\n if (options.providerDriver === \"d1\") {\n config.driver = \"d1-http\";\n }\n\n if (options.providerDriver === \"pglite\") {\n config.driver = \"pglite\";\n }\n\n if (options.dialect === \"sqlite\") {\n if (options.providerDriver === \"d1\") {\n const token = process.env.CLOUDFLARE_API_TOKEN;\n if (!token) {\n throw new AlephaError(\n \"CLOUDFLARE_API_TOKEN environment variable is not set. https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit\",\n );\n }\n\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n if (!accountId) {\n throw new AlephaError(\n \"CLOUDFLARE_ACCOUNT_ID environment variable is not set. https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit\",\n );\n }\n\n const url = options.providerUrl;\n if (!url.startsWith(\"d1://\")) {\n throw new AlephaError(\"D1 provider URL must start with 'd1://'.\");\n }\n\n const [, databaseId] = url\n .replace(\"d1://\", \"\")\n .replace(\"d1:\", \"\")\n .split(\":\");\n\n if (!databaseId) {\n throw new AlephaError(\n \"Database ID is missing in the D1 provider URL. Cloudflare D1 URL format: d1://<database_name>:<database_id>\",\n );\n }\n\n config.dbCredentials = {\n accountId,\n databaseId,\n token,\n };\n } else {\n let url = options.providerUrl;\n url = url.replace(\"sqlite://\", \"\").replace(\"file://\", \"\");\n url = this.fs.join(options.rootDir, url);\n\n config.dbCredentials = {\n url,\n };\n }\n }\n\n const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;\n\n return await this.utils.writeConfigFile(\n \"drizzle.config.js\",\n drizzleConfigJs,\n options.rootDir,\n );\n }\n}\n","import { $inject, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\n\nexport class DeployCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n\n /**\n * Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)\n *\n * Deploy command can be overridden by creating a alepha.config.ts in the project root:\n *\n * ```ts\n * import { defineConfig } from \"alepha/cli\";\n *\n * export default defineConfig({\n * commands: {\n * deploy: {\n * handler: async ({ root, mode, flags }) => {\n * // Custom deployment logic here\n * },\n * },\n * },\n * });\n * ```\n */\n public readonly deploy = $command({\n name: \"deploy\",\n description:\n \"Deploy the project to a hosting platform (e.g., Vercel, Cloudflare, Surge)\",\n mode: true,\n flags: t.object({\n build: t.boolean({\n description: \"Build the project before deployment\",\n default: false,\n }),\n migrate: t.boolean({\n description:\n \"Run database migrations before deployment (if applicable)\",\n default: false,\n }),\n }),\n env: t.object({\n VERCEL_TOKEN: t.optional(\n t.text({\n description: \"Vercel API token (e.g., xxxxxxxxxxxxxxxxxxxx)\",\n }),\n ),\n VERCEL_ORG_ID: t.optional(\n t.text({\n description: \"Vercel organization ID (e.g., team_abc123...)\",\n }),\n ),\n VERCEL_PROJECT_ID: t.optional(\n t.text({ description: \"Vercel project ID (e.g., prj_abc123...)\" }),\n ),\n CLOUDFLARE_API_TOKEN: t.optional(\n t.text({\n description: \"Cloudflare API token (e.g., xxxx-xxxx-xxxx-xxxx)\",\n }),\n ),\n CLOUDFLARE_ACCOUNT_ID: t.optional(\n t.text({\n description: \"Cloudflare account ID (e.g., abc123def456...)\",\n }),\n ),\n }),\n handler: async ({ root, mode, flags }) => {\n if (flags.build) {\n await this.utils.exec(\"alepha build\");\n }\n\n // Vercel deployment\n if (await this.utils.exists(root, \"dist/vercel.json\")) {\n if (flags.migrate) {\n this.log.debug(\"Running database migrations before deployment...\");\n await this.utils.exec(`alepha db migrate --mode=${mode}`);\n }\n await this.pm.ensureDependency(root, \"vercel\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n const command =\n `vercel . --cwd=dist ${mode === \"production\" ? \"--prod\" : \"\"}`.trim();\n this.log.debug(`Deploying to Vercel with command: ${command}`);\n await this.utils.exec(command);\n return;\n }\n\n // Cloudflare deployment\n if (await this.utils.exists(root, \"dist/wrangler.jsonc\")) {\n if (flags.migrate) {\n this.log.debug(\"Running database migrations before deployment...\");\n await this.utils.exec(`alepha db migrate --mode=${mode}`);\n }\n await this.pm.ensureDependency(root, \"wrangler\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n const command =\n `wrangler deploy ${mode === \"production\" ? \"\" : \"--env preview\"} --config=dist/wrangler.jsonc`.trim();\n this.log.info(`Deploying to Cloudflare with command: ${command}`);\n await this.utils.exec(command);\n return;\n }\n\n // Surge deployment\n if (await this.utils.exists(root, \"dist/public/404.html\")) {\n await this.pm.ensureDependency(root, \"surge\", {\n dev: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n const distPath = this.fs.join(root, \"dist/public\");\n this.log.debug(`Deploying to Surge from directory: ${distPath}`);\n await this.utils.exec(`surge ${distPath}`);\n return;\n }\n\n throw new AlephaError(\n \"No deployment configuration found in the dist folder.\",\n );\n },\n });\n}\n","import { $inject, type Alepha, AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { importVite, importViteReact, viteAlephaSsrPreload } from \"alepha/vite\";\nimport type { InlineConfig, Plugin, ViteDevServer } from \"vite\";\nimport type { AppEntry } from \"./AppEntryProvider.ts\";\n\nexport interface ViteDevServerOptions {\n /**\n * Root directory of the project.\n */\n root: string;\n\n /**\n * Path to the server entry file.\n */\n entry: AppEntry;\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/**\n * Vite development server with Alepha integration.\n *\n * Architecture:\n * - Vite runs in middleware mode (no HTTP server)\n * - Alepha is the HTTP server via server:onRequest event\n * - Request flow: Page requests → Alepha SSR, Assets → Vite middleware\n *\n * HMR Strategy:\n * - Browser-only changes (CSS, client components) → Vite HMR (React Fast Refresh)\n * - Server-only changes → Restart Alepha → Full browser reload\n * - Shared changes → Restart Alepha → Let Vite HMR propagate\n *\n * Features:\n * - Automatic .env reload detection\n * - Error recovery on next file change\n * - Optimized module invalidation (only changed files + importers)\n */\nexport class ViteDevServerProvider {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected server!: ViteDevServer;\n protected options!: ViteDevServerOptions;\n protected alepha: Alepha | null = null;\n protected hasError = false;\n protected changedFiles = new Set<string>();\n\n public async init(options: ViteDevServerOptions): Promise<Alepha> {\n this.options = options;\n await this.createViteServer();\n return await this.loadAlepha(true);\n }\n\n public async start(): Promise<void> {\n await this.alepha?.start();\n }\n\n /**\n * Create the Vite server in middleware mode.\n */\n protected async createViteServer(): Promise<void> {\n const { createServer } = await importVite();\n const viteReact = await importViteReact();\n\n const plugins: Plugin[] = [];\n if (viteReact) plugins.push(viteReact());\n plugins.push(viteAlephaSsrPreload());\n plugins.push(this.createHmrPlugin());\n\n this.server = await createServer({\n root: this.options.root,\n plugins,\n server: { middlewareMode: true },\n appType: \"custom\",\n customLogger: {\n info: () => {},\n warn: this.log.warn.bind(this.log),\n error: this.log.error.bind(this.log),\n warnOnce: this.log.warn.bind(this.log),\n clearScreen: () => {},\n hasWarned: false,\n hasErrorLogged: () => false,\n },\n } satisfies InlineConfig);\n\n // Intercept .env changes (Vite calls restart() for .env files)\n this.server.restart = async () => {\n const startTime = Date.now();\n try {\n this.hasError = true; // Force full invalidation for env changes\n await this.loadAlepha(false);\n await this.alepha?.start();\n this.log.debug(`Env reloaded in ${Date.now() - startTime}ms`);\n this.sendBrowserReload();\n } catch (err) {\n this.hasError = true;\n this.log.error(\"Reload failed\", err);\n this.log.warn(\"Waiting for file changes to retry...\");\n this.alepha = null;\n }\n };\n }\n\n /**\n * Vite plugin to handle HMR for Alepha.\n */\n protected createHmrPlugin(): Plugin {\n return {\n name: \"alepha-hmr\",\n handleHotUpdate: async (ctx) => {\n if (ctx.file.includes(\"/.idea/\")) return [];\n\n const firstModule = ctx.modules[0] as any;\n const isBrowserOnly = firstModule && !firstModule._ssrModule;\n const isServerOnly = firstModule && !firstModule._clientModule;\n\n // Browser-only: let Vite HMR handle it (React Fast Refresh)\n if (isBrowserOnly) return;\n\n // Server or shared change: restart Alepha\n const startTime = Date.now();\n\n try {\n this.changedFiles.add(ctx.file);\n await this.loadAlepha(false);\n await this.alepha?.start();\n this.log.debug(`Reloaded in ${Date.now() - startTime}ms`);\n\n // Server-only: full browser reload\n if (isServerOnly) {\n this.sendBrowserReload();\n return [];\n }\n\n // Shared: let HMR propagate to browser\n return;\n } catch (err) {\n this.hasError = true;\n this.log.error(\"Reload failed\", err);\n this.log.warn(\"Waiting for file changes to retry...\");\n this.alepha = null;\n return [];\n }\n },\n };\n }\n\n /**\n * Send browser reload signal via custom event.\n * Browser listens for 'alepha:reload' and does window.location.reload()\n */\n protected sendBrowserReload(): void {\n this.server.ws.send({\n type: \"custom\",\n event: \"alepha:reload\",\n data: {},\n });\n }\n\n /**\n * Setup environment variables for dev mode.\n */\n protected async setupEnvironment(): Promise<void> {\n const { loadEnv } = await importVite();\n const mode = process.env.NODE_ENV || \"development\";\n const env = loadEnv(mode, this.options.root, \"\");\n\n // Merge into process.env (only set if not already defined)\n for (const [key, value] of Object.entries(env)) {\n process.env[key] ??= value;\n }\n\n process.env.NODE_ENV ??= \"development\";\n process.env.VITE_ALEPHA_DEV = \"true\";\n process.env.SERVER_HOST ??= this.options.host?.toString() ?? \"localhost\";\n process.env.SERVER_PORT ??= String(\n this.options.port ??\n (process.env.SERVER_PORT ? Number(process.env.SERVER_PORT) : 3000),\n );\n }\n\n /**\n * Load or reload the Alepha instance.\n */\n protected async loadAlepha(isInitialLoad = false): Promise<Alepha> {\n if (this.alepha) {\n await this.alepha\n .stop()\n .catch((err) => this.log.warn(\"Error stopping Alepha\", err));\n this.alepha = null;\n }\n\n if (isInitialLoad || this.hasError) {\n this.server.moduleGraph.invalidateAll();\n } else {\n this.invalidateModulesWithImporters();\n }\n this.changedFiles.clear();\n\n // Snapshot and restore process.env to isolate each reload\n const envSnapshot = { ...process.env };\n await this.setupEnvironment();\n\n await this.server.ssrLoadModule(this.options.entry.server);\n\n const alepha: Alepha = (globalThis as any).__alepha;\n if (!alepha) {\n throw new AlephaError(\n \"Alepha instance not found after loading entry module\",\n );\n }\n\n // expose Vite server to Alepha for Logger SSR Fix stack traces\n alepha.store.set(\"alepha.vite.server\" as any, this.server);\n\n this.alepha = alepha;\n await this.setupAlepha();\n\n this.hasError = false;\n process.env = envSnapshot;\n\n return alepha;\n }\n\n public hasReact(): boolean {\n try {\n this.alepha?.inject(\"ReactServerProvider\");\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Setup Alepha instance with Vite middleware.\n */\n protected async setupAlepha(): Promise<void> {\n if (!this.alepha || !this.hasReact()) {\n return;\n }\n\n // Generate dev head content using Vite's transformIndexHtml\n // This lets Vite and all plugins (React, etc.) inject their scripts\n const devHead = await this.generateDevHead();\n this.alepha.store.set(\"alepha.react.ssr.manifest\" as any, { devHead });\n\n this.alepha.events.on(\"server:onRequest\", {\n priority: \"first\",\n callback: async ({ request }) => {\n const node = request.raw.node;\n if (!node || this.isPageRequest(node.req)) return;\n\n const handled = await this.runViteMiddleware(\n node.req,\n node.res,\n request,\n );\n if (handled) {\n request.reply.status = node.res.statusCode || 200;\n request.reply.body = null;\n }\n },\n });\n }\n\n /**\n * Generate dev head content by transforming a minimal HTML through Vite.\n * This lets Vite and all plugins inject their scripts (HMR client, React Fast Refresh, etc.).\n */\n protected async generateDevHead(): Promise<string> {\n const { browser, style } = this.options.entry;\n\n // Build minimal HTML with entry points\n const scripts: string[] = [];\n if (style) {\n scripts.push(`<link rel=\"stylesheet\" href=\"/${style}\">`);\n }\n if (browser) {\n scripts.push(`<script type=\"module\" src=\"/${browser}\"></script>`);\n }\n\n const minimalHtml = `<!DOCTYPE html><html><head>${scripts.join(\"\\n\")}</head><body></body></html>`;\n\n // Transform through Vite to inject all plugin scripts\n const transformed = await this.server.transformIndexHtml(\"/\", minimalHtml);\n\n // Extract head content\n const headMatch = transformed.match(/<head>([\\s\\S]*?)<\\/head>/i);\n return headMatch?.[1]?.trim() ?? \"\";\n }\n\n /**\n * Check if request is for an HTML page (not an asset).\n */\n protected isPageRequest(req: any): boolean {\n const url = req.url || \"/\";\n\n // Root and index.html are page requests\n if (url === \"/\" || url === \"/index.html\") return true;\n\n // Vite internal routes\n if (url.startsWith(\"/@\") || url.startsWith(\"/__vite\")) return false;\n\n // Files with extensions are assets\n if (/\\.\\w+$/.test(url.split(\"?\")[0])) return false;\n\n return true;\n }\n\n /**\n * Run Vite middleware and detect if it handled the request.\n */\n protected async runViteMiddleware(\n req: any,\n res: any,\n ctx: { metadata: any },\n ): Promise<boolean> {\n // Skip if response already started\n if (res.headersSent || res.writableEnded) {\n return false;\n }\n\n return new Promise((resolve) => {\n let resolved = false;\n\n const done = (handled: boolean) => {\n if (resolved) return;\n resolved = true;\n if (handled) ctx.metadata.vite = true;\n resolve(handled);\n };\n\n // Wrap response to prevent writes after we've resolved\n const originalSetHeader = res.setHeader.bind(res);\n const originalWriteHead = res.writeHead?.bind(res);\n const originalWrite = res.write.bind(res);\n const originalEnd = res.end.bind(res);\n\n const guardedCall = <T>(fn: (...args: any[]) => T, ...args: any[]): T => {\n if (resolved && ctx.metadata.vite) {\n // Vite already handled this request, ignore late writes from framework\n return undefined as T;\n }\n return fn(...args);\n };\n\n res.setHeader = (...args: any[]) =>\n guardedCall(originalSetHeader, ...args);\n if (originalWriteHead) {\n res.writeHead = (...args: any[]) =>\n guardedCall(originalWriteHead, ...args);\n }\n res.write = (...args: any[]) => guardedCall(originalWrite, ...args);\n res.end = (...args: any[]) => guardedCall(originalEnd, ...args);\n\n res.on(\"finish\", () => done(true));\n res.on(\"close\", () => res.headersSent && done(true));\n\n this.server.middlewares(req, res, () => done(false));\n\n // Check after microtask if Vite started writing (for async handlers)\n setImmediate(() => {\n if (res.headersSent || res.writableEnded) {\n done(true);\n }\n });\n });\n }\n\n /**\n * Invalidate modules and all their importers.\n */\n protected invalidateModulesWithImporters(): void {\n const invalidated = new Set<string>();\n const queue: string[] = [...this.changedFiles];\n\n while (queue.length > 0) {\n const file = queue.pop()!;\n if (invalidated.has(file)) continue;\n\n const mod = this.server.moduleGraph.getModuleById(file);\n if (!mod) continue;\n\n this.server.moduleGraph.invalidateModule(mod);\n invalidated.add(file);\n\n for (const importer of mod.importers) {\n if (importer.id && !invalidated.has(importer.id)) {\n queue.push(importer.id);\n }\n }\n }\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\nimport { ViteDevServerProvider } from \"../providers/ViteDevServerProvider.ts\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class DevCommand {\n protected readonly log = $logger();\n protected readonly fs = $inject(FileSystemProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n protected readonly alepha = $inject(Alepha);\n protected readonly viteDevServer = $inject(ViteDevServerProvider);\n protected readonly boot = $inject(AppEntryProvider);\n\n /**\n * Will run the project in watch mode.\n */\n public readonly dev = $command({\n name: \"dev\",\n description: \"Run the project in development mode\",\n handler: async ({ root }) => {\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n });\n\n const entry = await this.boot.getAppEntry(root);\n this.log.debug(\"Entry file found\", { entry });\n\n // -> here, we assume we use Vite as runner (api or fullstack)\n // but it's planned to support Bun runner in the future as well\n await this.viteDevServer.init({ root, entry });\n await this.viteDevServer.start();\n },\n });\n}\n","import { $atom, type Static, t } from \"alepha\";\n\n/**\n * Default scopes to ignore in changelog generation.\n * Commits with these scopes won't appear in release notes.\n */\nexport const DEFAULT_IGNORE = [\n \"project\",\n \"release\",\n \"starter\",\n \"example\",\n \"chore\",\n \"ci\",\n \"build\",\n \"test\",\n \"style\",\n];\n\n/**\n * Changelog configuration atom.\n *\n * Configure in `alepha.config.ts`:\n * ```ts\n * import { changelogOptions } from \"alepha/cli\";\n *\n * alepha.set(changelogOptions, {\n * ignore: [\"project\", \"release\", \"chore\", \"docs\"],\n * });\n * ```\n */\nexport const changelogOptions = $atom({\n name: \"alepha.cli.changelog.options\",\n schema: t.object({\n /**\n * Scopes to ignore (e.g., \"project\", \"release\", \"chore\").\n * Commits like `feat(chore): ...` will be excluded from changelog.\n */\n ignore: t.optional(t.array(t.string())),\n }),\n default: {\n ignore: DEFAULT_IGNORE,\n },\n});\n\nexport type ChangelogOptions = Static<typeof changelogOptions.schema>;\n","import { $logger } from \"alepha/logger\";\nimport {\n type ChangelogOptions,\n DEFAULT_IGNORE,\n} from \"../atoms/changelogOptions.ts\";\nimport type { Commit } from \"../commands/gen/changelog.ts\";\n\n/**\n * Service for parsing git commit messages into structured format.\n *\n * Only parses **conventional commits with a scope**:\n * - `feat(scope): description` → feature\n * - `fix(scope): description` → bug fix\n * - `feat(scope)!: description` → breaking change\n *\n * Commits without scope are ignored, allowing developers to commit\n * work-in-progress changes without polluting release notes:\n * - `cli: work in progress` → ignored (no type)\n * - `fix: quick patch` → ignored (no scope)\n * - `feat(cli): add command` → included\n */\nexport class GitMessageParser {\n protected readonly log = $logger();\n\n /**\n * Parse a git commit line into a structured Commit object.\n *\n * **Format:** `type(scope): description` or `type(scope)!: description`\n *\n * **Supported types:** feat, fix, docs, refactor, perf, revert\n *\n * **Breaking changes:** Use `!` before `:` (e.g., `feat(api)!: remove endpoint`)\n *\n * @returns Commit object or null if not matching/ignored\n */\n parseCommit(line: string, config: ChangelogOptions): Commit | null {\n // Extract hash and message from git log --oneline format\n const match = line.match(/^([a-f0-9]+)\\s+(.+)$/);\n if (!match) return null;\n\n const [, hash, message] = match;\n const ignore = config.ignore ?? DEFAULT_IGNORE;\n\n // Conventional commit with REQUIRED scope: type(scope): description\n // The `!` before `:` marks a breaking change\n const conventionalMatch = message.match(\n /^(feat|fix|docs|refactor|perf|revert)\\(([^)]+)\\)(!)?:\\s*(.+)$/i,\n );\n\n if (!conventionalMatch) {\n // No match - commit doesn't follow required format\n return null;\n }\n\n const [, type, scope, breakingMark, description] = conventionalMatch;\n\n // Check if scope should be ignored\n const baseScope = scope.split(\"/\")[0];\n if (ignore.includes(baseScope) || ignore.includes(scope)) {\n return null;\n }\n\n // Breaking change detection:\n // 1. Explicit `!` marker: feat(api)!: change\n // 2. Word \"breaking\" in description: feat(api): breaking change to auth\n const breaking =\n breakingMark === \"!\" || description.toLowerCase().includes(\"breaking\");\n\n return {\n hash: hash.substring(0, 8),\n type: type.toLowerCase(),\n scope,\n description: description.trim(),\n breaking,\n };\n }\n}\n","import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { $inject, $use, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { changelogOptions } from \"../../atoms/changelogOptions.ts\";\nimport { GitMessageParser } from \"../../services/GitMessageParser.ts\";\n\nexport {\n type ChangelogOptions,\n changelogOptions,\n DEFAULT_IGNORE,\n} from \"../../atoms/changelogOptions.ts\";\nexport { GitMessageParser } from \"../../services/GitMessageParser.ts\";\n\nconst execAsync = promisify(exec);\n\n// =============================================================================\n// GIT PROVIDER\n// =============================================================================\n\n/**\n * Git provider for executing git commands.\n * Can be substituted in tests with a mock implementation.\n */\nexport class GitProvider {\n async exec(cmd: string, cwd: string): Promise<string> {\n const { stdout } = await execAsync(`git ${cmd}`, { cwd });\n return stdout;\n }\n}\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface Commit {\n hash: string;\n type: string;\n scope: string | null;\n description: string;\n breaking: boolean;\n}\n\ninterface ChangelogEntry {\n features: Commit[];\n fixes: Commit[];\n}\n\n// =============================================================================\n// CHANGELOG COMMAND\n// =============================================================================\n\n/**\n * Changelog command for generating release notes from git commits.\n *\n * Usage:\n * - `alepha gen changelog` - Show unreleased changes since latest tag to HEAD\n * - `alepha gen changelog --from=1.0.0` - Show changes from version to HEAD\n * - `alepha gen changelog --from=1.0.0 --to=1.1.0` - Show changes between two refs\n * - `alepha gen changelog | tee -a CHANGELOG.md` - Append to file\n */\nexport class ChangelogCommand {\n protected readonly log = $logger();\n protected readonly git = $inject(GitProvider);\n protected readonly parser = $inject(GitMessageParser);\n protected readonly config = $use(changelogOptions);\n\n // ---------------------------------------------------------------------------\n // FORMATTING\n // ---------------------------------------------------------------------------\n\n /**\n * Format a single commit line.\n * Example: `- **cli**: add new command (\\`abc1234\\`)`\n * Breaking changes are flagged: `- **cli**: add new command [BREAKING] (\\`abc1234\\`)`\n */\n protected formatCommit(commit: Commit): string {\n const breaking = commit.breaking ? \" [BREAKING]\" : \"\";\n return `- **${commit.scope}**: ${commit.description}${breaking} (\\`${commit.hash}\\`)`;\n }\n\n /**\n * Format the changelog entry with sections.\n */\n protected formatEntry(entry: ChangelogEntry): string {\n const sections: string[] = [];\n\n if (entry.features.length > 0) {\n sections.push(\"### Features\\n\");\n for (const commit of entry.features) {\n sections.push(this.formatCommit(commit));\n }\n sections.push(\"\");\n }\n\n if (entry.fixes.length > 0) {\n sections.push(\"### Bug Fixes\\n\");\n for (const commit of entry.fixes) {\n sections.push(this.formatCommit(commit));\n }\n sections.push(\"\");\n }\n\n return sections.join(\"\\n\");\n }\n\n // ---------------------------------------------------------------------------\n // PARSING\n // ---------------------------------------------------------------------------\n\n /**\n * Parse git log output into a changelog entry.\n */\n protected parseCommits(commitsOutput: string): ChangelogEntry {\n const entry: ChangelogEntry = {\n features: [],\n fixes: [],\n };\n\n for (const line of commitsOutput.trim().split(\"\\n\")) {\n if (!line.trim()) continue;\n\n const commit = this.parser.parseCommit(line, this.config);\n if (!commit) {\n this.log.trace(\"Skipping commit\", { line });\n continue;\n }\n\n this.log.trace(\"Parsed commit\", { commit });\n\n // Categorize commit (breaking flag is preserved on the commit itself)\n if (commit.type === \"feat\") {\n entry.features.push(commit);\n } else if (commit.type === \"fix\") {\n entry.fixes.push(commit);\n }\n }\n\n return entry;\n }\n\n /**\n * Check if entry has any public commits.\n */\n protected hasChanges(entry: ChangelogEntry): boolean {\n return entry.features.length > 0 || entry.fixes.length > 0;\n }\n\n /**\n * Get the latest version tag.\n */\n protected async getLatestTag(\n git: (cmd: string) => Promise<string>,\n ): Promise<string | null> {\n const tagsOutput = await git(\"tag --sort=-version:refname\");\n const tags = tagsOutput\n .trim()\n .split(\"\\n\")\n .filter((tag) => tag.match(/^\\d+\\.\\d+\\.\\d+$/));\n\n return tags[0] || null;\n }\n\n // ---------------------------------------------------------------------------\n // COMMAND\n // ---------------------------------------------------------------------------\n\n public readonly command = $command({\n name: \"changelog\",\n description:\n \"Generate changelog from conventional commits (outputs to stdout)\",\n flags: t.object({\n /**\n * Show changes from this ref (tag, commit, branch).\n * Defaults to the latest version tag.\n * Example: --from=1.0.0\n */\n from: t.optional(\n t.string({\n aliases: [\"f\"],\n description: \"Starting ref (default: latest tag)\",\n }),\n ),\n /**\n * Show changes up to this ref (tag, commit, branch).\n * Defaults to HEAD.\n * Example: --to=main\n */\n to: t.optional(\n t.string({\n aliases: [\"t\"],\n description: \"Ending ref (default: HEAD)\",\n }),\n ),\n }),\n handler: async ({ flags, root }) => {\n const git = (cmd: string) => this.git.exec(cmd, root);\n\n // Determine the starting point\n let fromRef: string;\n\n if (flags.from) {\n // User specified a ref\n fromRef = flags.from;\n this.log.debug(\"Using specified from ref\", { from: fromRef });\n } else {\n // Use latest tag\n const latestTag = await this.getLatestTag(git);\n if (!latestTag) {\n process.stdout.write(\"No version tags found in repository\\n\");\n return;\n }\n fromRef = latestTag;\n this.log.debug(\"Using latest tag\", { from: fromRef });\n }\n\n // Determine the ending point\n const toRef = flags.to || \"HEAD\";\n this.log.debug(\"Using to ref\", { to: toRef });\n\n // Get commits in range\n const commitsOutput = await git(`log ${fromRef}..${toRef} --oneline`);\n\n if (!commitsOutput.trim()) {\n process.stdout.write(`No changes in range ${fromRef}..${toRef}\\n`);\n return;\n }\n\n // Parse and format\n const entry = this.parseCommits(commitsOutput);\n\n if (!this.hasChanges(entry)) {\n process.stdout.write(\n `No public changes in range ${fromRef}..${toRef}\\n`,\n );\n return;\n }\n\n // Output the formatted changelog (no header - caller adds it if needed)\n process.stdout.write(this.formatEntry(entry));\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../../services/AlephaCliUtils.ts\";\n\nexport class GenEnvCommand {\n protected readonly log = $logger();\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly fs = $inject(FileSystemProvider);\n\n public readonly command = $command({\n name: \"env\",\n description: \"Extract environment variables from server entry file\",\n flags: t.object({\n out: t.optional(\n t.text({\n aliases: [\"o\"],\n description: \"Output file path (e.g., .env)\",\n }),\n ),\n }),\n handler: async ({ root, flags }) => {\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n root,\n mode: \"development\",\n });\n\n try {\n const { env } = alepha.dump();\n\n let dotEnvFile = \"\";\n for (const [key, value] of Object.entries(env)) {\n if (value.description) {\n dotEnvFile += `# ${value.description.split(\"\\n\").join(\"\\n# \")}\\n`;\n }\n if (value.required && !value.default) {\n dotEnvFile += `# (required)\\n`;\n }\n if (value.enum) {\n dotEnvFile += `# Possible values: ${value.enum.join(\", \")}\\n`;\n }\n dotEnvFile += `#${key}=${value.default || \"\"}\\n\\n`;\n }\n\n if (flags.out) {\n await this.fs.writeFile(this.fs.join(root, flags.out), dotEnvFile);\n } else {\n this.log.info(dotEnvFile);\n }\n } catch (err) {\n this.log.error(\"Failed to extract environment variables\", err);\n }\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ServerSwaggerProvider } from \"alepha/server/swagger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../../services/AlephaCliUtils.ts\";\n\nexport class OpenApiCommand {\n protected readonly log = $logger();\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly fs = $inject(FileSystemProvider);\n\n public readonly command = $command({\n name: \"openapi\",\n description: \"Generate OpenAPI specification from actions\",\n flags: t.object({\n out: t.optional(\n t.text({\n aliases: [\"o\"],\n description: \"Output file path\",\n }),\n ),\n }),\n handler: async ({ root, flags }) => {\n const alepha = await this.utils.loadAlephaFromServerEntryFile({\n root,\n mode: \"development\",\n });\n\n try {\n const openapiProvider = alepha.inject(\n ServerSwaggerProvider,\n ) as ServerSwaggerProvider;\n\n await alepha.events.emit(\"configure\", alepha);\n\n let json: any = openapiProvider.json;\n\n if (!json) {\n json = openapiProvider.generateSwaggerDoc({\n info: {\n title: \"API Documentation\",\n version: \"1.0.0\",\n },\n });\n }\n\n if (!json) {\n this.log.error(\"No actions found to generate OpenAPI specification.\");\n return;\n }\n\n if (flags.out) {\n await this.fs.writeFile(\n this.fs.join(root, flags.out),\n JSON.stringify(json, null, 2),\n );\n } else {\n this.log.info(JSON.stringify(json, null, 2));\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"Service not found\")) {\n this.log.error(\n \"Missing $swagger() primitive in your server configuration.\",\n );\n return;\n }\n\n this.log.error(`OpenAPI generation failed - ${message}`, err);\n }\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { ChangelogCommand } from \"./gen/changelog.ts\";\nimport { GenEnvCommand } from \"./gen/env.ts\";\nimport { OpenApiCommand } from \"./gen/openapi.ts\";\n\nexport class GenCommand {\n protected readonly changelog = $inject(ChangelogCommand);\n protected readonly openapi = $inject(OpenApiCommand);\n protected readonly genEnv = $inject(GenEnvCommand);\n\n public readonly gen = $command({\n name: \"gen\",\n description: \"Generate code, documentation, ...\",\n children: [\n this.changelog.command,\n this.openapi.command,\n this.genEnv.command,\n ],\n handler: async ({ help }) => {\n help();\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class InitCommand {\n protected readonly log = $logger();\n protected readonly colors = $inject(ConsoleColorProvider);\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n protected readonly fs = $inject(FileSystemProvider);\n\n /**\n * Ensure the project has the necessary Alepha configuration files.\n * Add the correct dependencies to package.json and install them.\n */\n public readonly init = $command({\n name: \"init\",\n description: \"Add missing Alepha configuration files to the project\",\n args: t.optional(\n t.text({\n title: \"path\",\n trim: true,\n lowercase: true,\n }),\n ),\n flags: t.object({\n ai: t.optional(\n t.boolean({\n description:\n \"Add AI agent instructions (CLAUDE.md if claude CLI installed, else AGENTS.md)\",\n }),\n ),\n pm: t.optional(\n t.enum([\"yarn\", \"npm\", \"pnpm\", \"bun\"], {\n description: \"Package manager to use\",\n }),\n ),\n // choose which modules to scaffold\n api: t.optional(\n t.boolean({\n description: \"Include API module structure (src/api/)\",\n }),\n ),\n react: t.optional(\n t.boolean({\n aliases: [\"r\"],\n description: \"Include React dependencies and web module (src/web/)\",\n }),\n ),\n ui: t.optional(\n t.boolean({\n description:\n \"Include @alepha/ui (components, auth portal, admin portal)\",\n }),\n ),\n auth: t.optional(\n t.boolean({\n description:\n \"Include authentication (AppSecurity, $uiAuth). Implies --api --ui --react\",\n }),\n ),\n admin: t.optional(\n t.boolean({\n description: \"Include admin portal ($uiAdmin). Implies --auth\",\n }),\n ),\n test: t.optional(\n t.boolean({ description: \"Include Vitest and create test directory\" }),\n ),\n force: t.optional(\n t.boolean({\n aliases: [\"f\"],\n description: \"Override existing files\",\n }),\n ),\n }),\n handler: async ({ run, flags, root, args }) => {\n if (args) {\n root = this.fs.join(root, args);\n await this.fs.mkdir(root, { force: true });\n }\n\n // Flag cascading: --admin → --auth → --ui → --react, --api\n if (flags.admin) {\n flags.auth = true;\n }\n if (flags.auth) {\n flags.api = true;\n flags.ui = true;\n }\n if (flags.ui) {\n flags.react = true;\n }\n\n // Detect workspace context (are we inside packages/ or apps/ of a monorepo?)\n const workspace = await this.pm.getWorkspaceContext(root);\n\n // Detect agent type: claude CLI → CLAUDE.md, else → AGENTS.md\n let agentType: \"claude\" | \"agents\" | false = false;\n if (flags.ai) {\n const hasClaudeCli = await this.utils.isInstalledAsync(\"claude\");\n agentType = hasClaudeCli ? \"claude\" : \"agents\";\n }\n\n const isExpo = await this.pm.hasExpo(root);\n\n // Get git email for admin auto-promotion (if auth enabled)\n const adminEmail = flags.auth\n ? await this.utils.getGitEmail()\n : undefined;\n\n const force = !!flags.force;\n\n await run({\n name: \"ensuring configuration files\",\n handler: async () => {\n await this.scaffolder.ensureConfig(root, {\n force,\n packageJson: { ...flags, isPackage: workspace.isPackage },\n // Skip workspace-level configs if they exist at workspace root\n tsconfigJson: !workspace.config.tsconfigJson,\n biomeJson: !workspace.config.biomeJson,\n editorconfig: !workspace.config.editorconfig,\n agentMd: agentType\n ? { type: agentType, react: !!flags.react, ui: !!flags.ui }\n : false,\n });\n\n // Create project structure based on flags\n await this.scaffolder.ensureMainServerTs(root, {\n api: !!flags.api,\n react: !!flags.react && !isExpo,\n force,\n });\n if (flags.api) {\n await this.scaffolder.ensureApiProject(root, {\n auth: !!flags.auth,\n adminEmail,\n force,\n });\n }\n if (flags.react && !isExpo) {\n await this.scaffolder.ensureWebProject(root, {\n api: !!flags.api,\n ui: !!flags.ui,\n auth: !!flags.auth,\n admin: !!flags.admin,\n force,\n });\n }\n },\n });\n\n // Use workspace PM if detected, otherwise detect from current root\n const pmName = await this.pm.getPackageManager(\n workspace.workspaceRoot ?? root,\n flags.pm ?? workspace.packageManager ?? undefined,\n );\n\n // Only setup PM files if not in a workspace package\n if (!workspace.isPackage) {\n if (pmName === \"yarn\") {\n await this.pm.ensureYarn(root);\n await run(\"yarn set version stable\", { root });\n } else if (pmName === \"bun\") {\n await this.pm.ensureBun(root);\n } else if (pmName === \"pnpm\") {\n await this.pm.ensurePnpm(root);\n } else {\n await this.pm.ensureNpm(root);\n }\n }\n\n // Run install from workspace root if in a package, otherwise from current root\n const installRoot = workspace.workspaceRoot ?? root;\n await run(`${pmName} install`, {\n alias: `installing dependencies with ${pmName}`,\n root: installRoot,\n });\n\n // Create test directory if --test flag is set (vitest is in package.json)\n if (flags.test) {\n await this.scaffolder.ensureTestDir(root);\n }\n\n await run(`${pmName} run lint`, {\n alias: \"running linter\",\n root: installRoot,\n });\n\n // Initialize git repository if not in a workspace package\n if (!workspace.isPackage) {\n const gitInitialized = await this.scaffolder.ensureGitRepo(root, {\n force,\n });\n if (gitInitialized) {\n await run(\"git add .\", {\n alias: \"staging generated files\",\n root,\n });\n }\n }\n\n run.end();\n\n // Success message\n const projectName = args || \".\";\n const pmRun = pmName === \"npm\" ? \"npm run\" : pmName;\n const c = this.colors;\n\n this.log.info(\"\");\n this.log.info(` ${c.set(\"GREEN\", \"✓\")} Project ready!`);\n this.log.info(\"\");\n this.log.info(\n ` ${c.set(\"GREY_DARK\", \"$\")} cd ${c.set(\"CYAN\", projectName)}`,\n );\n this.log.info(\n ` ${c.set(\"GREY_DARK\", \"$\")} ${c.set(\"CYAN\", `${pmRun} dev`)}`,\n );\n\n if (adminEmail) {\n this.log.info(\"\");\n this.log.info(` Admin email: ${c.set(\"GREEN\", adminEmail)}`);\n this.log.info(\n ` ${c.set(\"GREY_DARK\", \"(from git config, change in src/api/AppSecurity.ts)\")}`,\n );\n }\n\n this.log.info(\"\");\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class LintCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n\n public readonly lint = $command({\n name: \"lint\",\n description: \"Run linter across the codebase using Biome\",\n handler: async ({ root }) => {\n await this.scaffolder.ensureConfig(root, {\n biomeJson: true,\n checkWorkspace: true,\n });\n\n await this.pm.ensureDependency(root, \"@biomejs/biome\", {\n checkWorkspace: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n\n await this.utils.exec(\"biome check --fix\");\n },\n });\n}\n","import { $inject, Alepha, t } from \"alepha\";\nimport { $command, CliProvider } from \"alepha/command\";\nimport { $logger, ConsoleColorProvider } from \"alepha/logger\";\nimport { version } from \"../version.ts\";\n\nexport class RootCommand {\n protected readonly log = $logger();\n protected readonly cli = $inject(CliProvider);\n protected readonly alepha = $inject(Alepha);\n protected readonly color = $inject(ConsoleColorProvider);\n\n /**\n * Called when no command is provided\n */\n public readonly root = $command({\n root: true,\n flags: t.object({\n version: t.optional(\n t.boolean({\n description: \"Show Alepha CLI version\",\n aliases: [\"v\"],\n }),\n ),\n }),\n handler: async ({ flags }) => {\n if (flags.version) {\n this.log.info(this.color.set(\"WHITE_BOLD\", `Alepha v${version}`));\n if (this.alepha.isBun()) {\n this.log.info(this.color.set(\"GREY_DARK\", `└─ Bun v${Bun.version}`));\n } else {\n this.log.info(\n this.color.set(\"GREY_DARK\", `└─ Node ${process.version}`),\n );\n }\n return;\n }\n\n this.cli.printHelp();\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class TestCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly scaffolder = $inject(ProjectScaffolder);\n\n public readonly test = $command({\n name: \"test\",\n description: \"Run tests using Vitest\",\n flags: t.object({\n config: t.optional(\n t.string({\n description: \"Path to Vitest config file\",\n alias: \"c\",\n }),\n ),\n }),\n env: t.object({\n VITEST_ARGS: t.optional(\n t.string({\n default: \"\",\n description:\n \"Additional arguments to pass to Vitest. E.g., --coverage\",\n }),\n ),\n }),\n handler: async ({ root, flags, env }) => {\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n });\n\n // Ensure vitest is installed before running\n await this.pm.ensureDependency(root, \"vitest\", {\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n\n const config = flags.config ? `--config=${flags.config}` : \"\";\n\n await this.utils.exec(`vitest run ${config} ${env.VITEST_ARGS}`);\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\nimport { ProjectScaffolder } from \"../services/ProjectScaffolder.ts\";\n\nexport class TypecheckCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n protected readonly log = $logger();\n protected readonly scaffolder = $inject(ProjectScaffolder);\n\n /**\n * Run TypeScript type checking across the codebase with no emit.\n */\n public readonly typecheck = $command({\n name: \"typecheck\",\n aliases: [\"tc\"],\n description: \"Check TypeScript types across the codebase\",\n handler: async ({ root }) => {\n this.log.info(\"Starting TypeScript type checking...\");\n\n await this.scaffolder.ensureConfig(root, {\n tsconfigJson: true,\n checkWorkspace: true,\n });\n\n await this.pm.ensureDependency(root, \"typescript\", {\n checkWorkspace: true,\n exec: (cmd, opts) => this.utils.exec(cmd, opts),\n });\n\n await this.utils.exec(\"tsc --noEmit\");\n\n this.log.info(\"TypeScript type checking completed successfully.\");\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { AlephaCliUtils } from \"../services/AlephaCliUtils.ts\";\nimport { PackageManagerUtils } from \"../services/PackageManagerUtils.ts\";\n\nexport class VerifyCommand {\n protected readonly utils = $inject(AlephaCliUtils);\n protected readonly pm = $inject(PackageManagerUtils);\n\n /**\n * Run a series of verification commands to ensure code quality and correctness.\n *\n * This command runs the following checks in order:\n * - Clean the project\n * - Format the code\n * - Lint the code\n * - Run tests (if Vitest is a dev dependency)\n * - Check database migrations (if a migrations directory exists)\n * - Type check the code\n * - Build the project\n * - Clean the project again\n */\n public readonly verify = $command({\n name: \"verify\",\n description: \"Verify the Alepha project\",\n handler: async ({ root, run }) => {\n await run(\"alepha clean\");\n await run(\"alepha format\");\n await run(\"alepha lint\");\n\n await run(\"alepha typecheck\");\n\n const pkg = await this.pm.readPackageJson(root);\n if (pkg.devDependencies?.vitest) {\n await run(\"alepha test\");\n }\n\n if (await this.utils.exists(root, \"migrations\")) {\n await run(\"alepha db check-migrations\");\n }\n\n const isExpo = await this.pm.hasExpo(root);\n if (!isExpo) {\n await run(\"alepha build\");\n }\n await run(\"alepha clean\");\n },\n });\n}\n","import { $hook, $inject, $module, Alepha } from \"alepha\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport { BuildCommand } from \"../commands/build.ts\";\nimport { CleanCommand } from \"../commands/clean.ts\";\nimport { DbCommand } from \"../commands/db.ts\";\nimport { DeployCommand } from \"../commands/deploy.ts\";\nimport { DevCommand } from \"../commands/dev.ts\";\nimport { GitProvider } from \"../commands/gen/changelog.ts\";\nimport { GenCommand } from \"../commands/gen.ts\";\nimport { InitCommand } from \"../commands/init.ts\";\nimport { LintCommand } from \"../commands/lint.ts\";\nimport { RootCommand } from \"../commands/root.ts\";\nimport { TestCommand } from \"../commands/test.ts\";\nimport { TypecheckCommand } from \"../commands/typecheck.ts\";\nimport { VerifyCommand } from \"../commands/verify.ts\";\nimport { AppEntryProvider } from \"../providers/AppEntryProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Allow to extend Alepha CLI via `alepha.config.ts` file located in the project root.\n */\n\nclass AlephaCliExtension {\n protected readonly alepha = $inject(Alepha);\n protected readonly fs = $inject(FileSystemProvider);\n\n protected readonly onConfigure = $hook({\n on: \"configure\",\n handler: async () => {\n const root = process.cwd();\n const extensionPath = this.fs.join(root, \"alepha.config.ts\");\n const hasExtension = await this.fs.exists(extensionPath);\n if (!hasExtension) {\n return;\n }\n\n // import\n const { default: Extension } = await import(extensionPath);\n if (typeof Extension !== \"function\") {\n return;\n }\n\n this.alepha.inject(Extension, {\n args: [this.alepha],\n });\n },\n });\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport const AlephaCli = $module({\n name: \"alepha.cli\",\n services: [\n AlephaCliExtension,\n // Commands (one per file)\n BuildCommand,\n CleanCommand,\n DbCommand,\n DeployCommand,\n DevCommand,\n InitCommand,\n LintCommand,\n RootCommand,\n TestCommand,\n TypecheckCommand,\n VerifyCommand,\n GenCommand,\n // Support services\n AppEntryProvider,\n GitProvider,\n ],\n});\n","import { access, readdir, readFile } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { join } from \"node:path\";\nimport { $inject, AlephaError } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { FileSystemProvider } from \"alepha/system\";\nimport type { InlineConfig } from \"tsdown\";\n\ninterface Module {\n name: string;\n dependencies: string[];\n native?: boolean;\n browser?: boolean;\n workerd?: boolean;\n bun?: boolean;\n node?: boolean;\n}\n\nexport class AlephaPackageBuilderCli {\n src = \"src\";\n dist = \"dist\";\n fs = $inject(FileSystemProvider);\n\n make = $command({\n root: true,\n handler: async ({ run, root }) => {\n const modules: Array<Module> = [];\n\n const pkgBuffer = await this.fs.readFile(\"package.json\");\n const pkgData = JSON.parse(pkgBuffer.toString(\"utf-8\"));\n const packageName = pkgData.name as string;\n\n await run(\"analyze modules\", async () => {\n modules.push(\n ...(await analyzeModules(this.fs.join(root, this.src), packageName)),\n );\n });\n\n pkgData.exports = {};\n\n for (const item of modules) {\n let m = `./${item.name.replace(\"core\", \"\")}`;\n if (m.endsWith(\"/\")) m = m.slice(0, -1);\n const path = m;\n\n pkgData.exports[path] = {};\n // order is important here for compatibility\n pkgData.exports[path].types = `./src/${item.name}/index.ts`;\n if (item.native) {\n pkgData.exports[path][\"react-native\"] =\n `./src/${item.name}/index.native.ts`;\n } else if (item.browser) {\n pkgData.exports[path][\"react-native\"] =\n `./src/${item.name}/index.browser.ts`;\n }\n\n if (item.workerd) {\n pkgData.exports[path].workerd = `./src/${item.name}/index.workerd.ts`;\n }\n\n if (item.browser) {\n pkgData.exports[path].browser = `./src/${item.name}/index.browser.ts`;\n }\n\n if (item.bun) {\n pkgData.exports[path].bun = `./src/${item.name}/index.bun.ts`;\n }\n\n pkgData.exports[path].import = `./src/${item.name}/index.ts`;\n pkgData.exports[path].default = `./src/${item.name}/index.ts`;\n }\n\n if (packageName === \"alepha\") {\n pkgData.exports[\"./tsconfig.base\"] = \"./tsconfig.base.json\";\n pkgData.exports[\"./package.json\"] = \"./package.json\";\n }\n\n if (packageName === \"@alepha/ui\") {\n pkgData.exports[\"./styles\"] = \"./src/core/styles.css\";\n pkgData.exports[\"./json/styles\"] = \"./src/json/styles.css\";\n }\n\n await this.fs.writeFile(\"package.json\", JSON.stringify(pkgData, null, 2));\n\n const tmpDir = this.fs.join(root, \"node_modules/.alepha\");\n await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});\n\n await this.fs.writeFile(\n this.fs.join(tmpDir, \"module-dependencies.json\"),\n JSON.stringify(modules, null, 2),\n );\n\n const tsconfigBuffer = await this.fs.readFile(\n this.fs.join(root, \"../../tsconfig.json\"),\n );\n\n const external: string[] = Object.keys(\n JSON.parse(tsconfigBuffer.toString(\"utf-8\")).compilerOptions.paths,\n );\n\n external.push(\"bun\");\n external.push(\"bun:sqlite\");\n\n await run.rm(this.dist);\n\n const build = async (item: Module) => {\n const entries: InlineConfig[] = [];\n const src = this.fs.join(root, this.src, item.name);\n const dest = this.fs.join(root, this.dist, item.name);\n\n entries.push({\n entry: this.fs.join(src, \"index.ts\"),\n outDir: dest,\n format: [\"esm\"],\n sourcemap: true,\n fixedExtension: false,\n platform: \"node\", // TODO: node must be enabled only if index.node.ts exists\n inlineOnly: false,\n external,\n dts: {\n sourcemap: true,\n },\n });\n\n if (item.native) {\n entries.push({\n entry: this.fs.join(src, \"index.native.ts\"),\n outDir: dest,\n platform: \"neutral\",\n sourcemap: true,\n dts: false,\n inlineOnly: false,\n external,\n });\n }\n\n if (item.browser) {\n entries.push({\n entry: this.fs.join(src, \"index.browser.ts\"),\n outDir: dest,\n platform: \"browser\",\n sourcemap: true,\n dts: false,\n inlineOnly: false,\n external,\n });\n }\n\n if (item.bun) {\n entries.push({\n entry: this.fs.join(src, \"index.bun.ts\"),\n outDir: dest,\n platform: \"node\",\n sourcemap: true,\n fixedExtension: false,\n dts: false,\n inlineOnly: false,\n external,\n });\n }\n\n const config = this.fs.join(\n tmpDir,\n `tsdown-${item.name.replace(\"/\", \"-\")}.config.js`,\n );\n await this.fs.writeFile(\n config,\n `export default ${JSON.stringify(entries, null, 2)};`,\n );\n\n // /!\\ Warning /!\\\n // avoid to call tsdown programmatically, when we spawn 8 processes at once it 'JavaScript heap out of memory' :---)\n await run(`npx tsdown -c=${config}`);\n };\n\n const concurrency = Math.ceil(os.cpus().length / 2);\n const queue = modules.slice();\n const workers: Promise<void>[] = [];\n for (let i = 0; i < concurrency; i++) {\n const worker = (async () => {\n while (queue.length > 0) {\n const item = queue.shift();\n if (item) {\n await build(item);\n } else {\n await new Promise((r) => setTimeout(r, 100));\n }\n }\n })();\n workers.push(worker);\n }\n await Promise.all(workers);\n },\n });\n}\n\nexport default AlephaPackageBuilderCli;\n\nasync function getAllFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n async function scan(currentDir: string) {\n const entries = await readdir(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n\n if (entry.isDirectory()) {\n await scan(fullPath);\n } else if (entry.isFile() && /\\.(ts|tsx)$/.test(entry.name)) {\n files.push(fullPath);\n }\n }\n }\n\n await scan(dir);\n return files;\n}\n\nfunction removeComments(content: string): string {\n // Remove single-line comments\n let cleaned = content.replace(/\\/\\/.*$/gm, \"\");\n\n // Remove multi-line comments\n cleaned = cleaned.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n\n return cleaned;\n}\n\nfunction extractAlephaDependencies(\n content: string,\n packageName: string,\n moduleName: string,\n): string[] {\n const deps = new Set<string>();\n const cleanedContent = removeComments(content);\n\n // Match: from \"alepha/xxx\" or from 'alepha/xxx'\n const importRegex = new RegExp(\n `from \"${packageName}/([a-zA-Z0-9_/]+)\";`,\n \"g\",\n );\n\n const matches = cleanedContent.matchAll(importRegex);\n for (const match of matches) {\n deps.add(match[1]);\n }\n\n return Array.from(deps);\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction detectCircularDependencies(modules: Module[]): void {\n const moduleMap = new Map(modules.map((m) => [m.name, m.dependencies]));\n\n function hasCycle(\n moduleName: string,\n visited: Set<string> = new Set(),\n path: string[] = [],\n ): string[] | null {\n if (visited.has(moduleName)) {\n // Found a cycle, return the path\n const cycleStart = path.indexOf(moduleName);\n return [...path.slice(cycleStart), moduleName];\n }\n\n const deps = moduleMap.get(moduleName);\n if (!deps) return null;\n\n visited.add(moduleName);\n path.push(moduleName);\n\n for (const dep of deps) {\n const cycle = hasCycle(dep, new Set(visited), [...path]);\n if (cycle) return cycle;\n }\n\n return null;\n }\n\n for (const module of modules) {\n const cycle = hasCycle(module.name);\n if (cycle) {\n throw new AlephaError(\n `Circular dependency detected: ${cycle.join(\" -> \")}`,\n );\n }\n }\n}\n\nexport async function analyzeModules(\n srcDir: string,\n packageName: string,\n): Promise<Module[]> {\n const modules: Module[] = [];\n\n async function scanDirectory(dir: string, prefix: string): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const moduleName = prefix ? `${prefix}/${entry.name}` : entry.name;\n const modulePath = join(dir, entry.name);\n\n // Check if this directory has an index.ts (is a module)\n const hasIndex = await fileExists(join(modulePath, \"index.ts\"));\n\n if (hasIndex) {\n // This is a module\n const dependencies = new Set<string>();\n\n // Check for browser/node/bun entry points\n const hasBrowser = await fileExists(\n join(modulePath, \"index.browser.ts\"),\n );\n const hasNative = await fileExists(\n join(modulePath, \"index.native.ts\"),\n );\n const hasBun = await fileExists(join(modulePath, \"index.bun.ts\"));\n const hasNode = await fileExists(join(modulePath, \"index.node.ts\"));\n const hasEdge = await fileExists(\n join(modulePath, \"index.workerd.ts\"),\n );\n\n // Get all .ts/.tsx files in this module\n const files = await getAllFiles(modulePath);\n\n for (const file of files) {\n const content = await readFile(file, \"utf-8\");\n const deps = extractAlephaDependencies(\n content,\n packageName,\n moduleName,\n );\n for (const dep of deps) {\n if (dep.endsWith(\".ts\")) {\n throw new Error(\n `Invalid dependency '${dep}' in module '${moduleName}'. Do not include file extensions in Alepha module imports.`,\n );\n }\n if (dep.includes(\"-\")) {\n throw new Error(\n `Invalid dependency '${dep}' in module '${moduleName}'. Use '/' instead of '-' in Alepha module imports.`,\n );\n }\n dependencies.add(dep);\n }\n }\n\n const module: Module = {\n name: moduleName,\n dependencies: Array.from(dependencies),\n };\n\n if (hasNative) module.native = true;\n if (hasEdge) module.workerd = true;\n if (hasBrowser) module.browser = true;\n if (hasBun) module.bun = true;\n if (hasNode) module.node = true;\n\n modules.push(module);\n } else {\n // No index.ts, check subdirectories for modules\n await scanDirectory(modulePath, moduleName);\n }\n }\n }\n }\n\n await scanDirectory(srcDir, \"\");\n\n // Check for circular dependencies\n detectCircularDependencies(modules);\n\n return modules;\n}\n","import type { Alepha } from \"alepha\";\nimport type { CommandPrimitive } from \"alepha/command\";\nimport {\n type AppEntryOptions,\n appEntryOptions,\n} from \"./atoms/appEntryOptions.ts\";\nimport { type BuildOptions, buildOptions } from \"./atoms/buildOptions.ts\";\n\nexport interface AlephaCliConfig {\n entry?: AppEntryOptions;\n /**\n * Add custom commands to the Alepha CLI.\n *\n * You can override 'deploy', 'build', 'dev', 'start' commands this way.\n * But you can also add your own commands and run them via `alepha <command>`.\n */\n commands?: Record<string, CommandPrimitive>;\n\n /**\n * Register more services to the Alepha CLI (enhancements, commands, etc.).\n */\n services?: Array<any>;\n\n /**\n * Configure Alepha build command.\n */\n build?: BuildOptions;\n\n /**\n * Environment variables to set before running commands.\n *\n * Always use .env files by default, this is only for dynamic values.\n */\n env?: Record<string, unknown>;\n}\n\nexport type AlephaCliConfigFn = (alepha: Alepha) => AlephaCliConfig;\n\nexport const defineConfig = (\n runConfig: AlephaCliConfig | AlephaCliConfigFn,\n) => {\n return (alepha: Alepha) => {\n const config =\n typeof runConfig === \"function\" ? runConfig(alepha) : runConfig;\n\n if (config.services) {\n for (const it of config.services) {\n alepha.with(it);\n }\n }\n\n if (config.env) {\n for (const [key, value] of Object.entries(config.env)) {\n process.env[key] = String(value);\n }\n }\n\n if (config.build) {\n alepha.set(buildOptions, config.build);\n }\n\n if (config.entry) {\n alepha.set(appEntryOptions, config.entry);\n }\n\n return {\n ...config.commands,\n };\n };\n};\n\n/**\n * @alias defineConfig\n */\nexport const defineAlephaConfig = defineConfig;\n"],"mappings":"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"}
|