perf(cli): prepare positional token schemas only for the selected command

This commit is contained in:
morluto committed 2026-10-24 10:20:36 +08:00
1 parent cc18e9ad0d
commit 315b23403f
2 files changed
+49 -10

No files matched your search

+15 -10
View File
@@ -62,20 +62,25 @@ export const rejectSurplusCliArguments = (
if (final !== undefined && tokenType(final) instanceof z.ZodArray) return;
let tail = "__rea_unbound_positionals";
while (Object.hasOwn(fields, tail)) tail += "_";
const args = z.object({
...Object.fromEntries(
entries.map(([name]) => [name, z.unknown().optional()]),
),
[tail]: z.array(z.string()).optional(),
});
const options =
command.options instanceof z.ZodObject
? optionTokenShape(command.options)
: undefined;
const optionsSchema =
command.options instanceof z.ZodObject ? command.options : undefined;
command.middleware = [
async (context, next) => {
const tokens = invocation.getStore();
if (tokens !== undefined) {
// Only the resolved command needs an inert token-binding schema.
// Keep the original schema references, but do not prepare every
// registered command for each one-shot invocation.
const args = z.object({
...Object.fromEntries(
entries.map(([name]) => [name, z.unknown().optional()]),
),
[tail]: z.array(z.string()).optional(),
});
const options =
optionsSchema === undefined
? undefined
: optionTokenShape(optionsSchema);
// Incur supplies the invoked path, including aliases, after resolving
// groups. No second router decides which command receives the tokens.
const parsed = Parser.parse(
@@ -175,3 +175,37 @@ it("uses resolved group and alias paths and preserves declared variadic inputs",
values: ["one", "two", "three"],
});
});
it("preserves counted aliases and negated booleans while checking the positional tail", async () => {
let runs = 0;
const cli = Cli.create("strict-counted-flags", { sync: false });
cli.command("capture", {
args: z.object({ path: z.string() }),
options: z.object({
enabled: z.boolean().default(true),
verbosity: z.number().default(0).meta({ count: true }),
}),
alias: { verbosity: "v" },
run: ({ args, options }) => {
runs++;
return { args, options };
},
});
installAdmission(cli);
const valid = await serve(cli, ["capture", "one", "--no-enabled", "-vvv"]);
expect(valid.exitCode).toBe(0);
expect(JSON.parse(valid.stdout)).toMatchObject({
args: { path: "one" },
options: { enabled: false, verbosity: 3 },
});
const surplus = await serve(cli, [
"capture",
"one",
"--no-enabled",
"-vvv",
"extra",
]);
expect(surplus.exitCode).toBe(1);
expect(surplus.stdout).toContain("Unexpected positional arguments");
expect(runs).toBe(1);
});