alepha 0.14.0 → 0.14.1
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/dist/api/audits/index.d.ts +417 -338
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +80 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +236 -157
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +21 -1
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +451 -4
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +833 -830
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/cli/index.d.ts +212 -29
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +320 -219
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +206 -9
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +306 -69
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/orm/index.d.ts +180 -126
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +486 -512
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/redis/index.js +2 -4
- package/dist/queue/redis/index.js.map +1 -1
- package/dist/redis/index.d.ts +400 -29
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +412 -21
- package/dist/redis/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +6 -6
- package/dist/security/index.d.ts +28 -28
- package/dist/security/index.d.ts.map +1 -1
- package/dist/server/auth/index.d.ts +155 -155
- package/dist/server/core/index.d.ts +0 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/health/index.d.ts +17 -17
- package/dist/server/helmet/index.d.ts +4 -1
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/topic/redis/index.js +3 -3
- package/dist/topic/redis/index.js.map +1 -1
- package/dist/vite/index.js +9 -6
- package/dist/vite/index.js.map +1 -1
- package/package.json +3 -3
- package/src/cli/apps/AlephaCli.ts +8 -3
- package/src/cli/apps/AlephaPackageBuilderCli.ts +3 -0
- package/src/cli/atoms/changelogOptions.ts +45 -0
- package/src/cli/commands/ChangelogCommands.ts +187 -317
- package/src/cli/commands/DeployCommands.ts +118 -0
- package/src/cli/commands/DrizzleCommands.ts +28 -8
- package/src/cli/commands/ViteCommands.ts +23 -9
- package/src/cli/defineConfig.ts +15 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/services/AlephaCliUtils.ts +4 -21
- package/src/cli/services/GitMessageParser.ts +77 -0
- package/src/command/helpers/EnvUtils.ts +37 -0
- package/src/command/index.ts +3 -1
- package/src/command/primitives/$command.ts +172 -6
- package/src/command/providers/CliProvider.ts +424 -91
- package/src/core/Alepha.ts +1 -1
- package/src/file/providers/NodeFileSystemProvider.ts +3 -1
- package/src/orm/index.ts +8 -4
- package/src/orm/interfaces/PgQueryWhere.ts +1 -26
- package/src/orm/providers/drivers/BunPostgresProvider.ts +225 -0
- package/src/orm/providers/drivers/BunSqliteProvider.ts +180 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +25 -0
- package/src/orm/providers/drivers/NodePostgresProvider.ts +0 -25
- package/src/orm/services/QueryManager.ts +10 -125
- package/src/queue/redis/providers/RedisQueueProvider.ts +2 -7
- package/src/redis/index.ts +65 -3
- package/src/redis/providers/BunRedisProvider.ts +304 -0
- package/src/redis/providers/BunRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/NodeRedisProvider.ts +280 -0
- package/src/redis/providers/NodeRedisSubscriberProvider.ts +94 -0
- package/src/redis/providers/RedisProvider.ts +134 -140
- package/src/redis/providers/RedisSubscriberProvider.ts +58 -49
- package/src/server/core/providers/BunHttpServerProvider.ts +0 -3
- package/src/server/core/providers/ServerBodyParserProvider.ts +3 -1
- package/src/server/core/providers/ServerProvider.ts +7 -4
- package/src/server/multipart/providers/ServerMultipartProvider.ts +3 -1
- package/src/server/proxy/providers/ServerProxyProvider.ts +1 -1
- package/src/topic/redis/providers/RedisTopicProvider.ts +3 -3
- package/src/vite/tasks/buildServer.ts +1 -0
- package/src/orm/services/PgJsonQueryManager.ts +0 -511
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["askFn: AskMethod","value: any","createPromptInterface","runFn: RunnerMethod","stdout","t","allGlobalFlags: Record<\n string,\n { aliases: string[]; description?: string; schema: TSchema }\n >","result: Record<string, any>","result: any[]","typeName","command"],"sources":["../../src/command/helpers/Asker.ts","../../src/command/helpers/PrettyPrint.ts","../../src/command/errors/CommandError.ts","../../src/command/helpers/Runner.ts","../../src/command/primitives/$command.ts","../../src/command/providers/CliProvider.ts","../../src/command/index.ts"],"sourcesContent":["import { stdin as input, stdout as output } from \"node:process\";\nimport { createInterface as createPromptInterface } from \"node:readline/promises\";\nimport {\n $inject,\n Alepha,\n AlephaError,\n type Static,\n type TSchema,\n type TString,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\n\nexport interface AskOptions<T extends TSchema = TString> {\n /**\n * Response schema expected.\n *\n * Recommended schemas:\n * - t.text() - for free text input\n * - t.number() - for numeric input\n * - t.boolean() - for yes/no input (accepts \"true\", \"false\", \"1\", \"0\")\n * - t.enum([\"option1\", \"option2\"]) - for predefined options\n *\n * You can use schema.default to provide a default value.\n *\n * @example\n * ```ts\n * ask(\"What is your name?\", { schema: t.text({ default: \"John Doe\" }) })\n * ```\n *\n * @default TString\n */\n schema?: T;\n\n /**\n * Custom validation function.\n * Throws an AlephaError in case of validation failure.\n */\n validate?: (value: Static<T>) => void;\n}\n\nexport interface AskMethod {\n <T extends TSchema = TString>(\n question: string,\n options?: AskOptions<T>,\n ): Promise<Static<T>>;\n\n permission: (question: string) => Promise<boolean>;\n}\n\nexport class Asker {\n protected readonly log = $logger();\n public readonly ask: AskMethod;\n protected readonly alepha = $inject(Alepha);\n\n constructor() {\n this.ask = this.createAskMethod();\n }\n\n protected createAskMethod(): AskMethod {\n const askFn: AskMethod = async <T extends TSchema = TString>(\n question: string,\n options: AskOptions<T> = {},\n ) => {\n return await this.prompt<T>(question, options);\n };\n\n askFn.permission = async (question: string) => {\n const response = await this.prompt(`${question} [Y/n]`, {\n schema: t.enum([\"Y\", \"y\", \"n\", \"no\", \"yes\"], { default: \"Y\" }),\n });\n return response.charAt(0).toLowerCase() === \"y\";\n };\n\n return askFn;\n }\n\n protected async prompt<T extends TSchema = TString>(\n question: string,\n options: AskOptions<T>,\n ): Promise<Static<T>> {\n const rl = this.createPromptInterface();\n let value: any;\n try {\n do {\n try {\n const answer = await rl.question(`${question}\\n> `);\n if (options.schema) {\n value = this.alepha.codec.decode(\n options.schema,\n answer ? answer.trim() : undefined,\n );\n } else {\n value = String(answer.trim());\n }\n if (options.validate) {\n options.validate(value);\n }\n } catch (error) {\n if (error instanceof AlephaError) {\n this.log.error(`${error.message}\\n`);\n value = undefined;\n } else {\n throw error;\n }\n }\n } while (value === undefined);\n } finally {\n rl.close();\n }\n\n return value;\n }\n\n protected createPromptInterface() {\n return createPromptInterface({ input, output });\n }\n}\n","import { $inject } from \"alepha\";\nimport { DateTimeProvider, type Interval } from \"alepha/datetime\";\n\nexport class PrettyPrint {\n protected dateTimeProvider = $inject(DateTimeProvider);\n protected spinnerInterval?: Interval;\n protected readonly frames = [\n \"⠋\",\n \"⠙\",\n \"⠹\",\n \"⠸\",\n \"⠼\",\n \"⠴\",\n \"⠦\",\n \"⠧\",\n \"⠇\",\n \"⠏\",\n ];\n protected tasks = new Map<\n string,\n {\n taskName: string;\n frameIndex: number;\n status: \"running\" | \"success\" | \"error\";\n duration?: string;\n }\n >();\n protected lastLineCount = 0;\n protected header?: string;\n protected commandStartTime?: number;\n\n // ANSI color codes\n protected readonly colors = {\n reset: \"\\x1b[0m\",\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n red: \"\\x1b[31m\",\n dim: \"\\x1b[2m\",\n };\n\n /**\n * Start a new command session with header\n */\n public startCommand(cliName: string, commandName: string): void {\n this.header = commandName ? `${cliName} ${commandName}` : cliName;\n this.commandStartTime = Date.now();\n this.tasks.clear();\n this.lastLineCount = 0;\n process.stdout.write(`┌─ ${this.header}\\n`);\n }\n\n /**\n * End the command session with footer\n */\n public endCommand(): void {\n if (this.commandStartTime) {\n const totalDuration = (\n (Date.now() - this.commandStartTime) /\n 1000\n ).toFixed(1);\n process.stdout.write(`└─ Done in ${totalDuration}s\\n`);\n }\n this.header = undefined;\n this.commandStartTime = undefined;\n }\n\n /**\n * Start an animated spinner with a task name\n */\n public startSpinner(id: string, taskName: string): void {\n this.tasks.set(id, {\n taskName,\n frameIndex: 0,\n status: \"running\",\n });\n\n // Start interval if not already running\n if (!this.spinnerInterval) {\n this.spinnerInterval = this.dateTimeProvider.createInterval(\n () => this.updateDisplay(),\n 80,\n true,\n );\n }\n\n this.updateDisplay();\n }\n\n /**\n * Stop the spinner and show success with a tick\n */\n public success(id: string, taskName?: string, duration?: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.status = \"success\";\n if (taskName) task.taskName = taskName;\n if (duration) task.duration = duration;\n this.updateDisplay();\n }\n\n this.checkIfAllDone();\n }\n\n /**\n * Stop the spinner and show error with a cross\n */\n public error(id: string, taskName?: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.status = \"error\";\n if (taskName) task.taskName = taskName;\n this.updateDisplay();\n }\n\n this.checkIfAllDone();\n }\n\n /**\n * Update the display for all tasks\n */\n protected updateDisplay(): void {\n // Clear previous lines\n if (this.lastLineCount > 0) {\n // Move cursor up and clear each line\n for (let i = 0; i < this.lastLineCount; i++) {\n process.stdout.write(\"\\x1b[1A\\x1b[2K\");\n }\n }\n\n // Render all tasks\n const taskArray = Array.from(this.tasks.values());\n const prefix = this.header ? \"│ \" : \"\";\n\n for (const task of taskArray) {\n let line = prefix;\n\n if (task.status === \"running\") {\n const frame = this.frames[task.frameIndex];\n line += `${this.colors.cyan}${frame}${this.colors.reset} ${this.colors.dim}${task.taskName}${this.colors.reset}`;\n task.frameIndex = (task.frameIndex + 1) % this.frames.length;\n } else if (task.status === \"success\") {\n const durationStr = task.duration\n ? ` ${this.colors.dim}${task.duration}${this.colors.reset}`\n : \"\";\n line += `${this.colors.green}✓${this.colors.reset} ${task.taskName}${durationStr}`;\n } else if (task.status === \"error\") {\n line += `${this.colors.red}✗${this.colors.reset} ${task.taskName}`;\n }\n\n process.stdout.write(`${line}\\n`);\n }\n\n this.lastLineCount = taskArray.length;\n }\n\n /**\n * Check if all tasks are done and stop the interval\n */\n protected checkIfAllDone(): void {\n const hasRunningTasks = Array.from(this.tasks.values()).some(\n (task) => task.status === \"running\",\n );\n\n if (!hasRunningTasks && this.spinnerInterval) {\n this.dateTimeProvider.clearInterval(this.spinnerInterval);\n this.spinnerInterval = undefined;\n }\n }\n\n /**\n * Stop the spinner without showing any symbol\n */\n public stopSpinner(): void {\n if (this.spinnerInterval) {\n this.dateTimeProvider.clearInterval(this.spinnerInterval);\n this.spinnerInterval = undefined;\n }\n }\n\n /**\n * Clear all tasks\n */\n public clear(): void {\n this.tasks.clear();\n this.stopSpinner();\n this.lastLineCount = 0;\n }\n}\n","import { AlephaError } from \"alepha\";\n\nexport class CommandError extends AlephaError {\n readonly name = \"CommandError\";\n}\n","import { exec } from \"node:child_process\";\nimport { cp, glob, rm } from \"node:fs/promises\";\nimport { $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { CommandError } from \"../errors/CommandError.ts\";\nimport { PrettyPrint } from \"./PrettyPrint.ts\";\n\nexport type Task = {\n name: string;\n handler: () => any;\n};\n\ninterface Timer {\n name: string;\n duration: string;\n}\n\nexport interface RunOptions {\n /**\n * Rename the command for logging purposes.\n */\n alias?: string;\n}\n\nexport interface RunnerMethod {\n (\n cmd: string | Task | Array<string | Task>,\n options?: RunOptions | (() => any),\n ): Promise<string>;\n rm: (glob: string | string[], options?: RunOptions) => Promise<string>;\n cp: (source: string, dest: string, options?: RunOptions) => Promise<string>;\n}\n\nexport class Runner {\n protected readonly log = $logger();\n protected readonly timers: Timer[] = [];\n protected readonly startTime: number = Date.now();\n protected readonly prettyPrint = $inject(PrettyPrint);\n protected readonly alepha = $inject(Alepha);\n public readonly run: RunnerMethod;\n protected cliName = \"\";\n protected commandName = \"\";\n protected firstTaskStarted = false;\n\n constructor() {\n this.run = this.createRunMethod();\n }\n\n protected get useDynamicLogger() {\n if (this.alepha.isCI()) {\n return false;\n }\n\n return this.alepha.env.LOG_FORMAT === \"raw\";\n }\n\n /**\n * Start a new command session with header (for pretty print mode)\n */\n public startCommand(cliName: string, commandName: string): void {\n this.cliName = cliName;\n this.commandName = commandName;\n }\n\n protected createRunMethod() {\n const runFn: RunnerMethod = async (\n cmd: string | Task | Array<string | Task>,\n options?: RunOptions | (() => any),\n ) => {\n if (this.useDynamicLogger && !this.firstTaskStarted) {\n this.prettyPrint.startCommand(this.cliName, this.commandName);\n }\n\n this.firstTaskStarted = true;\n\n if (Array.isArray(cmd)) {\n return await this.execute(\n cmd.map((it) =>\n typeof it === \"string\"\n ? { name: it, handler: () => this.exec(it) }\n : it,\n ),\n );\n }\n\n const alias = typeof options === \"object\" ? options.alias : undefined;\n const name = alias ?? (typeof cmd === \"string\" ? cmd : cmd.name);\n const handler =\n typeof options === \"function\"\n ? options\n : typeof cmd === \"string\"\n ? () => this.exec(cmd)\n : cmd.handler;\n\n return await this.execute({\n name,\n handler,\n });\n };\n\n runFn.rm = async (\n files: string | string[],\n options: RunOptions = {},\n ): Promise<string> => {\n if (Array.isArray(files) || files.includes(\"*\")) {\n return runFn({\n name:\n options.alias ??\n `rm -rf ${Array.isArray(files) ? files.join(\" \") : files}`,\n handler: async () => {\n for await (const file of glob(files)) {\n this.log.trace(`Removing ${file}`);\n await rm(file, { recursive: true, force: true });\n }\n },\n });\n }\n this.log.trace(`Removing ${files}`);\n return runFn({\n name: options.alias ?? `rm -rf ${files}`,\n handler: () => rm(files, { recursive: true, force: true }),\n });\n };\n\n runFn.cp = async (\n source: string,\n dist: string,\n options: RunOptions = {},\n ): Promise<string> => {\n this.log.trace(`Copying ${source} to ${dist}`);\n return runFn(\n {\n name: options.alias ?? `cp -r ${source} ${dist}`,\n handler: () => cp(source, dist, { recursive: true }),\n },\n options,\n );\n };\n\n return runFn;\n }\n\n protected async exec(cmd: string): Promise<string> {\n return await new Promise<string>((resolve, reject) => {\n exec(\n cmd,\n {\n env: {\n ...process.env,\n LOG_FORMAT: \"pretty\",\n },\n },\n (err, stdout) => {\n if (err) {\n err.stdout = stdout;\n reject(err);\n } else {\n resolve(stdout);\n }\n },\n );\n });\n }\n\n /**\n * Executes one or more tasks.\n *\n * @param task - A single task or an array of tasks to run in parallel.\n */\n protected async execute(task: Task | Task[]): Promise<string> {\n if (Array.isArray(task)) {\n await Promise.all(task.map((t) => this.executeTask(t)));\n return \"\"; // not supported for now\n } else {\n return await this.executeTask(task);\n }\n }\n\n /**\n * Prints a summary of all executed tasks and their durations.\n */\n public summary(): void {\n if (this.useDynamicLogger && this.firstTaskStarted) {\n this.prettyPrint.endCommand();\n return;\n }\n\n // Non-dynamic mode: use logging\n if (this.timers.length === 0) return;\n\n this.log.info(\"\");\n const totalTime = ((Date.now() - this.startTime) / 1000).toFixed(1);\n this.log.info(`Total time: ${totalTime}s`);\n this.log.info(``);\n }\n\n protected async executeTask(task: Task): Promise<string> {\n const now = Date.now();\n const taskId = task.name; // Use task name as unique ID\n\n // Setup dynamic logger\n if (this.useDynamicLogger) {\n this.prettyPrint.startSpinner(taskId, task.name);\n } else {\n this.log.info(`Starting '${task.name}' ...`);\n }\n\n let stdout = \"\";\n\n try {\n stdout = String((await task.handler()) ?? \"\");\n } catch (error) {\n // Clear spinner and show error\n if (this.useDynamicLogger) {\n this.prettyPrint.error(taskId, task.name);\n }\n if (error instanceof Error && \"stdout\" in error) {\n this.log.info(`\\n\\n${error.stdout}`);\n }\n throw new CommandError(`Task '${task.name}' failed`, { cause: error });\n }\n\n if (stdout) this.log.trace(stdout);\n\n const duration = ((Date.now() - now) / 1000).toFixed(1);\n\n // Clear spinner and show completion\n if (this.useDynamicLogger) {\n this.prettyPrint.success(taskId, task.name, `${duration}s`);\n } else {\n this.log.info(`Finished '${task.name}' after ${duration}s`);\n }\n\n this.timers.push({\n name: task.name,\n duration: `${duration}s`,\n });\n\n return stdout;\n }\n\n protected renderTable(data: string[][]): void {\n if (data.length === 0) return;\n\n const col1Width = Math.max(...data.map(([col1]) => col1.length), 7);\n const col2Width = Math.max(...data.map(([, col2]) => col2.length), 8);\n\n const divider = `+${\"-\".repeat(col1Width + 2)}+${\"-\".repeat(\n col2Width + 2,\n )}+`;\n this.log.info(divider);\n this.log.info(\n `| ${\"Command\".padEnd(col1Width)} | ${\"Duration\".padEnd(col2Width)} |`,\n );\n this.log.info(divider);\n for (const [col1, col2] of data) {\n this.log.info(\n `| ${col1.padEnd(col1Width)} | ${col2.padEnd(col2Width)} |`,\n );\n }\n this.log.info(divider);\n }\n}\n","import type * as fs from \"node:fs/promises\";\nimport type { glob } from \"node:fs/promises\";\nimport {\n type Async,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type TObject,\n type TSchema,\n t,\n} from \"alepha\";\nimport type { AskMethod } from \"../helpers/Asker.ts\";\nimport type { RunnerMethod } from \"../helpers/Runner.ts\";\n\n/**\n * Declares a CLI command.\n *\n * This primitive allows you to define a command, its flags, and its handler\n * within your Alepha application structure.\n */\nexport const $command = <T extends TObject, A extends TSchema>(\n options: CommandPrimitiveOptions<T, A>,\n) => createPrimitive(CommandPrimitive<T, A>, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface CommandPrimitiveOptions<T extends TObject, A extends TSchema> {\n /**\n * The handler function to execute when the command is matched.\n */\n handler: (args: CommandHandlerArgs<T, A>) => Async<void>;\n\n /**\n * The name of the command. If omitted, the property key is used.\n *\n * An empty string \"\" denotes the root command.\n */\n name?: string;\n\n /**\n * A short description of the command, shown in the help message.\n */\n description?: string;\n\n /**\n * An array of alternative names for the command.\n */\n aliases?: string[];\n\n /**\n * A TypeBox object schema defining the flags for the command.\n */\n flags?: T;\n\n /**\n * An optional TypeBox schema defining the arguments for the command.\n *\n * @example\n * args: t.text()\n * my-cli command <arg1: string>\n *\n * args: t.optional(t.text())\n * my-cli command [arg1: string]\n *\n * args: t.tuple([t.text(), t.number()])\n * my-cli command <arg1: string> <arg2: number>\n *\n * args: t.tuple([t.text(), t.optional(t.number())])\n * my-cli command <arg1: string> [arg2: number]\n */\n args?: A;\n\n /**\n * If false, skip summary message at the end of the command execution.\n * Summary will display only if ({ run }) method calls were made.\n */\n summary?: boolean;\n\n /**\n * Marks this command as the root command.\n * Equivalent to setting name to an empty string \"\".\n */\n root?: boolean;\n\n /**\n * Run this command's handler BEFORE the specified target command.\n *\n * Pre-hooks are not listed in help and cannot be called directly.\n * They receive the same parsed flags and args as the target command.\n *\n * @example\n * ```ts\n * class BuildCommands {\n * prebuild = $command({\n * pre: \"build\",\n * handler: async ({ run }) => {\n * await run(\"cleaning dist folder...\", () => fs.rm(\"dist\"));\n * }\n * });\n *\n * build = $command({\n * name: \"build\",\n * handler: async () => { ... }\n * });\n * }\n * ```\n */\n pre?: string;\n\n /**\n * Run this command's handler AFTER the specified target command.\n *\n * Post-hooks are not listed in help and cannot be called directly.\n * They receive the same parsed flags and args as the target command.\n *\n * @example\n * ```ts\n * class BuildCommands {\n * build = $command({\n * name: \"build\",\n * handler: async () => { ... }\n * });\n *\n * postbuild = $command({\n * post: \"build\",\n * handler: async ({ run }) => {\n * await run(\"generating checksums...\", generateChecksums);\n * }\n * });\n * }\n * ```\n */\n post?: string;\n\n /**\n * If true, this command will be hidden from the help output.\n */\n hide?: boolean;\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class CommandPrimitive<\n T extends TObject = TObject,\n A extends TSchema = TSchema,\n> extends Primitive<CommandPrimitiveOptions<T, A>> {\n public readonly flags = this.options.flags ?? t.object({});\n public readonly aliases = this.options.aliases ?? [];\n\n protected onInit() {\n if (this.options.pre || this.options.post) {\n this.options.hide ??= true;\n }\n }\n\n public get name(): string {\n if (this.options.root) {\n return \"\";\n }\n if (this.options.pre) {\n return `pre${this.options.pre}`;\n }\n if (this.options.post) {\n return `post${this.options.post}`;\n }\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n}\n\n$command[KIND] = CommandPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface CommandHandlerArgs<\n T extends TObject,\n A extends TSchema = TSchema,\n> {\n flags: Static<T>;\n args: A extends TSchema ? Static<A> : Array<string>;\n run: RunnerMethod;\n ask: AskMethod;\n glob: typeof glob;\n fs: typeof fs;\n\n /**\n * The root directory where the command is executed.\n */\n root: string;\n}\n","import * as fs from \"node:fs/promises\";\nimport { glob } from \"node:fs/promises\";\nimport {\n $atom,\n $env,\n $hook,\n $inject,\n $use,\n Alepha,\n type Static,\n type TObject,\n type TSchema,\n TypeBoxError,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { CommandError } from \"../errors/CommandError.ts\";\nimport { Asker } from \"../helpers/Asker.ts\";\nimport { Runner } from \"../helpers/Runner.ts\";\nimport {\n $command,\n type CommandHandlerArgs,\n type CommandPrimitive,\n} from \"../primitives/$command.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nconst envSchema = t.object({\n CLI_NAME: t.text({\n default: \"cli\",\n description: \"Name of the CLI application.\",\n }),\n CLI_DESCRIPTION: t.text({\n default: \"\",\n description: \"Description of the CLI application.\",\n }),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\n/**\n * CLI provider configuration atom\n */\nexport const cliOptions = $atom({\n name: \"alepha.command.cli.options\",\n schema: t.object({\n name: t.optional(\n t.string({\n description: \"Name of the CLI application.\",\n }),\n ),\n description: t.optional(\n t.string({\n description: \"Description of the CLI application.\",\n }),\n ),\n argv: t.optional(\n t.array(t.string(), {\n description: \"Command line arguments to parse.\",\n }),\n ),\n }),\n default: {},\n});\n\nexport type CliProviderOptions = Static<typeof cliOptions.schema>;\n\ndeclare module \"alepha\" {\n interface State {\n [cliOptions.key]: CliProviderOptions;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class CliProvider {\n protected readonly env = $env(envSchema);\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly runner = $inject(Runner);\n protected readonly asker = $inject(Asker);\n\n protected readonly options = $use(cliOptions);\n\n protected get name(): string {\n return this.options.name || this.env.CLI_NAME;\n }\n\n protected get description(): string {\n return this.options.description || this.env.CLI_DESCRIPTION;\n }\n\n protected get argv(): string[] {\n return (\n this.options.argv ||\n (typeof process !== \"undefined\" ? process.argv.slice(2) : [])\n );\n }\n\n protected readonly globalFlags = {\n help: {\n aliases: [\"h\", \"help\"],\n description: \"Show this help message\",\n schema: t.boolean(),\n },\n };\n\n protected readonly onReady = $hook({\n on: \"ready\",\n handler: async () => {\n const argv = [...this.argv];\n const commandName = argv.find((arg) => !arg.startsWith(\"-\")) ?? \"\";\n let command = this.findCommand(commandName);\n\n const globalFlags = this.parseFlags(\n argv,\n Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({\n key,\n ...value,\n })),\n );\n\n if (globalFlags.help) {\n this.printHelp(command);\n return;\n }\n\n if (!command) {\n // check if one command is the root command (name === \"\") and has 'args'\n const rootCommand = this.findCommand(\"\");\n if (rootCommand?.options.args) {\n command = rootCommand;\n } else {\n if (commandName !== \"\") {\n this.log.error(`Unknown command: '${commandName}'`);\n this.printHelp();\n }\n return;\n }\n }\n\n const commandFlags = this.parseCommandFlags(argv, command.flags);\n const commandArgs = this.parseCommandArgs(\n argv,\n command.options.args,\n command.name === \"\",\n command.flags,\n );\n\n await this.alepha.context.run(async () => {\n this.log.debug(`Executing command '${command.name}'...`, {\n flags: commandFlags,\n args: commandArgs,\n });\n\n const runner = this.runner;\n\n // Start command session for pretty print\n runner.startCommand(this.name, command.name);\n\n const args = {\n flags: commandFlags,\n args: commandArgs,\n run: runner.run,\n ask: this.asker.ask,\n fs,\n glob,\n root: process.cwd(),\n };\n\n // Execute pre-hooks\n const preHooks = this.findPreHooks(command.name);\n for (const hook of preHooks) {\n this.log.debug(`Executing pre-hook for '${command.name}'...`);\n await hook.options.handler(args as CommandHandlerArgs<TObject>);\n }\n\n // Execute main command\n await command.options.handler(args as CommandHandlerArgs<TObject>);\n\n // Execute post-hooks\n const postHooks = this.findPostHooks(command.name);\n for (const hook of postHooks) {\n this.log.debug(`Executing post-hook for '${command.name}'...`);\n await hook.options.handler(args as CommandHandlerArgs<TObject>);\n }\n\n if (command.options.summary !== false) {\n runner.summary();\n }\n\n this.log.debug(`Command '${command.name}' executed successfully.`);\n });\n },\n });\n\n public get commands(): CommandPrimitive<any>[] {\n return this.alepha.primitives($command);\n }\n\n protected findCommand(name: string): CommandPrimitive<TObject> | undefined {\n return this.commands.findLast(\n (command) => command.name === name || command.aliases.includes(name),\n );\n }\n\n /**\n * Find all pre-hooks for a command.\n */\n protected findPreHooks(commandName: string): CommandPrimitive<TObject>[] {\n return this.commands.filter((cmd) => cmd.name === `pre${commandName}`);\n }\n\n /**\n * Find all post-hooks for a command.\n */\n protected findPostHooks(commandName: string): CommandPrimitive<TObject>[] {\n return this.commands.filter((cmd) => cmd.name === `post${commandName}`);\n }\n\n /**\n * Get all global flags including those from the root command (name === \"\")\n */\n protected getAllGlobalFlags(): Record<\n string,\n { aliases: string[]; description?: string; schema: TSchema }\n > {\n const rootCommand = this.commands.find((cmd) => cmd.name === \"\");\n const allGlobalFlags: Record<\n string,\n { aliases: string[]; description?: string; schema: TSchema }\n > = { ...this.globalFlags };\n\n if (rootCommand) {\n // Add root command flags to global flags\n for (const [key, value] of Object.entries(rootCommand.flags.properties)) {\n allGlobalFlags[key] = {\n aliases: [\n key,\n ...((value as any).aliases ??\n ((value as any).alias ? [(value as any).alias] : undefined) ??\n []),\n ],\n description: (value as any).description,\n schema: value as TSchema,\n };\n }\n }\n\n return allGlobalFlags;\n }\n\n protected parseCommandFlags(\n argv: string[],\n schema: TObject,\n ): Record<string, any> {\n const flagDefs = Object.entries(schema.properties).map(([key, value]) => ({\n key,\n aliases: [\n key,\n ...((value as any).aliases ??\n ((value as any).alias ? [(value as any).alias] : undefined) ??\n []),\n ],\n description: (value as any).description,\n schema: value,\n }));\n\n const parsed = this.parseFlags(argv, flagDefs);\n\n // apply manually defaults for optional properties that have defaults\n for (const [key, value] of Object.entries(schema.properties)) {\n if (!(key in parsed) && t.schema.isOptional(value)) {\n const innerSchema = value;\n if (innerSchema && \"default\" in innerSchema) {\n parsed[key] = innerSchema.default;\n }\n }\n }\n\n try {\n return this.alepha.codec.decode(schema, parsed);\n } catch (error) {\n if (error instanceof TypeBoxError) {\n throw new CommandError(\n `Invalid flag: ${error.cause.instancePath || \"command\"} ${error.cause.message}`,\n );\n }\n throw error;\n }\n }\n\n protected parseFlags(\n argv: string[],\n flagDefs: { key: string; aliases: string[]; schema: TSchema }[],\n ): Record<string, any> {\n const result: Record<string, any> = {};\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (!arg.startsWith(\"-\")) continue;\n\n const [rawKey, ...valueParts] = arg.replace(/^-{1,2}/, \"\").split(\"=\");\n let value = valueParts.join(\"=\");\n\n const def = flagDefs.find((d) => d.aliases.includes(rawKey));\n if (!def) continue;\n\n if (t.schema.isBoolean(def.schema)) {\n result[def.key] = true;\n } else if (value) {\n // Value provided via --flag=value syntax\n try {\n if (t.schema.isObject(def.schema) || t.schema.isArray(def.schema)) {\n result[def.key] = JSON.parse(value);\n } else {\n result[def.key] = value;\n }\n } catch {\n throw new CommandError(`Invalid JSON value for flag --${rawKey}`);\n }\n } else {\n // Check for space-separated value: --flag value\n const nextArg = argv[i + 1];\n if (nextArg && !nextArg.startsWith(\"-\")) {\n value = nextArg;\n try {\n if (t.schema.isObject(def.schema) || t.schema.isArray(def.schema)) {\n result[def.key] = JSON.parse(value);\n } else {\n result[def.key] = value;\n }\n } catch {\n throw new CommandError(`Invalid JSON value for flag --${rawKey}`);\n }\n } else {\n throw new CommandError(`Flag --${rawKey} requires a value.`);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Get indices of argv elements that are consumed by flags (including space-separated values).\n */\n protected getFlagConsumedIndices(\n argv: string[],\n flagDefs: { key: string; aliases: string[]; schema: TSchema }[],\n ): Set<number> {\n const consumed = new Set<number>();\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (!arg.startsWith(\"-\")) continue;\n\n consumed.add(i);\n\n const [rawKey, ...valueParts] = arg.replace(/^-{1,2}/, \"\").split(\"=\");\n const hasEqualValue = valueParts.length > 0;\n\n const def = flagDefs.find((d) => d.aliases.includes(rawKey));\n if (!def) continue;\n\n // If not a boolean flag and no = value, the next arg is consumed as the value\n if (!t.schema.isBoolean(def.schema) && !hasEqualValue) {\n const nextArg = argv[i + 1];\n if (nextArg && !nextArg.startsWith(\"-\")) {\n consumed.add(i + 1);\n }\n }\n }\n\n return consumed;\n }\n\n protected parseCommandArgs(\n argv: string[],\n schema?: TSchema,\n isRootCommand = false,\n flagSchema?: TObject,\n ): any {\n if (!schema) {\n return undefined;\n }\n\n // Get indices consumed by flags (including space-separated values)\n const flagDefs = flagSchema\n ? Object.entries(flagSchema.properties).map(([key, value]) => ({\n key,\n aliases: [\n key,\n ...((value as any).aliases ??\n ((value as any).alias ? [(value as any).alias] : undefined) ??\n []),\n ],\n schema: value as TSchema,\n }))\n : [];\n const consumedIndices = this.getFlagConsumedIndices(argv, flagDefs);\n\n // Extract positional arguments (non-flag arguments that aren't consumed as flag values)\n const positionalArgs = argv.filter(\n (arg, idx) => !arg.startsWith(\"-\") && !consumedIndices.has(idx),\n );\n // For root commands, there's no command name to remove; otherwise slice off the command name\n const argsOnly = isRootCommand ? positionalArgs : positionalArgs.slice(1);\n\n try {\n if (t.schema.isOptional(schema)) {\n // Handle optional args: t.optional(t.text())\n if (argsOnly.length === 0) {\n return undefined;\n }\n return this.parseArgumentValue(argsOnly[0], schema);\n } else if (t.schema.isTuple(schema) && schema.items) {\n // Handle tuple args: t.tuple([t.text(), t.number()])\n const result: any[] = [];\n const items = schema.items;\n for (let i = 0; i < items.length; i++) {\n const itemSchema = items[i];\n if (i < argsOnly.length) {\n result.push(this.parseArgumentValue(argsOnly[i], itemSchema));\n } else if (t.schema.isOptional(itemSchema)) {\n result.push(undefined);\n } else {\n throw new CommandError(\n `Missing required argument at position ${i + 1}`,\n );\n }\n }\n return result;\n } else {\n // Handle single arg: t.text(), t.number(), etc.\n if (argsOnly.length === 0) {\n throw new CommandError(\"Missing required argument\");\n }\n return this.parseArgumentValue(argsOnly[0], schema);\n }\n } catch (error) {\n if (error instanceof TypeBoxError) {\n throw new CommandError(`Invalid argument: ${error.value.message}`);\n }\n throw error;\n }\n }\n\n protected parseArgumentValue(value: string, schema: TSchema): any {\n if (t.schema.isString(schema)) {\n return value;\n }\n\n if (t.schema.isNumber(schema) || t.schema.isInteger(schema)) {\n const num = Number(value);\n if (Number.isNaN(num)) {\n throw new CommandError(`Expected number, got \"${value}\"`);\n }\n if (t.schema.isInteger(schema) && !Number.isInteger(num)) {\n throw new CommandError(`Expected integer, got \"${value}\"`);\n }\n return num;\n }\n\n if (t.schema.isBoolean(schema)) {\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"1\") return true;\n if (lower === \"false\" || lower === \"0\") return false;\n throw new CommandError(`Expected boolean, got \"${value}\"`);\n }\n\n // For other types, return the string value and let TypeBox validate it\n return value;\n }\n\n protected generateArgsUsage(schema?: TSchema): string {\n if (!schema) {\n return \"\";\n }\n\n if (t.schema.isOptional(schema)) {\n const typeName = this.getTypeName(schema);\n const key = \"title\" in schema ? (schema as any).title : \"arg1\";\n return ` [${key}${typeName}]`;\n }\n\n if (t.schema.isTuple(schema) && schema.items) {\n const items = schema.items;\n const args = items.map((item, index) => {\n const argName = `arg${index + 1}`;\n const typeName = this.getTypeName(item);\n if (t.schema.isOptional(item)) {\n return `[${argName}${typeName}]`;\n }\n return `<${argName}${typeName}>`;\n });\n return ` ${args.join(\" \")}`;\n }\n\n const typeName = this.getTypeName(schema);\n const key = \"title\" in schema ? (schema as any).title : \"arg1\";\n return ` <${key}${typeName}>`;\n }\n\n protected getTypeName(schema: TSchema): string {\n if (!schema) return \"\";\n\n // Check TypeBox type guards first\n if (t.schema.isString(schema)) return \"\";\n if (t.schema.isNumber(schema)) return \": number\";\n if (t.schema.isInteger(schema)) return \": integer\";\n if (t.schema.isBoolean(schema)) return \": boolean\";\n\n return \"\";\n }\n\n public printHelp(command?: CommandPrimitive<any>): void {\n const cliName = this.name || \"cli\";\n this.log.info(\"\"); // Newline\n\n if (command?.name) {\n // Command-specific help\n const argsUsage = this.generateArgsUsage(command.options.args);\n const usage = `${cliName} ${command.name}${argsUsage}`.trim();\n this.log.info(`Usage: \\`${usage}\\``);\n\n if (command.options.description) {\n this.log.info(``);\n this.log.info(`\\t${command.options.description}`);\n }\n\n this.log.info(\"\");\n this.log.info(\"Flags:\");\n\n const flags = [\n ...Object.entries(command.flags.properties).map(([key, value]) => ({\n key,\n schema: value,\n aliases: (value as any).alias ?? [key],\n description: (value as any).description,\n })),\n ...Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({\n key,\n ...value,\n })),\n ];\n\n const maxFlagLength = this.getMaxFlagLength(flags);\n for (const { aliases, description } of flags) {\n const flagStr = (Array.isArray(aliases) ? aliases : [aliases])\n .map((a: string) => (a.length === 1 ? `-${a}` : `--${a}`))\n .join(\", \");\n this.log.info(\n ` ${flagStr.padEnd(maxFlagLength)} # ${description ?? \"\"}`,\n );\n }\n } else {\n // general help\n this.log.info(this.description || \"Available commands:\");\n this.log.info(\"\");\n this.log.info(\"Commands:\");\n const maxCmdLength = this.getMaxCmdLength(this.commands);\n\n for (const command of this.commands) {\n // skip root command and hooks in list\n if (command.name === \"\" || command.options.hide) {\n continue;\n }\n\n const cmdStr = [command.name, ...command.aliases].join(\", \");\n const argsUsage = this.generateArgsUsage(command.options.args);\n const fullCmdStr = `${cmdStr}${argsUsage}`;\n this.log.info(\n ` ${cliName} ${fullCmdStr.padEnd(maxCmdLength)} # ${command.options.description ?? \"\"}`,\n );\n }\n\n this.log.info(\"\");\n this.log.info(\"Flags:\");\n const globalFlags = Object.values(this.getAllGlobalFlags());\n const maxFlagLength = this.getMaxFlagLength(globalFlags);\n for (const { aliases, description } of globalFlags) {\n const flagStr = aliases\n .map((a) => (a.length === 1 ? `-${a}` : `--${a}`))\n .join(\", \");\n this.log.info(\n ` ${flagStr.padEnd(maxFlagLength)} # ${description ?? \"\"}`,\n );\n }\n }\n this.log.info(\"\"); // Newline\n }\n\n private getMaxCmdLength(commands: CommandPrimitive[]): number {\n return Math.max(\n ...commands\n .filter((c) => !c.options.hide && c.name !== \"\")\n .map((c) => {\n const cmdStr = [c.name, ...c.aliases].join(\", \");\n const argsUsage = this.generateArgsUsage(c.options.args);\n return `${cmdStr}${argsUsage}`.length;\n }),\n );\n }\n\n private getMaxFlagLength(flags: { aliases: string[] }[]): number {\n return Math.max(\n ...flags.map((f) => {\n const aliases = Array.isArray(f.aliases) ? f.aliases : [f.aliases];\n return aliases\n .map((a) => (a.length === 1 ? `-${a}` : `--${a}`))\n .join(\", \").length;\n }),\n );\n }\n}\n","import { $module } from \"alepha\";\nimport { Asker } from \"./helpers/Asker.ts\";\nimport { PrettyPrint } from \"./helpers/PrettyPrint.ts\";\nimport { Runner } from \"./helpers/Runner.ts\";\nimport { $command } from \"./primitives/$command.ts\";\nimport { CliProvider } from \"./providers/CliProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./errors/CommandError.ts\";\nexport * from \"./helpers/Asker.ts\";\nexport * from \"./helpers/PrettyPrint.ts\";\nexport * from \"./helpers/Runner.ts\";\nexport * from \"./primitives/$command.ts\";\nexport * from \"./providers/CliProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * This module provides a powerful way to build command-line interfaces\n * directly within your Alepha application, using declarative primitives.\n *\n * It allows you to define commands using the `$command` primitive.\n *\n * @see {@link $command}\n * @module alepha.command\n */\nexport const AlephaCommand = $module({\n name: \"alepha.command\",\n primitives: [$command],\n services: [CliProvider, Runner, Asker, PrettyPrint],\n});\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"typebox\" {\n interface StringOptions {\n /**\n * Additional aliases for the flags.\n *\n * @module alepha.command\n */\n aliases?: string[];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["askFn: AskMethod","value: any","createPromptInterface","runFn: RunnerMethod","stdout","t","modeValue: string | undefined","result: string[]","consumedArgs: string[]","result: Record<string, any>","missing: string[]","result: any[]","typeName","command","path: string[]"],"sources":["../../src/command/helpers/Asker.ts","../../src/command/helpers/EnvUtils.ts","../../src/command/helpers/PrettyPrint.ts","../../src/command/errors/CommandError.ts","../../src/command/helpers/Runner.ts","../../src/command/primitives/$command.ts","../../src/command/providers/CliProvider.ts","../../src/command/index.ts"],"sourcesContent":["import { stdin as input, stdout as output } from \"node:process\";\nimport { createInterface as createPromptInterface } from \"node:readline/promises\";\nimport {\n $inject,\n Alepha,\n AlephaError,\n type Static,\n type TSchema,\n type TString,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\n\nexport interface AskOptions<T extends TSchema = TString> {\n /**\n * Response schema expected.\n *\n * Recommended schemas:\n * - t.text() - for free text input\n * - t.number() - for numeric input\n * - t.boolean() - for yes/no input (accepts \"true\", \"false\", \"1\", \"0\")\n * - t.enum([\"option1\", \"option2\"]) - for predefined options\n *\n * You can use schema.default to provide a default value.\n *\n * @example\n * ```ts\n * ask(\"What is your name?\", { schema: t.text({ default: \"John Doe\" }) })\n * ```\n *\n * @default TString\n */\n schema?: T;\n\n /**\n * Custom validation function.\n * Throws an AlephaError in case of validation failure.\n */\n validate?: (value: Static<T>) => void;\n}\n\nexport interface AskMethod {\n <T extends TSchema = TString>(\n question: string,\n options?: AskOptions<T>,\n ): Promise<Static<T>>;\n\n permission: (question: string) => Promise<boolean>;\n}\n\nexport class Asker {\n protected readonly log = $logger();\n public readonly ask: AskMethod;\n protected readonly alepha = $inject(Alepha);\n\n constructor() {\n this.ask = this.createAskMethod();\n }\n\n protected createAskMethod(): AskMethod {\n const askFn: AskMethod = async <T extends TSchema = TString>(\n question: string,\n options: AskOptions<T> = {},\n ) => {\n return await this.prompt<T>(question, options);\n };\n\n askFn.permission = async (question: string) => {\n const response = await this.prompt(`${question} [Y/n]`, {\n schema: t.enum([\"Y\", \"y\", \"n\", \"no\", \"yes\"], { default: \"Y\" }),\n });\n return response.charAt(0).toLowerCase() === \"y\";\n };\n\n return askFn;\n }\n\n protected async prompt<T extends TSchema = TString>(\n question: string,\n options: AskOptions<T>,\n ): Promise<Static<T>> {\n const rl = this.createPromptInterface();\n let value: any;\n try {\n do {\n try {\n const answer = await rl.question(`${question}\\n> `);\n if (options.schema) {\n value = this.alepha.codec.decode(\n options.schema,\n answer ? answer.trim() : undefined,\n );\n } else {\n value = String(answer.trim());\n }\n if (options.validate) {\n options.validate(value);\n }\n } catch (error) {\n if (error instanceof AlephaError) {\n this.log.error(`${error.message}\\n`);\n value = undefined;\n } else {\n throw error;\n }\n }\n } while (value === undefined);\n } finally {\n rl.close();\n }\n\n return value;\n }\n\n protected createPromptInterface() {\n return createPromptInterface({ input, output });\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { $logger } from \"alepha/logger\";\n\nexport class EnvUtils {\n protected readonly log = $logger();\n\n /**\n * Load environment variables from .env files into process.env.\n * By default, it loads from \".env\" and \".env.local\".\n * You can specify additional files to load, e.g. [\".env\", \".env.production\"].\n */\n public async loadEnv(\n root: string,\n files: string[] = [\".env\"],\n ): Promise<void> {\n for (const it of files) {\n for (const file of [it, `${it}.local`]) {\n const envPath = join(root, file);\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 ${file} file found at ${envPath}, skipping load.`);\n }\n }\n }\n }\n}\n","import { $inject } from \"alepha\";\nimport { DateTimeProvider, type Interval } from \"alepha/datetime\";\n\nexport class PrettyPrint {\n protected dateTimeProvider = $inject(DateTimeProvider);\n protected spinnerInterval?: Interval;\n protected readonly frames = [\n \"⠋\",\n \"⠙\",\n \"⠹\",\n \"⠸\",\n \"⠼\",\n \"⠴\",\n \"⠦\",\n \"⠧\",\n \"⠇\",\n \"⠏\",\n ];\n protected tasks = new Map<\n string,\n {\n taskName: string;\n frameIndex: number;\n status: \"running\" | \"success\" | \"error\";\n duration?: string;\n }\n >();\n protected lastLineCount = 0;\n protected header?: string;\n protected commandStartTime?: number;\n\n // ANSI color codes\n protected readonly colors = {\n reset: \"\\x1b[0m\",\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n red: \"\\x1b[31m\",\n dim: \"\\x1b[2m\",\n };\n\n /**\n * Start a new command session with header\n */\n public startCommand(cliName: string, commandName: string): void {\n this.header = commandName ? `${cliName} ${commandName}` : cliName;\n this.commandStartTime = Date.now();\n this.tasks.clear();\n this.lastLineCount = 0;\n process.stdout.write(`┌─ ${this.header}\\n`);\n }\n\n /**\n * End the command session with footer\n */\n public endCommand(): void {\n if (this.commandStartTime) {\n const totalDuration = (\n (Date.now() - this.commandStartTime) /\n 1000\n ).toFixed(1);\n process.stdout.write(`└─ Done in ${totalDuration}s\\n`);\n }\n this.header = undefined;\n this.commandStartTime = undefined;\n }\n\n /**\n * Start an animated spinner with a task name\n */\n public startSpinner(id: string, taskName: string): void {\n this.tasks.set(id, {\n taskName,\n frameIndex: 0,\n status: \"running\",\n });\n\n // Start interval if not already running\n if (!this.spinnerInterval) {\n this.spinnerInterval = this.dateTimeProvider.createInterval(\n () => this.updateDisplay(),\n 80,\n true,\n );\n }\n\n this.updateDisplay();\n }\n\n /**\n * Stop the spinner and show success with a tick\n */\n public success(id: string, taskName?: string, duration?: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.status = \"success\";\n if (taskName) task.taskName = taskName;\n if (duration) task.duration = duration;\n this.updateDisplay();\n }\n\n this.checkIfAllDone();\n }\n\n /**\n * Stop the spinner and show error with a cross\n */\n public error(id: string, taskName?: string): void {\n const task = this.tasks.get(id);\n if (task) {\n task.status = \"error\";\n if (taskName) task.taskName = taskName;\n this.updateDisplay();\n }\n\n this.checkIfAllDone();\n }\n\n /**\n * Update the display for all tasks\n */\n protected updateDisplay(): void {\n // Clear previous lines\n if (this.lastLineCount > 0) {\n // Move cursor up and clear each line\n for (let i = 0; i < this.lastLineCount; i++) {\n process.stdout.write(\"\\x1b[1A\\x1b[2K\");\n }\n }\n\n // Render all tasks\n const taskArray = Array.from(this.tasks.values());\n const prefix = this.header ? \"│ \" : \"\";\n\n for (const task of taskArray) {\n let line = prefix;\n\n if (task.status === \"running\") {\n const frame = this.frames[task.frameIndex];\n line += `${this.colors.cyan}${frame}${this.colors.reset} ${this.colors.dim}${task.taskName}${this.colors.reset}`;\n task.frameIndex = (task.frameIndex + 1) % this.frames.length;\n } else if (task.status === \"success\") {\n const durationStr = task.duration\n ? ` ${this.colors.dim}${task.duration}${this.colors.reset}`\n : \"\";\n line += `${this.colors.green}✓${this.colors.reset} ${task.taskName}${durationStr}`;\n } else if (task.status === \"error\") {\n line += `${this.colors.red}✗${this.colors.reset} ${task.taskName}`;\n }\n\n process.stdout.write(`${line}\\n`);\n }\n\n this.lastLineCount = taskArray.length;\n }\n\n /**\n * Check if all tasks are done and stop the interval\n */\n protected checkIfAllDone(): void {\n const hasRunningTasks = Array.from(this.tasks.values()).some(\n (task) => task.status === \"running\",\n );\n\n if (!hasRunningTasks && this.spinnerInterval) {\n this.dateTimeProvider.clearInterval(this.spinnerInterval);\n this.spinnerInterval = undefined;\n }\n }\n\n /**\n * Stop the spinner without showing any symbol\n */\n public stopSpinner(): void {\n if (this.spinnerInterval) {\n this.dateTimeProvider.clearInterval(this.spinnerInterval);\n this.spinnerInterval = undefined;\n }\n }\n\n /**\n * Clear all tasks\n */\n public clear(): void {\n this.tasks.clear();\n this.stopSpinner();\n this.lastLineCount = 0;\n }\n}\n","import { AlephaError } from \"alepha\";\n\nexport class CommandError extends AlephaError {\n readonly name = \"CommandError\";\n}\n","import { exec } from \"node:child_process\";\nimport { cp, glob, rm } from \"node:fs/promises\";\nimport { $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { CommandError } from \"../errors/CommandError.ts\";\nimport { PrettyPrint } from \"./PrettyPrint.ts\";\n\nexport type Task = {\n name: string;\n handler: () => any;\n};\n\ninterface Timer {\n name: string;\n duration: string;\n}\n\nexport interface RunOptions {\n /**\n * Rename the command for logging purposes.\n */\n alias?: string;\n}\n\nexport interface RunnerMethod {\n (\n cmd: string | Task | Array<string | Task>,\n options?: RunOptions | (() => any),\n ): Promise<string>;\n rm: (glob: string | string[], options?: RunOptions) => Promise<string>;\n cp: (source: string, dest: string, options?: RunOptions) => Promise<string>;\n}\n\nexport class Runner {\n protected readonly log = $logger();\n protected readonly timers: Timer[] = [];\n protected readonly startTime: number = Date.now();\n protected readonly prettyPrint = $inject(PrettyPrint);\n protected readonly alepha = $inject(Alepha);\n public readonly run: RunnerMethod;\n protected cliName = \"\";\n protected commandName = \"\";\n protected firstTaskStarted = false;\n\n constructor() {\n this.run = this.createRunMethod();\n }\n\n protected get useDynamicLogger() {\n if (this.alepha.isCI()) {\n return false;\n }\n\n return this.alepha.env.LOG_FORMAT === \"raw\";\n }\n\n /**\n * Start a new command session with header (for pretty print mode)\n */\n public startCommand(cliName: string, commandName: string): void {\n this.cliName = cliName;\n this.commandName = commandName;\n }\n\n protected createRunMethod() {\n const runFn: RunnerMethod = async (\n cmd: string | Task | Array<string | Task>,\n options?: RunOptions | (() => any),\n ) => {\n if (this.useDynamicLogger && !this.firstTaskStarted) {\n this.prettyPrint.startCommand(this.cliName, this.commandName);\n }\n\n this.firstTaskStarted = true;\n\n if (Array.isArray(cmd)) {\n return await this.execute(\n cmd.map((it) =>\n typeof it === \"string\"\n ? { name: it, handler: () => this.exec(it) }\n : it,\n ),\n );\n }\n\n const alias = typeof options === \"object\" ? options.alias : undefined;\n const name = alias ?? (typeof cmd === \"string\" ? cmd : cmd.name);\n const handler =\n typeof options === \"function\"\n ? options\n : typeof cmd === \"string\"\n ? () => this.exec(cmd)\n : cmd.handler;\n\n return await this.execute({\n name,\n handler,\n });\n };\n\n runFn.rm = async (\n files: string | string[],\n options: RunOptions = {},\n ): Promise<string> => {\n if (Array.isArray(files) || files.includes(\"*\")) {\n return runFn({\n name:\n options.alias ??\n `rm -rf ${Array.isArray(files) ? files.join(\" \") : files}`,\n handler: async () => {\n for await (const file of glob(files)) {\n this.log.trace(`Removing ${file}`);\n await rm(file, { recursive: true, force: true });\n }\n },\n });\n }\n this.log.trace(`Removing ${files}`);\n return runFn({\n name: options.alias ?? `rm -rf ${files}`,\n handler: () => rm(files, { recursive: true, force: true }),\n });\n };\n\n runFn.cp = async (\n source: string,\n dist: string,\n options: RunOptions = {},\n ): Promise<string> => {\n this.log.trace(`Copying ${source} to ${dist}`);\n return runFn(\n {\n name: options.alias ?? `cp -r ${source} ${dist}`,\n handler: () => cp(source, dist, { recursive: true }),\n },\n options,\n );\n };\n\n return runFn;\n }\n\n protected async exec(cmd: string): Promise<string> {\n return await new Promise<string>((resolve, reject) => {\n exec(\n cmd,\n {\n env: {\n ...process.env,\n LOG_FORMAT: \"pretty\",\n },\n },\n (err, stdout) => {\n if (err) {\n err.stdout = stdout;\n reject(err);\n } else {\n resolve(stdout);\n }\n },\n );\n });\n }\n\n /**\n * Executes one or more tasks.\n *\n * @param task - A single task or an array of tasks to run in parallel.\n */\n protected async execute(task: Task | Task[]): Promise<string> {\n if (Array.isArray(task)) {\n await Promise.all(task.map((t) => this.executeTask(t)));\n return \"\"; // not supported for now\n } else {\n return await this.executeTask(task);\n }\n }\n\n /**\n * Prints a summary of all executed tasks and their durations.\n */\n public summary(): void {\n if (this.useDynamicLogger && this.firstTaskStarted) {\n this.prettyPrint.endCommand();\n return;\n }\n\n // Non-dynamic mode: use logging\n if (this.timers.length === 0) return;\n\n this.log.info(\"\");\n const totalTime = ((Date.now() - this.startTime) / 1000).toFixed(1);\n this.log.info(`Total time: ${totalTime}s`);\n this.log.info(``);\n }\n\n protected async executeTask(task: Task): Promise<string> {\n const now = Date.now();\n const taskId = task.name; // Use task name as unique ID\n\n // Setup dynamic logger\n if (this.useDynamicLogger) {\n this.prettyPrint.startSpinner(taskId, task.name);\n } else {\n this.log.info(`Starting '${task.name}' ...`);\n }\n\n let stdout = \"\";\n\n try {\n stdout = String((await task.handler()) ?? \"\");\n } catch (error) {\n // Clear spinner and show error\n if (this.useDynamicLogger) {\n this.prettyPrint.error(taskId, task.name);\n }\n if (error instanceof Error && \"stdout\" in error) {\n this.log.info(`\\n\\n${error.stdout}`);\n }\n throw new CommandError(`Task '${task.name}' failed`, { cause: error });\n }\n\n if (stdout) this.log.trace(stdout);\n\n const duration = ((Date.now() - now) / 1000).toFixed(1);\n\n // Clear spinner and show completion\n if (this.useDynamicLogger) {\n this.prettyPrint.success(taskId, task.name, `${duration}s`);\n } else {\n this.log.info(`Finished '${task.name}' after ${duration}s`);\n }\n\n this.timers.push({\n name: task.name,\n duration: `${duration}s`,\n });\n\n return stdout;\n }\n\n protected renderTable(data: string[][]): void {\n if (data.length === 0) return;\n\n const col1Width = Math.max(...data.map(([col1]) => col1.length), 7);\n const col2Width = Math.max(...data.map(([, col2]) => col2.length), 8);\n\n const divider = `+${\"-\".repeat(col1Width + 2)}+${\"-\".repeat(\n col2Width + 2,\n )}+`;\n this.log.info(divider);\n this.log.info(\n `| ${\"Command\".padEnd(col1Width)} | ${\"Duration\".padEnd(col2Width)} |`,\n );\n this.log.info(divider);\n for (const [col1, col2] of data) {\n this.log.info(\n `| ${col1.padEnd(col1Width)} | ${col2.padEnd(col2Width)} |`,\n );\n }\n this.log.info(divider);\n }\n}\n","import type * as fs from \"node:fs/promises\";\nimport type { glob } from \"node:fs/promises\";\nimport {\n type Async,\n createPrimitive,\n KIND,\n Primitive,\n type Static,\n type TObject,\n type TSchema,\n t,\n} from \"alepha\";\nimport type { AskMethod } from \"../helpers/Asker.ts\";\nimport type { RunnerMethod } from \"../helpers/Runner.ts\";\n\n/**\n * Declares a CLI command.\n *\n * This primitive allows you to define a command, its flags, and its handler\n * within your Alepha application structure.\n */\nexport const $command = <\n T extends TObject,\n A extends TSchema,\n E extends TObject,\n>(\n options: CommandPrimitiveOptions<T, A, E>,\n) => createPrimitive(CommandPrimitive<T, A, E>, options);\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface CommandPrimitiveOptions<\n T extends TObject,\n A extends TSchema,\n E extends TObject = TObject,\n> {\n /**\n * The handler function to execute when the command is matched.\n *\n * For parent commands with children, the handler is called when:\n * - The parent command is invoked without a subcommand\n * - The parent command is invoked with --help (to show available subcommands)\n */\n handler: (args: CommandHandlerArgs<T, A, E>) => Async<void>;\n\n /**\n * The name of the command. If omitted, the property key is used.\n *\n * An empty string \"\" denotes the root command.\n */\n name?: string;\n\n /**\n * A short description of the command, shown in the help message.\n */\n description?: string;\n\n /**\n * An array of alternative names for the command.\n */\n aliases?: string[];\n\n /**\n * A TypeBox object schema defining the flags for the command.\n */\n flags?: T;\n\n /**\n * A TypeBox object schema defining required environment variables.\n *\n * Environment variables are validated before the handler runs (fail fast).\n * They are displayed in the help output under \"Env:\" section.\n *\n * @example\n * ```ts\n * $command({\n * env: t.object({\n * VERCEL_TOKEN: t.text({ description: \"Vercel API token\" }),\n * VERCEL_ORG_ID: t.optional(t.text({ description: \"Organization ID\" })),\n * }),\n * handler: async ({ env }) => {\n * // env.VERCEL_TOKEN is typed & guaranteed to exist\n * console.log(env.VERCEL_TOKEN);\n * }\n * })\n * ```\n */\n env?: E;\n\n /**\n * An optional TypeBox schema defining the arguments for the command.\n *\n * @example\n * args: t.text()\n * my-cli command <arg1: string>\n *\n * args: t.optional(t.text())\n * my-cli command [arg1: string]\n *\n * args: t.tuple([t.text(), t.number()])\n * my-cli command <arg1: string> <arg2: number>\n *\n * args: t.tuple([t.text(), t.optional(t.number())])\n * my-cli command <arg1: string> [arg2: number]\n */\n args?: A;\n\n /**\n * If false, skip summary message at the end of the command execution.\n * Summary will display only if ({ run }) method calls were made.\n */\n summary?: boolean;\n\n /**\n * Marks this command as the root command.\n * Equivalent to setting name to an empty string \"\".\n */\n root?: boolean;\n\n /**\n * Run this command's handler BEFORE the specified target command.\n *\n * Pre-hooks are not listed in help and cannot be called directly.\n * They receive the same parsed flags and args as the target command.\n *\n * @example\n * ```ts\n * class BuildCommands {\n * prebuild = $command({\n * pre: \"build\",\n * handler: async ({ run }) => {\n * await run(\"cleaning dist folder...\", () => fs.rm(\"dist\"));\n * }\n * });\n *\n * build = $command({\n * name: \"build\",\n * handler: async () => { ... }\n * });\n * }\n * ```\n */\n pre?: string;\n\n /**\n * Run this command's handler AFTER the specified target command.\n *\n * Post-hooks are not listed in help and cannot be called directly.\n * They receive the same parsed flags and args as the target command.\n *\n * @example\n * ```ts\n * class BuildCommands {\n * build = $command({\n * name: \"build\",\n * handler: async () => { ... }\n * });\n *\n * postbuild = $command({\n * post: \"build\",\n * handler: async ({ run }) => {\n * await run(\"generating checksums...\", generateChecksums);\n * }\n * });\n * }\n * ```\n */\n post?: string;\n\n /**\n * If true, this command will be hidden from the help output.\n */\n hide?: boolean;\n\n /**\n * Adds a `--mode, -m` flag to load environment files.\n *\n * When enabled:\n * - Loads `.env` and `.env.local` by default\n * - With `--mode production`, also loads `.env.production` and `.env.production.local`\n * - The mode value is exposed in the handler as `mode: string | undefined`\n *\n * Set to `true` to enable with no default, or a string to set a default mode.\n *\n * This follows Vite's environment loading convention.\n * @see https://vite.dev/guide/env-and-mode\n *\n * @example\n * ```ts\n * // No default mode\n * build = $command({\n * mode: true,\n * handler: async ({ mode }) => {\n * console.log(`Building for ${mode ?? 'development'}...`);\n * }\n * });\n *\n * // Default mode \"production\"\n * deploy = $command({\n * mode: \"production\",\n * handler: async ({ mode }) => {\n * console.log(`Deploying for ${mode}...`); // always defined\n * }\n * });\n * ```\n *\n * Usage:\n * - `cli build` - loads .env (mode = undefined)\n * - `cli build --mode production` - loads .env and .env.production\n * - `cli deploy` - loads .env and .env.production (default mode)\n * - `cli deploy --mode staging` - loads .env and .env.staging\n */\n mode?: boolean | string;\n\n /**\n * Child commands (subcommands) for this command.\n *\n * When children are defined, the command becomes a parent command that\n * can be invoked with space-separated subcommands:\n *\n * @example\n * ```ts\n * class DeployCommands {\n * // Subcommands\n * vercel = $command({\n * description: \"Deploy to Vercel\",\n * handler: async () => { ... }\n * });\n *\n * cloudflare = $command({\n * description: \"Deploy to Cloudflare\",\n * handler: async () => { ... }\n * });\n *\n * // Parent command with children\n * deploy = $command({\n * description: \"Deploy the application\",\n * children: [this.vercel, this.cloudflare],\n * handler: async () => {\n * // Called when \"deploy\" is invoked without subcommand\n * console.log(\"Available: deploy vercel, deploy cloudflare\");\n * }\n * });\n * }\n * ```\n *\n * This allows CLI usage like:\n * - `cli deploy vercel` - runs the vercel subcommand\n * - `cli deploy cloudflare` - runs the cloudflare subcommand\n * - `cli deploy` - runs the parent handler (shows available subcommands)\n * - `cli deploy --help` - shows help with all available subcommands\n */\n children?: CommandPrimitive<any, any>[];\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class CommandPrimitive<\n T extends TObject = TObject,\n A extends TSchema = TSchema,\n E extends TObject = TObject,\n> extends Primitive<CommandPrimitiveOptions<T, A, E>> {\n public readonly flags = this.options.flags ?? t.object({});\n public readonly env = this.options.env ?? t.object({});\n public readonly aliases = this.options.aliases ?? [];\n\n protected onInit() {\n if (this.options.pre || this.options.post) {\n this.options.hide ??= true;\n }\n }\n\n public get name(): string {\n if (this.options.root) {\n return \"\";\n }\n if (this.options.pre) {\n return `pre${this.options.pre}`;\n }\n if (this.options.post) {\n return `post${this.options.post}`;\n }\n return this.options.name ?? `${this.config.propertyKey}`;\n }\n\n /**\n * Get the child commands (subcommands) for this command.\n */\n public get children(): CommandPrimitive<any, any>[] {\n return this.options.children ?? [];\n }\n\n /**\n * Check if this command has child commands (is a parent command).\n */\n public get hasChildren(): boolean {\n return this.children.length > 0;\n }\n\n /**\n * Find a child command by name or alias.\n */\n public findChild(name: string): CommandPrimitive<any, any> | undefined {\n return this.children.find(\n (child) => child.name === name || child.aliases.includes(name),\n );\n }\n}\n\n$command[KIND] = CommandPrimitive;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface CommandHandlerArgs<\n T extends TObject,\n A extends TSchema = TSchema,\n E extends TObject = TObject,\n> {\n flags: Static<T>;\n args: A extends TSchema ? Static<A> : Array<string>;\n env: Static<E>;\n run: RunnerMethod;\n ask: AskMethod;\n glob: typeof glob;\n fs: typeof fs;\n\n /**\n * The root directory where the command is executed.\n */\n root: string;\n\n /**\n * Display help for the current command.\n *\n * Useful for parent commands with children to show available subcommands\n * when invoked without a specific subcommand.\n *\n * @example\n * ```ts\n * deploy = $command({\n * children: [this.vercel, this.cloudflare],\n * handler: async ({ help }) => {\n * help(); // Shows available subcommands\n * }\n * });\n * ```\n */\n help: () => void;\n\n /**\n * The current execution mode (e.g., \"development\", \"production\", \"staging\").\n *\n * Use --mode flag to set this value when running the command.\n */\n mode?: string;\n}\n","import * as fs from \"node:fs/promises\";\nimport { glob } from \"node:fs/promises\";\nimport {\n $atom,\n $env,\n $hook,\n $inject,\n $use,\n Alepha,\n type Static,\n type TObject,\n type TSchema,\n TypeBoxError,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { CommandError } from \"../errors/CommandError.ts\";\nimport { Asker } from \"../helpers/Asker.ts\";\nimport { EnvUtils } from \"../helpers/EnvUtils.ts\";\nimport { Runner } from \"../helpers/Runner.ts\";\nimport {\n $command,\n type CommandHandlerArgs,\n type CommandPrimitive,\n} from \"../primitives/$command.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nconst envSchema = t.object({\n CLI_NAME: t.text({\n default: \"cli\",\n description: \"Name of the CLI application.\",\n }),\n CLI_DESCRIPTION: t.text({\n default: \"\",\n description: \"Description of the CLI application.\",\n }),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\n/**\n * CLI provider configuration atom\n */\nexport const cliOptions = $atom({\n name: \"alepha.command.cli.options\",\n schema: t.object({\n name: t.optional(\n t.string({\n description: \"Name of the CLI application.\",\n }),\n ),\n description: t.optional(\n t.string({\n description: \"Description of the CLI application.\",\n }),\n ),\n argv: t.optional(\n t.array(t.string(), {\n description: \"Command line arguments to parse.\",\n }),\n ),\n }),\n default: {},\n});\n\nexport type CliProviderOptions = Static<typeof cliOptions.schema>;\n\ndeclare module \"alepha\" {\n interface State {\n [cliOptions.key]: CliProviderOptions;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class CliProvider {\n protected readonly env = $env(envSchema);\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n protected readonly runner = $inject(Runner);\n protected readonly asker = $inject(Asker);\n protected readonly envUtils = $inject(EnvUtils);\n\n protected readonly options = $use(cliOptions);\n\n protected get name(): string {\n return this.options.name || this.env.CLI_NAME;\n }\n\n protected get description(): string {\n return this.options.description || this.env.CLI_DESCRIPTION;\n }\n\n protected get argv(): string[] {\n return (\n this.options.argv ||\n (typeof process !== \"undefined\" ? process.argv.slice(2) : [])\n );\n }\n\n protected readonly globalFlags = {\n help: {\n aliases: [\"h\", \"help\"],\n description: \"Show this help message\",\n schema: t.boolean(),\n },\n };\n\n protected readonly onReady = $hook({\n on: \"ready\",\n handler: async () => {\n const argv = [...this.argv];\n\n // Extract positional arguments (potential command path)\n const positionalArgs = argv.filter((arg) => !arg.startsWith(\"-\"));\n\n // Resolve command using the new resolution logic\n const { command, consumedArgs } = this.resolveCommand(positionalArgs);\n\n const globalFlags = this.parseFlags(\n argv,\n Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({\n key,\n ...value,\n })),\n );\n\n if (globalFlags.help) {\n this.printHelp(command);\n return;\n }\n\n if (!command) {\n // Check if there's a root command (name === \"\")\n const rootCommand = this.findCommand(\"\");\n\n // If we have positional args but no matching command, show error\n const commandName = positionalArgs[0] ?? \"\";\n if (commandName !== \"\" && !rootCommand?.options.args) {\n this.log.error(`Unknown command: '${commandName}'`);\n this.printHelp();\n return;\n }\n\n // Execute root command if it exists\n if (rootCommand) {\n await this.executeCommand(rootCommand, argv, true);\n return;\n }\n\n // No command found and no root command\n return;\n }\n\n // Remove consumed command path args from argv for argument parsing\n const remainingArgv = this.removeConsumedArgs(argv, consumedArgs);\n\n // Since we've removed the command path, treat it like a root command for parsing\n await this.executeCommand(command, remainingArgv, true);\n },\n });\n\n /**\n * Execute a command with the given argv.\n */\n protected async executeCommand(\n command: CommandPrimitive<TObject>,\n argv: string[],\n isRootCommand: boolean,\n ): Promise<void> {\n const root = process.cwd();\n\n // Handle --mode flag if command has mode option enabled\n let modeValue: string | undefined;\n if (command.options.mode) {\n modeValue = this.parseModeFlag(argv);\n // Use default mode if not provided and mode is a string\n if (modeValue === undefined && typeof command.options.mode === \"string\") {\n modeValue = command.options.mode;\n }\n await this.loadModeEnv(root, modeValue);\n }\n\n const commandFlags = this.parseCommandFlags(argv, command.flags);\n const commandArgs = this.parseCommandArgs(\n argv,\n command.options.args,\n isRootCommand,\n command.flags,\n );\n const commandEnv = this.parseCommandEnv(command.env, command.name);\n\n await this.alepha.context.run(async () => {\n this.log.debug(`Executing command '${command.name}'...`, {\n flags: commandFlags,\n args: commandArgs,\n mode: modeValue,\n });\n\n const runner = this.runner;\n\n // Start command session for pretty print\n runner.startCommand(this.name, command.name);\n\n const args = {\n flags: commandFlags,\n args: commandArgs,\n env: commandEnv,\n run: runner.run,\n ask: this.asker.ask,\n fs,\n glob,\n root,\n help: () => this.printHelp(command),\n mode: modeValue,\n };\n\n // Execute pre-hooks\n const preHooks = this.findPreHooks(command.name);\n for (const hook of preHooks) {\n this.log.debug(`Executing pre-hook for '${command.name}'...`);\n await hook.options.handler(args as CommandHandlerArgs<TObject>);\n }\n\n // Execute main command\n await command.options.handler(args as CommandHandlerArgs<TObject>);\n\n // Execute post-hooks\n const postHooks = this.findPostHooks(command.name);\n for (const hook of postHooks) {\n this.log.debug(`Executing post-hook for '${command.name}'...`);\n await hook.options.handler(args as CommandHandlerArgs<TObject>);\n }\n\n if (command.options.summary !== false) {\n runner.summary();\n }\n\n this.log.debug(`Command '${command.name}' executed successfully.`);\n });\n }\n\n /**\n * Remove consumed command path arguments from argv.\n */\n protected removeConsumedArgs(\n argv: string[],\n consumedArgs: string[],\n ): string[] {\n const result: string[] = [];\n let consumedIndex = 0;\n\n for (const arg of argv) {\n if (arg.startsWith(\"-\")) {\n result.push(arg);\n } else if (\n consumedIndex < consumedArgs.length &&\n arg === consumedArgs[consumedIndex]\n ) {\n consumedIndex++;\n // Skip this arg, it's part of the command path\n } else {\n result.push(arg);\n }\n }\n\n return result;\n }\n\n /**\n * Resolve a command from positional arguments.\n *\n * Supports:\n * 1. Space-separated subcommands: `deploy vercel` -> finds deploy command, then vercel child\n * 2. Colon notation (backwards compat): `deploy:vercel` -> finds command with name \"deploy:vercel\"\n * 3. Simple commands: `build` -> finds command with name \"build\"\n */\n protected resolveCommand(positionalArgs: string[]): {\n command: CommandPrimitive<TObject> | undefined;\n consumedArgs: string[];\n } {\n if (positionalArgs.length === 0) {\n return { command: undefined, consumedArgs: [] };\n }\n\n const firstArg = positionalArgs[0];\n\n // First, try colon notation for backwards compatibility (e.g., \"deploy:vercel\")\n if (firstArg.includes(\":\")) {\n const command = this.findCommand(firstArg);\n if (command) {\n return { command, consumedArgs: [firstArg] };\n }\n }\n\n // Try to find command with space-separated subcommand path\n let currentCommand = this.findCommand(firstArg);\n const consumedArgs: string[] = [];\n\n if (!currentCommand) {\n return { command: undefined, consumedArgs: [] };\n }\n\n consumedArgs.push(firstArg);\n\n // Walk through remaining args to find nested subcommands\n for (let i = 1; i < positionalArgs.length; i++) {\n const arg = positionalArgs[i];\n\n if (!currentCommand.hasChildren) {\n break;\n }\n\n const childCommand = currentCommand.findChild(arg);\n if (childCommand) {\n currentCommand = childCommand;\n consumedArgs.push(arg);\n } else {\n // No matching child, stop here\n break;\n }\n }\n\n return { command: currentCommand, consumedArgs };\n }\n\n public get commands(): CommandPrimitive<any>[] {\n return this.alepha.primitives($command);\n }\n\n protected findCommand(name: string): CommandPrimitive<TObject> | undefined {\n return this.commands.findLast(\n (command) => command.name === name || command.aliases.includes(name),\n );\n }\n\n /**\n * Find all pre-hooks for a command.\n */\n protected findPreHooks(commandName: string): CommandPrimitive<TObject>[] {\n return this.commands.filter((cmd) => cmd.name === `pre${commandName}`);\n }\n\n /**\n * Find all post-hooks for a command.\n */\n protected findPostHooks(commandName: string): CommandPrimitive<TObject>[] {\n return this.commands.filter((cmd) => cmd.name === `post${commandName}`);\n }\n\n /**\n * Get global flags (help only, root command flags are NOT global).\n */\n protected getAllGlobalFlags(): Record<\n string,\n { aliases: string[]; description?: string; schema: TSchema }\n > {\n return { ...this.globalFlags };\n }\n\n protected parseCommandFlags(\n argv: string[],\n schema: TObject,\n ): Record<string, any> {\n const flagDefs = Object.entries(schema.properties).map(([key, value]) => ({\n key,\n aliases: [\n key,\n ...((value as any).aliases ??\n ((value as any).alias ? [(value as any).alias] : undefined) ??\n []),\n ],\n description: (value as any).description,\n schema: value,\n }));\n\n const parsed = this.parseFlags(argv, flagDefs);\n\n // apply manually defaults for optional properties that have defaults\n for (const [key, value] of Object.entries(schema.properties)) {\n if (!(key in parsed) && t.schema.isOptional(value)) {\n const innerSchema = value;\n if (innerSchema && \"default\" in innerSchema) {\n parsed[key] = innerSchema.default;\n }\n }\n }\n\n try {\n return this.alepha.codec.decode(schema, parsed);\n } catch (error) {\n if (error instanceof TypeBoxError) {\n throw new CommandError(\n `Invalid flag: ${error.cause.instancePath || \"command\"} ${error.cause.message}`,\n );\n }\n throw error;\n }\n }\n\n protected parseCommandEnv(\n schema: TObject,\n commandName: string,\n ): Record<string, any> {\n const result: Record<string, any> = {};\n const missing: string[] = [];\n\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const value = process.env[key];\n\n if (value !== undefined) {\n result[key] = value;\n } else if (t.schema.isOptional(propSchema)) {\n // Check for default value\n if (\"default\" in propSchema) {\n result[key] = propSchema.default;\n }\n } else {\n missing.push(key);\n }\n }\n\n if (missing.length > 0) {\n const vars = missing.join(\", \");\n throw new CommandError(\n `Missing required environment variable${missing.length > 1 ? \"s\" : \"\"}: ${vars}`,\n );\n }\n\n try {\n return this.alepha.codec.decode(schema, result);\n } catch (error) {\n if (error instanceof TypeBoxError) {\n throw new CommandError(\n `Invalid environment variable: ${error.cause.instancePath || \"env\"} ${error.cause.message}`,\n );\n }\n throw error;\n }\n }\n\n /**\n * Parse --mode or -m flag from argv.\n */\n protected parseModeFlag(argv: string[]): string | undefined {\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n\n // Handle --mode=value or -m=value\n if (arg.startsWith(\"--mode=\") || arg.startsWith(\"-m=\")) {\n return arg.split(\"=\")[1];\n }\n\n // Handle --mode value or -m value\n if (arg === \"--mode\" || arg === \"-m\") {\n const nextArg = argv[i + 1];\n if (nextArg && !nextArg.startsWith(\"-\")) {\n return nextArg;\n }\n throw new CommandError(\"Flag --mode requires a value.\");\n }\n }\n\n return undefined;\n }\n\n /**\n * Load environment files based on mode.\n */\n protected async loadModeEnv(\n root: string,\n mode: string | undefined,\n ): Promise<void> {\n const envFiles = [\".env\"];\n if (mode) {\n envFiles.push(`.env.${mode}`);\n }\n this.log.debug(`Loading env files: ${envFiles.join(\", \")}`);\n await this.envUtils.loadEnv(root, envFiles);\n }\n\n protected parseFlags(\n argv: string[],\n flagDefs: { key: string; aliases: string[]; schema: TSchema }[],\n ): Record<string, any> {\n const result: Record<string, any> = {};\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (!arg.startsWith(\"-\")) continue;\n\n const [rawKey, ...valueParts] = arg.replace(/^-{1,2}/, \"\").split(\"=\");\n let value = valueParts.join(\"=\");\n\n const def = flagDefs.find((d) => d.aliases.includes(rawKey));\n if (!def) continue;\n\n if (t.schema.isBoolean(def.schema)) {\n result[def.key] = true;\n } else if (value) {\n // Value provided via --flag=value syntax\n try {\n if (t.schema.isObject(def.schema) || t.schema.isArray(def.schema)) {\n result[def.key] = JSON.parse(value);\n } else {\n result[def.key] = value;\n }\n } catch {\n throw new CommandError(`Invalid JSON value for flag --${rawKey}`);\n }\n } else {\n // Check for space-separated value: --flag value\n const nextArg = argv[i + 1];\n if (nextArg && !nextArg.startsWith(\"-\")) {\n value = nextArg;\n try {\n if (t.schema.isObject(def.schema) || t.schema.isArray(def.schema)) {\n result[def.key] = JSON.parse(value);\n } else {\n result[def.key] = value;\n }\n } catch {\n throw new CommandError(`Invalid JSON value for flag --${rawKey}`);\n }\n } else {\n throw new CommandError(`Flag --${rawKey} requires a value.`);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Get indices of argv elements that are consumed by flags (including space-separated values).\n */\n protected getFlagConsumedIndices(\n argv: string[],\n flagDefs: { key: string; aliases: string[]; schema: TSchema }[],\n ): Set<number> {\n const consumed = new Set<number>();\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (!arg.startsWith(\"-\")) continue;\n\n consumed.add(i);\n\n const [rawKey, ...valueParts] = arg.replace(/^-{1,2}/, \"\").split(\"=\");\n const hasEqualValue = valueParts.length > 0;\n\n const def = flagDefs.find((d) => d.aliases.includes(rawKey));\n if (!def) continue;\n\n // If not a boolean flag and no = value, the next arg is consumed as the value\n if (!t.schema.isBoolean(def.schema) && !hasEqualValue) {\n const nextArg = argv[i + 1];\n if (nextArg && !nextArg.startsWith(\"-\")) {\n consumed.add(i + 1);\n }\n }\n }\n\n return consumed;\n }\n\n protected parseCommandArgs(\n argv: string[],\n schema?: TSchema,\n isRootCommand = false,\n flagSchema?: TObject,\n ): any {\n if (!schema) {\n return undefined;\n }\n\n // Get indices consumed by flags (including space-separated values)\n const flagDefs = flagSchema\n ? Object.entries(flagSchema.properties).map(([key, value]) => ({\n key,\n aliases: [\n key,\n ...((value as any).aliases ??\n ((value as any).alias ? [(value as any).alias] : undefined) ??\n []),\n ],\n schema: value as TSchema,\n }))\n : [];\n const consumedIndices = this.getFlagConsumedIndices(argv, flagDefs);\n\n // Extract positional arguments (non-flag arguments that aren't consumed as flag values)\n const positionalArgs = argv.filter(\n (arg, idx) => !arg.startsWith(\"-\") && !consumedIndices.has(idx),\n );\n // For root commands, there's no command name to remove; otherwise slice off the command name\n const argsOnly = isRootCommand ? positionalArgs : positionalArgs.slice(1);\n\n try {\n if (t.schema.isOptional(schema)) {\n // Handle optional args: t.optional(t.text())\n if (argsOnly.length === 0) {\n return undefined;\n }\n return this.parseArgumentValue(argsOnly[0], schema);\n } else if (t.schema.isTuple(schema) && schema.items) {\n // Handle tuple args: t.tuple([t.text(), t.number()])\n const result: any[] = [];\n const items = schema.items;\n for (let i = 0; i < items.length; i++) {\n const itemSchema = items[i];\n if (i < argsOnly.length) {\n result.push(this.parseArgumentValue(argsOnly[i], itemSchema));\n } else if (t.schema.isOptional(itemSchema)) {\n result.push(undefined);\n } else {\n throw new CommandError(\n `Missing required argument at position ${i + 1}`,\n );\n }\n }\n return result;\n } else {\n // Handle single arg: t.text(), t.number(), etc.\n if (argsOnly.length === 0) {\n throw new CommandError(\"Missing required argument\");\n }\n return this.parseArgumentValue(argsOnly[0], schema);\n }\n } catch (error) {\n if (error instanceof TypeBoxError) {\n throw new CommandError(`Invalid argument: ${error.value.message}`);\n }\n throw error;\n }\n }\n\n protected parseArgumentValue(value: string, schema: TSchema): any {\n if (t.schema.isString(schema)) {\n return value;\n }\n\n if (t.schema.isNumber(schema) || t.schema.isInteger(schema)) {\n const num = Number(value);\n if (Number.isNaN(num)) {\n throw new CommandError(`Expected number, got \"${value}\"`);\n }\n if (t.schema.isInteger(schema) && !Number.isInteger(num)) {\n throw new CommandError(`Expected integer, got \"${value}\"`);\n }\n return num;\n }\n\n if (t.schema.isBoolean(schema)) {\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"1\") return true;\n if (lower === \"false\" || lower === \"0\") return false;\n throw new CommandError(`Expected boolean, got \"${value}\"`);\n }\n\n // For other types, return the string value and let TypeBox validate it\n return value;\n }\n\n protected generateArgsUsage(schema?: TSchema): string {\n if (!schema) {\n return \"\";\n }\n\n if (t.schema.isOptional(schema)) {\n const typeName = this.getTypeName(schema);\n const key = \"title\" in schema ? (schema as any).title : \"arg1\";\n return ` [${key}${typeName}]`;\n }\n\n if (t.schema.isTuple(schema) && schema.items) {\n const items = schema.items;\n const args = items.map((item, index) => {\n const argName = `arg${index + 1}`;\n const typeName = this.getTypeName(item);\n if (t.schema.isOptional(item)) {\n return `[${argName}${typeName}]`;\n }\n return `<${argName}${typeName}>`;\n });\n return ` ${args.join(\" \")}`;\n }\n\n const typeName = this.getTypeName(schema);\n const key = \"title\" in schema ? (schema as any).title : \"arg1\";\n return ` <${key}${typeName}>`;\n }\n\n protected getTypeName(schema: TSchema): string {\n if (!schema) return \"\";\n\n // Check TypeBox type guards first\n if (t.schema.isString(schema)) return \"\";\n if (t.schema.isNumber(schema)) return \": number\";\n if (t.schema.isInteger(schema)) return \": integer\";\n if (t.schema.isBoolean(schema)) return \": boolean\";\n\n return \"\";\n }\n\n public printHelp(command?: CommandPrimitive<any>): void {\n const cliName = this.name || \"cli\";\n this.log.info(\"\"); // Newline\n\n if (command?.name) {\n // Command-specific help\n const hasChildren = command.hasChildren;\n const argsUsage = hasChildren\n ? \" <command>\"\n : this.generateArgsUsage(command.options.args);\n const commandPath = this.getCommandPath(command);\n const usage = `${cliName} ${commandPath}${argsUsage}`.trim();\n this.log.info(`Usage: \\`${usage}\\``);\n\n if (command.options.description) {\n this.log.info(``);\n this.log.info(`\\t${command.options.description}`);\n }\n\n // Show subcommands if this is a parent command\n if (hasChildren) {\n this.log.info(\"\");\n this.log.info(\"Commands:\");\n const maxSubCmdLength = this.getMaxChildCmdLength(command.children);\n\n for (const child of command.children) {\n if (child.options.hide) {\n continue;\n }\n const childArgsUsage = this.generateArgsUsage(child.options.args);\n const cmdStr = [child.name, ...child.aliases].join(\", \");\n const fullCmdStr = `${cmdStr}${childArgsUsage}`;\n this.log.info(\n ` ${cliName} ${command.name} ${fullCmdStr.padEnd(maxSubCmdLength)} # ${child.options.description ?? \"\"}`,\n );\n }\n }\n\n this.log.info(\"\");\n this.log.info(\"Flags:\");\n\n const flags = [\n ...Object.entries(command.flags.properties).map(([key, value]) => ({\n key,\n schema: value,\n aliases: (value as any).alias ?? [key],\n description: (value as any).description,\n })),\n // Add --mode flag if command has mode option enabled\n ...(command.options.mode\n ? [\n {\n key: \"mode\",\n aliases: [\"m\", \"mode\"],\n description:\n typeof command.options.mode === \"string\"\n ? `Environment mode - loads .env.{mode} (default: ${command.options.mode})`\n : \"Environment mode (e.g., production, staging) - loads .env.{mode}\",\n },\n ]\n : []),\n ...Object.entries(this.getAllGlobalFlags()).map(([key, value]) => ({\n key,\n ...value,\n })),\n ];\n\n const maxFlagLength = this.getMaxFlagLength(flags);\n for (const { aliases, description } of flags) {\n const flagStr = (Array.isArray(aliases) ? aliases : [aliases])\n .map((a: string) => (a.length === 1 ? `-${a}` : `--${a}`))\n .join(\", \");\n this.log.info(\n ` ${flagStr.padEnd(maxFlagLength)} # ${description ?? \"\"}`,\n );\n }\n\n // Show environment variables if defined\n const envVars = Object.entries(command.env.properties);\n if (envVars.length > 0) {\n this.log.info(\"\");\n this.log.info(\"Env:\");\n const maxEnvLength = Math.max(...envVars.map(([key]) => key.length));\n for (const [key, schema] of envVars) {\n const isOptional = t.schema.isOptional(schema as TSchema);\n const description = (schema as any).description ?? \"\";\n const optionalStr = isOptional ? \" (optional)\" : \"\";\n this.log.info(\n ` ${key.padEnd(maxEnvLength)} # ${description}${optionalStr}`,\n );\n }\n }\n } else {\n // general help\n this.log.info(this.description || \"Available commands:\");\n this.log.info(\"\");\n this.log.info(\"Commands:\");\n\n // Get top-level commands (commands that are not children of other commands)\n const topLevelCommands = this.getTopLevelCommands();\n const maxCmdLength = this.getMaxCmdLength(topLevelCommands);\n\n for (const command of topLevelCommands) {\n // skip root command and hooks in list\n if (command.name === \"\" || command.options.hide) {\n continue;\n }\n\n const cmdStr = [command.name, ...command.aliases].join(\", \");\n const argsUsage = command.hasChildren\n ? \" <command>\"\n : this.generateArgsUsage(command.options.args);\n const fullCmdStr = `${cmdStr}${argsUsage}`;\n this.log.info(\n ` ${cliName} ${fullCmdStr.padEnd(maxCmdLength)} # ${command.options.description ?? \"\"}`,\n );\n }\n\n this.log.info(\"\");\n this.log.info(\"Flags:\");\n\n // In general help, also show root command flags\n const rootCommand = this.commands.find((cmd) => cmd.name === \"\");\n const rootFlags = rootCommand\n ? Object.entries(rootCommand.flags.properties).map(([key, value]) => ({\n key,\n aliases: [\n key,\n ...((value as any).aliases ??\n ((value as any).alias ? [(value as any).alias] : undefined) ??\n []),\n ],\n description: (value as any).description,\n }))\n : [];\n\n const globalFlags = [\n ...rootFlags,\n ...Object.values(this.getAllGlobalFlags()),\n ];\n const maxFlagLength = this.getMaxFlagLength(globalFlags);\n for (const { aliases, description } of globalFlags) {\n const flagStr = aliases\n .map((a) => (a.length === 1 ? `-${a}` : `--${a}`))\n .join(\", \");\n this.log.info(\n ` ${flagStr.padEnd(maxFlagLength)} # ${description ?? \"\"}`,\n );\n }\n }\n this.log.info(\"\"); // Newline\n }\n\n /**\n * Get the full command path (e.g., \"deploy vercel\" for a child command).\n */\n protected getCommandPath(command: CommandPrimitive<any>): string {\n const path: string[] = [command.name];\n let current = command;\n\n // Walk up the tree to find parents\n while (true) {\n const parent = this.findParentCommand(current);\n if (!parent) break;\n path.unshift(parent.name);\n current = parent;\n }\n\n return path.join(\" \");\n }\n\n /**\n * Find the parent command of a given command.\n */\n protected findParentCommand(\n command: CommandPrimitive<any>,\n ): CommandPrimitive<any> | undefined {\n for (const cmd of this.commands) {\n if (cmd.children.includes(command)) {\n return cmd;\n }\n }\n return undefined;\n }\n\n /**\n * Get top-level commands (commands that are not children of other commands).\n */\n protected getTopLevelCommands(): CommandPrimitive<any>[] {\n const allChildren = new Set<CommandPrimitive<any>>();\n\n // Collect all children\n for (const command of this.commands) {\n for (const child of command.children) {\n allChildren.add(child);\n }\n }\n\n // Return commands that are not children\n return this.commands.filter((cmd) => !allChildren.has(cmd));\n }\n\n /**\n * Get max length for child command display.\n */\n protected getMaxChildCmdLength(children: CommandPrimitive<any>[]): number {\n return Math.max(\n ...children\n .filter((c) => !c.options.hide)\n .map((c) => {\n const cmdStr = [c.name, ...c.aliases].join(\", \");\n const argsUsage = this.generateArgsUsage(c.options.args);\n return `${cmdStr}${argsUsage}`.length;\n }),\n 0,\n );\n }\n\n protected getMaxCmdLength(commands: CommandPrimitive[]): number {\n return Math.max(\n ...commands\n .filter((c) => !c.options.hide && c.name !== \"\")\n .map((c) => {\n const cmdStr = [c.name, ...c.aliases].join(\", \");\n const argsUsage = c.hasChildren\n ? \" <command>\"\n : this.generateArgsUsage(c.options.args);\n return `${cmdStr}${argsUsage}`.length;\n }),\n );\n }\n\n private getMaxFlagLength(flags: { aliases: string[] }[]): number {\n return Math.max(\n ...flags.map((f) => {\n const aliases = Array.isArray(f.aliases) ? f.aliases : [f.aliases];\n return aliases\n .map((a) => (a.length === 1 ? `-${a}` : `--${a}`))\n .join(\", \").length;\n }),\n );\n }\n}\n","import { $module } from \"alepha\";\nimport { Asker } from \"./helpers/Asker.ts\";\nimport { EnvUtils } from \"./helpers/EnvUtils.ts\";\nimport { PrettyPrint } from \"./helpers/PrettyPrint.ts\";\nimport { Runner } from \"./helpers/Runner.ts\";\nimport { $command } from \"./primitives/$command.ts\";\nimport { CliProvider } from \"./providers/CliProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./errors/CommandError.ts\";\nexport * from \"./helpers/Asker.ts\";\nexport * from \"./helpers/EnvUtils.ts\";\nexport * from \"./helpers/PrettyPrint.ts\";\nexport * from \"./helpers/Runner.ts\";\nexport * from \"./primitives/$command.ts\";\nexport * from \"./providers/CliProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * This module provides a powerful way to build command-line interfaces\n * directly within your Alepha application, using declarative primitives.\n *\n * It allows you to define commands using the `$command` primitive.\n *\n * @see {@link $command}\n * @module alepha.command\n */\nexport const AlephaCommand = $module({\n name: \"alepha.command\",\n primitives: [$command],\n services: [CliProvider, Runner, Asker, PrettyPrint, EnvUtils],\n});\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"typebox\" {\n interface StringOptions {\n /**\n * Additional aliases for the flags.\n *\n * @module alepha.command\n */\n aliases?: string[];\n }\n}\n"],"mappings":";;;;;;;;;;;AAkDA,IAAa,QAAb,MAAmB;CACjB,AAAmB,MAAM,SAAS;CAClC,AAAgB;CAChB,AAAmB,SAAS,QAAQ,OAAO;CAE3C,cAAc;AACZ,OAAK,MAAM,KAAK,iBAAiB;;CAGnC,AAAU,kBAA6B;EACrC,MAAMA,QAAmB,OACvB,UACA,UAAyB,EAAE,KACxB;AACH,UAAO,MAAM,KAAK,OAAU,UAAU,QAAQ;;AAGhD,QAAM,aAAa,OAAO,aAAqB;AAI7C,WAHiB,MAAM,KAAK,OAAO,GAAG,SAAS,SAAS,EACtD,QAAQ,EAAE,KAAK;IAAC;IAAK;IAAK;IAAK;IAAM;IAAM,EAAE,EAAE,SAAS,KAAK,CAAC,EAC/D,CAAC,EACc,OAAO,EAAE,CAAC,aAAa,KAAK;;AAG9C,SAAO;;CAGT,MAAgB,OACd,UACA,SACoB;EACpB,MAAM,KAAK,KAAK,uBAAuB;EACvC,IAAIC;AACJ,MAAI;AACF;AACE,QAAI;KACF,MAAM,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,MAAM;AACnD,SAAI,QAAQ,OACV,SAAQ,KAAK,OAAO,MAAM,OACxB,QAAQ,QACR,SAAS,OAAO,MAAM,GAAG,OAC1B;SAED,SAAQ,OAAO,OAAO,MAAM,CAAC;AAE/B,SAAI,QAAQ,SACV,SAAQ,SAAS,MAAM;aAElB,OAAO;AACd,SAAI,iBAAiB,aAAa;AAChC,WAAK,IAAI,MAAM,GAAG,MAAM,QAAQ,IAAI;AACpC,cAAQ;WAER,OAAM;;UAGH,UAAU;YACX;AACR,MAAG,OAAO;;AAGZ,SAAO;;CAGT,AAAU,wBAAwB;AAChC,SAAOC,gBAAsB;GAAE;GAAO;GAAQ,CAAC;;;;;;AC/GnD,IAAa,WAAb,MAAsB;CACpB,AAAmB,MAAM,SAAS;;;;;;CAOlC,MAAa,QACX,MACA,QAAkB,CAAC,OAAO,EACX;AACf,OAAK,MAAM,MAAM,MACf,MAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,GAAG,QAAQ,EAAE;GACtC,MAAM,UAAU,KAAK,MAAM,KAAK;AAChC,OAAI;IAEF,MAAM,SADa,MAAM,SAAS,SAAS,OAAO,EACzB,MAAM,KAAK;AACpC,SAAK,MAAM,QAAQ,OAAO;KACxB,MAAM,CAAC,KAAK,GAAG,QAAQ,KAAK,MAAM,IAAI;AACtC,SAAI,KAAK;MACP,MAAM,QAAQ,KAAK,KAAK,IAAI;AAC5B,cAAQ,IAAI,IAAI,MAAM,IAAI,MAAM,MAAM;;;AAG1C,SAAK,IAAI,MAAM,qCAAqC,UAAU;WACxD;AACN,SAAK,IAAI,MAAM,MAAM,KAAK,iBAAiB,QAAQ,kBAAkB;;;;;;;;AC5B/E,IAAa,cAAb,MAAyB;CACvB,AAAU,mBAAmB,QAAQ,iBAAiB;CACtD,AAAU;CACV,AAAmB,SAAS;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,AAAU,wBAAQ,IAAI,KAQnB;CACH,AAAU,gBAAgB;CAC1B,AAAU;CACV,AAAU;CAGV,AAAmB,SAAS;EAC1B,OAAO;EACP,MAAM;EACN,OAAO;EACP,KAAK;EACL,KAAK;EACN;;;;CAKD,AAAO,aAAa,SAAiB,aAA2B;AAC9D,OAAK,SAAS,cAAc,GAAG,QAAQ,GAAG,gBAAgB;AAC1D,OAAK,mBAAmB,KAAK,KAAK;AAClC,OAAK,MAAM,OAAO;AAClB,OAAK,gBAAgB;AACrB,UAAQ,OAAO,MAAM,MAAM,KAAK,OAAO,IAAI;;;;;CAM7C,AAAO,aAAmB;AACxB,MAAI,KAAK,kBAAkB;GACzB,MAAM,kBACH,KAAK,KAAK,GAAG,KAAK,oBACnB,KACA,QAAQ,EAAE;AACZ,WAAQ,OAAO,MAAM,cAAc,cAAc,KAAK;;AAExD,OAAK,SAAS;AACd,OAAK,mBAAmB;;;;;CAM1B,AAAO,aAAa,IAAY,UAAwB;AACtD,OAAK,MAAM,IAAI,IAAI;GACjB;GACA,YAAY;GACZ,QAAQ;GACT,CAAC;AAGF,MAAI,CAAC,KAAK,gBACR,MAAK,kBAAkB,KAAK,iBAAiB,qBACrC,KAAK,eAAe,EAC1B,IACA,KACD;AAGH,OAAK,eAAe;;;;;CAMtB,AAAO,QAAQ,IAAY,UAAmB,UAAyB;EACrE,MAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAC/B,MAAI,MAAM;AACR,QAAK,SAAS;AACd,OAAI,SAAU,MAAK,WAAW;AAC9B,OAAI,SAAU,MAAK,WAAW;AAC9B,QAAK,eAAe;;AAGtB,OAAK,gBAAgB;;;;;CAMvB,AAAO,MAAM,IAAY,UAAyB;EAChD,MAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAC/B,MAAI,MAAM;AACR,QAAK,SAAS;AACd,OAAI,SAAU,MAAK,WAAW;AAC9B,QAAK,eAAe;;AAGtB,OAAK,gBAAgB;;;;;CAMvB,AAAU,gBAAsB;AAE9B,MAAI,KAAK,gBAAgB,EAEvB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,eAAe,IACtC,SAAQ,OAAO,MAAM,iBAAiB;EAK1C,MAAM,YAAY,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC;EACjD,MAAM,SAAS,KAAK,SAAS,QAAQ;AAErC,OAAK,MAAM,QAAQ,WAAW;GAC5B,IAAI,OAAO;AAEX,OAAI,KAAK,WAAW,WAAW;IAC7B,MAAM,QAAQ,KAAK,OAAO,KAAK;AAC/B,YAAQ,GAAG,KAAK,OAAO,OAAO,QAAQ,KAAK,OAAO,MAAM,GAAG,KAAK,OAAO,MAAM,KAAK,WAAW,KAAK,OAAO;AACzG,SAAK,cAAc,KAAK,aAAa,KAAK,KAAK,OAAO;cAC7C,KAAK,WAAW,WAAW;IACpC,MAAM,cAAc,KAAK,WACrB,KAAK,KAAK,OAAO,MAAM,KAAK,WAAW,KAAK,OAAO,UACnD;AACJ,YAAQ,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK,WAAW;cAC5D,KAAK,WAAW,QACzB,SAAQ,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,MAAM,GAAG,KAAK;AAG1D,WAAQ,OAAO,MAAM,GAAG,KAAK,IAAI;;AAGnC,OAAK,gBAAgB,UAAU;;;;;CAMjC,AAAU,iBAAuB;AAK/B,MAAI,CAJoB,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC,MACrD,SAAS,KAAK,WAAW,UAC3B,IAEuB,KAAK,iBAAiB;AAC5C,QAAK,iBAAiB,cAAc,KAAK,gBAAgB;AACzD,QAAK,kBAAkB;;;;;;CAO3B,AAAO,cAAoB;AACzB,MAAI,KAAK,iBAAiB;AACxB,QAAK,iBAAiB,cAAc,KAAK,gBAAgB;AACzD,QAAK,kBAAkB;;;;;;CAO3B,AAAO,QAAc;AACnB,OAAK,MAAM,OAAO;AAClB,OAAK,aAAa;AAClB,OAAK,gBAAgB;;;;;;ACvLzB,IAAa,eAAb,cAAkC,YAAY;CAC5C,AAAS,OAAO;;;;;AC8BlB,IAAa,SAAb,MAAoB;CAClB,AAAmB,MAAM,SAAS;CAClC,AAAmB,SAAkB,EAAE;CACvC,AAAmB,YAAoB,KAAK,KAAK;CACjD,AAAmB,cAAc,QAAQ,YAAY;CACrD,AAAmB,SAAS,QAAQ,OAAO;CAC3C,AAAgB;CAChB,AAAU,UAAU;CACpB,AAAU,cAAc;CACxB,AAAU,mBAAmB;CAE7B,cAAc;AACZ,OAAK,MAAM,KAAK,iBAAiB;;CAGnC,IAAc,mBAAmB;AAC/B,MAAI,KAAK,OAAO,MAAM,CACpB,QAAO;AAGT,SAAO,KAAK,OAAO,IAAI,eAAe;;;;;CAMxC,AAAO,aAAa,SAAiB,aAA2B;AAC9D,OAAK,UAAU;AACf,OAAK,cAAc;;CAGrB,AAAU,kBAAkB;EAC1B,MAAMC,QAAsB,OAC1B,KACA,YACG;AACH,OAAI,KAAK,oBAAoB,CAAC,KAAK,iBACjC,MAAK,YAAY,aAAa,KAAK,SAAS,KAAK,YAAY;AAG/D,QAAK,mBAAmB;AAExB,OAAI,MAAM,QAAQ,IAAI,CACpB,QAAO,MAAM,KAAK,QAChB,IAAI,KAAK,OACP,OAAO,OAAO,WACV;IAAE,MAAM;IAAI,eAAe,KAAK,KAAK,GAAG;IAAE,GAC1C,GACL,CACF;GAIH,MAAM,QADQ,OAAO,YAAY,WAAW,QAAQ,QAAQ,YACrC,OAAO,QAAQ,WAAW,MAAM,IAAI;GAC3D,MAAM,UACJ,OAAO,YAAY,aACf,UACA,OAAO,QAAQ,iBACP,KAAK,KAAK,IAAI,GACpB,IAAI;AAEZ,UAAO,MAAM,KAAK,QAAQ;IACxB;IACA;IACD,CAAC;;AAGJ,QAAM,KAAK,OACT,OACA,UAAsB,EAAE,KACJ;AACpB,OAAI,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS,IAAI,CAC7C,QAAO,MAAM;IACX,MACE,QAAQ,SACR,UAAU,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,IAAI,GAAG;IACrD,SAAS,YAAY;AACnB,gBAAW,MAAM,QAAQ,KAAK,MAAM,EAAE;AACpC,WAAK,IAAI,MAAM,YAAY,OAAO;AAClC,YAAM,GAAG,MAAM;OAAE,WAAW;OAAM,OAAO;OAAM,CAAC;;;IAGrD,CAAC;AAEJ,QAAK,IAAI,MAAM,YAAY,QAAQ;AACnC,UAAO,MAAM;IACX,MAAM,QAAQ,SAAS,UAAU;IACjC,eAAe,GAAG,OAAO;KAAE,WAAW;KAAM,OAAO;KAAM,CAAC;IAC3D,CAAC;;AAGJ,QAAM,KAAK,OACT,QACA,MACA,UAAsB,EAAE,KACJ;AACpB,QAAK,IAAI,MAAM,WAAW,OAAO,MAAM,OAAO;AAC9C,UAAO,MACL;IACE,MAAM,QAAQ,SAAS,SAAS,OAAO,GAAG;IAC1C,eAAe,GAAG,QAAQ,MAAM,EAAE,WAAW,MAAM,CAAC;IACrD,EACD,QACD;;AAGH,SAAO;;CAGT,MAAgB,KAAK,KAA8B;AACjD,SAAO,MAAM,IAAI,SAAiB,SAAS,WAAW;AACpD,QACE,KACA,EACE,KAAK;IACH,GAAG,QAAQ;IACX,YAAY;IACb,EACF,GACA,KAAK,aAAW;AACf,QAAI,KAAK;AACP,SAAI,SAASC;AACb,YAAO,IAAI;UAEX,SAAQA,SAAO;KAGpB;IACD;;;;;;;CAQJ,MAAgB,QAAQ,MAAsC;AAC5D,MAAI,MAAM,QAAQ,KAAK,EAAE;AACvB,SAAM,QAAQ,IAAI,KAAK,KAAK,QAAM,KAAK,YAAYC,IAAE,CAAC,CAAC;AACvD,UAAO;QAEP,QAAO,MAAM,KAAK,YAAY,KAAK;;;;;CAOvC,AAAO,UAAgB;AACrB,MAAI,KAAK,oBAAoB,KAAK,kBAAkB;AAClD,QAAK,YAAY,YAAY;AAC7B;;AAIF,MAAI,KAAK,OAAO,WAAW,EAAG;AAE9B,OAAK,IAAI,KAAK,GAAG;EACjB,MAAM,cAAc,KAAK,KAAK,GAAG,KAAK,aAAa,KAAM,QAAQ,EAAE;AACnE,OAAK,IAAI,KAAK,eAAe,UAAU,GAAG;AAC1C,OAAK,IAAI,KAAK,GAAG;;CAGnB,MAAgB,YAAY,MAA6B;EACvD,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,SAAS,KAAK;AAGpB,MAAI,KAAK,iBACP,MAAK,YAAY,aAAa,QAAQ,KAAK,KAAK;MAEhD,MAAK,IAAI,KAAK,aAAa,KAAK,KAAK,OAAO;EAG9C,IAAID,WAAS;AAEb,MAAI;AACF,cAAS,OAAQ,MAAM,KAAK,SAAS,IAAK,GAAG;WACtC,OAAO;AAEd,OAAI,KAAK,iBACP,MAAK,YAAY,MAAM,QAAQ,KAAK,KAAK;AAE3C,OAAI,iBAAiB,SAAS,YAAY,MACxC,MAAK,IAAI,KAAK,OAAO,MAAM,SAAS;AAEtC,SAAM,IAAI,aAAa,SAAS,KAAK,KAAK,WAAW,EAAE,OAAO,OAAO,CAAC;;AAGxE,MAAIA,SAAQ,MAAK,IAAI,MAAMA,SAAO;EAElC,MAAM,aAAa,KAAK,KAAK,GAAG,OAAO,KAAM,QAAQ,EAAE;AAGvD,MAAI,KAAK,iBACP,MAAK,YAAY,QAAQ,QAAQ,KAAK,MAAM,GAAG,SAAS,GAAG;MAE3D,MAAK,IAAI,KAAK,aAAa,KAAK,KAAK,UAAU,SAAS,GAAG;AAG7D,OAAK,OAAO,KAAK;GACf,MAAM,KAAK;GACX,UAAU,GAAG,SAAS;GACvB,CAAC;AAEF,SAAOA;;CAGT,AAAU,YAAY,MAAwB;AAC5C,MAAI,KAAK,WAAW,EAAG;EAEvB,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC,UAAU,KAAK,OAAO,EAAE,EAAE;EACnE,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,GAAG,UAAU,KAAK,OAAO,EAAE,EAAE;EAErE,MAAM,UAAU,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC,GAAG,IAAI,OACnD,YAAY,EACb,CAAC;AACF,OAAK,IAAI,KAAK,QAAQ;AACtB,OAAK,IAAI,KACP,KAAK,UAAU,OAAO,UAAU,CAAC,KAAK,WAAW,OAAO,UAAU,CAAC,IACpE;AACD,OAAK,IAAI,KAAK,QAAQ;AACtB,OAAK,MAAM,CAAC,MAAM,SAAS,KACzB,MAAK,IAAI,KACP,KAAK,KAAK,OAAO,UAAU,CAAC,KAAK,KAAK,OAAO,UAAU,CAAC,IACzD;AAEH,OAAK,IAAI,KAAK,QAAQ;;;;;;;;;;;;AC/O1B,MAAa,YAKX,YACG,gBAAgB,kBAA2B,QAAQ;AAsOxD,IAAa,mBAAb,cAIU,UAA4C;CACpD,AAAgB,QAAQ,KAAK,QAAQ,SAAS,EAAE,OAAO,EAAE,CAAC;CAC1D,AAAgB,MAAM,KAAK,QAAQ,OAAO,EAAE,OAAO,EAAE,CAAC;CACtD,AAAgB,UAAU,KAAK,QAAQ,WAAW,EAAE;CAEpD,AAAU,SAAS;AACjB,MAAI,KAAK,QAAQ,OAAO,KAAK,QAAQ,KACnC,MAAK,QAAQ,SAAS;;CAI1B,IAAW,OAAe;AACxB,MAAI,KAAK,QAAQ,KACf,QAAO;AAET,MAAI,KAAK,QAAQ,IACf,QAAO,MAAM,KAAK,QAAQ;AAE5B,MAAI,KAAK,QAAQ,KACf,QAAO,OAAO,KAAK,QAAQ;AAE7B,SAAO,KAAK,QAAQ,QAAQ,GAAG,KAAK,OAAO;;;;;CAM7C,IAAW,WAAyC;AAClD,SAAO,KAAK,QAAQ,YAAY,EAAE;;;;;CAMpC,IAAW,cAAuB;AAChC,SAAO,KAAK,SAAS,SAAS;;;;;CAMhC,AAAO,UAAU,MAAsD;AACrE,SAAO,KAAK,SAAS,MAClB,UAAU,MAAM,SAAS,QAAQ,MAAM,QAAQ,SAAS,KAAK,CAC/D;;;AAIL,SAAS,QAAQ;;;;ACzRjB,MAAM,YAAY,EAAE,OAAO;CACzB,UAAU,EAAE,KAAK;EACf,SAAS;EACT,aAAa;EACd,CAAC;CACF,iBAAiB,EAAE,KAAK;EACtB,SAAS;EACT,aAAa;EACd,CAAC;CACH,CAAC;;;;AASF,MAAa,aAAa,MAAM;CAC9B,MAAM;CACN,QAAQ,EAAE,OAAO;EACf,MAAM,EAAE,SACN,EAAE,OAAO,EACP,aAAa,gCACd,CAAC,CACH;EACD,aAAa,EAAE,SACb,EAAE,OAAO,EACP,aAAa,uCACd,CAAC,CACH;EACD,MAAM,EAAE,SACN,EAAE,MAAM,EAAE,QAAQ,EAAE,EAClB,aAAa,oCACd,CAAC,CACH;EACF,CAAC;CACF,SAAS,EAAE;CACZ,CAAC;AAYF,IAAa,cAAb,MAAyB;CACvB,AAAmB,MAAM,KAAK,UAAU;CACxC,AAAmB,SAAS,QAAQ,OAAO;CAC3C,AAAmB,MAAM,SAAS;CAClC,AAAmB,SAAS,QAAQ,OAAO;CAC3C,AAAmB,QAAQ,QAAQ,MAAM;CACzC,AAAmB,WAAW,QAAQ,SAAS;CAE/C,AAAmB,UAAU,KAAK,WAAW;CAE7C,IAAc,OAAe;AAC3B,SAAO,KAAK,QAAQ,QAAQ,KAAK,IAAI;;CAGvC,IAAc,cAAsB;AAClC,SAAO,KAAK,QAAQ,eAAe,KAAK,IAAI;;CAG9C,IAAc,OAAiB;AAC7B,SACE,KAAK,QAAQ,SACZ,OAAO,YAAY,cAAc,QAAQ,KAAK,MAAM,EAAE,GAAG,EAAE;;CAIhE,AAAmB,cAAc,EAC/B,MAAM;EACJ,SAAS,CAAC,KAAK,OAAO;EACtB,aAAa;EACb,QAAQ,EAAE,SAAS;EACpB,EACF;CAED,AAAmB,UAAU,MAAM;EACjC,IAAI;EACJ,SAAS,YAAY;GACnB,MAAM,OAAO,CAAC,GAAG,KAAK,KAAK;GAG3B,MAAM,iBAAiB,KAAK,QAAQ,QAAQ,CAAC,IAAI,WAAW,IAAI,CAAC;GAGjE,MAAM,EAAE,SAAS,iBAAiB,KAAK,eAAe,eAAe;AAUrE,OARoB,KAAK,WACvB,MACA,OAAO,QAAQ,KAAK,mBAAmB,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;IAC9D;IACA,GAAG;IACJ,EAAE,CACJ,CAEe,MAAM;AACpB,SAAK,UAAU,QAAQ;AACvB;;AAGF,OAAI,CAAC,SAAS;IAEZ,MAAM,cAAc,KAAK,YAAY,GAAG;IAGxC,MAAM,cAAc,eAAe,MAAM;AACzC,QAAI,gBAAgB,MAAM,CAAC,aAAa,QAAQ,MAAM;AACpD,UAAK,IAAI,MAAM,qBAAqB,YAAY,GAAG;AACnD,UAAK,WAAW;AAChB;;AAIF,QAAI,aAAa;AACf,WAAM,KAAK,eAAe,aAAa,MAAM,KAAK;AAClD;;AAIF;;GAIF,MAAM,gBAAgB,KAAK,mBAAmB,MAAM,aAAa;AAGjE,SAAM,KAAK,eAAe,SAAS,eAAe,KAAK;;EAE1D,CAAC;;;;CAKF,MAAgB,eACd,SACA,MACA,eACe;EACf,MAAM,OAAO,QAAQ,KAAK;EAG1B,IAAIE;AACJ,MAAI,QAAQ,QAAQ,MAAM;AACxB,eAAY,KAAK,cAAc,KAAK;AAEpC,OAAI,cAAc,UAAa,OAAO,QAAQ,QAAQ,SAAS,SAC7D,aAAY,QAAQ,QAAQ;AAE9B,SAAM,KAAK,YAAY,MAAM,UAAU;;EAGzC,MAAM,eAAe,KAAK,kBAAkB,MAAM,QAAQ,MAAM;EAChE,MAAM,cAAc,KAAK,iBACvB,MACA,QAAQ,QAAQ,MAChB,eACA,QAAQ,MACT;EACD,MAAM,aAAa,KAAK,gBAAgB,QAAQ,KAAK,QAAQ,KAAK;AAElE,QAAM,KAAK,OAAO,QAAQ,IAAI,YAAY;AACxC,QAAK,IAAI,MAAM,sBAAsB,QAAQ,KAAK,OAAO;IACvD,OAAO;IACP,MAAM;IACN,MAAM;IACP,CAAC;GAEF,MAAM,SAAS,KAAK;AAGpB,UAAO,aAAa,KAAK,MAAM,QAAQ,KAAK;GAE5C,MAAM,OAAO;IACX,OAAO;IACP,MAAM;IACN,KAAK;IACL,KAAK,OAAO;IACZ,KAAK,KAAK,MAAM;IAChB;IACA;IACA;IACA,YAAY,KAAK,UAAU,QAAQ;IACnC,MAAM;IACP;GAGD,MAAM,WAAW,KAAK,aAAa,QAAQ,KAAK;AAChD,QAAK,MAAM,QAAQ,UAAU;AAC3B,SAAK,IAAI,MAAM,2BAA2B,QAAQ,KAAK,MAAM;AAC7D,UAAM,KAAK,QAAQ,QAAQ,KAAoC;;AAIjE,SAAM,QAAQ,QAAQ,QAAQ,KAAoC;GAGlE,MAAM,YAAY,KAAK,cAAc,QAAQ,KAAK;AAClD,QAAK,MAAM,QAAQ,WAAW;AAC5B,SAAK,IAAI,MAAM,4BAA4B,QAAQ,KAAK,MAAM;AAC9D,UAAM,KAAK,QAAQ,QAAQ,KAAoC;;AAGjE,OAAI,QAAQ,QAAQ,YAAY,MAC9B,QAAO,SAAS;AAGlB,QAAK,IAAI,MAAM,YAAY,QAAQ,KAAK,0BAA0B;IAClE;;;;;CAMJ,AAAU,mBACR,MACA,cACU;EACV,MAAMC,SAAmB,EAAE;EAC3B,IAAI,gBAAgB;AAEpB,OAAK,MAAM,OAAO,KAChB,KAAI,IAAI,WAAW,IAAI,CACrB,QAAO,KAAK,IAAI;WAEhB,gBAAgB,aAAa,UAC7B,QAAQ,aAAa,eAErB;MAGA,QAAO,KAAK,IAAI;AAIpB,SAAO;;;;;;;;;;CAWT,AAAU,eAAe,gBAGvB;AACA,MAAI,eAAe,WAAW,EAC5B,QAAO;GAAE,SAAS;GAAW,cAAc,EAAE;GAAE;EAGjD,MAAM,WAAW,eAAe;AAGhC,MAAI,SAAS,SAAS,IAAI,EAAE;GAC1B,MAAM,UAAU,KAAK,YAAY,SAAS;AAC1C,OAAI,QACF,QAAO;IAAE;IAAS,cAAc,CAAC,SAAS;IAAE;;EAKhD,IAAI,iBAAiB,KAAK,YAAY,SAAS;EAC/C,MAAMC,eAAyB,EAAE;AAEjC,MAAI,CAAC,eACH,QAAO;GAAE,SAAS;GAAW,cAAc,EAAE;GAAE;AAGjD,eAAa,KAAK,SAAS;AAG3B,OAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;GAC9C,MAAM,MAAM,eAAe;AAE3B,OAAI,CAAC,eAAe,YAClB;GAGF,MAAM,eAAe,eAAe,UAAU,IAAI;AAClD,OAAI,cAAc;AAChB,qBAAiB;AACjB,iBAAa,KAAK,IAAI;SAGtB;;AAIJ,SAAO;GAAE,SAAS;GAAgB;GAAc;;CAGlD,IAAW,WAAoC;AAC7C,SAAO,KAAK,OAAO,WAAW,SAAS;;CAGzC,AAAU,YAAY,MAAqD;AACzE,SAAO,KAAK,SAAS,UAClB,YAAY,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,SAAS,KAAK,CACrE;;;;;CAMH,AAAU,aAAa,aAAkD;AACvE,SAAO,KAAK,SAAS,QAAQ,QAAQ,IAAI,SAAS,MAAM,cAAc;;;;;CAMxE,AAAU,cAAc,aAAkD;AACxE,SAAO,KAAK,SAAS,QAAQ,QAAQ,IAAI,SAAS,OAAO,cAAc;;;;;CAMzE,AAAU,oBAGR;AACA,SAAO,EAAE,GAAG,KAAK,aAAa;;CAGhC,AAAU,kBACR,MACA,QACqB;EACrB,MAAM,WAAW,OAAO,QAAQ,OAAO,WAAW,CAAC,KAAK,CAAC,KAAK,YAAY;GACxE;GACA,SAAS,CACP,KACA,GAAK,MAAc,YACf,MAAc,QAAQ,CAAE,MAAc,MAAM,GAAG,WACjD,EAAE,CACL;GACD,aAAc,MAAc;GAC5B,QAAQ;GACT,EAAE;EAEH,MAAM,SAAS,KAAK,WAAW,MAAM,SAAS;AAG9C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,WAAW,CAC1D,KAAI,EAAE,OAAO,WAAW,EAAE,OAAO,WAAW,MAAM,EAAE;GAClD,MAAM,cAAc;AACpB,OAAI,eAAe,aAAa,YAC9B,QAAO,OAAO,YAAY;;AAKhC,MAAI;AACF,UAAO,KAAK,OAAO,MAAM,OAAO,QAAQ,OAAO;WACxC,OAAO;AACd,OAAI,iBAAiB,aACnB,OAAM,IAAI,aACR,iBAAiB,MAAM,MAAM,gBAAgB,UAAU,GAAG,MAAM,MAAM,UACvE;AAEH,SAAM;;;CAIV,AAAU,gBACR,QACA,aACqB;EACrB,MAAMC,SAA8B,EAAE;EACtC,MAAMC,UAAoB,EAAE;AAE5B,OAAK,MAAM,CAAC,KAAK,eAAe,OAAO,QAAQ,OAAO,WAAW,EAAE;GACjE,MAAM,QAAQ,QAAQ,IAAI;AAE1B,OAAI,UAAU,OACZ,QAAO,OAAO;YACL,EAAE,OAAO,WAAW,WAAW,EAExC;QAAI,aAAa,WACf,QAAO,OAAO,WAAW;SAG3B,SAAQ,KAAK,IAAI;;AAIrB,MAAI,QAAQ,SAAS,GAAG;GACtB,MAAM,OAAO,QAAQ,KAAK,KAAK;AAC/B,SAAM,IAAI,aACR,wCAAwC,QAAQ,SAAS,IAAI,MAAM,GAAG,IAAI,OAC3E;;AAGH,MAAI;AACF,UAAO,KAAK,OAAO,MAAM,OAAO,QAAQ,OAAO;WACxC,OAAO;AACd,OAAI,iBAAiB,aACnB,OAAM,IAAI,aACR,iCAAiC,MAAM,MAAM,gBAAgB,MAAM,GAAG,MAAM,MAAM,UACnF;AAEH,SAAM;;;;;;CAOV,AAAU,cAAc,MAAoC;AAC1D,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;AAGjB,OAAI,IAAI,WAAW,UAAU,IAAI,IAAI,WAAW,MAAM,CACpD,QAAO,IAAI,MAAM,IAAI,CAAC;AAIxB,OAAI,QAAQ,YAAY,QAAQ,MAAM;IACpC,MAAM,UAAU,KAAK,IAAI;AACzB,QAAI,WAAW,CAAC,QAAQ,WAAW,IAAI,CACrC,QAAO;AAET,UAAM,IAAI,aAAa,gCAAgC;;;;;;;CAU7D,MAAgB,YACd,MACA,MACe;EACf,MAAM,WAAW,CAAC,OAAO;AACzB,MAAI,KACF,UAAS,KAAK,QAAQ,OAAO;AAE/B,OAAK,IAAI,MAAM,sBAAsB,SAAS,KAAK,KAAK,GAAG;AAC3D,QAAM,KAAK,SAAS,QAAQ,MAAM,SAAS;;CAG7C,AAAU,WACR,MACA,UACqB;EACrB,MAAMD,SAA8B,EAAE;AAEtC,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;AACjB,OAAI,CAAC,IAAI,WAAW,IAAI,CAAE;GAE1B,MAAM,CAAC,QAAQ,GAAG,cAAc,IAAI,QAAQ,WAAW,GAAG,CAAC,MAAM,IAAI;GACrE,IAAI,QAAQ,WAAW,KAAK,IAAI;GAEhC,MAAM,MAAM,SAAS,MAAM,MAAM,EAAE,QAAQ,SAAS,OAAO,CAAC;AAC5D,OAAI,CAAC,IAAK;AAEV,OAAI,EAAE,OAAO,UAAU,IAAI,OAAO,CAChC,QAAO,IAAI,OAAO;YACT,MAET,KAAI;AACF,QAAI,EAAE,OAAO,SAAS,IAAI,OAAO,IAAI,EAAE,OAAO,QAAQ,IAAI,OAAO,CAC/D,QAAO,IAAI,OAAO,KAAK,MAAM,MAAM;QAEnC,QAAO,IAAI,OAAO;WAEd;AACN,UAAM,IAAI,aAAa,iCAAiC,SAAS;;QAE9D;IAEL,MAAM,UAAU,KAAK,IAAI;AACzB,QAAI,WAAW,CAAC,QAAQ,WAAW,IAAI,EAAE;AACvC,aAAQ;AACR,SAAI;AACF,UAAI,EAAE,OAAO,SAAS,IAAI,OAAO,IAAI,EAAE,OAAO,QAAQ,IAAI,OAAO,CAC/D,QAAO,IAAI,OAAO,KAAK,MAAM,MAAM;UAEnC,QAAO,IAAI,OAAO;aAEd;AACN,YAAM,IAAI,aAAa,iCAAiC,SAAS;;UAGnE,OAAM,IAAI,aAAa,UAAU,OAAO,oBAAoB;;;AAKlE,SAAO;;;;;CAMT,AAAU,uBACR,MACA,UACa;EACb,MAAM,2BAAW,IAAI,KAAa;AAElC,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;AACjB,OAAI,CAAC,IAAI,WAAW,IAAI,CAAE;AAE1B,YAAS,IAAI,EAAE;GAEf,MAAM,CAAC,QAAQ,GAAG,cAAc,IAAI,QAAQ,WAAW,GAAG,CAAC,MAAM,IAAI;GACrE,MAAM,gBAAgB,WAAW,SAAS;GAE1C,MAAM,MAAM,SAAS,MAAM,MAAM,EAAE,QAAQ,SAAS,OAAO,CAAC;AAC5D,OAAI,CAAC,IAAK;AAGV,OAAI,CAAC,EAAE,OAAO,UAAU,IAAI,OAAO,IAAI,CAAC,eAAe;IACrD,MAAM,UAAU,KAAK,IAAI;AACzB,QAAI,WAAW,CAAC,QAAQ,WAAW,IAAI,CACrC,UAAS,IAAI,IAAI,EAAE;;;AAKzB,SAAO;;CAGT,AAAU,iBACR,MACA,QACA,gBAAgB,OAChB,YACK;AACL,MAAI,CAAC,OACH;EAIF,MAAM,WAAW,aACb,OAAO,QAAQ,WAAW,WAAW,CAAC,KAAK,CAAC,KAAK,YAAY;GAC3D;GACA,SAAS,CACP,KACA,GAAK,MAAc,YACf,MAAc,QAAQ,CAAE,MAAc,MAAM,GAAG,WACjD,EAAE,CACL;GACD,QAAQ;GACT,EAAE,GACH,EAAE;EACN,MAAM,kBAAkB,KAAK,uBAAuB,MAAM,SAAS;EAGnE,MAAM,iBAAiB,KAAK,QACzB,KAAK,QAAQ,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAChE;EAED,MAAM,WAAW,gBAAgB,iBAAiB,eAAe,MAAM,EAAE;AAEzE,MAAI;AACF,OAAI,EAAE,OAAO,WAAW,OAAO,EAAE;AAE/B,QAAI,SAAS,WAAW,EACtB;AAEF,WAAO,KAAK,mBAAmB,SAAS,IAAI,OAAO;cAC1C,EAAE,OAAO,QAAQ,OAAO,IAAI,OAAO,OAAO;IAEnD,MAAME,SAAgB,EAAE;IACxB,MAAM,QAAQ,OAAO;AACrB,SAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;KACrC,MAAM,aAAa,MAAM;AACzB,SAAI,IAAI,SAAS,OACf,QAAO,KAAK,KAAK,mBAAmB,SAAS,IAAI,WAAW,CAAC;cACpD,EAAE,OAAO,WAAW,WAAW,CACxC,QAAO,KAAK,OAAU;SAEtB,OAAM,IAAI,aACR,yCAAyC,IAAI,IAC9C;;AAGL,WAAO;UACF;AAEL,QAAI,SAAS,WAAW,EACtB,OAAM,IAAI,aAAa,4BAA4B;AAErD,WAAO,KAAK,mBAAmB,SAAS,IAAI,OAAO;;WAE9C,OAAO;AACd,OAAI,iBAAiB,aACnB,OAAM,IAAI,aAAa,qBAAqB,MAAM,MAAM,UAAU;AAEpE,SAAM;;;CAIV,AAAU,mBAAmB,OAAe,QAAsB;AAChE,MAAI,EAAE,OAAO,SAAS,OAAO,CAC3B,QAAO;AAGT,MAAI,EAAE,OAAO,SAAS,OAAO,IAAI,EAAE,OAAO,UAAU,OAAO,EAAE;GAC3D,MAAM,MAAM,OAAO,MAAM;AACzB,OAAI,OAAO,MAAM,IAAI,CACnB,OAAM,IAAI,aAAa,yBAAyB,MAAM,GAAG;AAE3D,OAAI,EAAE,OAAO,UAAU,OAAO,IAAI,CAAC,OAAO,UAAU,IAAI,CACtD,OAAM,IAAI,aAAa,0BAA0B,MAAM,GAAG;AAE5D,UAAO;;AAGT,MAAI,EAAE,OAAO,UAAU,OAAO,EAAE;GAC9B,MAAM,QAAQ,MAAM,aAAa;AACjC,OAAI,UAAU,UAAU,UAAU,IAAK,QAAO;AAC9C,OAAI,UAAU,WAAW,UAAU,IAAK,QAAO;AAC/C,SAAM,IAAI,aAAa,0BAA0B,MAAM,GAAG;;AAI5D,SAAO;;CAGT,AAAU,kBAAkB,QAA0B;AACpD,MAAI,CAAC,OACH,QAAO;AAGT,MAAI,EAAE,OAAO,WAAW,OAAO,EAAE;GAC/B,MAAMC,aAAW,KAAK,YAAY,OAAO;AAEzC,UAAO,KADK,WAAW,SAAU,OAAe,QAAQ,SACtCA,WAAS;;AAG7B,MAAI,EAAE,OAAO,QAAQ,OAAO,IAAI,OAAO,MAUrC,QAAO,IATO,OAAO,MACF,KAAK,MAAM,UAAU;GACtC,MAAM,UAAU,MAAM,QAAQ;GAC9B,MAAMA,aAAW,KAAK,YAAY,KAAK;AACvC,OAAI,EAAE,OAAO,WAAW,KAAK,CAC3B,QAAO,IAAI,UAAUA,WAAS;AAEhC,UAAO,IAAI,UAAUA,WAAS;IAC9B,CACc,KAAK,IAAI;EAG3B,MAAM,WAAW,KAAK,YAAY,OAAO;AAEzC,SAAO,KADK,WAAW,SAAU,OAAe,QAAQ,SACtC,SAAS;;CAG7B,AAAU,YAAY,QAAyB;AAC7C,MAAI,CAAC,OAAQ,QAAO;AAGpB,MAAI,EAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AACtC,MAAI,EAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AACtC,MAAI,EAAE,OAAO,UAAU,OAAO,CAAE,QAAO;AACvC,MAAI,EAAE,OAAO,UAAU,OAAO,CAAE,QAAO;AAEvC,SAAO;;CAGT,AAAO,UAAU,SAAuC;EACtD,MAAM,UAAU,KAAK,QAAQ;AAC7B,OAAK,IAAI,KAAK,GAAG;AAEjB,MAAI,SAAS,MAAM;GAEjB,MAAM,cAAc,QAAQ;GAC5B,MAAM,YAAY,cACd,eACA,KAAK,kBAAkB,QAAQ,QAAQ,KAAK;GAEhD,MAAM,QAAQ,GAAG,QAAQ,GADL,KAAK,eAAe,QAAQ,GACN,YAAY,MAAM;AAC5D,QAAK,IAAI,KAAK,YAAY,MAAM,IAAI;AAEpC,OAAI,QAAQ,QAAQ,aAAa;AAC/B,SAAK,IAAI,KAAK,GAAG;AACjB,SAAK,IAAI,KAAK,KAAK,QAAQ,QAAQ,cAAc;;AAInD,OAAI,aAAa;AACf,SAAK,IAAI,KAAK,GAAG;AACjB,SAAK,IAAI,KAAK,YAAY;IAC1B,MAAM,kBAAkB,KAAK,qBAAqB,QAAQ,SAAS;AAEnE,SAAK,MAAM,SAAS,QAAQ,UAAU;AACpC,SAAI,MAAM,QAAQ,KAChB;KAEF,MAAM,iBAAiB,KAAK,kBAAkB,MAAM,QAAQ,KAAK;KAEjE,MAAM,aAAa,GADJ,CAAC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,KAAK,GACzB;AAC/B,UAAK,IAAI,KACP,OAAO,QAAQ,GAAG,QAAQ,KAAK,GAAG,WAAW,OAAO,gBAAgB,CAAC,KAAK,MAAM,QAAQ,eAAe,KACxG;;;AAIL,QAAK,IAAI,KAAK,GAAG;AACjB,QAAK,IAAI,KAAK,SAAS;GAEvB,MAAM,QAAQ;IACZ,GAAG,OAAO,QAAQ,QAAQ,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,YAAY;KACjE;KACA,QAAQ;KACR,SAAU,MAAc,SAAS,CAAC,IAAI;KACtC,aAAc,MAAc;KAC7B,EAAE;IAEH,GAAI,QAAQ,QAAQ,OAChB,CACE;KACE,KAAK;KACL,SAAS,CAAC,KAAK,OAAO;KACtB,aACE,OAAO,QAAQ,QAAQ,SAAS,WAC5B,kDAAkD,QAAQ,QAAQ,KAAK,KACvE;KACP,CACF,GACD,EAAE;IACN,GAAG,OAAO,QAAQ,KAAK,mBAAmB,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;KACjE;KACA,GAAG;KACJ,EAAE;IACJ;GAED,MAAM,gBAAgB,KAAK,iBAAiB,MAAM;AAClD,QAAK,MAAM,EAAE,SAAS,iBAAiB,OAAO;IAC5C,MAAM,WAAW,MAAM,QAAQ,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAC1D,KAAK,MAAe,EAAE,WAAW,IAAI,IAAI,MAAM,KAAK,IAAK,CACzD,KAAK,KAAK;AACb,SAAK,IAAI,KACP,OAAO,QAAQ,OAAO,cAAc,CAAC,KAAK,eAAe,KAC1D;;GAIH,MAAM,UAAU,OAAO,QAAQ,QAAQ,IAAI,WAAW;AACtD,OAAI,QAAQ,SAAS,GAAG;AACtB,SAAK,IAAI,KAAK,GAAG;AACjB,SAAK,IAAI,KAAK,OAAO;IACrB,MAAM,eAAe,KAAK,IAAI,GAAG,QAAQ,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC;AACpE,SAAK,MAAM,CAAC,KAAK,WAAW,SAAS;KACnC,MAAM,aAAa,EAAE,OAAO,WAAW,OAAkB;KACzD,MAAM,cAAe,OAAe,eAAe;KACnD,MAAM,cAAc,aAAa,gBAAgB;AACjD,UAAK,IAAI,KACP,OAAO,IAAI,OAAO,aAAa,CAAC,KAAK,cAAc,cACpD;;;SAGA;AAEL,QAAK,IAAI,KAAK,KAAK,eAAe,sBAAsB;AACxD,QAAK,IAAI,KAAK,GAAG;AACjB,QAAK,IAAI,KAAK,YAAY;GAG1B,MAAM,mBAAmB,KAAK,qBAAqB;GACnD,MAAM,eAAe,KAAK,gBAAgB,iBAAiB;AAE3D,QAAK,MAAMC,aAAW,kBAAkB;AAEtC,QAAIA,UAAQ,SAAS,MAAMA,UAAQ,QAAQ,KACzC;IAOF,MAAM,aAAa,GAJJ,CAACA,UAAQ,MAAM,GAAGA,UAAQ,QAAQ,CAAC,KAAK,KAAK,GAC1CA,UAAQ,cACtB,eACA,KAAK,kBAAkBA,UAAQ,QAAQ,KAAK;AAEhD,SAAK,IAAI,KACP,OAAO,QAAQ,GAAG,WAAW,OAAO,aAAa,CAAC,KAAKA,UAAQ,QAAQ,eAAe,KACvF;;AAGH,QAAK,IAAI,KAAK,GAAG;AACjB,QAAK,IAAI,KAAK,SAAS;GAGvB,MAAM,cAAc,KAAK,SAAS,MAAM,QAAQ,IAAI,SAAS,GAAG;GAchE,MAAM,cAAc,CAClB,GAdgB,cACd,OAAO,QAAQ,YAAY,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,YAAY;IAClE;IACA,SAAS,CACP,KACA,GAAK,MAAc,YACf,MAAc,QAAQ,CAAE,MAAc,MAAM,GAAG,WACjD,EAAE,CACL;IACD,aAAc,MAAc;IAC7B,EAAE,GACH,EAAE,EAIJ,GAAG,OAAO,OAAO,KAAK,mBAAmB,CAAC,CAC3C;GACD,MAAM,gBAAgB,KAAK,iBAAiB,YAAY;AACxD,QAAK,MAAM,EAAE,SAAS,iBAAiB,aAAa;IAClD,MAAM,UAAU,QACb,KAAK,MAAO,EAAE,WAAW,IAAI,IAAI,MAAM,KAAK,IAAK,CACjD,KAAK,KAAK;AACb,SAAK,IAAI,KACP,OAAO,QAAQ,OAAO,cAAc,CAAC,KAAK,eAAe,KAC1D;;;AAGL,OAAK,IAAI,KAAK,GAAG;;;;;CAMnB,AAAU,eAAe,SAAwC;EAC/D,MAAMC,OAAiB,CAAC,QAAQ,KAAK;EACrC,IAAI,UAAU;AAGd,SAAO,MAAM;GACX,MAAM,SAAS,KAAK,kBAAkB,QAAQ;AAC9C,OAAI,CAAC,OAAQ;AACb,QAAK,QAAQ,OAAO,KAAK;AACzB,aAAU;;AAGZ,SAAO,KAAK,KAAK,IAAI;;;;;CAMvB,AAAU,kBACR,SACmC;AACnC,OAAK,MAAM,OAAO,KAAK,SACrB,KAAI,IAAI,SAAS,SAAS,QAAQ,CAChC,QAAO;;;;;CASb,AAAU,sBAA+C;EACvD,MAAM,8BAAc,IAAI,KAA4B;AAGpD,OAAK,MAAM,WAAW,KAAK,SACzB,MAAK,MAAM,SAAS,QAAQ,SAC1B,aAAY,IAAI,MAAM;AAK1B,SAAO,KAAK,SAAS,QAAQ,QAAQ,CAAC,YAAY,IAAI,IAAI,CAAC;;;;;CAM7D,AAAU,qBAAqB,UAA2C;AACxE,SAAO,KAAK,IACV,GAAG,SACA,QAAQ,MAAM,CAAC,EAAE,QAAQ,KAAK,CAC9B,KAAK,MAAM;AAGV,UAAO,GAFQ,CAAC,EAAE,MAAM,GAAG,EAAE,QAAQ,CAAC,KAAK,KAAK,GAC9B,KAAK,kBAAkB,EAAE,QAAQ,KAAK,GACzB;IAC/B,EACJ,EACD;;CAGH,AAAU,gBAAgB,UAAsC;AAC9D,SAAO,KAAK,IACV,GAAG,SACA,QAAQ,MAAM,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,GAAG,CAC/C,KAAK,MAAM;AAKV,UAAO,GAJQ,CAAC,EAAE,MAAM,GAAG,EAAE,QAAQ,CAAC,KAAK,KAAK,GAC9B,EAAE,cAChB,eACA,KAAK,kBAAkB,EAAE,QAAQ,KAAK,GACX;IAC/B,CACL;;CAGH,AAAQ,iBAAiB,OAAwC;AAC/D,SAAO,KAAK,IACV,GAAG,MAAM,KAAK,MAAM;AAElB,WADgB,MAAM,QAAQ,EAAE,QAAQ,GAAG,EAAE,UAAU,CAAC,EAAE,QAAQ,EAE/D,KAAK,MAAO,EAAE,WAAW,IAAI,IAAI,MAAM,KAAK,IAAK,CACjD,KAAK,KAAK,CAAC;IACd,CACH;;;;;;;;;;;;;;;ACv5BL,MAAa,gBAAgB,QAAQ;CACnC,MAAM;CACN,YAAY,CAAC,SAAS;CACtB,UAAU;EAAC;EAAa;EAAQ;EAAO;EAAa;EAAS;CAC9D,CAAC"}
|