export interface ParsedCliArguments { command?: string; positional: string[]; flags: Record; } const SHORT_FLAG_MAP: Record = { c: "config", C: "cwd", j: "json", h: "help", }; export function parseCliArguments(argv: string[]): ParsedCliArguments { const positional: string[] = []; const flags: Record = {}; let parsingFlags = true; for (let index = 0; index < argv.length; index += 1) { const token = argv[index]; if (parsingFlags && token === "--") { parsingFlags = false; continue; } if (parsingFlags && token.startsWith("--")) { const [rawName, inlineValue] = token.slice(2).split("=", 2); const name = normalizeFlagName(rawName); if (inlineValue !== undefined) { flags[name] = coerceValue(inlineValue); continue; } const maybeValue = argv[index + 1]; if (maybeValue && !maybeValue.startsWith("-")) { flags[name] = coerceValue(maybeValue); index += 1; } else { flags[name] = true; } continue; } if (parsingFlags && token.startsWith("-") && token.length > 1) { const shorts = token.slice(1); for (let sIndex = 0; sIndex < shorts.length; sIndex += 1) { const flagKey = SHORT_FLAG_MAP[shorts[sIndex]]; if (!flagKey) continue; if (sIndex < shorts.length - 1) { flags[flagKey] = true; continue; } const maybeValue = argv[index + 1]; if (maybeValue && !maybeValue.startsWith("-")) { flags[flagKey] = coerceValue(maybeValue); index += 1; } else { flags[flagKey] = true; } } continue; } positional.push(token); } const [command, ...rest] = positional; return { command, positional: rest, flags }; } function normalizeFlagName(rawName: string): string { return rawName.replace(/-([a-z])/g, (_, letter: string) => letter.toUpperCase()); } function coerceValue(value: string): string | boolean { if (value === "true") return true; if (value === "false") return false; return value; }