import assert from "assert"; const argv = [...process.argv]; function next() { return argv.shift(); } function peek() { return argv[0]; } const positional: Array = []; const named: { [key: string]: string | boolean } = {}; while (argv.length) { const arg = next(); if (arg === undefined) break; if (arg.startsWith("--")) { const match = arg.match(/^--([^=]*)(=?)(.*)$/); assert(match); const name = match[1]; if (!name.length) continue; let value: string | boolean = true; if (match[2] === "=") { if (match[3].length) { value = match[3]; } } else { const nextArg = peek(); if (nextArg && !nextArg.startsWith("-")) { next(); value = nextArg; } } named[name] = value; } else if (arg.startsWith("-")) { const match = arg.match(/^-(.*?)(=?)([^=a-zA-Z]*)$/); assert(match); const names = match[1].split(""); if (!names.length) continue; while (names.length > 1) { const name = names.shift(); if (name && name.length) { named[name] = true; } } let lastName = names.shift(); if (!lastName) continue; let lastValue: string | boolean = true; if (match[2] === "=") { if (match[3].length) { lastValue = match[3]; } } else { const nextArg = peek(); if (nextArg && !nextArg.startsWith("-")) { next(); lastValue = nextArg; } } named[lastName] = lastValue; } else { positional.push(arg); } } function getArg(...nameOrPositions: Array) { let value: string | boolean | undefined; for (const nameOrPosition of nameOrPositions) { if (typeof nameOrPosition === "string") { const name = nameOrPosition; if (name in named) { value = named[name]; break; } } else if (Number.isInteger(nameOrPosition)) { const position = nameOrPosition; if (position < positional.length) { return positional[position]; } } } return value; } export const ArgParse = { argv: { _: positional, ...named, }, getStringArg(...nameOrPositions: Array): string | undefined { const value = getArg(...nameOrPositions); if (typeof value === "string") { return value; } }, getBooleanArg(...nameOrPositions: Array): boolean { return Boolean(getArg(...nameOrPositions)); }, getIntegerArg( ...nameOrPositions: Array ): number | undefined { const value = Number(getArg(...nameOrPositions)); if (Number.isInteger(value)) { return value; } }, };