Advanced CLI-John Usage
Learn advanced command routing, event handling, and complex CLI application patterns.
Command Hierarchies
Build nested commands:
ts
import { CLI } from "@briklab/lib/cli-john";
import * as process from "node:process";
const cli = new CLI(process);
// Main command
cli.command("config").on("command", ({ commandArgs }) => {
const subCommand = commandArgs[0];
if (subCommand === "get") {
console.log("Getting config...");
} else if (subCommand === "set") {
console.log(`Setting config to ${commandArgs[1]}`);
} else if (subCommand === "list") {
console.log("Listing configs");
}
});
cli.run();Multiple Command Handlers
Attach multiple command handlers to compose behavior:
ts
import { CLI } from "@briklab/lib/cli-john";
import * as process from "node:process";
const cli = new CLI(process);
cli.command("deploy")
.on("command", ({ commandArgs }) => {
console.log(`Deploying to ${commandArgs[0] || "production"}`);
})
.on("command", () => {
console.log("Deployment command received");
});
cli.run();Live Demo - CLI Usage
Console
No logs yet.
Argument Parsing
Extract and validate arguments:
ts
import { CLI } from "@briklab/lib/cli-john";
import * as process from "node:process";
const cli = new CLI(process);
cli.command("user").on("command", ({ commandArgs }) => {
const command = commandArgs[0];
const name = commandArgs[1];
const email = commandArgs[2];
if (command === "create") {
console.log(`Creating user: ${name} (${email})`);
} else if (command === "update") {
console.log(`Updating user: ${name}`);
} else if (command === "delete") {
console.log(`Deleting user: ${name}`);
}
});
cli.run();Command Registry
Organize commands in a registry:
ts
import { CLI } from "@briklab/lib/cli-john";
import * as process from "node:process";
class CommandRegistry {
private cli: CLI;
private commands: Map<string, () => void> = new Map();
constructor(cli: CLI) {
this.cli = cli;
}
register(name: string, handler: () => void): void {
this.commands.set(name, handler);
this.cli.command(name).on("command", handler);
}
listCommands(): void {
console.log("Available commands:");
this.commands.forEach((_, name) => {
console.log(` ${name}`);
});
}
}
const cli = new CLI(process);
const registry = new CommandRegistry(cli);
registry.register("start", () => console.log("Starting..."));
registry.register("stop", () => console.log("Stopping..."));
registry.register("status", () => console.log("Status OK"));
cli.run();Fallback Handling
Handle unknown or missing subcommands inside a command handler:
ts
import { CLI } from "@briklab/lib/cli-john";
import * as process from "node:process";
const cli = new CLI(process);
cli.command("help").on("command", () => {
console.log("Available commands:");
console.log(" start - Start the application");
console.log(" stop - Stop the application");
console.log(" status - Show status");
console.log(" help - Show this message");
});
cli.command("app").on("command", ({ commandArgs }) => {
const subcommand = commandArgs[0];
if (subcommand === "start") {
console.log("Starting the application");
return;
}
if (subcommand === "stop") {
console.log("Stopping the application");
return;
}
if (subcommand === "status") {
console.log("Application status: running");
return;
}
console.error(`Unknown subcommand: ${subcommand || "(none)"}`);
console.error("Run `app help` for usage.");
});
cli.run();Next Steps
- Getting Started: Back to basics
- Examples: Real-world use cases