feat: Add illegal flag verification

This commit is contained in:
qcq01083097
2026-06-04 17:36:47 +08:00
parent f3c35c411b
commit ea37be0e30
2 changed files with 57 additions and 0 deletions
+17
View File
@@ -25,6 +25,15 @@ interface FlagSchema {
arrays: Set<string>;
}
function buildAllowedFlagKeys(options: OptionDef[]): Set<string> {
const keys = new Set<string>();
for (const opt of options) {
const key = flagKey(opt);
if (key) keys.add(key);
}
return keys;
}
function buildSchema(options: OptionDef[]): FlagSchema {
const booleans = new Set<string>();
const numbers = new Set<string>();
@@ -91,6 +100,7 @@ export function scanCommandPath(argv: string[], globalOptions: OptionDef[] = [])
* - default: string
*/
export function parseFlags(argv: string[], options: OptionDef[]): GlobalFlags {
const allowedKeys = buildAllowedFlagKeys(options);
const schema = buildSchema(options);
const flags: GlobalFlags = {
quiet: false,
@@ -130,6 +140,13 @@ export function parseFlags(argv: string[], options: OptionDef[]): GlobalFlags {
const camelKey = kebabToCamel(key);
if (!allowedKeys.has(camelKey)) {
throw new BailianError(
`Unknown flag "--${key}". Run with --help to see available options.`,
ExitCode.USAGE,
);
}
if (schema.booleans.has(camelKey)) {
(flags as Record<string, unknown>)[camelKey] = true;
i++;
+40
View File
@@ -0,0 +1,40 @@
import { expect, test } from "vite-plus/test";
import { ExitCode, GLOBAL_OPTIONS } from "bailian-cli-core";
import { parseFlags } from "../src/args.ts";
const IMAGE_GENERATE_OPTIONS = [
{ flag: "--prompt <text>", description: "Image description", required: true },
{ flag: "--model <model>", description: "Model ID" },
{ flag: "--watermark <bool>", description: "Enable watermark (true/false). Default: true." },
];
test("parseFlags rejects unknown long flags", () => {
expect(() =>
parseFlags(["--prompt", "cat", "--xxxx", "a"], [...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS]),
).toThrowError(
expect.objectContaining({
name: "BailianError",
exitCode: ExitCode.USAGE,
message: expect.stringContaining('Unknown flag "--xxxx"'),
}),
);
});
test("parseFlags rejects unknown flags with = syntax", () => {
expect(() =>
parseFlags(
["--prompt=cat", "--unknown-flag=yes"],
[...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS],
),
).toThrow(/Unknown flag "--unknown-flag"/);
});
test("parseFlags accepts defined command and global flags", () => {
const flags = parseFlags(
["--quiet", "--prompt", "cat", "--watermark", "false"],
[...GLOBAL_OPTIONS, ...IMAGE_GENERATE_OPTIONS],
);
expect(flags.quiet).toBe(true);
expect(flags.prompt).toBe("cat");
expect(flags.watermark).toBe("false");
});