SafetyVantage Coding Challenge
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

109 lines
2.6 KiB

import assert from "assert";
const argv = [...process.argv];
function next() {
return argv.shift();
}
function peek() {
return argv[0];
}
const positional: Array<string | boolean> = [];
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<string | number>) {
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 | number>): string | undefined {
const value = getArg(...nameOrPositions);
if (typeof value === "string") {
return value;
}
},
getBooleanArg(...nameOrPositions: Array<string | number>): boolean {
return Boolean(getArg(...nameOrPositions));
},
getIntegerArg(
...nameOrPositions: Array<string | number>
): number | undefined {
const value = Number(getArg(...nameOrPositions));
if (Number.isInteger(value)) {
return value;
}
},
};