alepha 0.13.1 → 0.13.2
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 +1 -1
- package/dist/api-files/index.d.ts +28 -91
- package/dist/api-files/index.js +10 -755
- package/dist/api-files/index.js.map +1 -1
- package/dist/api-jobs/index.d.ts +46 -46
- package/dist/api-jobs/index.js +13 -13
- package/dist/api-jobs/index.js.map +1 -1
- package/dist/api-notifications/index.d.ts +129 -146
- package/dist/api-notifications/index.js +17 -39
- package/dist/api-notifications/index.js.map +1 -1
- package/dist/api-parameters/index.d.ts +21 -22
- package/dist/api-parameters/index.js +22 -22
- package/dist/api-parameters/index.js.map +1 -1
- package/dist/api-users/index.d.ts +223 -2000
- package/dist/api-users/index.js +914 -4787
- package/dist/api-users/index.js.map +1 -1
- package/dist/api-verifications/index.d.ts +96 -96
- package/dist/batch/index.d.ts +13 -13
- package/dist/batch/index.js +8 -8
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +14 -14
- package/dist/bucket/index.js +12 -12
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/index.d.ts +11 -11
- package/dist/cache/index.js +9 -9
- package/dist/cache/index.js.map +1 -1
- package/dist/cli/index.d.ts +28 -26
- package/dist/cli/index.js +50 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +19 -19
- package/dist/command/index.js +25 -25
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +218 -218
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +232 -232
- package/dist/core/index.js +218 -218
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +2113 -0
- package/dist/core/index.native.js.map +1 -0
- package/dist/datetime/index.d.ts +9 -9
- package/dist/datetime/index.js +7 -7
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +16 -16
- package/dist/email/index.js +9 -9
- package/dist/email/index.js.map +1 -1
- package/dist/file/index.js +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/index.d.ts +9 -9
- package/dist/lock/index.js +8 -8
- package/dist/lock/index.js.map +1 -1
- package/dist/lock-redis/index.js +3 -66
- package/dist/lock-redis/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -5
- package/dist/logger/index.js +8 -8
- package/dist/logger/index.js.map +1 -1
- package/dist/orm/index.browser.js +114 -114
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.d.ts +218 -218
- package/dist/orm/index.js +46 -46
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/index.d.ts +29 -29
- package/dist/queue/index.js +20 -20
- package/dist/queue/index.js.map +1 -1
- package/dist/queue-redis/index.d.ts +2 -2
- package/dist/redis/index.d.ts +10 -10
- package/dist/retry/index.d.ts +19 -19
- package/dist/retry/index.js +7 -7
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +16 -16
- package/dist/scheduler/index.js +9 -9
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +80 -80
- package/dist/security/index.js +32 -32
- package/dist/security/index.js.map +1 -1
- package/dist/server/index.browser.js +1 -1
- package/dist/server/index.browser.js.map +1 -1
- package/dist/server/index.d.ts +101 -101
- package/dist/server/index.js +16 -16
- package/dist/server/index.js.map +1 -1
- package/dist/server-auth/index.browser.js +4 -982
- package/dist/server-auth/index.browser.js.map +1 -1
- package/dist/server-auth/index.d.ts +204 -785
- package/dist/server-auth/index.js +47 -1239
- package/dist/server-auth/index.js.map +1 -1
- package/dist/server-cache/index.d.ts +10 -10
- package/dist/server-cache/index.js +2 -2
- package/dist/server-cache/index.js.map +1 -1
- package/dist/server-compress/index.d.ts +4 -4
- package/dist/server-compress/index.js +1 -1
- package/dist/server-compress/index.js.map +1 -1
- package/dist/server-cookies/index.browser.js +8 -8
- package/dist/server-cookies/index.browser.js.map +1 -1
- package/dist/server-cookies/index.d.ts +17 -17
- package/dist/server-cookies/index.js +10 -10
- package/dist/server-cookies/index.js.map +1 -1
- package/dist/server-cors/index.d.ts +17 -17
- package/dist/server-cors/index.js +9 -9
- package/dist/server-cors/index.js.map +1 -1
- package/dist/server-health/index.d.ts +19 -19
- package/dist/server-helmet/index.d.ts +1 -1
- package/dist/server-links/index.browser.js +12 -12
- package/dist/server-links/index.browser.js.map +1 -1
- package/dist/server-links/index.d.ts +59 -251
- package/dist/server-links/index.js +23 -502
- package/dist/server-links/index.js.map +1 -1
- package/dist/server-metrics/index.d.ts +4 -4
- package/dist/server-multipart/index.d.ts +2 -2
- package/dist/server-proxy/index.d.ts +12 -12
- package/dist/server-proxy/index.js +10 -10
- package/dist/server-proxy/index.js.map +1 -1
- package/dist/server-rate-limit/index.d.ts +22 -22
- package/dist/server-rate-limit/index.js +12 -12
- package/dist/server-rate-limit/index.js.map +1 -1
- package/dist/server-security/index.d.ts +22 -22
- package/dist/server-security/index.js +15 -15
- package/dist/server-security/index.js.map +1 -1
- package/dist/server-static/index.d.ts +14 -14
- package/dist/server-static/index.js +8 -8
- package/dist/server-static/index.js.map +1 -1
- package/dist/server-swagger/index.d.ts +25 -184
- package/dist/server-swagger/index.js +21 -724
- package/dist/server-swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +14 -14
- package/dist/sms/index.js +9 -9
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +11 -11
- package/dist/thread/index.js +17 -17
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/index.d.ts +26 -26
- package/dist/topic/index.js +16 -16
- package/dist/topic/index.js.map +1 -1
- package/dist/topic-redis/index.d.ts +1 -1
- package/dist/vite/index.d.ts +3 -3
- package/dist/vite/index.js +8 -8
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +11 -11
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +58 -58
- package/dist/websocket/index.js +13 -13
- package/dist/websocket/index.js.map +1 -1
- package/package.json +113 -52
- package/src/api-files/services/FileService.ts +5 -7
- package/src/api-jobs/index.ts +1 -1
- package/src/api-jobs/{descriptors → primitives}/$job.ts +8 -8
- package/src/api-jobs/providers/JobProvider.ts +9 -9
- package/src/api-jobs/services/JobService.ts +5 -5
- package/src/api-notifications/index.ts +5 -15
- package/src/api-notifications/{descriptors → primitives}/$notification.ts +10 -10
- package/src/api-notifications/services/NotificationSenderService.ts +3 -3
- package/src/api-parameters/index.ts +1 -1
- package/src/api-parameters/{descriptors → primitives}/$config.ts +7 -12
- package/src/api-users/index.ts +1 -1
- package/src/api-users/{descriptors → primitives}/$userRealm.ts +8 -8
- package/src/api-users/providers/UserRealmProvider.ts +1 -1
- package/src/batch/index.ts +3 -3
- package/src/batch/{descriptors → primitives}/$batch.ts +13 -16
- package/src/bucket/index.ts +8 -8
- package/src/bucket/{descriptors → primitives}/$bucket.ts +8 -8
- package/src/bucket/providers/LocalFileStorageProvider.ts +3 -3
- package/src/cache/index.ts +4 -4
- package/src/cache/{descriptors → primitives}/$cache.ts +15 -15
- package/src/cli/apps/AlephaPackageBuilderCli.ts +24 -2
- package/src/cli/commands/DrizzleCommands.ts +6 -6
- package/src/cli/commands/VerifyCommands.ts +1 -1
- package/src/cli/commands/ViteCommands.ts +6 -1
- package/src/cli/services/ProjectUtils.ts +34 -3
- package/src/command/index.ts +5 -5
- package/src/command/{descriptors → primitives}/$command.ts +9 -12
- package/src/command/providers/CliProvider.ts +10 -10
- package/src/core/Alepha.ts +30 -33
- package/src/core/constants/KIND.ts +1 -1
- package/src/core/constants/OPTIONS.ts +1 -1
- package/src/core/helpers/{descriptor.ts → primitive.ts} +18 -18
- package/src/core/helpers/ref.ts +1 -1
- package/src/core/index.shared.ts +8 -8
- package/src/core/{descriptors → primitives}/$context.ts +5 -5
- package/src/core/{descriptors → primitives}/$hook.ts +4 -4
- package/src/core/{descriptors → primitives}/$inject.ts +2 -2
- package/src/core/{descriptors → primitives}/$module.ts +9 -9
- package/src/core/{descriptors → primitives}/$use.ts +2 -2
- package/src/core/providers/CodecManager.ts +1 -1
- package/src/core/providers/JsonSchemaCodec.ts +1 -1
- package/src/core/providers/StateManager.ts +2 -2
- package/src/datetime/index.ts +3 -3
- package/src/datetime/{descriptors → primitives}/$interval.ts +6 -6
- package/src/email/index.ts +4 -4
- package/src/email/{descriptors → primitives}/$email.ts +8 -8
- package/src/file/index.ts +1 -1
- package/src/lock/index.ts +3 -3
- package/src/lock/{descriptors → primitives}/$lock.ts +10 -10
- package/src/logger/index.ts +8 -8
- package/src/logger/{descriptors → primitives}/$logger.ts +2 -2
- package/src/logger/services/Logger.ts +1 -1
- package/src/orm/constants/PG_SYMBOLS.ts +2 -2
- package/src/orm/index.browser.ts +2 -2
- package/src/orm/index.ts +8 -8
- package/src/orm/{descriptors → primitives}/$entity.ts +11 -11
- package/src/orm/{descriptors → primitives}/$repository.ts +2 -2
- package/src/orm/{descriptors → primitives}/$sequence.ts +8 -8
- package/src/orm/{descriptors → primitives}/$transaction.ts +4 -4
- package/src/orm/providers/PostgresTypeProvider.ts +3 -3
- package/src/orm/providers/RepositoryProvider.ts +4 -4
- package/src/orm/providers/drivers/DatabaseProvider.ts +7 -7
- package/src/orm/services/ModelBuilder.ts +9 -9
- package/src/orm/services/PgRelationManager.ts +2 -2
- package/src/orm/services/PostgresModelBuilder.ts +5 -5
- package/src/orm/services/Repository.ts +7 -7
- package/src/orm/services/SqliteModelBuilder.ts +5 -5
- package/src/queue/index.ts +7 -7
- package/src/queue/{descriptors → primitives}/$consumer.ts +15 -15
- package/src/queue/{descriptors → primitives}/$queue.ts +12 -12
- package/src/queue/providers/WorkerProvider.ts +7 -7
- package/src/retry/index.ts +3 -3
- package/src/retry/{descriptors → primitives}/$retry.ts +14 -14
- package/src/scheduler/index.ts +3 -3
- package/src/scheduler/{descriptors → primitives}/$scheduler.ts +9 -9
- package/src/scheduler/providers/CronProvider.ts +1 -1
- package/src/security/index.ts +9 -9
- package/src/security/{descriptors → primitives}/$permission.ts +7 -7
- package/src/security/{descriptors → primitives}/$realm.ts +6 -12
- package/src/security/{descriptors → primitives}/$role.ts +12 -12
- package/src/security/{descriptors → primitives}/$serviceAccount.ts +8 -8
- package/src/server/index.browser.ts +1 -1
- package/src/server/index.ts +14 -14
- package/src/server/{descriptors → primitives}/$action.ts +13 -13
- package/src/server/{descriptors → primitives}/$route.ts +9 -9
- package/src/server/providers/NodeHttpServerProvider.ts +1 -1
- package/src/server/services/HttpClient.ts +1 -1
- package/src/server-auth/index.browser.ts +1 -1
- package/src/server-auth/index.ts +6 -6
- package/src/server-auth/{descriptors → primitives}/$auth.ts +10 -10
- package/src/server-auth/{descriptors → primitives}/$authCredentials.ts +4 -4
- package/src/server-auth/{descriptors → primitives}/$authGithub.ts +4 -4
- package/src/server-auth/{descriptors → primitives}/$authGoogle.ts +4 -4
- package/src/server-auth/providers/ServerAuthProvider.ts +4 -4
- package/src/server-cache/providers/ServerCacheProvider.ts +7 -7
- package/src/server-compress/providers/ServerCompressProvider.ts +3 -3
- package/src/server-cookies/index.browser.ts +2 -2
- package/src/server-cookies/index.ts +5 -5
- package/src/server-cookies/{descriptors → primitives}/$cookie.browser.ts +12 -12
- package/src/server-cookies/{descriptors → primitives}/$cookie.ts +13 -13
- package/src/server-cookies/providers/ServerCookiesProvider.ts +4 -4
- package/src/server-cookies/services/CookieParser.ts +1 -1
- package/src/server-cors/index.ts +3 -3
- package/src/server-cors/{descriptors → primitives}/$cors.ts +11 -13
- package/src/server-cors/providers/ServerCorsProvider.ts +5 -5
- package/src/server-links/index.browser.ts +5 -5
- package/src/server-links/index.ts +9 -9
- package/src/server-links/{descriptors → primitives}/$remote.ts +11 -11
- package/src/server-links/providers/LinkProvider.ts +7 -7
- package/src/server-links/providers/{RemoteDescriptorProvider.ts → RemotePrimitiveProvider.ts} +6 -6
- package/src/server-links/providers/ServerLinksProvider.ts +3 -3
- package/src/server-proxy/index.ts +3 -3
- package/src/server-proxy/{descriptors → primitives}/$proxy.ts +8 -8
- package/src/server-proxy/providers/ServerProxyProvider.ts +4 -4
- package/src/server-rate-limit/index.ts +6 -6
- package/src/server-rate-limit/{descriptors → primitives}/$rateLimit.ts +13 -13
- package/src/server-rate-limit/providers/ServerRateLimitProvider.ts +5 -5
- package/src/server-security/index.ts +3 -3
- package/src/server-security/{descriptors → primitives}/$basicAuth.ts +13 -13
- package/src/server-security/providers/ServerBasicAuthProvider.ts +5 -5
- package/src/server-security/providers/ServerSecurityProvider.ts +4 -4
- package/src/server-static/index.ts +3 -3
- package/src/server-static/{descriptors → primitives}/$serve.ts +8 -10
- package/src/server-static/providers/ServerStaticProvider.ts +6 -6
- package/src/server-swagger/index.ts +5 -5
- package/src/server-swagger/{descriptors → primitives}/$swagger.ts +9 -9
- package/src/server-swagger/providers/ServerSwaggerProvider.ts +11 -10
- package/src/sms/index.ts +4 -4
- package/src/sms/{descriptors → primitives}/$sms.ts +8 -8
- package/src/thread/index.ts +3 -3
- package/src/thread/{descriptors → primitives}/$thread.ts +13 -13
- package/src/thread/providers/ThreadProvider.ts +7 -9
- package/src/topic/index.ts +5 -5
- package/src/topic/{descriptors → primitives}/$subscriber.ts +14 -14
- package/src/topic/{descriptors → primitives}/$topic.ts +10 -10
- package/src/topic/providers/TopicProvider.ts +4 -4
- package/src/vite/tasks/copyAssets.ts +1 -1
- package/src/vite/tasks/generateSitemap.ts +3 -3
- package/src/vite/tasks/prerenderPages.ts +2 -2
- package/src/vite/tasks/runAlepha.ts +2 -2
- package/src/websocket/index.browser.ts +3 -3
- package/src/websocket/index.shared.ts +2 -2
- package/src/websocket/index.ts +4 -4
- package/src/websocket/interfaces/WebSocketInterfaces.ts +3 -3
- package/src/websocket/{descriptors → primitives}/$channel.ts +10 -10
- package/src/websocket/{descriptors → primitives}/$websocket.ts +8 -8
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +7 -7
- package/src/websocket/providers/WebSocketServerProvider.ts +3 -3
- package/src/websocket/services/WebSocketClient.ts +5 -5
- package/src/api-notifications/providers/MemorySmsProvider.ts +0 -20
- package/src/api-notifications/providers/SmsProvider.ts +0 -8
- /package/src/core/{descriptors → primitives}/$atom.ts +0 -0
- /package/src/core/{descriptors → primitives}/$env.ts +0 -0
- /package/src/server-auth/{descriptors → primitives}/$authApple.ts +0 -0
- /package/src/server-links/{descriptors → primitives}/$client.ts +0 -0
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["dependencies: Record<string, string>","devDependencies: Record<string, string>","packageJson","tasks: Promise<void>[]","g: any","config: Record<string, any>","viteAlephaBuildOptions: ViteAlephaBuildOptions","modules: Array<Module>","entries: InlineConfig[]","workers: Promise<void>[]","files: string[]","modules: Module[]","module: Module"],"sources":["../../src/cli/services/ProcessRunner.ts","../../src/cli/assets/appRouterTs.ts","../../src/cli/assets/biomeJson.ts","../../src/cli/assets/indexHtml.ts","../../src/cli/assets/mainBrowserTs.ts","../../src/cli/assets/tsconfigJson.ts","../../src/cli/assets/viteConfigTs.ts","../../src/cli/version.ts","../../src/cli/services/ProjectUtils.ts","../../src/cli/commands/BiomeCommands.ts","../../src/cli/commands/CoreCommands.ts","../../src/cli/commands/DrizzleCommands.ts","../../src/cli/commands/VerifyCommands.ts","../../src/cli/commands/ViteCommands.ts","../../src/cli/apps/AlephaCli.ts","../../src/cli/apps/AlephaPackageBuilderCli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $logger } from \"alepha/logger\";\n\n/**\n * Service for running external processes with logging support.\n *\n * This service wraps Node.js child_process functionality and provides:\n * - Automatic logging of executed commands\n * - Promise-based execution\n * - Inherited stdio for seamless output\n * - Working directory context\n * - Config file management in node_modules/.alepha\n */\nexport class ProcessRunner {\n protected readonly log = $logger();\n\n /**\n * Execute a command using npx with inherited stdio.\n *\n * @param command - The command to execute (will be passed to npx)\n * @param env - Optional environment variables to set for the command\n * @returns Promise that resolves when the process exits\n *\n * @example\n * ```ts\n * const runner = alepha.inject(ProcessRunner);\n * await runner.exec(\"tsx watch src/index.ts\");\n * ```\n */\n public async exec(\n command: string,\n env: Record<string, string> = {},\n ): Promise<void> {\n this.log.debug(`Executing command: npx ${command}`, { cwd: process.cwd() });\n\n const prog = spawn(\"npx\", command.split(\" \"), {\n stdio: \"inherit\",\n cwd: process.cwd(),\n env: {\n ...process.env,\n ...env,\n NODE_OPTIONS: \"--import tsx\",\n },\n });\n\n await new Promise<void>((resolve) =>\n prog.on(\"exit\", () => {\n resolve();\n }),\n );\n }\n\n /**\n * Write a configuration file to node_modules/.alepha directory.\n *\n * Creates the .alepha directory if it doesn't exist and writes the file with the given content.\n *\n * @param name - The name of the config file to create\n * @param content - The content to write to the file\n * @param root - The root directory (defaults to process.cwd())\n * @returns The absolute path to the created file\n *\n * @example\n * ```ts\n * const runner = alepha.inject(ProcessRunner);\n * const configPath = await runner.writeConfigFile(\"biome.json\", biomeConfig);\n * ```\n */\n public async writeConfigFile(\n name: string,\n content: string,\n root = process.cwd(),\n ): Promise<string> {\n const dir = join(root, \"node_modules\", \".alepha\");\n\n await mkdir(dir, {\n recursive: true,\n }).catch(() => null);\n\n const path = join(dir, name);\n await writeFile(path, content);\n\n this.log.debug(`Config file written: ${path}`);\n\n return path;\n }\n}\n","export const appRouterTs = () => `\nimport { $page } from \"@alepha/react\";\n\nexport class AppRouter {\n home = $page({\n component: () => \"Hello World\",\n });\n}\n`.trim()\n","export const biomeJson = `\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 \"indentStyle\": \"space\"\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 indexHtml = (\n browserEntry: string,\n) => `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>App</title>\n</head>\n<body>\n<div id=\"root\"></div>\n<script type=\"module\" src=\"${browserEntry}\"></script>\n</body>\n</html>\n`.trim()\n","export const mainBrowserTs = () => `\nimport { Alepha, run } from \"alepha\";\nimport { AppRouter } from \"./AppRouter.ts\";\n\nconst alepha = Alepha.create();\n\nalepha.with(AppRouter);\n\nrun(alepha);\n`.trim()\n","export const tsconfigJson = `\n{\n \"extends\": \"alepha/tsconfig.base\"\n}\n`.trim();\n","export const viteConfigTs = (\n serverEntry?: string,\n) => `\nimport { viteAlepha } from \"alepha/vite\";\n\nexport default {\n plugins: [\n viteAlepha(${serverEntry ? `{ serverEntry: \"${serverEntry}\" }` : \"\"}),\n ],\n test: {\n globals: true,\n },\n};\n`.trim()\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 { access, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $inject, Alepha, AlephaError } from \"alepha\";\nimport { FileSystemProvider } from \"alepha/file\";\nimport { $logger } from \"alepha/logger\";\nimport type { DrizzleKitProvider, RepositoryProvider } from \"alepha/orm\";\nimport { boot } from \"alepha/vite\";\nimport { tsImport } from \"tsx/esm/api\";\nimport { appRouterTs } from \"../assets/appRouterTs.ts\";\nimport { biomeJson } from \"../assets/biomeJson.ts\";\nimport { indexHtml } from \"../assets/indexHtml.ts\";\nimport { mainBrowserTs } from \"../assets/mainBrowserTs.ts\";\nimport { tsconfigJson } from \"../assets/tsconfigJson.ts\";\nimport { viteConfigTs } from \"../assets/viteConfigTs.ts\";\nimport { version } from \"../version.ts\";\nimport { ProcessRunner } from \"./ProcessRunner.ts\";\n\n/**\n * Utility service for common project operations used by CLI commands.\n *\n * This service provides helper methods for:\n * - Project configuration file management (tsconfig.json, package.json, etc.)\n * - Package manager setup (Yarn, npm, pnpm)\n * - Sample project downloading\n * - Drizzle ORM/Kit utilities\n * - Alepha instance loading\n */\nexport class ProjectUtils {\n protected readonly log = $logger();\n protected readonly runner = $inject(ProcessRunner);\n protected readonly fs = $inject(FileSystemProvider);\n\n // ===================================================================================================================\n // Package Manager & Project Setup\n // ===================================================================================================================\n\n /**\n * Ensure Yarn is configured in the project directory.\n *\n * Creates a .yarnrc.yml file with node-modules linker if it doesn't exist.\n *\n * @param root - The root directory of the project\n */\n public async ensureYarn(root: string): Promise<void> {\n await this.ensureFileExists(\n root,\n \".yarnrc.yml\",\n \"nodeLinker: node-modules\",\n false,\n );\n\n // remove lock files from other package managers\n await this.fs.rm(join(root, \"package-lock.json\"), { force: true });\n await this.fs.rm(join(root, \"pnpm-lock.yaml\"), { force: true });\n }\n\n /**\n * Generate package.json content with Alepha dependencies.\n *\n * @param modes - Configuration for which dependencies to include\n * @returns Package.json partial with dependencies, devDependencies, and scripts\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 dependencies: Record<string, string> = {\n alepha: `^${version}`,\n };\n\n const devDependencies: Record<string, string> = {};\n\n if (modes.react) {\n dependencies[\"@alepha/react\"] = `^${version}`;\n dependencies.react = \"^19.2.0\";\n dependencies[\"react-dom\"] = \"^19.2.0\";\n devDependencies[\"@types/react\"] = \"^19.2.0\";\n }\n\n if (modes.admin) {\n dependencies[\"@alepha/ui\"] = `^${version}`;\n }\n\n return {\n type: \"module\",\n dependencies,\n devDependencies,\n scripts: {\n dev: \"alepha dev\",\n build: \"alepha build\",\n verify: \"alepha verify\",\n },\n };\n }\n\n /**\n * Ensure package.json exists and has correct configuration.\n *\n * Creates a new package.json if none exists, or updates an existing one to:\n * - Set \"type\": \"module\"\n * - Add Alepha dependencies\n * - Add standard scripts\n *\n * @param root - The root directory of the project\n * @param modes - Configuration for which dependencies to include\n */\n public async ensurePackageJson(\n root: string,\n modes: DependencyModes,\n ): Promise<void> {\n const packageJsonPath = join(root, \"package.json\");\n try {\n await access(packageJsonPath);\n } catch (error) {\n await writeFile(\n packageJsonPath,\n JSON.stringify(this.generatePackageJsonContent(modes), null, 2),\n );\n return;\n }\n\n const content = await readFile(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(content);\n\n const newPackageJson = this.generatePackageJsonContent(modes);\n\n packageJson.type = \"module\";\n packageJson.dependencies ??= {};\n packageJson.devDependencies ??= {};\n packageJson.scripts ??= {};\n\n Object.assign(packageJson.dependencies, newPackageJson.dependencies);\n Object.assign(packageJson.devDependencies, newPackageJson.devDependencies);\n Object.assign(packageJson.scripts, newPackageJson.scripts);\n\n await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));\n }\n\n public async ensureConfig(\n root: string,\n opts: {\n packageJson?: boolean | DependencyModes;\n tsconfigJson?: boolean;\n viteConfigTs?: boolean;\n indexHtml?: boolean;\n biomeJson?: boolean;\n },\n ) {\n const tasks: Promise<void>[] = [];\n\n if (opts.packageJson) {\n tasks.push(\n this.ensurePackageJson(\n root,\n typeof opts.packageJson === \"boolean\" ? {} : opts.packageJson,\n ),\n );\n }\n if (opts.tsconfigJson) {\n tasks.push(this.ensureTsConfig(root));\n }\n if (opts.viteConfigTs) {\n tasks.push(this.ensureViteConfig(root));\n }\n if (opts.indexHtml) {\n tasks.push(this.ensureIndexHtml(root));\n }\n if (opts.biomeJson) {\n tasks.push(this.ensureBiomeConfig(root));\n }\n\n await Promise.all(tasks);\n }\n\n /**\n * Ensure package.json exists and is configured as ES module.\n *\n * Similar to ensurePackageJson but only validates/sets the \"type\": \"module\" field.\n * Throws an error if no package.json exists.\n *\n * @param root - The root directory of the project\n * @throws {AlephaError} If no package.json is found\n */\n public async ensurePackageJsonModule(root: string): Promise<void> {\n const packageJsonPath = join(root, \"package.json\");\n try {\n await access(packageJsonPath);\n } catch (error) {\n throw new AlephaError(\n \"No package.json found in project root. Run 'npx alepha init' to create one.\",\n );\n }\n\n const content = await readFile(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(content);\n if (!packageJson.type || packageJson.type !== \"module\") {\n packageJson.type = \"module\";\n await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));\n }\n }\n\n /**\n * Ensure tsconfig.json exists in the project.\n *\n * Creates a standard Alepha tsconfig.json if none exists.\n *\n * @param root - The root directory of the project\n */\n public async ensureTsConfig(root: string): Promise<void> {\n await this.ensureFileExists(root, \"tsconfig.json\", tsconfigJson, true);\n }\n\n /**\n * Ensure vite.config.ts exists in the project.\n *\n * Creates a standard Alepha vite.config.ts if none exists.\n */\n public async ensureViteConfig(root: string): Promise<void> {\n await this.ensureFileExists(root, \"vite.config.ts\", viteConfigTs(), false);\n }\n\n protected async ensureFileExists(\n root: string,\n name: string,\n content: string,\n checkParentDirectories: boolean = false,\n ): Promise<void> {\n const configPath = join(root, name);\n\n if (!checkParentDirectories) {\n try {\n await access(configPath);\n return;\n } catch {\n await writeFile(configPath, content);\n return;\n }\n }\n\n let found = false;\n let currentDir = root;\n const maxIterations = 10; // safety to prevent infinite loops\n let level = 0;\n\n while (level < maxIterations) {\n try {\n await access(join(currentDir, name));\n found = true;\n break;\n } catch {\n const parentDir = join(currentDir, \"..\");\n if (parentDir === currentDir) {\n break;\n }\n currentDir = parentDir;\n }\n level += 1;\n }\n\n if (!found) {\n await writeFile(configPath, content);\n }\n }\n\n // ===================================================================================================================\n // Biome Configuration\n // ===================================================================================================================\n\n /**\n * Get the path to Biome configuration file.\n *\n * Looks for an existing biome.json in the project root, or creates one if it doesn't exist.\n */\n public async ensureBiomeConfig(root: string): Promise<void> {\n await this.ensureFileExists(root, \"biome.json\", biomeJson, true);\n }\n\n // ===================================================================================================================\n // Vite Configuration\n // ===================================================================================================================\n\n /**\n * Get the path to Vite configuration file.\n *\n * Looks for an existing vite.config.ts in the project root, or creates one if it doesn't exist.\n *\n * @param root - The root directory of the project (defaults to process.cwd())\n * @param serverEntry - Optional path to the server entry file to include in the config\n * @returns Absolute path to the vite.config.ts file\n */\n public async getViteConfigPath(\n root: string,\n serverEntry?: string,\n ): Promise<string> {\n try {\n const viteConfigPath = join(root, \"vite.config.ts\");\n await access(viteConfigPath);\n return viteConfigPath;\n } catch {\n return this.runner.writeConfigFile(\n \"vite.config.ts\",\n viteConfigTs(serverEntry),\n );\n }\n }\n\n // ===================================================================================================================\n // Drizzle ORM & Kit Utilities\n // ===================================================================================================================\n\n /**\n * Load Alepha instance from a server entry file.\n *\n * Dynamically imports the server entry file and extracts the Alepha instance.\n * Skips the automatic start process.\n *\n * @param rootDir - The root directory of the project\n * @param explicitEntry - Optional explicit path to the entry file\n * @returns Object containing the Alepha instance and the entry file path\n * @throws {AlephaError} If the Alepha instance cannot be found\n */\n public async loadAlephaFromServerEntryFile(\n rootDir?: string,\n explicitEntry?: string,\n ): Promise<{\n alepha: Alepha;\n entry: string;\n }> {\n process.env.ALEPHA_CLI_IMPORT = \"true\";\n\n const entry = await boot.getServerEntry(rootDir, explicitEntry);\n const mod = await tsImport(entry, {\n parentURL: import.meta.url,\n });\n\n this.log.debug(`Load entry: ${entry}`);\n\n // check if alepha is correctly exported\n if (mod.default instanceof Alepha) {\n return {\n alepha: mod.default,\n entry,\n };\n }\n\n // else, try with global variable\n const g: any = global;\n if (g.__alepha) {\n return {\n alepha: g.__alepha,\n entry,\n };\n }\n\n throw new AlephaError(\n `Could not find Alepha instance in entry file: ${entry}`,\n );\n }\n\n /**\n * Generate JavaScript code for Drizzle entities export.\n *\n * Creates a temporary entities.js file that imports from the entry file\n * and exports database models for Drizzle Kit to process.\n *\n * @param entry - Path to the server entry file\n * @param provider - Name of the database provider\n * @param models - Array of model names to export\n * @returns JavaScript code as a string\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 * Prepare Drizzle configuration files for a database provider.\n *\n * Creates temporary entities.js and drizzle.config.js files needed\n * for Drizzle Kit commands to run properly.\n *\n * @param options - Configuration options including kit, provider info, and paths\n * @returns Path to the generated drizzle.config.js file\n */\n public async prepareDrizzleConfig(options: {\n kit: any;\n provider: any;\n providerName: string;\n providerUrl: 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.generateEntitiesJs(\n options.entry,\n options.providerName,\n models,\n );\n\n const entitiesJsPath = await this.runner.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.providerName === \"pglite\") {\n config.driver = \"pglite\";\n }\n\n const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;\n\n return await this.runner.writeConfigFile(\n \"drizzle.config.js\",\n drizzleConfigJs,\n options.rootDir,\n );\n }\n\n /**\n * Run a drizzle-kit command for all database providers in an Alepha instance.\n *\n * Iterates through all repository providers, prepares Drizzle config for each,\n * and executes the specified drizzle-kit command.\n *\n * @param options - Configuration including command to run, flags, and logging\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 }): Promise<void> {\n const rootDir = options.root;\n this.log.debug(`Using project root: ${rootDir}`);\n\n const { alepha, entry } = await this.loadAlephaFromServerEntryFile(\n rootDir,\n options.args,\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 descriptor of repositoryProvider.getRepositories()) {\n const provider = descriptor.provider;\n const providerName = provider.name;\n const dialect = provider.dialect;\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 dialect,\n entry,\n rootDir,\n });\n\n const flags = options.commandFlags ? ` ${options.commandFlags}` : \"\";\n await this.runner.exec(\n `drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`,\n );\n }\n }\n\n public async getPackageManager(\n root: string,\n ): Promise<\"yarn\" | \"pnpm\" | \"npm\"> {\n if (await this.fs.exists(join(root, \"yarn.lock\"))) {\n return \"yarn\";\n } else if (await this.fs.exists(join(root, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n } else {\n return \"npm\";\n }\n }\n\n public async ensureIndexHtml(root: string) {\n if (await this.fs.exists(join(root, \"index.html\"))) {\n return;\n }\n\n const serverEntry = \"src/main.server.ts\";\n const browserEntry = \"src/main.browser.ts\";\n const appRouter = \"src/AppRouter.ts\";\n\n await this.fs.writeFile(join(root, \"index.html\"), indexHtml(browserEntry));\n\n try {\n await this.fs.mkdir(join(root, \"src\"), { recursive: true });\n } catch {}\n\n if (!(await this.fs.exists(join(root, browserEntry)))) {\n await this.fs.writeFile(join(root, browserEntry), mainBrowserTs());\n }\n\n if (!(await this.fs.exists(join(root, serverEntry)))) {\n await this.fs.writeFile(join(root, serverEntry), mainBrowserTs());\n }\n\n if (!(await this.fs.exists(join(root, appRouter)))) {\n await this.fs.writeFile(join(root, appRouter), appRouterTs());\n }\n }\n\n public async hasDir(root: string, dirName: string): Promise<boolean> {\n return this.fs.exists(join(root, dirName));\n }\n\n async readPackageJson(root: string): Promise<Record<string, any>> {\n const packageJson = await this.fs\n .createFile({\n path: join(root, \"package.json\"),\n })\n .text();\n return JSON.parse(packageJson);\n }\n}\n\nexport interface DependencyModes {\n react?: boolean;\n admin?: boolean;\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\n\nexport class BiomeCommands {\n protected readonly log = $logger();\n protected readonly runner = $inject(ProcessRunner);\n protected readonly utils = $inject(ProjectUtils);\n\n public readonly format = $command({\n name: \"format\",\n description: \"Format the codebase using Biome\",\n handler: async ({ root }) => {\n await this.utils.ensureConfig(root, { biomeJson: true });\n await this.runner.exec(`biome format --fix`);\n },\n });\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.utils.ensureConfig(root, { biomeJson: true });\n await this.runner.exec(`biome check --formatter-enabled=false --fix`);\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command, CliProvider } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\nimport { version } from \"../version.ts\";\n\nexport class CoreCommands {\n protected readonly log = $logger();\n protected readonly cli = $inject(CliProvider);\n protected readonly utils = $inject(ProjectUtils);\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(version);\n return;\n }\n\n this.cli.printHelp();\n },\n });\n\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 /**\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 flags: t.object({\n // TODO:\n // force: t.boolean({\n // description: \"If true, all config files will be overwritten\",\n // }),\n // choose package manager\n yarn: t.optional(t.boolean({ description: \"Use Yarn package manager\" })),\n pnpm: t.optional(t.boolean({ description: \"Use pnpm package manager\" })),\n // choose which dependencies to add\n react: t.optional(\n t.boolean({ description: \"Include Alepha React dependencies\" }),\n ),\n admin: t.optional(\n t.boolean({ description: \"Include Alepha admin panel dependencies\" }),\n ),\n }),\n handler: async ({ run, flags, root }) => {\n await run({\n name: \"Ensuring configuration files\",\n handler: async () => {\n await this.utils.ensureConfig(root, {\n tsconfigJson: true,\n packageJson: flags,\n biomeJson: true,\n viteConfigTs: true,\n indexHtml: !!flags.react,\n });\n },\n });\n\n // TODO: check if all alepha dependencies are same version\n\n const guessedPm = await this.utils.getPackageManager(root);\n\n if (flags.yarn || guessedPm === \"yarn\") {\n await this.utils.ensureYarn(root);\n await run(\"yarn set version stable\");\n await run(\"yarn install\", {\n alias: \"Installing dependencies with Yarn\",\n });\n } else {\n await run(\"npm install\", {\n alias: \"Installing dependencies with npm\",\n });\n }\n },\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $inject, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport type { DrizzleKitProvider, RepositoryProvider } from \"alepha/orm\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.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});\n\nexport class DrizzleCommands {\n log = $logger();\n runner = $inject(ProcessRunner);\n utils = $inject(ProjectUtils);\n\n /**\n * Check if database migrations are up to date.\n */\n check = $command({\n name: \"db: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 { alepha } = await this.utils.loadAlephaFromServerEntryFile(\n rootDir,\n args,\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 descriptor of repositoryProvider.getRepositories()) {\n const provider = descriptor.provider;\n const providerName = provider.name;\n if (accepted.has(providerName)) {\n continue;\n }\n\n accepted.add(providerName);\n\n const migrationDir = join(rootDir, \"migrations\", providerName);\n\n const journalFile = await readFile(\n `${migrationDir}/meta/_journal.json`,\n \"utf-8\",\n ).catch(() => null);\n\n if (!journalFile) {\n this.log.info(`No migration journal found.`);\n return;\n }\n\n const journal = JSON.parse(journalFile);\n const lastMigration = journal.entries[journal.entries.length - 1];\n const lastSnapshot = JSON.parse(\n await readFile(\n `${migrationDir}/meta/${String(lastMigration.idx).padStart(4, \"0\")}_snapshot.json`,\n \"utf-8\",\n ),\n );\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 * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository descriptors to gather database models.\n * - Creates temporary entity definitions based on the current database schema.\n * - Writes these definitions to a temporary schema file. (node_modules/.db/entities.ts)\n * - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.\n */\n generate = $command({\n name: \"db:generate\",\n description: \"Generate migration files based on current database schema\",\n summary: false,\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 await this.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"generate\",\n commandFlags,\n provider: flags.provider,\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 * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository descriptors to gather database models.\n * - Creates temporary entity definitions and Drizzle config.\n * - Invokes Drizzle Kit's push command to apply schema changes directly.\n */\n push = $command({\n name: \"db:push\",\n description: \"Push database schema changes directly to the database\",\n summary: false,\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.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"push\",\n provider: flags.provider,\n logMessage: (providerName, dialect) =>\n `Push '${providerName}' schema (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Apply pending database migrations\n *\n * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository descriptors to gather database models.\n * - Creates temporary entity definitions and Drizzle config.\n * - Invokes Drizzle Kit's migrate command to apply pending migrations.\n */\n migrate = $command({\n name: \"db:migrate\",\n description: \"Apply pending database migrations\",\n summary: false,\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.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"migrate\",\n provider: flags.provider,\n logMessage: (providerName, dialect) =>\n `Migrate '${providerName}' database (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Launch Drizzle Studio database browser\n *\n * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository descriptors to gather database models.\n * - Creates temporary entity definitions and Drizzle config.\n * - Invokes Drizzle Kit's studio command to launch the web-based database browser.\n */\n studio = $command({\n name: \"db:studio\",\n description: \"Launch Drizzle Studio database browser\",\n summary: false,\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.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"studio\",\n provider: flags.provider,\n logMessage: (providerName, dialect) =>\n `Launch Studio for '${providerName}' (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Drop database schema (development only)\n *\n * @experimental\n */\n drop = $command({\n name: \"db:drop\",\n description: \"Drop database schema (development only)\",\n summary: false,\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 ({ flags }) => {\n // TODO: Implement db:drop\n this.log.warn(\"db:drop is not yet implemented\");\n if (flags.provider) {\n this.log.info(`Provider filter: ${flags.provider}`);\n }\n },\n });\n\n /**\n * Seed database with initial data\n *\n * @experimental\n */\n seed = $command({\n name: \"db:seed\",\n description: \"Seed database with initial data\",\n summary: false,\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 ({ flags }) => {\n // TODO: Implement db:seed\n this.log.warn(\"db:seed is not yet implemented\");\n if (flags.provider) {\n this.log.info(`Provider filter: ${flags.provider}`);\n }\n },\n });\n\n /**\n * Show pending database migrations status\n *\n * @experimental\n */\n status = $command({\n name: \"db:status\",\n description: \"Show pending database migrations status\",\n summary: false,\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 ({ flags }) => {\n // TODO: Implement db:status\n this.log.warn(\"db:status is not yet implemented\");\n if (flags.provider) {\n this.log.info(`Provider filter: ${flags.provider}`);\n }\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\n\nexport class VerifyCommands {\n protected readonly processRunner = $inject(ProcessRunner);\n protected readonly utils = $inject(ProjectUtils);\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.utils.readPackageJson(root);\n if (pkg.devDependencies?.vitest) {\n await run(\"alepha test\");\n }\n\n if (await this.utils.hasDir(root, \"migrations\")) {\n await run(\"alepha db:check-migrations\");\n }\n\n await run(\"alepha build\");\n await run(\"alepha clean\");\n },\n });\n\n /**\n * Run TypeScript type checking across the codebase with no emit.\n */\n public readonly typecheck = $command({\n name: \"typecheck\",\n description: \"Check TypeScript types across the codebase\",\n handler: async () => {\n await this.processRunner.exec(\"tsc --noEmit\");\n },\n });\n}\n","import { access, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $env, $inject, OPTIONS, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport {\n boot,\n buildClient,\n buildServer,\n copyAssets,\n generateCloudflare,\n generateDocker,\n generateSitemap,\n generateVercel,\n prerenderPages,\n type ViteAlephaBuildOptions,\n} from \"alepha/vite\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\n\nexport class ViteCommands {\n protected readonly log = $logger();\n protected readonly runner = $inject(ProcessRunner);\n protected readonly utils = $inject(ProjectUtils);\n\n protected readonly env = $env(\n t.object({\n VITEST_ARGS: t.string({ default: \"\" }),\n }),\n );\n\n public readonly run = $command({\n name: \"run\",\n description: \"Run a TypeScript file directly\",\n flags: t.object({\n watch: t.optional(\n t.boolean({ description: \"Watch file for changes\", alias: \"w\" }),\n ),\n }),\n summary: false,\n args: t.text({ title: \"path\", description: \"Filepath to run\" }),\n handler: async ({ args, flags, root }) => {\n await this.utils.ensureTsConfig(root);\n await this.runner.exec(`tsx ${flags.watch ? \"watch \" : \"\"}${args}`);\n },\n });\n\n /**\n * Will run the project in watch mode.\n *\n * - If an index.html file is found in the project root, it will run Vite in dev mode.\n * - Otherwise, it will look for a server entry file and run it with tsx in watch mode.\n */\n public readonly dev = $command({\n name: \"dev\",\n description: \"Run the project in development mode\",\n args: t.optional(t.text({ title: \"path\", description: \"Filepath to run\" })),\n handler: async ({ args, root }) => {\n await this.utils.ensureConfig(root, {\n viteConfigTs: true,\n tsconfigJson: true,\n });\n\n const entry = await boot.getServerEntry(root, args);\n this.log.trace(\"Entry file found\", { entry });\n\n try {\n await access(join(root, \"index.html\"));\n } catch {\n this.log.trace(\"No index.html found, running entry file with tsx\");\n await this.runner.exec(`tsx watch ${entry}`);\n return;\n }\n\n await this.runner.exec(`vite`);\n },\n });\n\n public readonly build = $command({\n name: \"build\",\n description: \"Build the project for production\",\n args: t.optional(\n t.text({ title: \"path\", description: \"Filepath to build\" }),\n ),\n flags: t.object({\n stats: t.optional(\n t.boolean({\n description: \"Generate build stats report\",\n }),\n ),\n vercel: t.optional(\n t.boolean({\n description: \"Generate Vercel deployment configuration\",\n }),\n ),\n cloudflare: t.optional(\n t.boolean({\n description: \"Generate Cloudflare Workers configuration\",\n }),\n ),\n docker: t.optional(\n t.boolean({\n description: \"Generate Docker configuration\",\n }),\n ),\n sitemap: t.optional(\n t.text({\n description: \"Generate sitemap.xml with base URL\",\n }),\n ),\n prerender: t.optional(\n t.boolean({\n description: \"Pre-render static pages\",\n }),\n ),\n }),\n handler: async ({ flags, args, run, root }) => {\n // Tell viteAlephaBuild plugin to skip - CLI handles all tasks\n process.env.ALEPHA_BUILD_MODE = \"cli\";\n\n await this.utils.ensureConfig(root, {\n viteConfigTs: true,\n tsconfigJson: true,\n });\n\n const entry = await boot.getServerEntry(root, args);\n this.log.trace(\"Entry file found\", { entry });\n\n const distDir = \"dist\";\n const clientDir = \"public\";\n\n await run.rm(\"dist\", {\n alias: \"clean dist\",\n });\n\n const viteConfig = await import(join(root, \"vite.config.ts\"));\n const viteAlephaBuildOptions: ViteAlephaBuildOptions =\n viteConfig?.default?.plugins.find((it: any) => !!it[OPTIONS])?.[\n OPTIONS\n ] ?? {};\n\n const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;\n\n let hasClient = false;\n try {\n await access(join(root, \"index.html\"));\n hasClient = true;\n } catch {\n // No index.html\n }\n\n // Build client\n if (hasClient) {\n await run({\n name: \"vite build client\",\n handler: () =>\n buildClient({\n silent: true,\n dist: `${distDir}/${clientDir}`,\n stats,\n }),\n });\n }\n\n // Build server\n await run({\n name: \"vite build server\",\n handler: async () => {\n // Check if client template exists\n let clientBuilt = false;\n try {\n await readFile(`${distDir}/${clientDir}/index.html`, \"utf-8\");\n clientBuilt = true;\n } catch {\n // No client build\n }\n\n await buildServer({\n silent: true,\n entry,\n distDir,\n clientDir: clientBuilt ? clientDir : undefined,\n stats,\n });\n\n // Server will handle index.html if both client & server are built\n if (clientBuilt) {\n await unlink(`${distDir}/${clientDir}/index.html`);\n }\n },\n });\n\n // Copy assets\n // TODO: only copy if assets are found? Currently will always run\n await run({\n name: \"copy assets\",\n handler: () =>\n copyAssets({\n entry: `${distDir}/index.js`,\n distDir,\n }),\n });\n\n if (hasClient) {\n // Generate sitemap\n const sitemapBaseUrl =\n flags.sitemap ??\n (typeof viteAlephaBuildOptions.client === \"object\"\n ? viteAlephaBuildOptions.client.sitemap?.hostname\n : undefined);\n\n if (sitemapBaseUrl) {\n await run({\n name: \"add sitemap\",\n handler: async () => {\n await writeFile(\n `${distDir}/${clientDir}/sitemap.xml`,\n await generateSitemap({\n entry: `${distDir}/index.js`,\n baseUrl: sitemapBaseUrl,\n }),\n );\n },\n });\n }\n\n // Pre-render static pages\n const shouldPrerender =\n flags.prerender ??\n (typeof viteAlephaBuildOptions.client === \"object\"\n ? viteAlephaBuildOptions.client.prerender\n : false);\n\n if (shouldPrerender) {\n await run({\n name: \"pre-render pages\",\n handler: async () => {\n await prerenderPages({\n dist: `${distDir}/${clientDir}`,\n entry: `${distDir}/index.js`,\n });\n },\n });\n }\n }\n\n // Generate deployment configurations\n if (flags.vercel || viteAlephaBuildOptions.vercel) {\n const config =\n typeof viteAlephaBuildOptions.vercel === \"object\"\n ? viteAlephaBuildOptions.vercel\n : {};\n await run({\n name: \"add Vercel config\",\n handler: () =>\n generateVercel({\n distDir,\n clientDir,\n config,\n }),\n });\n }\n\n if (flags.cloudflare || viteAlephaBuildOptions.cloudflare) {\n await run({\n name: \"add Cloudflare config\",\n handler: () =>\n generateCloudflare({\n distDir,\n }),\n });\n }\n\n if (flags.docker || viteAlephaBuildOptions.docker) {\n const dockerConfig =\n typeof viteAlephaBuildOptions.docker === \"object\"\n ? viteAlephaBuildOptions.docker\n : {};\n await run({\n name: \"add Docker config\",\n handler: () =>\n generateDocker({\n distDir,\n ...dockerConfig,\n }),\n });\n }\n },\n });\n\n public readonly test = $command({\n name: \"test\",\n description: \"Run tests using Vitest\",\n handler: async ({ root }) => {\n await this.utils.ensureConfig(root, {\n tsconfigJson: true,\n viteConfigTs: true,\n });\n\n // check if vitest is installed\n try {\n await import(\"vitest\");\n } catch {\n this.log.error(\n \"Vitest is not installed. Please install it with `npm install -D vitest` or `yarn add -D vitest`.\",\n );\n process.exit(1);\n }\n\n await this.runner.exec(`vitest run ${this.env.VITEST_ARGS}`);\n },\n });\n}\n","import { $module } from \"alepha\";\nimport { BiomeCommands } from \"../commands/BiomeCommands.ts\";\nimport { CoreCommands } from \"../commands/CoreCommands.ts\";\nimport { DrizzleCommands } from \"../commands/DrizzleCommands.ts\";\nimport { VerifyCommands } from \"../commands/VerifyCommands.ts\";\nimport { ViteCommands } from \"../commands/ViteCommands.ts\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\n\nexport const AlephaCli = $module({\n name: \"alepha.cli\",\n services: [\n ProcessRunner,\n CoreCommands,\n DrizzleCommands,\n VerifyCommands,\n ViteCommands,\n BiomeCommands,\n ],\n});\n","import { access, readdir, readFile } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { join } from \"node:path\";\nimport { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { FileSystemProvider } from \"alepha/file\";\nimport type { InlineConfig } from \"tsdown\";\n\ninterface Module {\n name: string;\n dependencies: string[];\n browser?: 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 pkg = await readFile(\"package.json\", \"utf-8\");\n const pkgData = JSON.parse(pkg);\n const packageName = pkgData.name as string;\n\n await run(\"analyze modules\", async () => {\n modules.push(\n ...(await analyzeModules(join(root, this.src), packageName)),\n );\n });\n\n pkgData.exports = {};\n\n for (const item of modules) {\n const path =\n item.name === \"core\" ? \".\" : `./${item.name.replace(\"-\", \"/\")}`;\n pkgData.exports[path] = {};\n // order is important here for compatibility\n pkgData.exports[path].types = `./src/${item.name}/index.ts`;\n if (item.browser) {\n pkgData.exports[path].browser = `./src/${item.name}/index.browser.ts`;\n }\n pkgData.exports[path].import = `./src/${item.name}/index.ts`;\n pkgData.exports[path].require = `./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\"] = \"./styles.css\";\n }\n\n await this.fs.writeFile(\"package.json\", JSON.stringify(pkgData, null, 2));\n\n const tmpDir = join(root, \"node_modules/.alepha\");\n await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});\n\n await this.fs.writeFile(\n join(tmpDir, \"module-dependencies.json\"),\n JSON.stringify(modules, null, 2),\n );\n\n const external = [\n \"alepha\",\n packageName,\n ...modules.map((item) => `${packageName}/${item.name}`),\n ];\n\n await run.rm(this.dist);\n\n const build = async (item: Module) => {\n const entries: InlineConfig[] = [];\n const src = join(root, this.src, item.name);\n const dest = join(root, this.dist, item.name);\n\n entries.push({\n entry: 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 external,\n });\n\n if (item.browser) {\n entries.push({\n entry: join(src, \"index.browser.ts\"),\n outDir: dest,\n platform: \"browser\",\n sourcemap: true,\n dts: false,\n external,\n });\n }\n\n const config = join(tmpDir, `tsdown-${item.name}.config.js`);\n await this.fs.writeFile(\n config,\n `export default ${JSON.stringify(entries, null, 2)};`,\n );\n await run(`npx tsdown -c=${config}`);\n await this.fs.rm(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\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 Error(`Circular dependency detected: ${cycle.join(\" -> \")}`);\n }\n }\n}\n\nexport async function analyzeModules(\n srcDir: string,\n packageName: string,\n): Promise<Module[]> {\n const modules: Module[] = [];\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const moduleName = entry.name;\n const modulePath = join(srcDir, moduleName);\n const dependencies = new Set<string>();\n\n // Check for browser/node entry points\n const hasBrowser = await fileExists(join(modulePath, \"index.browser.ts\"));\n const hasNode = await fileExists(join(modulePath, \"index.node.ts\"));\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 (hasBrowser) module.browser = true;\n if (hasNode) module.node = true;\n\n modules.push(module);\n }\n }\n\n // Check for circular dependencies\n detectCircularDependencies(modules);\n\n return modules;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["dependencies: Record<string, string>","devDependencies: Record<string, string>","packageJson","tasks: Promise<void>[]","g: any","config: Record<string, any>","viteAlephaBuildOptions: ViteAlephaBuildOptions","modules: Array<Module>","entries: InlineConfig[]","workers: Promise<void>[]","files: string[]","modules: Module[]","module: Module"],"sources":["../../src/cli/services/ProcessRunner.ts","../../src/cli/assets/appRouterTs.ts","../../src/cli/assets/biomeJson.ts","../../src/cli/assets/indexHtml.ts","../../src/cli/assets/mainBrowserTs.ts","../../src/cli/assets/tsconfigJson.ts","../../src/cli/assets/viteConfigTs.ts","../../src/cli/version.ts","../../src/cli/services/ProjectUtils.ts","../../src/cli/commands/BiomeCommands.ts","../../src/cli/commands/CoreCommands.ts","../../src/cli/commands/DrizzleCommands.ts","../../src/cli/commands/VerifyCommands.ts","../../src/cli/commands/ViteCommands.ts","../../src/cli/apps/AlephaCli.ts","../../src/cli/apps/AlephaPackageBuilderCli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $logger } from \"alepha/logger\";\n\n/**\n * Service for running external processes with logging support.\n *\n * This service wraps Node.js child_process functionality and provides:\n * - Automatic logging of executed commands\n * - Promise-based execution\n * - Inherited stdio for seamless output\n * - Working directory context\n * - Config file management in node_modules/.alepha\n */\nexport class ProcessRunner {\n protected readonly log = $logger();\n\n /**\n * Execute a command using npx with inherited stdio.\n *\n * @param command - The command to execute (will be passed to npx)\n * @param env - Optional environment variables to set for the command\n * @returns Promise that resolves when the process exits\n *\n * @example\n * ```ts\n * const runner = alepha.inject(ProcessRunner);\n * await runner.exec(\"tsx watch src/index.ts\");\n * ```\n */\n public async exec(\n command: string,\n env: Record<string, string> = {},\n ): Promise<void> {\n this.log.debug(`Executing command: npx ${command}`, { cwd: process.cwd() });\n\n const prog = spawn(\"npx\", command.split(\" \"), {\n stdio: \"inherit\",\n cwd: process.cwd(),\n env: {\n ...process.env,\n ...env,\n NODE_OPTIONS: \"--import tsx\",\n },\n });\n\n await new Promise<void>((resolve) =>\n prog.on(\"exit\", () => {\n resolve();\n }),\n );\n }\n\n /**\n * Write a configuration file to node_modules/.alepha directory.\n *\n * Creates the .alepha directory if it doesn't exist and writes the file with the given content.\n *\n * @param name - The name of the config file to create\n * @param content - The content to write to the file\n * @param root - The root directory (defaults to process.cwd())\n * @returns The absolute path to the created file\n *\n * @example\n * ```ts\n * const runner = alepha.inject(ProcessRunner);\n * const configPath = await runner.writeConfigFile(\"biome.json\", biomeConfig);\n * ```\n */\n public async writeConfigFile(\n name: string,\n content: string,\n root = process.cwd(),\n ): Promise<string> {\n const dir = join(root, \"node_modules\", \".alepha\");\n\n await mkdir(dir, {\n recursive: true,\n }).catch(() => null);\n\n const path = join(dir, name);\n await writeFile(path, content);\n\n this.log.debug(`Config file written: ${path}`);\n\n return path;\n }\n}\n","export const appRouterTs = () => `\nimport { $page } from \"@alepha/react\";\n\nexport class AppRouter {\n home = $page({\n component: () => \"Hello World\",\n });\n}\n`.trim()\n","export const biomeJson = `\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 \"indentStyle\": \"space\"\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 indexHtml = (\n browserEntry: string,\n) => `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>App</title>\n</head>\n<body>\n<div id=\"root\"></div>\n<script type=\"module\" src=\"${browserEntry}\"></script>\n</body>\n</html>\n`.trim()\n","export const mainBrowserTs = () => `\nimport { Alepha, run } from \"alepha\";\nimport { AppRouter } from \"./AppRouter.ts\";\n\nconst alepha = Alepha.create();\n\nalepha.with(AppRouter);\n\nrun(alepha);\n`.trim()\n","export const tsconfigJson = `\n{\n \"extends\": \"alepha/tsconfig.base\"\n}\n`.trim();\n","export const viteConfigTs = (\n serverEntry?: string,\n) => `\nimport { viteAlepha } from \"alepha/vite\";\n\nexport default {\n plugins: [\n viteAlepha(${serverEntry ? `{ serverEntry: \"${serverEntry}\" }` : \"\"}),\n ],\n test: {\n globals: true,\n },\n};\n`.trim()\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 { access, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $inject, Alepha, AlephaError } from \"alepha\";\nimport { FileSystemProvider } from \"alepha/file\";\nimport { $logger } from \"alepha/logger\";\nimport type { DrizzleKitProvider, RepositoryProvider } from \"alepha/orm\";\nimport { boot } from \"alepha/vite\";\nimport { tsImport } from \"tsx/esm/api\";\nimport { appRouterTs } from \"../assets/appRouterTs.ts\";\nimport { biomeJson } from \"../assets/biomeJson.ts\";\nimport { indexHtml } from \"../assets/indexHtml.ts\";\nimport { mainBrowserTs } from \"../assets/mainBrowserTs.ts\";\nimport { tsconfigJson } from \"../assets/tsconfigJson.ts\";\nimport { viteConfigTs } from \"../assets/viteConfigTs.ts\";\nimport { version } from \"../version.ts\";\nimport { ProcessRunner } from \"./ProcessRunner.ts\";\n\n/**\n * Utility service for common project operations used by CLI commands.\n *\n * This service provides helper methods for:\n * - Project configuration file management (tsconfig.json, package.json, etc.)\n * - Package manager setup (Yarn, npm, pnpm)\n * - Sample project downloading\n * - Drizzle ORM/Kit utilities\n * - Alepha instance loading\n */\nexport class ProjectUtils {\n protected readonly log = $logger();\n protected readonly runner = $inject(ProcessRunner);\n protected readonly fs = $inject(FileSystemProvider);\n\n // ===================================================================================================================\n // Package Manager & Project Setup\n // ===================================================================================================================\n\n /**\n * Ensure Yarn is configured in the project directory.\n *\n * Creates a .yarnrc.yml file with node-modules linker if it doesn't exist.\n *\n * @param root - The root directory of the project\n */\n public async ensureYarn(root: string): Promise<void> {\n await this.ensureFileExists(\n root,\n \".yarnrc.yml\",\n \"nodeLinker: node-modules\",\n false,\n );\n\n // remove lock files from other package managers\n await this.fs.rm(join(root, \"package-lock.json\"), { force: true });\n await this.fs.rm(join(root, \"pnpm-lock.yaml\"), { force: true });\n }\n\n /**\n * Generate package.json content with Alepha dependencies.\n *\n * @param modes - Configuration for which dependencies to include\n * @returns Package.json partial with dependencies, devDependencies, and scripts\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 dependencies: Record<string, string> = {\n alepha: `^${version}`,\n };\n\n const devDependencies: Record<string, string> = {};\n\n if (modes.react) {\n dependencies[\"@alepha/react\"] = `^${version}`;\n dependencies.react = \"^19.2.0\";\n dependencies[\"react-dom\"] = \"^19.2.0\";\n devDependencies[\"@types/react\"] = \"^19.2.0\";\n }\n\n if (modes.admin) {\n dependencies[\"@alepha/ui\"] = `^${version}`;\n }\n\n return {\n type: \"module\",\n dependencies,\n devDependencies,\n scripts: {\n dev: \"alepha dev\",\n build: \"alepha build\",\n verify: \"alepha verify\",\n },\n };\n }\n\n /**\n * Ensure package.json exists and has correct configuration.\n *\n * Creates a new package.json if none exists, or updates an existing one to:\n * - Set \"type\": \"module\"\n * - Add Alepha dependencies\n * - Add standard scripts\n *\n * @param root - The root directory of the project\n * @param modes - Configuration for which dependencies to include\n */\n public async ensurePackageJson(\n root: string,\n modes: DependencyModes,\n ): Promise<void> {\n const packageJsonPath = join(root, \"package.json\");\n try {\n await access(packageJsonPath);\n } catch (error) {\n await writeFile(\n packageJsonPath,\n JSON.stringify(this.generatePackageJsonContent(modes), null, 2),\n );\n return;\n }\n\n const content = await readFile(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(content);\n\n const newPackageJson = this.generatePackageJsonContent(modes);\n\n packageJson.type = \"module\";\n packageJson.dependencies ??= {};\n packageJson.devDependencies ??= {};\n packageJson.scripts ??= {};\n\n Object.assign(packageJson.dependencies, newPackageJson.dependencies);\n Object.assign(packageJson.devDependencies, newPackageJson.devDependencies);\n Object.assign(packageJson.scripts, newPackageJson.scripts);\n\n await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));\n }\n\n public async ensureConfig(\n root: string,\n opts: {\n packageJson?: boolean | DependencyModes;\n tsconfigJson?: boolean;\n viteConfigTs?: boolean;\n indexHtml?: boolean;\n biomeJson?: boolean;\n },\n ) {\n const tasks: Promise<void>[] = [];\n\n if (opts.packageJson) {\n tasks.push(\n this.ensurePackageJson(\n root,\n typeof opts.packageJson === \"boolean\" ? {} : opts.packageJson,\n ),\n );\n }\n if (opts.tsconfigJson) {\n tasks.push(this.ensureTsConfig(root));\n }\n if (opts.viteConfigTs) {\n tasks.push(this.ensureViteConfig(root));\n }\n if (opts.indexHtml) {\n tasks.push(this.ensureIndexHtml(root));\n }\n if (opts.biomeJson) {\n tasks.push(this.ensureBiomeConfig(root));\n }\n\n await Promise.all(tasks);\n }\n\n /**\n * Ensure package.json exists and is configured as ES module.\n *\n * Similar to ensurePackageJson but only validates/sets the \"type\": \"module\" field.\n * Throws an error if no package.json exists.\n *\n * @param root - The root directory of the project\n * @throws {AlephaError} If no package.json is found\n */\n public async ensurePackageJsonModule(root: string): Promise<void> {\n const packageJsonPath = join(root, \"package.json\");\n try {\n await access(packageJsonPath);\n } catch (error) {\n throw new AlephaError(\n \"No package.json found in project root. Run 'npx alepha init' to create one.\",\n );\n }\n\n const content = await readFile(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(content);\n if (!packageJson.type || packageJson.type !== \"module\") {\n packageJson.type = \"module\";\n await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));\n }\n }\n\n /**\n * Ensure tsconfig.json exists in the project.\n *\n * Creates a standard Alepha tsconfig.json if none exists.\n *\n * @param root - The root directory of the project\n */\n public async ensureTsConfig(root: string): Promise<void> {\n await this.ensureFileExists(root, \"tsconfig.json\", tsconfigJson, true);\n }\n\n /**\n * Ensure vite.config.ts exists in the project.\n *\n * Creates a standard Alepha vite.config.ts if none exists.\n */\n public async ensureViteConfig(root: string): Promise<void> {\n await this.ensureFileExists(root, \"vite.config.ts\", viteConfigTs(), false);\n }\n\n protected async ensureFileExists(\n root: string,\n name: string,\n content: string,\n checkParentDirectories: boolean = false,\n ): Promise<void> {\n const configPath = join(root, name);\n\n if (!checkParentDirectories) {\n try {\n await access(configPath);\n return;\n } catch {\n await writeFile(configPath, content);\n return;\n }\n }\n\n let found = false;\n let currentDir = root;\n const maxIterations = 10; // safety to prevent infinite loops\n let level = 0;\n\n while (level < maxIterations) {\n try {\n await access(join(currentDir, name));\n found = true;\n break;\n } catch {\n const parentDir = join(currentDir, \"..\");\n if (parentDir === currentDir) {\n break;\n }\n currentDir = parentDir;\n }\n level += 1;\n }\n\n if (!found) {\n await writeFile(configPath, content);\n }\n }\n\n // ===================================================================================================================\n // Biome Configuration\n // ===================================================================================================================\n\n /**\n * Get the path to Biome configuration file.\n *\n * Looks for an existing biome.json in the project root, or creates one if it doesn't exist.\n */\n public async ensureBiomeConfig(root: string): Promise<void> {\n await this.ensureFileExists(root, \"biome.json\", biomeJson, true);\n }\n\n // ===================================================================================================================\n // Vite Configuration\n // ===================================================================================================================\n\n /**\n * Get the path to Vite configuration file.\n *\n * Looks for an existing vite.config.ts in the project root, or creates one if it doesn't exist.\n *\n * @param root - The root directory of the project (defaults to process.cwd())\n * @param serverEntry - Optional path to the server entry file to include in the config\n * @returns Absolute path to the vite.config.ts file\n */\n public async getViteConfigPath(\n root: string,\n serverEntry?: string,\n ): Promise<string> {\n try {\n const viteConfigPath = join(root, \"vite.config.ts\");\n await access(viteConfigPath);\n return viteConfigPath;\n } catch {\n return this.runner.writeConfigFile(\n \"vite.config.ts\",\n viteConfigTs(serverEntry),\n );\n }\n }\n\n // ===================================================================================================================\n // Drizzle ORM & Kit Utilities\n // ===================================================================================================================\n\n /**\n * Load Alepha instance from a server entry file.\n *\n * Dynamically imports the server entry file and extracts the Alepha instance.\n * Skips the automatic start process.\n *\n * @param rootDir - The root directory of the project\n * @param explicitEntry - Optional explicit path to the entry file\n * @returns Object containing the Alepha instance and the entry file path\n * @throws {AlephaError} If the Alepha instance cannot be found\n */\n public async loadAlephaFromServerEntryFile(\n rootDir?: string,\n explicitEntry?: string,\n ): Promise<{\n alepha: Alepha;\n entry: string;\n }> {\n process.env.ALEPHA_CLI_IMPORT = \"true\";\n\n const entry = await boot.getServerEntry(rootDir, explicitEntry);\n const mod = await tsImport(entry, {\n parentURL: import.meta.url,\n });\n\n this.log.debug(`Load entry: ${entry}`);\n\n // check if alepha is correctly exported\n if (mod.default instanceof Alepha) {\n return {\n alepha: mod.default,\n entry,\n };\n }\n\n // else, try with global variable\n const g: any = global;\n if (g.__alepha) {\n return {\n alepha: g.__alepha,\n entry,\n };\n }\n\n throw new AlephaError(\n `Could not find Alepha instance in entry file: ${entry}`,\n );\n }\n\n /**\n * Generate JavaScript code for Drizzle entities export.\n *\n * Creates a temporary entities.js file that imports from the entry file\n * and exports database models for Drizzle Kit to process.\n *\n * @param entry - Path to the server entry file\n * @param provider - Name of the database provider\n * @param models - Array of model names to export\n * @returns JavaScript code as a string\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 * Prepare Drizzle configuration files for a database provider.\n *\n * Creates temporary entities.js and drizzle.config.js files needed\n * for Drizzle Kit commands to run properly.\n *\n * @param options - Configuration options including kit, provider info, and paths\n * @returns Path to the generated drizzle.config.js file\n */\n public async prepareDrizzleConfig(options: {\n kit: any;\n provider: any;\n providerName: string;\n providerUrl: 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.generateEntitiesJs(\n options.entry,\n options.providerName,\n models,\n );\n\n const entitiesJsPath = await this.runner.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.dialect === \"sqlite\") {\n let url = options.providerUrl;\n url = url.replace(\"sqlite://\", \"\").replace(\"file://\", \"\");\n url = join(options.rootDir, url);\n\n config.dbCredentials = {\n url,\n };\n }\n\n if (options.providerName === \"pglite\") {\n config.driver = \"pglite\";\n }\n\n const drizzleConfigJs = `export default ${JSON.stringify(config, null, 2)}`;\n\n return await this.runner.writeConfigFile(\n \"drizzle.config.js\",\n drizzleConfigJs,\n options.rootDir,\n );\n }\n\n public async loadEnvFile(root: string): Promise<void> {\n const envPath = join(root, \".env\");\n try {\n const envContent = await readFile(envPath, \"utf8\");\n const lines = envContent.split(\"\\n\");\n for (const line of lines) {\n const [key, ...rest] = line.split(\"=\");\n if (key) {\n const value = rest.join(\"=\");\n process.env[key.trim()] = value.trim();\n }\n }\n this.log.debug(`Loaded environment variables from ${envPath}`);\n } catch {\n this.log.debug(`No .env file found at ${envPath}, skipping load.`);\n }\n }\n\n /**\n * Run a drizzle-kit command for all database providers in an Alepha instance.\n *\n * Iterates through all repository providers, prepares Drizzle config for each,\n * and executes the specified drizzle-kit command.\n *\n * @param options - Configuration including command to run, flags, and logging\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 }): Promise<void> {\n const rootDir = options.root;\n\n await this.loadEnvFile(rootDir);\n\n this.log.debug(`Using project root: ${rootDir}`);\n\n const { alepha, entry } = await this.loadAlephaFromServerEntryFile(\n rootDir,\n options.args,\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 (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 dialect,\n entry,\n rootDir,\n });\n\n const flags = options.commandFlags ? ` ${options.commandFlags}` : \"\";\n await this.runner.exec(\n `drizzle-kit ${options.command} --config=${drizzleConfigJsPath}${flags}`,\n );\n }\n }\n\n public async getPackageManager(\n root: string,\n ): Promise<\"yarn\" | \"pnpm\" | \"npm\"> {\n if (await this.fs.exists(join(root, \"yarn.lock\"))) {\n return \"yarn\";\n } else if (await this.fs.exists(join(root, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n } else {\n return \"npm\";\n }\n }\n\n public async ensureIndexHtml(root: string) {\n if (await this.fs.exists(join(root, \"index.html\"))) {\n return;\n }\n\n const serverEntry = \"src/main.server.ts\";\n const browserEntry = \"src/main.browser.ts\";\n const appRouter = \"src/AppRouter.ts\";\n\n await this.fs.writeFile(join(root, \"index.html\"), indexHtml(browserEntry));\n\n try {\n await this.fs.mkdir(join(root, \"src\"), { recursive: true });\n } catch {}\n\n if (!(await this.fs.exists(join(root, browserEntry)))) {\n await this.fs.writeFile(join(root, browserEntry), mainBrowserTs());\n }\n\n if (!(await this.fs.exists(join(root, serverEntry)))) {\n await this.fs.writeFile(join(root, serverEntry), mainBrowserTs());\n }\n\n if (!(await this.fs.exists(join(root, appRouter)))) {\n await this.fs.writeFile(join(root, appRouter), appRouterTs());\n }\n }\n\n public async exists(root: string, dirName: string): Promise<boolean> {\n return this.fs.exists(join(root, dirName));\n }\n\n async readPackageJson(root: string): Promise<Record<string, any>> {\n const packageJson = await this.fs\n .createFile({\n path: join(root, \"package.json\"),\n })\n .text();\n return JSON.parse(packageJson);\n }\n}\n\nexport interface DependencyModes {\n react?: boolean;\n admin?: boolean;\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\n\nexport class BiomeCommands {\n protected readonly log = $logger();\n protected readonly runner = $inject(ProcessRunner);\n protected readonly utils = $inject(ProjectUtils);\n\n public readonly format = $command({\n name: \"format\",\n description: \"Format the codebase using Biome\",\n handler: async ({ root }) => {\n await this.utils.ensureConfig(root, { biomeJson: true });\n await this.runner.exec(`biome format --fix`);\n },\n });\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.utils.ensureConfig(root, { biomeJson: true });\n await this.runner.exec(`biome check --formatter-enabled=false --fix`);\n },\n });\n}\n","import { $inject, t } from \"alepha\";\nimport { $command, CliProvider } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\nimport { version } from \"../version.ts\";\n\nexport class CoreCommands {\n protected readonly log = $logger();\n protected readonly cli = $inject(CliProvider);\n protected readonly utils = $inject(ProjectUtils);\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(version);\n return;\n }\n\n this.cli.printHelp();\n },\n });\n\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 /**\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 flags: t.object({\n // TODO:\n // force: t.boolean({\n // description: \"If true, all config files will be overwritten\",\n // }),\n // choose package manager\n yarn: t.optional(t.boolean({ description: \"Use Yarn package manager\" })),\n pnpm: t.optional(t.boolean({ description: \"Use pnpm package manager\" })),\n // choose which dependencies to add\n react: t.optional(\n t.boolean({ description: \"Include Alepha React dependencies\" }),\n ),\n admin: t.optional(\n t.boolean({ description: \"Include Alepha admin panel dependencies\" }),\n ),\n }),\n handler: async ({ run, flags, root }) => {\n await run({\n name: \"Ensuring configuration files\",\n handler: async () => {\n await this.utils.ensureConfig(root, {\n tsconfigJson: true,\n packageJson: flags,\n biomeJson: true,\n viteConfigTs: true,\n indexHtml: !!flags.react,\n });\n },\n });\n\n // TODO: check if all alepha dependencies are same version\n\n const guessedPm = await this.utils.getPackageManager(root);\n\n if (flags.yarn || guessedPm === \"yarn\") {\n await this.utils.ensureYarn(root);\n await run(\"yarn set version stable\");\n await run(\"yarn install\", {\n alias: \"Installing dependencies with Yarn\",\n });\n } else {\n await run(\"npm install\", {\n alias: \"Installing dependencies with npm\",\n });\n }\n },\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $inject, AlephaError, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport type { DrizzleKitProvider, RepositoryProvider } from \"alepha/orm\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.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});\n\nexport class DrizzleCommands {\n log = $logger();\n runner = $inject(ProcessRunner);\n utils = $inject(ProjectUtils);\n\n /**\n * Check if database migrations are up to date.\n */\n check = $command({\n name: \"db: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 { alepha } = await this.utils.loadAlephaFromServerEntryFile(\n rootDir,\n args,\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 = join(rootDir, \"migrations\", providerName);\n\n const journalFile = await readFile(\n `${migrationDir}/meta/_journal.json`,\n \"utf-8\",\n ).catch(() => null);\n\n if (!journalFile) {\n this.log.info(`No migration journal found.`);\n return;\n }\n\n const journal = JSON.parse(journalFile);\n const lastMigration = journal.entries[journal.entries.length - 1];\n const lastSnapshot = JSON.parse(\n await readFile(\n `${migrationDir}/meta/${String(lastMigration.idx).padStart(4, \"0\")}_snapshot.json`,\n \"utf-8\",\n ),\n );\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 * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository primitives to gather database models.\n * - Creates temporary entity definitions based on the current database schema.\n * - Writes these definitions to a temporary schema file. (node_modules/.db/entities.ts)\n * - Invokes Drizzle Kit's CLI to generate migration files based on the current schema.\n */\n generate = $command({\n name: \"db:generate\",\n description: \"Generate migration files based on current database schema\",\n summary: false,\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 await this.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"generate\",\n commandFlags,\n provider: flags.provider,\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 * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository primitives to gather database models.\n * - Creates temporary entity definitions and Drizzle config.\n * - Invokes Drizzle Kit's push command to apply schema changes directly.\n */\n push = $command({\n name: \"db:push\",\n description: \"Push database schema changes directly to the database\",\n summary: false,\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.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"push\",\n provider: flags.provider,\n logMessage: (providerName, dialect) =>\n `Push '${providerName}' schema (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Apply pending database migrations\n *\n * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository primitives to gather database models.\n * - Creates temporary entity definitions and Drizzle config.\n * - Invokes Drizzle Kit's migrate command to apply pending migrations.\n */\n migrate = $command({\n name: \"db:migrate\",\n description: \"Apply pending database migrations\",\n summary: false,\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.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"migrate\",\n provider: flags.provider,\n logMessage: (providerName, dialect) =>\n `Migrate '${providerName}' database (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Launch Drizzle Studio database browser\n *\n * - Loads the Alepha instance from the specified entry file.\n * - Retrieves all repository primitives to gather database models.\n * - Creates temporary entity definitions and Drizzle config.\n * - Invokes Drizzle Kit's studio command to launch the web-based database browser.\n */\n studio = $command({\n name: \"db:studio\",\n description: \"Launch Drizzle Studio database browser\",\n summary: false,\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.utils.runDrizzleKitCommand({\n root,\n args,\n command: \"studio\",\n provider: flags.provider,\n logMessage: (providerName, dialect) =>\n `Launch Studio for '${providerName}' (${dialect}) ...`,\n });\n },\n });\n\n /**\n * Drop database schema (development only)\n *\n * @experimental\n */\n drop = $command({\n name: \"db:drop\",\n description: \"Drop database schema (development only)\",\n summary: false,\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 ({ flags }) => {\n // TODO: Implement db:drop\n this.log.warn(\"db:drop is not yet implemented\");\n if (flags.provider) {\n this.log.info(`Provider filter: ${flags.provider}`);\n }\n },\n });\n\n /**\n * Seed database with initial data\n *\n * @experimental\n */\n seed = $command({\n name: \"db:seed\",\n description: \"Seed database with initial data\",\n summary: false,\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 ({ flags }) => {\n // TODO: Implement db:seed\n this.log.warn(\"db:seed is not yet implemented\");\n if (flags.provider) {\n this.log.info(`Provider filter: ${flags.provider}`);\n }\n },\n });\n\n /**\n * Show pending database migrations status\n *\n * @experimental\n */\n status = $command({\n name: \"db:status\",\n description: \"Show pending database migrations status\",\n summary: false,\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 ({ flags }) => {\n // TODO: Implement db:status\n this.log.warn(\"db:status is not yet implemented\");\n if (flags.provider) {\n this.log.info(`Provider filter: ${flags.provider}`);\n }\n },\n });\n}\n","import { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\n\nexport class VerifyCommands {\n protected readonly processRunner = $inject(ProcessRunner);\n protected readonly utils = $inject(ProjectUtils);\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.utils.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 await run(\"alepha build\");\n await run(\"alepha clean\");\n },\n });\n\n /**\n * Run TypeScript type checking across the codebase with no emit.\n */\n public readonly typecheck = $command({\n name: \"typecheck\",\n description: \"Check TypeScript types across the codebase\",\n handler: async () => {\n await this.processRunner.exec(\"tsc --noEmit\");\n },\n });\n}\n","import { access, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $env, $inject, OPTIONS, t } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { $logger } from \"alepha/logger\";\nimport {\n boot,\n buildClient,\n buildServer,\n copyAssets,\n generateCloudflare,\n generateDocker,\n generateSitemap,\n generateVercel,\n prerenderPages,\n type ViteAlephaBuildOptions,\n} from \"alepha/vite\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\nimport { ProjectUtils } from \"../services/ProjectUtils.ts\";\n\nexport class ViteCommands {\n protected readonly log = $logger();\n protected readonly runner = $inject(ProcessRunner);\n protected readonly utils = $inject(ProjectUtils);\n\n protected readonly env = $env(\n t.object({\n VITEST_ARGS: t.string({ default: \"\" }),\n }),\n );\n\n public readonly run = $command({\n name: \"run\",\n description: \"Run a TypeScript file directly\",\n flags: t.object({\n watch: t.optional(\n t.boolean({ description: \"Watch file for changes\", alias: \"w\" }),\n ),\n }),\n summary: false,\n args: t.text({ title: \"path\", description: \"Filepath to run\" }),\n handler: async ({ args, flags, root }) => {\n await this.utils.ensureTsConfig(root);\n await this.runner.exec(`tsx ${flags.watch ? \"watch \" : \"\"}${args}`);\n },\n });\n\n /**\n * Will run the project in watch mode.\n *\n * - If an index.html file is found in the project root, it will run Vite in dev mode.\n * - Otherwise, it will look for a server entry file and run it with tsx in watch mode.\n */\n public readonly dev = $command({\n name: \"dev\",\n description: \"Run the project in development mode\",\n args: t.optional(t.text({ title: \"path\", description: \"Filepath to run\" })),\n handler: async ({ args, root }) => {\n await this.utils.ensureConfig(root, {\n viteConfigTs: true,\n tsconfigJson: true,\n });\n\n const entry = await boot.getServerEntry(root, args);\n this.log.trace(\"Entry file found\", { entry });\n\n try {\n await access(join(root, \"index.html\"));\n } catch {\n this.log.trace(\"No index.html found, running entry file with tsx\");\n let cmd = \"tsx --watch\";\n if (await this.utils.exists(root, \".env\")) {\n cmd += ` --env-file=./.env`;\n }\n cmd += ` ${entry}`;\n await this.runner.exec(cmd);\n return;\n }\n\n await this.runner.exec(`vite`);\n },\n });\n\n public readonly build = $command({\n name: \"build\",\n description: \"Build the project for production\",\n args: t.optional(\n t.text({ title: \"path\", description: \"Filepath to build\" }),\n ),\n flags: t.object({\n stats: t.optional(\n t.boolean({\n description: \"Generate build stats report\",\n }),\n ),\n vercel: t.optional(\n t.boolean({\n description: \"Generate Vercel deployment configuration\",\n }),\n ),\n cloudflare: t.optional(\n t.boolean({\n description: \"Generate Cloudflare Workers configuration\",\n }),\n ),\n docker: t.optional(\n t.boolean({\n description: \"Generate Docker configuration\",\n }),\n ),\n sitemap: t.optional(\n t.text({\n description: \"Generate sitemap.xml with base URL\",\n }),\n ),\n prerender: t.optional(\n t.boolean({\n description: \"Pre-render static pages\",\n }),\n ),\n }),\n handler: async ({ flags, args, run, root }) => {\n // Tell viteAlephaBuild plugin to skip - CLI handles all tasks\n process.env.ALEPHA_BUILD_MODE = \"cli\";\n\n await this.utils.ensureConfig(root, {\n viteConfigTs: true,\n tsconfigJson: true,\n });\n\n const entry = await boot.getServerEntry(root, args);\n this.log.trace(\"Entry file found\", { entry });\n\n const distDir = \"dist\";\n const clientDir = \"public\";\n\n await run.rm(\"dist\", {\n alias: \"clean dist\",\n });\n\n const viteConfig = await import(join(root, \"vite.config.ts\"));\n const viteAlephaBuildOptions: ViteAlephaBuildOptions =\n viteConfig?.default?.plugins.find((it: any) => !!it[OPTIONS])?.[\n OPTIONS\n ] ?? {};\n\n const stats = flags.stats ?? viteAlephaBuildOptions.stats ?? false;\n\n let hasClient = false;\n try {\n await access(join(root, \"index.html\"));\n hasClient = true;\n } catch {\n // No index.html\n }\n\n // Build client\n if (hasClient) {\n await run({\n name: \"vite build client\",\n handler: () =>\n buildClient({\n silent: true,\n dist: `${distDir}/${clientDir}`,\n stats,\n }),\n });\n }\n\n // Build server\n await run({\n name: \"vite build server\",\n handler: async () => {\n // Check if client template exists\n let clientBuilt = false;\n try {\n await readFile(`${distDir}/${clientDir}/index.html`, \"utf-8\");\n clientBuilt = true;\n } catch {\n // No client build\n }\n\n await buildServer({\n silent: true,\n entry,\n distDir,\n clientDir: clientBuilt ? clientDir : undefined,\n stats,\n });\n\n // Server will handle index.html if both client & server are built\n if (clientBuilt) {\n await unlink(`${distDir}/${clientDir}/index.html`);\n }\n },\n });\n\n // Copy assets\n // TODO: only copy if assets are found? Currently will always run\n await run({\n name: \"copy assets\",\n handler: () =>\n copyAssets({\n entry: `${distDir}/index.js`,\n distDir,\n }),\n });\n\n if (hasClient) {\n // Generate sitemap\n const sitemapBaseUrl =\n flags.sitemap ??\n (typeof viteAlephaBuildOptions.client === \"object\"\n ? viteAlephaBuildOptions.client.sitemap?.hostname\n : undefined);\n\n if (sitemapBaseUrl) {\n await run({\n name: \"add sitemap\",\n handler: async () => {\n await writeFile(\n `${distDir}/${clientDir}/sitemap.xml`,\n await generateSitemap({\n entry: `${distDir}/index.js`,\n baseUrl: sitemapBaseUrl,\n }),\n );\n },\n });\n }\n\n // Pre-render static pages\n const shouldPrerender =\n flags.prerender ??\n (typeof viteAlephaBuildOptions.client === \"object\"\n ? viteAlephaBuildOptions.client.prerender\n : false);\n\n if (shouldPrerender) {\n await run({\n name: \"pre-render pages\",\n handler: async () => {\n await prerenderPages({\n dist: `${distDir}/${clientDir}`,\n entry: `${distDir}/index.js`,\n });\n },\n });\n }\n }\n\n // Generate deployment configurations\n if (flags.vercel || viteAlephaBuildOptions.vercel) {\n const config =\n typeof viteAlephaBuildOptions.vercel === \"object\"\n ? viteAlephaBuildOptions.vercel\n : {};\n await run({\n name: \"add Vercel config\",\n handler: () =>\n generateVercel({\n distDir,\n clientDir,\n config,\n }),\n });\n }\n\n if (flags.cloudflare || viteAlephaBuildOptions.cloudflare) {\n await run({\n name: \"add Cloudflare config\",\n handler: () =>\n generateCloudflare({\n distDir,\n }),\n });\n }\n\n if (flags.docker || viteAlephaBuildOptions.docker) {\n const dockerConfig =\n typeof viteAlephaBuildOptions.docker === \"object\"\n ? viteAlephaBuildOptions.docker\n : {};\n await run({\n name: \"add Docker config\",\n handler: () =>\n generateDocker({\n distDir,\n ...dockerConfig,\n }),\n });\n }\n },\n });\n\n public readonly test = $command({\n name: \"test\",\n description: \"Run tests using Vitest\",\n handler: async ({ root }) => {\n await this.utils.ensureConfig(root, {\n tsconfigJson: true,\n viteConfigTs: true,\n });\n\n // check if vitest is installed\n try {\n await import(\"vitest\");\n } catch {\n this.log.error(\n \"Vitest is not installed. Please install it with `npm install -D vitest` or `yarn add -D vitest`.\",\n );\n process.exit(1);\n }\n\n await this.runner.exec(`vitest run ${this.env.VITEST_ARGS}`);\n },\n });\n}\n","import { $module } from \"alepha\";\nimport { BiomeCommands } from \"../commands/BiomeCommands.ts\";\nimport { CoreCommands } from \"../commands/CoreCommands.ts\";\nimport { DrizzleCommands } from \"../commands/DrizzleCommands.ts\";\nimport { VerifyCommands } from \"../commands/VerifyCommands.ts\";\nimport { ViteCommands } from \"../commands/ViteCommands.ts\";\nimport { ProcessRunner } from \"../services/ProcessRunner.ts\";\n\nexport const AlephaCli = $module({\n name: \"alepha.cli\",\n services: [\n ProcessRunner,\n CoreCommands,\n DrizzleCommands,\n VerifyCommands,\n ViteCommands,\n BiomeCommands,\n ],\n});\n","import { access, readdir, readFile } from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport { join } from \"node:path\";\nimport { $inject } from \"alepha\";\nimport { $command } from \"alepha/command\";\nimport { FileSystemProvider } from \"alepha/file\";\nimport type { InlineConfig } from \"tsdown\";\n\ninterface Module {\n name: string;\n dependencies: string[];\n native?: boolean;\n browser?: 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 pkg = await readFile(\"package.json\", \"utf-8\");\n const pkgData = JSON.parse(pkg);\n const packageName = pkgData.name as string;\n\n await run(\"analyze modules\", async () => {\n modules.push(\n ...(await analyzeModules(join(root, this.src), packageName)),\n );\n });\n\n pkgData.exports = {};\n\n for (const item of modules) {\n const path =\n item.name === \"core\" ? \".\" : `./${item.name.replace(\"-\", \"/\")}`;\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 if (item.browser) {\n pkgData.exports[path].browser = `./src/${item.name}/index.browser.ts`;\n }\n pkgData.exports[path].import = `./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\"] = \"./styles.css\";\n }\n\n await this.fs.writeFile(\"package.json\", JSON.stringify(pkgData, null, 2));\n\n const tmpDir = join(root, \"node_modules/.alepha\");\n await this.fs.mkdir(tmpDir, { recursive: true }).catch(() => {});\n\n await this.fs.writeFile(\n join(tmpDir, \"module-dependencies.json\"),\n JSON.stringify(modules, null, 2),\n );\n\n const external = [\n \"alepha\",\n packageName,\n ...modules.map(\n (item) => `${packageName}/${item.name.replace(\"-\", \"/\")}`,\n ),\n ];\n\n await run.rm(this.dist);\n\n const build = async (item: Module) => {\n const entries: InlineConfig[] = [];\n const src = join(root, this.src, item.name);\n const dest = join(root, this.dist, item.name);\n\n entries.push({\n entry: 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 external,\n });\n\n if (item.native) {\n entries.push({\n entry: join(src, \"index.native.ts\"),\n outDir: dest,\n platform: \"neutral\",\n sourcemap: true,\n dts: false,\n external,\n });\n }\n\n if (item.browser) {\n entries.push({\n entry: join(src, \"index.browser.ts\"),\n outDir: dest,\n platform: \"browser\",\n sourcemap: true,\n dts: false,\n external,\n });\n }\n\n const config = join(tmpDir, `tsdown-${item.name}.config.js`);\n await this.fs.writeFile(\n config,\n `export default ${JSON.stringify(entries, null, 2)};`,\n );\n await run(`npx tsdown -c=${config}`);\n await this.fs.rm(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\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 Error(`Circular dependency detected: ${cycle.join(\" -> \")}`);\n }\n }\n}\n\nexport async function analyzeModules(\n srcDir: string,\n packageName: string,\n): Promise<Module[]> {\n const modules: Module[] = [];\n const entries = await readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const moduleName = entry.name;\n const modulePath = join(srcDir, moduleName);\n const dependencies = new Set<string>();\n\n // Check for browser/node entry points\n const hasBrowser = await fileExists(join(modulePath, \"index.browser.ts\"));\n const hasNative = await fileExists(join(modulePath, \"index.native.ts\"));\n const hasNode = await fileExists(join(modulePath, \"index.node.ts\"));\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 (hasBrowser) module.browser = true;\n if (hasNode) module.node = true;\n\n modules.push(module);\n }\n }\n\n // Check for circular dependencies\n detectCircularDependencies(modules);\n\n return modules;\n}\n"],"mappings":"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"}
|
package/dist/command/index.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import * as alepha1 from "alepha";
|
|
2
|
-
import { Alepha, AlephaError, Async,
|
|
2
|
+
import { Alepha, AlephaError, Async, KIND, Primitive, Static, TObject, TSchema, TString } from "alepha";
|
|
3
3
|
import * as alepha_logger0 from "alepha/logger";
|
|
4
4
|
import { DateTimeProvider, Interval } from "alepha/datetime";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
6
6
|
import { glob } from "node:fs/promises";
|
|
7
7
|
import * as readline_promises0 from "readline/promises";
|
|
8
8
|
|
|
9
|
+
//#region src/command/errors/CommandError.d.ts
|
|
10
|
+
declare class CommandError extends AlephaError {
|
|
11
|
+
readonly name = "CommandError";
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
9
14
|
//#region src/command/helpers/Asker.d.ts
|
|
10
15
|
interface AskOptions<T extends TSchema = TString> {
|
|
11
16
|
/**
|
|
@@ -157,18 +162,18 @@ declare class Runner {
|
|
|
157
162
|
protected renderTable(data: string[][]): void;
|
|
158
163
|
}
|
|
159
164
|
//#endregion
|
|
160
|
-
//#region src/command/
|
|
165
|
+
//#region src/command/primitives/$command.d.ts
|
|
161
166
|
/**
|
|
162
167
|
* Declares a CLI command.
|
|
163
168
|
*
|
|
164
|
-
* This
|
|
169
|
+
* This primitive allows you to define a command, its flags, and its handler
|
|
165
170
|
* within your Alepha application structure.
|
|
166
171
|
*/
|
|
167
172
|
declare const $command: {
|
|
168
|
-
<T extends TObject, A extends TSchema>(options:
|
|
169
|
-
[KIND]: typeof
|
|
173
|
+
<T extends TObject, A extends TSchema>(options: CommandPrimitiveOptions<T, A>): CommandPrimitive<T, A>;
|
|
174
|
+
[KIND]: typeof CommandPrimitive;
|
|
170
175
|
};
|
|
171
|
-
interface
|
|
176
|
+
interface CommandPrimitiveOptions<T extends TObject, A extends TSchema> {
|
|
172
177
|
/**
|
|
173
178
|
* The handler function to execute when the command is matched.
|
|
174
179
|
*/
|
|
@@ -219,7 +224,7 @@ interface CommandDescriptorOptions<T extends TObject, A extends TSchema> {
|
|
|
219
224
|
*/
|
|
220
225
|
root?: boolean;
|
|
221
226
|
}
|
|
222
|
-
declare class
|
|
227
|
+
declare class CommandPrimitive<T extends TObject = TObject, A extends TSchema = TSchema> extends Primitive<CommandPrimitiveOptions<T, A>> {
|
|
223
228
|
readonly flags: TObject<{}>;
|
|
224
229
|
readonly aliases: string[];
|
|
225
230
|
get name(): string;
|
|
@@ -237,11 +242,6 @@ interface CommandHandlerArgs<T extends TObject, A extends TSchema = TSchema> {
|
|
|
237
242
|
root: string;
|
|
238
243
|
}
|
|
239
244
|
//#endregion
|
|
240
|
-
//#region src/command/errors/CommandError.d.ts
|
|
241
|
-
declare class CommandError extends AlephaError {
|
|
242
|
-
readonly name = "CommandError";
|
|
243
|
-
}
|
|
244
|
-
//#endregion
|
|
245
245
|
//#region src/command/providers/CliProvider.d.ts
|
|
246
246
|
declare const envSchema: TObject<{
|
|
247
247
|
CLI_NAME: alepha1.TString;
|
|
@@ -288,9 +288,9 @@ declare class CliProvider {
|
|
|
288
288
|
schema: alepha1.TBoolean;
|
|
289
289
|
};
|
|
290
290
|
};
|
|
291
|
-
protected readonly onReady: alepha1.
|
|
292
|
-
get commands():
|
|
293
|
-
protected findCommand(name: string):
|
|
291
|
+
protected readonly onReady: alepha1.HookPrimitive<"ready">;
|
|
292
|
+
get commands(): CommandPrimitive<any>[];
|
|
293
|
+
protected findCommand(name: string): CommandPrimitive<TObject> | undefined;
|
|
294
294
|
/**
|
|
295
295
|
* Get all global flags including those from the root command (name === "")
|
|
296
296
|
*/
|
|
@@ -309,7 +309,7 @@ declare class CliProvider {
|
|
|
309
309
|
protected parseArgumentValue(value: string, schema: TSchema): any;
|
|
310
310
|
protected generateArgsUsage(schema?: TSchema): string;
|
|
311
311
|
protected getTypeName(schema: TSchema): string;
|
|
312
|
-
printHelp(command?:
|
|
312
|
+
printHelp(command?: CommandPrimitive<any>): void;
|
|
313
313
|
private getMaxCmdLength;
|
|
314
314
|
private getMaxFlagLength;
|
|
315
315
|
}
|
|
@@ -317,9 +317,9 @@ declare class CliProvider {
|
|
|
317
317
|
//#region src/command/index.d.ts
|
|
318
318
|
/**
|
|
319
319
|
* This module provides a powerful way to build command-line interfaces
|
|
320
|
-
* directly within your Alepha application, using declarative
|
|
320
|
+
* directly within your Alepha application, using declarative primitives.
|
|
321
321
|
*
|
|
322
|
-
* It allows you to define commands using the `$command`
|
|
322
|
+
* It allows you to define commands using the `$command` primitive.
|
|
323
323
|
*
|
|
324
324
|
* @see {@link $command}
|
|
325
325
|
* @module alepha.command
|
|
@@ -336,5 +336,5 @@ declare module "typebox" {
|
|
|
336
336
|
}
|
|
337
337
|
}
|
|
338
338
|
//#endregion
|
|
339
|
-
export { $command, AlephaCommand, AskMethod, AskOptions, Asker, CliProvider, CliProviderOptions,
|
|
339
|
+
export { $command, AlephaCommand, AskMethod, AskOptions, Asker, CliProvider, CliProviderOptions, CommandError, CommandHandlerArgs, CommandPrimitive, CommandPrimitiveOptions, PrettyPrint, RunOptions, Runner, RunnerMethod, Task, cliOptions };
|
|
340
340
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/command/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError,
|
|
1
|
+
import { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError, KIND, Primitive, TypeBoxError, createPrimitive, t } from "alepha";
|
|
2
2
|
import { stdin, stdout } from "node:process";
|
|
3
3
|
import { createInterface } from "node:readline/promises";
|
|
4
4
|
import { $logger } from "alepha/logger";
|
|
@@ -7,25 +7,6 @@ import { exec } from "node:child_process";
|
|
|
7
7
|
import * as fs from "node:fs/promises";
|
|
8
8
|
import { cp, glob, rm } from "node:fs/promises";
|
|
9
9
|
|
|
10
|
-
//#region src/command/descriptors/$command.ts
|
|
11
|
-
/**
|
|
12
|
-
* Declares a CLI command.
|
|
13
|
-
*
|
|
14
|
-
* This descriptor allows you to define a command, its flags, and its handler
|
|
15
|
-
* within your Alepha application structure.
|
|
16
|
-
*/
|
|
17
|
-
const $command = (options) => createDescriptor(CommandDescriptor, options);
|
|
18
|
-
var CommandDescriptor = class extends Descriptor {
|
|
19
|
-
flags = this.options.flags ?? t.object({});
|
|
20
|
-
aliases = this.options.aliases ?? [];
|
|
21
|
-
get name() {
|
|
22
|
-
if (this.options.root) return "";
|
|
23
|
-
return this.options.name ?? `${this.config.propertyKey}`;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
$command[KIND] = CommandDescriptor;
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
10
|
//#region src/command/helpers/Asker.ts
|
|
30
11
|
var Asker = class {
|
|
31
12
|
log = $logger();
|
|
@@ -357,6 +338,25 @@ var Runner = class {
|
|
|
357
338
|
}
|
|
358
339
|
};
|
|
359
340
|
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/command/primitives/$command.ts
|
|
343
|
+
/**
|
|
344
|
+
* Declares a CLI command.
|
|
345
|
+
*
|
|
346
|
+
* This primitive allows you to define a command, its flags, and its handler
|
|
347
|
+
* within your Alepha application structure.
|
|
348
|
+
*/
|
|
349
|
+
const $command = (options) => createPrimitive(CommandPrimitive, options);
|
|
350
|
+
var CommandPrimitive = class extends Primitive {
|
|
351
|
+
flags = this.options.flags ?? t.object({});
|
|
352
|
+
aliases = this.options.aliases ?? [];
|
|
353
|
+
get name() {
|
|
354
|
+
if (this.options.root) return "";
|
|
355
|
+
return this.options.name ?? `${this.config.propertyKey}`;
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
$command[KIND] = CommandPrimitive;
|
|
359
|
+
|
|
360
360
|
//#endregion
|
|
361
361
|
//#region src/command/providers/CliProvider.ts
|
|
362
362
|
const envSchema = t.object({
|
|
@@ -451,7 +451,7 @@ var CliProvider = class {
|
|
|
451
451
|
}
|
|
452
452
|
});
|
|
453
453
|
get commands() {
|
|
454
|
-
return this.alepha.
|
|
454
|
+
return this.alepha.primitives($command);
|
|
455
455
|
}
|
|
456
456
|
findCommand(name) {
|
|
457
457
|
return this.commands.find((command) => command.name === name || command.aliases.includes(name));
|
|
@@ -635,16 +635,16 @@ var CliProvider = class {
|
|
|
635
635
|
//#region src/command/index.ts
|
|
636
636
|
/**
|
|
637
637
|
* This module provides a powerful way to build command-line interfaces
|
|
638
|
-
* directly within your Alepha application, using declarative
|
|
638
|
+
* directly within your Alepha application, using declarative primitives.
|
|
639
639
|
*
|
|
640
|
-
* It allows you to define commands using the `$command`
|
|
640
|
+
* It allows you to define commands using the `$command` primitive.
|
|
641
641
|
*
|
|
642
642
|
* @see {@link $command}
|
|
643
643
|
* @module alepha.command
|
|
644
644
|
*/
|
|
645
645
|
const AlephaCommand = $module({
|
|
646
646
|
name: "alepha.command",
|
|
647
|
-
|
|
647
|
+
primitives: [$command],
|
|
648
648
|
services: [
|
|
649
649
|
CliProvider,
|
|
650
650
|
Runner,
|
|
@@ -654,5 +654,5 @@ const AlephaCommand = $module({
|
|
|
654
654
|
});
|
|
655
655
|
|
|
656
656
|
//#endregion
|
|
657
|
-
export { $command, AlephaCommand, Asker, CliProvider,
|
|
657
|
+
export { $command, AlephaCommand, Asker, CliProvider, CommandError, CommandPrimitive, PrettyPrint, Runner, cliOptions };
|
|
658
658
|
//# sourceMappingURL=index.js.map
|