Arg Parser

Reusable command-line argument parser for tools sitting on top of the framework. Operators declare a parser declaratively (top-level flags + named commands + per-command flags) and call .parse(argv) to get a typed result, or .help() to render usage text.

Throws ArgParserError on invalid input (unknown flag, missing required, type-coercion failure, prototype-pollution attempt) so a bad CLI invocation fails at parse-time with a clear message instead of running a subcommand with garbage. -- ends flag parsing; --help / -h is reserved and renders top-level or per-command usage. Flag names __proto__ / constructor / prototype are refused as a prototype-pollution defense, even though parsed flags live in an Object.create(null) bag.

Type coercion: string (as-is), number (Number(), rejects NaN), boolean (presence + accepts "true"/"false"/"1"/"0"/"yes"/"no"), list (repeated flags or single comma-separated value). Defaults apply before required-checks, so a flag with both required: true and a default is always satisfied. Aliases are single ASCII letters (-d ./app.db--db ./app.db); multi-char aliases are flag names, not aliases.

parseRaw(argv) is the framework-internal minimal splitter used by lib/cli.js subcommand handlers — same prototype-pollution defense and -- terminator semantics, but no command/flag schema.

b.argParser.create(opts) #

stable0.8.48
{
  programName: string,    // optional; rendered in usage text
  description: string,    // optional; one-line program summary
  flags:       Array,     // top-level flag specs
  commands:    Array,     // command specs (each carries its own flags)

  // Each flag spec: { name, alias?, type?, required?, default?, description? }
  //   type ∈ { "string", "number", "boolean", "list" }; default "string"
  //   alias is a single ASCII letter
  //   forbidden names: __proto__, constructor, prototype
  //
  // Each command spec: { name, description?, flags?, handler? }
}

Build a CLI parser from a declarative spec — top-level flags plus named commands with their own per-command flag lists. Returns { parse, help }. Validates the spec at construction time so misconfigured aliases / duplicate names / unsupported types throw before any argv is seen.

var ap = b.argParser.create({
  programName: "blamejs",
  description: "Server-side framework CLI",
  flags: [
    { name: "verbose", alias: "v", type: "boolean",
      description: "Verbose output" },
  ],
  commands: [
    {
      name: "migrate",
      description: "Run database migrations",
      flags: [
        { name: "db",  type: "string", required: true,
          description: "Path to sqlite file" },
        { name: "dir", type: "string", default: "./migrations" },
      ],
    },
  ],
});

var parsed = ap.parse(["migrate", "--db", "./app.db", "-v"]);
parsed.command;          // → "migrate"
parsed.flags.db;         // → "./app.db"
parsed.flags.verbose;    // → true
parsed.flags.dir;        // → "./migrations" (default)
parsed.positionals;      // → []

ap.help();               // → top-level usage string
ap.help("migrate");      // → "Usage: blamejs migrate [flags] ..."

b.argParser.parseRaw(argv, opts?) #

stable0.8.48
{
  booleanNames: string[],   // long-flag names that never consume a following token as a value (default: none)
}

Minimal positional + flag splitter used by lib/cli.js subcommand handlers. Returns { pos, flags } where flags is an Object.create(null) bag — no schema validation, no command dispatch. Refuses prototype-pollution flag names (__proto__, constructor, prototype). Treats -x as a boolean shortcut; supports --key value, --key=value, and bare --bool. -- terminates flag parsing.

Pass opts.booleanNames (an array of long-flag names) to declare flags that never consume a following token as their value — a bare --version stays boolean instead of swallowing the next token, so --version foo yields flags.version === true with foo left as a positional. An inline --version=x still records the explicit value.

A flag repeated on the command line accumulates every occurrence into an array, in order — --watch a --watch b yields ["a", "b"], not just the last value. A flag seen once stays a scalar. This keeps repeatable flags (the dev command's --arg / --watch / --ignore) from silently dropping all but the final occurrence.

var r = b.argParser.parseRaw(
  ["build", "--target=node", "-v", "--out", "dist", "--", "extra"]);
r.pos;             // → ["build", "extra"]
r.flags.target;    // → "node"
r.flags.v;         // → true
r.flags.out;       // → "dist"

Last updated 2026-08-08T16:39:49.652Z by seeder.