From a7d8bf5d1cbd5d6ebee0e806a0840634c845b47c Mon Sep 17 00:00:00 2001 From: tmm Date: Wed, 8 Apr 2026 19:57:27 -0400 Subject: [PATCH] fix: register aliases from Root CLI when mounted via cli.command() --- .changeset/fix-root-cli-command-aliases.md | 5 +++++ src/Cli.test.ts | 11 +++++++++++ src/Cli.ts | 7 +++++++ 3 files changed, 23 insertions(+) create mode 100644 .changeset/fix-root-cli-command-aliases.md diff --git a/.changeset/fix-root-cli-command-aliases.md b/.changeset/fix-root-cli-command-aliases.md new file mode 100644 index 0000000..e08c8ef --- /dev/null +++ b/.changeset/fix-root-cli-command-aliases.md @@ -0,0 +1,5 @@ +--- +"incur": patch +--- + +Fixed Root CLIs created with `Cli.create` and `aliases` not registering those aliases as command aliases when mounted via `cli.command()`. diff --git a/src/Cli.test.ts b/src/Cli.test.ts index 083df23..1eafd0a 100644 --- a/src/Cli.test.ts +++ b/src/Cli.test.ts @@ -4617,4 +4617,15 @@ describe('command aliases', () => { const { output } = await serve(makeAliasedCli(), ['exten']) expect(output).toMatch(/did you mean.*extension/i) }) + + test('root CLI aliases register as command aliases', async () => { + const update = Cli.create('update', { + aliases: ['upgrade'], + description: 'Update packages', + run: () => ({ result: 'updated' }), + }) + const cli = Cli.create('pkg').command(update) + const { output } = await serve(cli, ['upgrade']) + expect(output).toContain('updated') + }) }) diff --git a/src/Cli.ts b/src/Cli.ts index 414626f..bbac2fa 100644 --- a/src/Cli.ts +++ b/src/Cli.ts @@ -252,6 +252,9 @@ export function create( const mountedRootDef = toRootDefinition.get(nameOrCli) if (mountedRootDef) { commands.set(nameOrCli.name, mountedRootDef) + const rootAliases = toRootAliases.get(nameOrCli) + if (rootAliases) + for (const a of rootAliases) commands.set(a, { _alias: true, target: nameOrCli.name }) return cli } const sub = nameOrCli as Cli @@ -308,6 +311,7 @@ export function create( } if (rootDef) toRootDefinition.set(cli as unknown as Root, rootDef) + if (rootDef && def.aliases) toRootAliases.set(cli as unknown as Root, def.aliases) if (def.options) toRootOptions.set(cli, def.options) if (def.config !== undefined) toConfigEnabled.set(cli, true) if (def.outputPolicy) toOutputPolicy.set(cli, def.outputPolicy) @@ -2414,6 +2418,9 @@ export const toConfigEnabled = new WeakMap() /** @internal Maps CLI instances to their output policy. */ const toOutputPolicy = new WeakMap() +/** @internal Maps root CLI instances to their command aliases. */ +const toRootAliases = new WeakMap() + /** @internal Sentinel symbol for `ok()` and `error()` return values. */ const sentinel = Symbol.for('incur.sentinel')