### Display CLI Version Source: https://github.com/drizzle-team/brocli/blob/main/README.md Example of how the CLI version is displayed when the --version flag is used. ```bash ~ bun run index.ts --version 1.0.0 ``` -------------------------------- ### Run Echo Command with Default and Custom Text Source: https://github.com/drizzle-team/brocli/blob/main/README.md Demonstrates running the 'echo' command. The first example shows the default behavior, and the second shows how to provide custom text. ```bash ~ bun run index.ts echo echo ~ bun run index.ts echo text text ``` -------------------------------- ### getCommandNameWithParents() - Get Full Command Path Source: https://context7.com/drizzle-team/brocli/llms.txt The getCommandNameWithParents function returns the full command path, including parent commands. This is useful for generating help text or error messages for nested subcommands. ```APIDOC ## getCommandNameWithParents() ### Description Returns the full command path including parent commands, useful for generating help text or error messages for nested subcommands. ### Method Function Call ### Endpoint N/A (Local Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { getCommandNameWithParents, command } from "@drizzle-team/brocli"; const deepCommand = command({ name: "config", subcommands: [ command({ name: "database", subcommands: [ command({ name: "set", handler: () => {}, }), ], }), ], }); const setCommand = deepCommand.subcommands![0]!.subcommands![0]!; const fullName = getCommandNameWithParents(setCommand); console.log(fullName); // "config database set" ``` ### Response #### Success Response (string) - **fullName** (string) - The full command path, with parent commands separated by spaces. #### Response Example ``` "config database set" ``` ``` -------------------------------- ### Execute CLI with Full Configuration using run() Source: https://context7.com/drizzle-team/brocli/llms.txt The `run()` function can be configured with options such as CLI name, description, version, custom help handlers, global options, and lifecycle hooks for advanced CLI behavior. ```typescript import { run, command, string, boolean, number } from "@drizzle-team/brocli"; const commands = [ command({ name: "deploy", options: { environment: string().enum("dev", "staging", "prod").required(), dryRun: boolean().alias("n").desc("Perform dry run"), }, handler: (opts) => { console.log(`Deploying to ${opts.environment}`); }, }), ]; // Run with full configuration run(commands, { // CLI name (used in help text) name: "mycli", description: "My awesome CLI tool", // Version string or callback version: "1.0.0", // Or async version callback: // version: async () => { // const pkg = await import("./package.json"); // console.log(pkg.version); // }, // Custom help handler help: () => { console.log("My CLI - Custom Help"); console.log("Commands: deploy, config, user"); }, // Global options available to all commands globals: { verbose: boolean().alias("v").desc("Enable verbose output").default(false), config: string().alias("c").desc("Config file path"), }, // Lifecycle hooks hook: (event, command, globalOptions) => { if (event === "before") { console.log(`Starting command: ${command.name}`); if (globalOptions.verbose) console.log("Verbose mode enabled"); } if (event === "after") { console.log(`Completed command: ${command.name}`); } }, // Omit undefined options from handler input omitKeysOfUndefinedOptions: true, // Custom argument source (default: process.argv) // argSource: ["node", "script.js", "deploy", "--environment", "prod"], }); ``` -------------------------------- ### Execute CLI with Basic Configuration using run() Source: https://context7.com/drizzle-team/brocli/llms.txt The `run()` function executes the CLI by parsing arguments and invoking handlers. It accepts an array of commands. ```typescript import { run, command, string, boolean, number } from "@drizzle-team/brocli"; const commands = [ command({ name: "deploy", options: { environment: string().enum("dev", "staging", "prod").required(), dryRun: boolean().alias("n").desc("Perform dry run"), }, handler: (opts) => { console.log(`Deploying to ${opts.environment}`); }, }), ]; // Basic run run(commands); ``` -------------------------------- ### Defining Commands with Options Source: https://github.com/drizzle-team/brocli/blob/main/README.md This snippet demonstrates how to define a command with various options, including string and boolean types, aliases, and descriptions. It also shows how to use transform and handler functions. ```APIDOC ## Defining Commands To define commands, use the `command()` function from `@drizzle-team/brocli`. ### Method N/A (This is a library function, not an API endpoint) ### Endpoint N/A ### Parameters - **name** (string) - Required - The unique name for the command. Must not start with `-` and cannot be `true`, `false`, `0`, or `1` (case-insensitive). - **aliases** (string[]) - Optional - Aliases for the command. Must not start with `-` and cannot be `true`, `false`, `0`, or `1` (case-insensitive). - **desc** (string) - Optional - A detailed description of the command for help messages. - **shortDesc** (string) - Optional - A brief description of the command. - **hidden** (boolean) - Optional - If `true`, the command will be hidden from help messages. Defaults to `false`. - **options** (object) - Optional - An object defining the command's options using functions like `string()` and `boolean()`. - **transform** (function) - Optional - A function to preprocess options before they are passed to the handler. The return type of this function determines the input type for the handler. - **handler** (function) - Required (if no subcommands) - The function to execute when the command is invoked and options are parsed successfully. - **help** (function | string) - Optional - A function or string to display custom help information for the command. Takes precedence over the theme's `commandHelp` event. - **subcommands** (Command[]) - Optional - An array of subcommands that can be nested under this command. A command cannot have both subcommands and positional options. - **metadata** (any) - Optional - Arbitrary data to attach to the command, useful for documentation generation. ### Request Example ```typescript import { command, type Command, string, boolean, type TypeOf } from '@drizzle-team/brocli' const commandOptions = { opt1: string(), opt2: boolean('flag').alias('f'), } const commands: Command[] = [] commands.push(command({ name: 'command', aliases: ['c', 'cmd'], desc: 'Description goes here', shortDesc: 'Short description', hidden: false, options: commandOptions, transform: (options) => { // Preprocess options here... return processedOptions }, handler: (processedOptions) => { // Your logic goes here... }, help: () => 'This command works like this: ...', subcommands: [ command( // You can define subcommands like this ) ] })); ``` ### Response N/A (This describes library usage, not an API response) ``` -------------------------------- ### run() Source: https://github.com/drizzle-team/brocli/blob/main/README.md Parses shell arguments and executes the provided commands. ```APIDOC ## run(commands, config) ### Description Parses the shell arguments and triggers the execution of the appropriate command handler. ### Parameters - **commands** (array) - Required - An array of command objects created via `command()`. - **config** (object) - Optional - Global configuration: - **version** (string|function) - Optional - Version string or async callback to display version information. ### Request Example ```ts run([push], { version: "1.0.0", }); ``` ``` -------------------------------- ### Configure Version Output for CLI Source: https://github.com/drizzle-team/brocli/blob/main/README.md Shows how to configure a static version string for the CLI, which can be displayed using the --version or -v flags. ```typescript ... run([echo], { version: "1.0.0", ); ``` -------------------------------- ### Creating Handlers Source: https://github.com/drizzle-team/brocli/blob/main/README.md Methods for defining command handlers and inferring option types. ```APIDOC ## Creating Handlers ### TypeOf Utility type to infer the type of options passed to a handler. ### handler(options, callback) Helper function to define a command handler with typed options. ### Example ```typescript import { string, boolean, handler } from '@drizzle-team/brocli' const commandOptions = { opt1: string(), opt2: boolean('flag').alias('f'), } export const commandHandler = handler(commandOptions, (options) => { // Logic here }); ``` ``` -------------------------------- ### Execute CLI commands with run Source: https://github.com/drizzle-team/brocli/blob/main/README.md Initializes the CLI application by passing a command array and configuration object to the run function. ```Typescript import { command, type Command, run, string, boolean, type TypeOf } from '@drizzle-team/brocli' const commandOptions = { opt1: string(), opt2: boolean('flag').alias('f'), // And so on... } const commandHandler = (options: TypeOf) => { // Your logic goes here... } const commands: Command[] = [] commands.push(command({ name: 'command', aliases: ['c', 'cmd'], desc: 'Description goes here', hidden: false, options: commandOptions, handler: commandHandler, })); // And so on... run(commands, { name: 'mysoft', description: 'MySoft CLI', omitKeysOfUndefinedOptions: true, argSource: customEnvironmentArgvStorage, version: '1.0.0', help: () => { console.log('Command list:'); commands.forEach(c => console.log('This command does ... and has options ...')); }, theme: async (event) => { if (event.type === 'commandHelp') { await myCustomUniversalCommandHelp(event.command); return true; } if (event.type === 'unknownError') { console.log('Something went wrong...'); return true; } return false; }, globals: { flag: boolean('gflag').description('Global flag').default(false) }, hook: (event, command, globals) => { if(event === 'before') console.log(`Command '${command.name}' started with flag ${globals.flag}`) if(event === 'after') console.log(`Command '${command.name}' succesfully finished it's work with flag ${globals.flag}`) } }) ``` -------------------------------- ### command() Source: https://github.com/drizzle-team/brocli/blob/main/README.md Defines a new CLI command with its configuration, options, and execution logic. ```APIDOC ## command(config) ### Description Defines a command for the CLI application. This is the primary building block for creating CLI functionality. ### Parameters - **config** (object) - Required - Configuration object for the command: - **name** (string) - Required - The name of the command. - **desc** (string) - Optional - Full description for help output. - **shortDesc** (string) - Optional - Short description for help output. - **aliases** (string[]) - Optional - Array of command aliases. - **options** (object) - Optional - Typed list of shell arguments. - **transform** (function) - Optional - Hook to modify CLI params before the handler. - **handler** (function) - Required - The business logic executed when the command is run. - **help** (string|function) - Optional - Custom help text or callback. - **hidden** (boolean) - Optional - Whether to hide the command from help output. - **metadata** (object) - Optional - Meta information for documentation generation. ### Request Example ```ts const push = command({ name: "push", options: { dialect: string().enum("postgresql", "mysql", "sqlite"), databaseSchema: string().required(), databaseUrl: string().required(), strict: boolean().default(false), }, handler: (opts) => { // Business logic here }, }); ``` ``` -------------------------------- ### Define Command with Specific Options Source: https://github.com/drizzle-team/brocli/blob/main/README.md Declares a command named 'cmd' with options for dialect, schema, and URL, demonstrating required string inputs. ```typescript import { command } from "@drizzle-team/brocli"; const cmd = command({ name: "cmd", options: { dialect: string().enum("postgresql", "mysql", "sqlite"), schema: string().required(), url: string().required(), }, handler: (opts) => { ... }, }); ``` -------------------------------- ### Validate command behavior with test() Source: https://context7.com/drizzle-team/brocli/llms.txt Demonstrates how to use the test() function to parse arguments against a command definition and verify the resulting output or error state. ```typescript import { test, command, string, boolean, number } from "@drizzle-team/brocli"; const myCommand = command({ name: "build", options: { target: string().enum("web", "node", "electron").required(), minify: boolean().default(true), workers: number().int().min(1).max(8).default(4), }, transform: (opts) => ({ ...opts, outputDir: `./dist/${opts.target}`, }), handler: () => {}, // Not executed during test }); // Test valid arguments const result1 = await test(myCommand, "--target web --minify false --workers 2"); // result1 = { // type: "handler", // options: { // target: "web", // minify: false, // workers: 2, // outputDir: "./dist/web" // Transform was applied // } // } // Test help flag const result2 = await test(myCommand, "--help"); // result2 = { type: "help" } // Test version flag const result3 = await test(myCommand, "--version"); // result3 = { type: "version" } // Test validation error const result4 = await test(myCommand, "--target invalid"); // result4 = { // type: "error", // error: BroCliError { ... } // } // Test missing required option const result5 = await test(myCommand, "--minify"); // result5 = { // type: "error", // error: BroCliError { message: "missing required options..." } // } // Use in unit tests import { expect, describe, it } from "vitest"; describe("build command", () => { it("parses valid arguments", async () => { const result = await test(myCommand, "--target node"); expect(result.type).toBe("handler"); if (result.type === "handler") { expect(result.options.target).toBe("node"); expect(result.options.minify).toBe(true); // default expect(result.options.workers).toBe(4); // default } }); it("rejects invalid enum values", async () => { const result = await test(myCommand, "--target mobile"); expect(result.type).toBe("error"); }); }); ``` -------------------------------- ### Define a Push Command with Options Source: https://github.com/drizzle-team/brocli/blob/main/README.md Defines a 'push' command with various options including dialect, database schema, URL, and a strict flag. The handler is a placeholder for the command's logic. ```typescript import { command, string, boolean, run } from "@drizzle-team/brocli"; const push = command({ name: "push", options: { dialect: string().enum("postgresql", "mysql", "sqlite"), databaseSchema: string().required(), databaseUrl: string().required(), strict: boolean().default(false), }, handler: (opts) => { ... }, }); run([push]); // parse shell arguments and run command ``` -------------------------------- ### Option Extensions Source: https://github.com/drizzle-team/brocli/blob/main/README.md Methods to configure and constrain CLI options. ```APIDOC ## Option Extensions - `.alias(...aliases: string[])` - Defines aliases for the option. - `.desc(description: string)` - Sets the description for the help command. - `.required()` - Marks the option as required. - `.default(value: string | boolean)` - Sets a default value. - `.hidden()` - Hides the option from the help command. - `.enum(values: [string, ...string[]])` - Limits string values to a specific set. - `.int()` - Ensures the number is an integer. - `.min(value: number)` - Sets the minimum value for numbers. - `.max(value: number)` - Sets the maximum value for numbers. ``` -------------------------------- ### Async Version Callback for CLI Source: https://github.com/drizzle-team/brocli/blob/main/README.md Illustrates using an asynchronous callback function to determine and print the CLI version, allowing for I/O operations. ```typescript import { run, command, positional } from "@drizzle-team/brocli"; const version = async () => { // you can run async here, for example fetch version of runtime-dependend library const envVersion = process.env.CLI_VERSION; console.log(chalk.gray(envVersion), "\n"); }; const echo = command({ ... }); run([echo], { version: version, ); ``` -------------------------------- ### Command Definition Source: https://context7.com/drizzle-team/brocli/llms.txt Defines a CLI command with its name, options, handler, and optional metadata like aliases, descriptions, and transform hooks. ```APIDOC ## Command Definition Defines a CLI command with name, options, handler, and optional metadata. Commands can have aliases, descriptions, subcommands, and transform hooks. ### Example: Basic Command with Reusable Options ```typescript import { command, string, boolean, number, type TypeOf } from "@drizzle-team/brocli"; const databaseOptions = { host: string().alias("h").desc("Database host").default("localhost"), port: number().alias("p").desc("Database port").default(5432), database: string().alias("d").desc("Database name").required(), ssl: boolean().desc("Use SSL connection").default(false), }; const ping = command({ name: "ping", aliases: ["p", "check"], desc: "Check database connection", shortDesc: "Check connection", options: databaseOptions, handler: (opts) => { console.log(`Pinging ${opts.host}:${opts.port}/${opts.database}`); }, }); ``` ### Example: Command with Transform Hook ```typescript import { command, string, number } from "@drizzle-team/brocli"; const databaseOptions = { host: string().alias("h").desc("Database host").default("localhost"), port: number().alias("p").desc("Database port").default(5432), database: string().alias("d").desc("Database name").required(), ssl: boolean().desc("Use SSL connection").default(false), }; const migrate = command({ name: "migrate", desc: "Run database migrations", options: { ...databaseOptions, direction: string().enum("up", "down").default("up"), steps: number().int().min(1).desc("Number of migrations to run"), }, transform: async (opts) => { const connectionString = `postgres://${opts.host}:${opts.port}/${opts.database}`; return { connectionString, direction: opts.direction, steps: opts.steps ?? (opts.direction === "up" ? Infinity : 1), }; }, handler: (transformed) => { console.log(`Migrating ${transformed.direction}: ${transformed.connectionString}`); }, }); ``` ### Example: Hidden and Custom Help Commands ```typescript import { command } from "@drizzle-team/brocli"; const internal = command({ name: "internal", hidden: true, handler: () => console.log("Internal command"), }); const help = command({ name: "info", help: () => { console.log("Custom help output for info command"); console.log("Usage: mycli info [options]"); }, handler: () => {}, }); ``` ### Parameters #### Command Definition Parameters - **name** (string) - Required - The name of the command. - **aliases** (string[]) - Optional - Aliases for the command. - **desc** (string) - Optional - Description of the command. - **shortDesc** (string) - Optional - Short description for help menus. - **options** (object) - Optional - An object defining the command's options. - **handler** (function) - Required - The function to execute when the command is run. - **transform** (function) - Optional - A function to preprocess options before the handler. - **hidden** (boolean) - Optional - If true, the command will not appear in help output. - **help** (function) - Optional - A function to provide custom help text. ``` -------------------------------- ### string() Option Builder Source: https://context7.com/drizzle-team/brocli/llms.txt Defines a string-type CLI option with support for enums, aliases, defaults, and required validation. ```APIDOC ## string() Option Builder ### Description Creates a string-type option that accepts values via `--option=value` or `--option value` syntax. ### Parameters - **enum** (array) - Optional - Restricts input to specific allowed values. - **alias** (string/array) - Optional - Defines short or alternative flags. - **desc** (string) - Optional - Description for help output. - **required** (boolean) - Optional - Marks the option as mandatory. - **default** (string) - Optional - Sets a fallback value if not provided. ### Request Example ```typescript string().alias("o").enum("a", "b").desc("Description").required() ``` ``` -------------------------------- ### Implement Custom CLI Theme with EventHandler Source: https://context7.com/drizzle-team/brocli/llms.txt Use the `EventHandler` to intercept and customize CLI events like help screens, errors, and version information. This allows for a branded and user-friendly CLI experience. ```typescript import { run, command, string, type BroCliEvent, type EventHandler } from "@drizzle-team/brocli"; const customTheme: EventHandler = (event, globalOptions) => { switch (event.type) { case "global_help": console.log("\n=== My CLI Tool ===\n"); console.log("Available commands:"); event.commands.forEach(cmd => { if (!cmd.hidden) { console.log(` ${cmd.name.padEnd(15)} ${cmd.shortDesc || cmd.desc || ""}`); } }); console.log("\nUse --help with any command for details"); return true; // Handled case "command_help": console.log(`\n=== ${event.command.name} ===`); console.log(event.command.desc || "No description"); return true; case "version": console.log("v1.0.0 - Built with Brocli"); return true; case "error": if (event.violation === "missing_args_error") { console.error(`Error: Missing required options: ${event.missing.map(m => m[0]).join(", ")}`); return true; } if (event.violation === "unknown_command_error") { console.error(`Error: Unknown command "${event.offender}"`); console.error("Run with --help to see available commands"); return true; } return false; // Use default handler for other errors } return false; // Use default handler }; run(commands, { theme: customTheme, }); ``` -------------------------------- ### Option Builder Functions Source: https://github.com/drizzle-team/brocli/blob/main/README.md Functions used to define different types of CLI options. ```APIDOC ## Option Builder Functions ### string(name?: string) Defines a string-type option. Requires data via `--option=value` or `--option value`. ### number(name?: string) Defines a number-type option. Requires data via `--option=value` or `--option value`. ### boolean(name?: string) Defines a boolean-type option. Requires data via `--option`. ### positional(displayName?: string) Defines a positional-type option. Requires data passed after a command as `command value`. ``` -------------------------------- ### Define CLI Commands Source: https://context7.com/drizzle-team/brocli/llms.txt Use command() to define CLI commands with options, handlers, and optional metadata. Transform hooks allow for pre-processing or validating options before they reach the handler. ```typescript import { command, string, boolean, number, type TypeOf } from "@drizzle-team/brocli"; // Define reusable options const databaseOptions = { host: string().alias("h").desc("Database host").default("localhost"), port: number().alias("p").desc("Database port").default(5432), database: string().alias("d").desc("Database name").required(), ssl: boolean().desc("Use SSL connection").default(false), }; // Basic command with inline handler const ping = command({ name: "ping", aliases: ["p", "check"], desc: "Check database connection", shortDesc: "Check connection", options: databaseOptions, handler: (opts) => { console.log(`Pinging ${opts.host}:${opts.port}/${opts.database}`); }, }); // Command with transform hook (preprocess options before handler) const migrate = command({ name: "migrate", desc: "Run database migrations", options: { ...databaseOptions, direction: string().enum("up", "down").default("up"), steps: number().int().min(1).desc("Number of migrations to run"), }, transform: async (opts) => { // Transform runs before handler, can modify/validate options const connectionString = `postgres://${opts.host}:${opts.port}/${opts.database}`; return { connectionString, direction: opts.direction, steps: opts.steps ?? (opts.direction === "up" ? Infinity : 1), }; }, handler: (transformed) => { // Handler receives transformed options with new types console.log(`Migrating ${transformed.direction}: ${transformed.connectionString}`); }, }); // Hidden command (won't appear in help) const internal = command({ name: "internal", hidden: true, handler: () => console.log("Internal command"), }); // Command with custom help text const help = command({ name: "info", help: () => { console.log("Custom help output for info command"); console.log("Usage: mycli info [options]"); }, handler: () => {}, }); ``` -------------------------------- ### Define string options with Brocli Source: https://context7.com/drizzle-team/brocli/llms.txt Use the string builder to define options that accept text input, supporting enums, defaults, and required validation. ```typescript import { string, command, run } from "@drizzle-team/brocli"; const migrate = command({ name: "migrate", options: { // Basic string option (uses key name as CLI flag) schema: string().desc("Path to schema file"), // String with custom CLI name output: string("out").alias("o").desc("Output folder"), // Required string with enum values dialect: string() .alias("-d", "-dlc") .enum("postgresql", "mysql", "sqlite") .desc("Database dialect") .required(), // String with default value config: string() .alias("c", "cfg") .desc("Path to config file") .default("./drizzle.config.ts"), }, handler: (opts) => { // opts.dialect is typed as "postgresql" | "mysql" | "sqlite" // opts.schema is typed as string | undefined // opts.config is typed as string (default makes it non-undefined) console.log(`Migrating ${opts.dialect} with schema: ${opts.schema}`); }, }); run([migrate]); // Usage: mycli migrate --dialect postgresql --schema ./schema.ts -o ./output ``` -------------------------------- ### Define a CLI command with Brocli Source: https://github.com/drizzle-team/brocli/blob/main/README.md Use the command() function to define a command structure including options, aliases, and handlers. ```typescript import { command, type Command, string, boolean, type TypeOf } from '@drizzle-team/brocli' const commandOptions = { opt1: string(), opt2: boolean('flag').alias('f'), // And so on... } const commands: Command[] = [] commands.push(command({ name: 'command', aliases: ['c', 'cmd'], desc: 'Description goes here', shortDesc: 'Short description' hidden: false, options: commandOptions, transform: (options) => { // Preprocess options here... return processedOptions }, handler: (processedOptions) => { // Your logic goes here... }, help: () => 'This command works like this: ...', subcommands: [ command( // You can define subcommands like this ) ] })); ``` -------------------------------- ### Simple Echo Command with Positional Argument Source: https://github.com/drizzle-team/brocli/blob/main/README.md Creates a simple 'echo' command that accepts a positional argument for text. If no text is provided, it defaults to 'echo'. ```typescript import { run, command, positional } from "@drizzle-team/brocli"; const echo = command({ name: "echo", options: { text: positional().desc("Text to echo").default("echo"), }, handler: (opts) => { console.log(opts.text); }, }); run([echo]) ``` -------------------------------- ### Creating handlers with the handler helper Source: https://github.com/drizzle-team/brocli/blob/main/README.md Use the handler helper to define command options and the handler function together while maintaining type safety. ```typescript import { string, boolean, handler } from '@drizzle-team/brocli' const commandOptions = { opt1: string(), opt2: boolean('flag').alias('f'), // And so on... } export const commandHandler = handler(commandOptions, (options) => { // Your logic goes here... }); ``` -------------------------------- ### number() Option Builder Source: https://context7.com/drizzle-team/brocli/llms.txt Defines a number-type CLI option with support for numeric constraints like min, max, and integer validation. ```APIDOC ## number() Option Builder ### Description Creates a number-type option with support for min/max constraints, integer validation, and default values. ### Parameters - **min** (number) - Optional - Minimum allowed value. - **max** (number) - Optional - Maximum allowed value. - **int** (boolean) - Optional - Enforces integer-only validation. - **alias** (string/array) - Optional - Defines short or alternative flags. - **desc** (string) - Optional - Description for help output. - **required** (boolean) - Optional - Marks the option as mandatory. - **default** (number) - Optional - Sets a fallback value if not provided. ### Request Example ```typescript number().min(1).max(10).int().desc("Retry count").default(3) ``` ``` -------------------------------- ### Define Push Command with Transform Hook Source: https://github.com/drizzle-team/brocli/blob/main/README.md Defines a 'push' command with options and includes a 'transform' hook to modify or process options before they are passed to the handler. ```typescript import { command, string, boolean } from "@drizzle-team/brocli"; const push = command({ name: "push", options: { dialect: string().enum("postgresql", "mysql", "sqlite"), databaseSchema: string().required(), databaseUrl: string().required(), strict: boolean().default(false), }, transform: (opts) => { }, handler: (opts) => { ... }, }); ``` -------------------------------- ### Define Typed Handlers with handler() Utility Source: https://context7.com/drizzle-team/brocli/llms.txt The `handler` utility simplifies creating type-safe command handlers. It allows defining options separately, enabling type inference for handler arguments and improving code organization and testability. ```typescript import { handler, string, boolean, command, run, type TypeOf } from "@drizzle-team/brocli"; // Define options separately const deployOptions = { environment: string().enum("dev", "staging", "prod").required(), branch: string().alias("b").desc("Git branch").default("main"), force: boolean().alias("f").desc("Force deployment").default(false), notify: boolean().alias("n").desc("Send notifications").default(true), }; // Type inference for external use type DeployOptions = TypeOf; // DeployOptions = { // environment: "dev" | "staging" | "prod"; // branch: string; // force: boolean; // notify: boolean; // } // Define handler with full type safety const deployHandler = handler(deployOptions, async (opts) => { console.log(`Deploying ${opts.branch} to ${opts.environment}`); if (opts.force) { console.log("Force deployment enabled"); } // Simulate deployment await new Promise(resolve => setTimeout(resolve, 1000)); if (opts.notify) { console.log("Sending deployment notification..."); } return { success: true, environment: opts.environment }; }); // Use in command const deploy = command({ name: "deploy", aliases: ["d"], desc: "Deploy application to environment", options: deployOptions, handler: deployHandler, }); run([deploy]); ``` -------------------------------- ### boolean() Option Builder Source: https://context7.com/drizzle-team/brocli/llms.txt Defines a boolean-type CLI option that supports flags, true/false values, and hidden states. ```APIDOC ## boolean() Option Builder ### Description Creates a boolean-type option that accepts values via `--flag`, `--flag=true`, or `--flag false` syntax. ### Parameters - **alias** (string/array) - Optional - Defines short or alternative flags. - **desc** (string) - Optional - Description for help output. - **hidden** (boolean) - Optional - If true, hides the option from help output. - **default** (boolean) - Optional - Sets a fallback value if not provided. ### Request Example ```typescript boolean().alias("v").desc("Enable verbose mode").default(true) ``` ``` -------------------------------- ### Define and Nest Subcommands in Brocli Source: https://context7.com/drizzle-team/brocli/llms.txt Use the `command` function to define individual commands and group them into parent commands using the `subcommands` property. This allows for hierarchical command structures. ```typescript import { command, string, boolean, run } from "@drizzle-team/brocli"; // Define subcommands const userCreate = command({ name: "create", desc: "Create a new user", options: { email: string().alias("e").desc("User email").required(), admin: boolean().alias("a").desc("Grant admin privileges").default(false), }, handler: (opts) => { console.log(`Creating user: ${opts.email}, admin: ${opts.admin}`); }, }); const userDelete = command({ name: "delete", aliases: ["rm"], desc: "Delete a user", options: { email: string().alias("e").desc("User email").required(), force: boolean().alias("f").desc("Skip confirmation").default(false), }, handler: (opts) => { console.log(`Deleting user: ${opts.email}`); }, }); const userList = command({ name: "list", aliases: ["ls"], desc: "List all users", handler: () => { console.log("Listing all users..."); }, }); // Parent command with subcommands (handler is optional when subcommands exist) const user = command({ name: "user", aliases: ["u"], desc: "User management commands", subcommands: [userCreate, userDelete, userList], }); // Deep nesting example const configGet = command({ name: "get", options: { key: string().required() }, handler: (opts) => console.log(`Getting config: ${opts.key}`), }); const configSet = command({ name: "set", options: { key: string().required(), value: string().required(), }, handler: (opts) => console.log(`Setting ${opts.key}=${opts.value}`), }); const config = command({ name: "config", subcommands: [configGet, configSet], }); run([user, config]); ``` -------------------------------- ### Positional Arguments Source: https://context7.com/drizzle-team/brocli/llms.txt Defines how to create positional arguments that capture values without flags, including single, multiple, and enum-constrained positionals. ```APIDOC ## Positional Arguments Creates a positional argument that captures values passed after the command without a flag prefix. ### Example: Basic Positional Argument ```typescript import { positional, string, command, run } from "@drizzle-team/brocli"; const echo = command({ name: "echo", options: { text: positional("message").desc("Text to echo").default("Hello"), }, handler: (opts) => { console.log(opts.text); }, }); run([echo]); // Usage: mycli echo "Hello World" ``` ### Example: Multiple Positional Arguments and Enum Constraint ```typescript import { positional, string, command, run } from "@drizzle-team/brocli"; const copy = command({ name: "copy", options: { source: positional("source").desc("Source file").required(), destination: positional("dest").desc("Destination path").required(), mode: positional("mode").enum("overwrite", "append", "skip").default("overwrite"), recursive: string().alias("r").desc("Copy recursively"), }, handler: (opts) => { console.log(`Copying ${opts.source} to ${opts.destination} (${opts.mode})`); }, }); run([copy]); // Usage: mycli copy ./src ./dist overwrite -r // Usage: mycli copy ./file.txt ./backup.txt ``` ### Parameters #### Positional Argument Definition - **name** (string) - Required - The name of the positional argument. - **desc** (string) - Optional - Description of the argument. - **default** (any) - Optional - Default value if not provided. - **required** (boolean) - Optional - Whether the argument is required. - **enum** (...string) - Optional - Allowed values for the argument. ``` -------------------------------- ### Extract Command Metadata with commandsInfo Source: https://context7.com/drizzle-team/brocli/llms.txt Use commandsInfo to generate structured metadata from command definitions for documentation or introspection. The output includes details on options, aliases, and nested subcommands. ```typescript import { commandsInfo, command, string, boolean, positional } from "@drizzle-team/brocli"; const commands = [ command({ name: "generate", aliases: ["g", "gen"], desc: "Generate database migrations", shortDesc: "Generate migrations", metadata: { category: "database", priority: 1 }, options: { dialect: string().enum("pg", "mysql", "sqlite").required().desc("Database dialect"), output: string().alias("o").desc("Output directory").default("./migrations"), name: positional("migration-name").desc("Migration name"), }, handler: () => {}, }), command({ name: "migrate", desc: "Run pending migrations", options: { dryRun: boolean().alias("n").desc("Preview changes without applying"), }, subcommands: [ command({ name: "up", desc: "Apply migrations", handler: () => {}, }), command({ name: "down", desc: "Rollback migrations", options: { steps: positional("steps").desc("Number of migrations to rollback"), }, handler: () => {}, }), ], }), ]; const info = commandsInfo(commands); console.log(JSON.stringify(info, null, 2)); // Output: // { // "generate": { // "name": "generate", // "aliases": ["g", "gen"], // "desc": "Generate database migrations", // "shortDesc": "Generate migrations", // "metadata": { "category": "database", "priority": 1 }, // "options": { // "dialect": { // "name": "--dialect", // "aliases": [], // "type": "string", // "description": "Database dialect", // "isRequired": true, // "enumVals": ["pg", "mysql", "sqlite"] // }, // "output": { // "name": "--output", // "aliases": ["-o"], // "type": "string", // "description": "Output directory", // "default": "./migrations" // }, // "name": { // "name": "migration-name", // "aliases": [], // "type": "positional", // "description": "Migration name" // } // } // }, // "migrate": { // "name": "migrate", // "desc": "Run pending migrations", // "options": { ... }, // "subcommands": { // "up": { ... }, // "down": { ... } // } // } // } // Use for documentation generation function generateDocs(info: ReturnType) { let docs = "# CLI Reference\n\n"; for (const [name, cmd] of Object.entries(info)) { docs += `## ${name}\n\n`; docs += `${cmd.desc || "No description"}\n\n`; if (cmd.aliases?.length) { docs += `**Aliases:** ${cmd.aliases.join(", ")}\n\n`; } if (cmd.options) { docs += "**Options:**\n\n"; for (const [optName, opt] of Object.entries(cmd.options)) { const aliases = opt.aliases?.length ? ` (${opt.aliases.join(", ")})` : ""; const required = opt.isRequired ? " **(required)**" : ""; const defaultVal = opt.default !== undefined ? ` (default: ${opt.default})` : ""; docs += `- \`${opt.name}\`${aliases}${required}: ${opt.description || ""}${defaultVal}\n`; } } docs += "\n"; } return docs; } ``` -------------------------------- ### Resolve Command Paths with getCommandNameWithParents Source: https://context7.com/drizzle-team/brocli/llms.txt Use getCommandNameWithParents to retrieve the full command path, which is useful for generating help text or identifying commands in error handlers. ```typescript import { getCommandNameWithParents, command } from "@drizzle-team/brocli"; const deepCommand = command({ name: "config", subcommands: [ command({ name: "database", subcommands: [ command({ name: "set", handler: () => {}, }), ], }), ], }); // Access nested command const setCommand = deepCommand.subcommands![0]!.subcommands![0]!; const fullName = getCommandNameWithParents(setCommand); console.log(fullName); // "config database set" // Useful in error handling or custom themes const customTheme = (event) => { if (event.type === "error" && event.violation === "missing_args_error") { const cmdName = event.command === "globals" ? "global options" : getCommandNameWithParents(event.command); console.error(`Command '${cmdName}' is missing required options`); return true; } return false; }; ``` -------------------------------- ### Define number options with Brocli Source: https://context7.com/drizzle-team/brocli/llms.txt Use the number builder to enforce numeric inputs with min/max constraints and integer validation. ```typescript import { number, command, run } from "@drizzle-team/brocli"; const serve = command({ name: "serve", options: { // Basic number option port: number().alias("p").desc("Port number").default(3000), // Number with min/max constraints workers: number() .alias("w") .min(1) .max(16) .desc("Number of worker threads"), // Integer-only number retries: number() .alias("r") .int() .min(0) .max(10) .desc("Number of retry attempts") .default(3), // Required number timeout: number().alias("t").desc("Timeout in ms").required(), }, handler: (opts) => { // opts.port is typed as number (has default) // opts.workers is typed as number | undefined // opts.retries is typed as number (has default) // opts.timeout is typed as number (required) console.log(`Server starting on port ${opts.port}`); console.log(`Timeout: ${opts.timeout}ms, Retries: ${opts.retries}`); }, }); run([serve]); // Usage: mycli serve --port 8080 --workers 4 --timeout 5000 // Error: mycli serve --workers 20 (above max of 16) // Error: mycli serve --retries 3.5 (not an integer) ``` -------------------------------- ### Define boolean options with Brocli Source: https://context7.com/drizzle-team/brocli/llms.txt Use the boolean builder for flags that toggle functionality, supporting defaults and hidden states. ```typescript import { boolean, string, command, run } from "@drizzle-team/brocli"; const build = command({ name: "build", options: { // Basic boolean flag verbose: boolean().alias("v").desc("Enable verbose output"), // Boolean with default value minify: boolean().alias("m").desc("Minify output").default(true), // Hidden boolean (won't show in help) debug: boolean("dbg").alias("g").hidden(), // Boolean with custom name strict: boolean("strict-mode").alias("s").desc("Enable strict mode"), }, handler: (opts) => { // opts.verbose is typed as boolean | undefined // opts.minify is typed as boolean (has default) if (opts.verbose) console.log("Verbose mode enabled"); if (opts.minify) console.log("Minifying output..."); }, }); run([build]); // Usage: mycli build --verbose --minify=false -g // Usage: mycli build -v --strict-mode true ```