fix(cli): preserve lazy placeholder options

This commit is contained in:
Peter Steinberger
2026-04-26 04:37:36 +01:00
parent e74f2e1501
commit 0ca9c4dcb0
4 changed files with 75 additions and 4 deletions

View File

@@ -5,6 +5,12 @@ import { registerLazyCommand } from "./register-lazy-command.js";
export type CommandGroupPlaceholder = {
name: string;
description: string;
options?: readonly CommandGroupPlaceholderOption[];
};
export type CommandGroupPlaceholderOption = {
flags: string;
description: string;
};
export type CommandGroupEntry = {
@@ -53,6 +59,7 @@ export function registerLazyCommandGroup(
program,
name: placeholder.name,
description: placeholder.description,
options: placeholder.options,
removeNames: [...new Set(getCommandGroupNames(entry))],
register: async () => {
await entry.register(program);

View File

@@ -6,21 +6,55 @@ type RegisterLazyCommandParams = {
program: Command;
name: string;
description: string;
options?: readonly {
flags: string;
description: string;
}[];
removeNames?: string[];
register: () => Promise<void> | void;
};
function resolvePlaceholderOptionArgs(command: Command): string[] {
const out: string[] = [];
for (const option of command.options) {
const value = command.getOptionValue(option.attributeName());
if (value === undefined || value === false) {
continue;
}
const flag = option.long ?? option.short;
if (!flag) {
continue;
}
out.push(flag);
if (value !== true) {
out.push(String(value));
}
}
return out;
}
export function registerLazyCommand({
program,
name,
description,
options,
removeNames,
register,
}: RegisterLazyCommandParams): void {
const placeholder = program.command(name).description(description);
for (const option of options ?? []) {
placeholder.option(option.flags, option.description);
}
placeholder.allowUnknownOption(true);
placeholder.allowExcessArguments(true);
placeholder.action(async (...actionArgs) => {
const actionCommand = actionArgs.at(-1) as (Command & { args?: string[] }) | undefined;
if (actionCommand) {
actionCommand.args = [
...resolvePlaceholderOptionArgs(actionCommand),
...(actionCommand.args ?? []),
];
}
for (const commandName of new Set(removeNames ?? [name])) {
removeCommandByName(program, commandName);
}