parse-args.ts

 1export interface ParsedArgs {
 2  command?: string;
 3  options: Record<string, string | boolean>;
 4  positional: string[];
 5}
 6
 7export function parseArgs(args: string[]): ParsedArgs {
 8  const [, , command, ...rest] = args;
 9  const options: Record<string, string | boolean> = {};
10  const positional: string[] = [];
11
12  for (let i = 0; i < rest.length; i += 1) {
13    const arg = rest[i];
14    if (!arg) continue;
15
16    if (arg.startsWith("--")) {
17      const eqIndex = arg.indexOf("=", 2);
18      let key: string;
19      let value: string | undefined;
20      if (eqIndex !== -1) {
21        key = arg.slice(2, eqIndex);
22        value = arg.slice(eqIndex + 1);
23      } else {
24        key = arg.slice(2);
25      }
26      if (!key) continue;
27      if (value !== undefined) {
28        options[key] = value;
29      } else if (rest[i + 1] && !rest[i + 1]?.startsWith("-")) {
30        options[key] = rest[i + 1] as string;
31        i += 1;
32      } else {
33        options[key] = true;
34      }
35    } else if (arg.startsWith("-")) {
36      const short = arg.slice(1);
37      if (short === "u" && rest[i + 1] && !rest[i + 1]!.startsWith("-")) {
38        options["uri"] = rest[i + 1] as string;
39        i += 1;
40      } else if (short === "f") {
41        options["full"] = true;
42      } else {
43        options[short] = true;
44      }
45    } else {
46      positional.push(arg);
47    }
48  }
49
50  return { command, options, positional };
51}