Crust logoCrust

resolveCommand()

Resolve a subcommand from an argv array by walking the command tree.

Walks the subcommand tree to find the target command for the given argv. Subcommand matching happens before flag parsing.

Signature

function resolveCommand(
  command: CommandNode,
  argv: string[],
): CommandRoute;

Parameters

ParameterTypeDescription
commandCommandNodeThe root command node to resolve from
argvstring[]The argv array to resolve against

Returns

interface CommandRoute {
  command: CommandNode;    // The resolved (sub)command
  argv: string[];           // Remaining argv after subcommand names consumed
  commandPath: string[];    // Full command path (e.g., ["my-cli", "build"])
}

Throws

  • CrustError("COMMAND_NOT_FOUND") — When an unknown subcommand is given on a container command (no run)

The error includes structured details:

interface CommandNotFoundErrorDetails {
  input: string;              // The unknown subcommand name
  available: string[];         // Valid subcommand names
  commandPath: string[];       // Path to the parent command
  parentCommand: CommandNode;  // The parent command node
}

Resolution Algorithm

  1. Start at the root command
  2. Take the first token from argv
  3. If it starts with -, stop (it's a flag, not a subcommand)
  4. If it matches a subcommand key, recurse into that subcommand
  5. If no match and the current command has run(), stop (token is a positional arg)
  6. If no match and the current command has no run(), throw COMMAND_NOT_FOUND
  7. Repeat until no more subcommand matches

Examples

Basic Resolution

import { Crust, resolveCommand } from "@crustjs/core";

const app = new Crust("my-cli")
  .command("build", (cmd) =>
    cmd.run(() => {})
  );

const route = resolveCommand(app._node, ["build", "--minify"]);
// route.command.meta.name === "build"
// route.argv === ["--minify"]
// route.commandPath === ["my-cli", "build"]

Nested Subcommands

const route = resolveCommand(app._node, ["create", "component", "Button"]);
// route.command.meta.name === "component"
// route.argv === ["Button"]
// route.commandPath === ["my-cli", "create", "component"]

No Subcommand Match

// If command has run(), unknown tokens are positional args
const route = resolveCommand(app._node, ["readme.md"]);
// route.command === app._node
// route.argv === ["readme.md"]

// If command has NO run(), unknown tokens throw COMMAND_NOT_FOUND
resolveCommand(containerCmd._node, ["unknown"]);
// Throws: CrustError("COMMAND_NOT_FOUND", ...)

On this page