argument-parser/src/parseArgument.ts

66 lines
2.6 KiB
TypeScript

import IOption from './IOption';
import verifyAndStoreOptionValue from './verifyAndStoreOptionValue';
export default function parseArgument(
{ spec, fail, outputArgs, requiredOptions, shortToLongLookup }: {
spec: { [key: string]: IOption },
fail: (errorMessage: string) => never,
outputArgs: { [key: string]: string },
requiredOptions: { [key: string]: boolean },
shortToLongLookup: { [key: string]: string },
},
previousOption: string,
arg: string,
): string {
if (previousOption === '') {
/** We expect an option, must be one of:
* - `--option value`
* - `--option=value`
* - `-o value`
* - `-o=value`
*/
if (arg === '-' || arg === '--') {
return fail(`Empty option "-" or "--" is not supported.`);
} else if (arg.startsWith('--')) { //long argument
let option = arg.substr(2);
let value;
//If there's a =, immediately read the value
if (option.indexOf('=') !== -1) {
[option, value] = option.split('=', 2);
}
//Check that argument name is valid
if (spec[option] === undefined) {
return fail(`Unknown option "--${option}".`);
}
//If value was provided, check that value is correct and remove name for next loop iteration
if (value !== undefined) {
verifyAndStoreOptionValue({option, value, verify: spec[option].verify, message: spec[option].message, fail, outputArgs, requiredOptions});
return '';
}
return option;
} else if (arg.startsWith('-')) { //short argument
let option = arg.substr(1);
let value;
//If there's a =, immediately read the value
if (option.indexOf('=') !== -1) {
[option, value] = option.split('=', 2);
}
//Check that argument name is valid
if (shortToLongLookup[option] === undefined) {
return fail(`Unknown short option "-${option}".`);
}
option = shortToLongLookup[option];
//If value was provided, check that value is correct and remove name for next loop iteration
if (value !== undefined) {
verifyAndStoreOptionValue({option, value, verify: spec[option].verify, message: spec[option].message, fail, outputArgs, requiredOptions});
return '';
}
return option;
} else {
return fail(`Arguments must be preceded by an option but there was no option in front of "${arg}".`);
}
} else { //We expect a value, can be anything
verifyAndStoreOptionValue({option: previousOption, value: arg, verify: spec[previousOption].verify, message: spec[previousOption].message, fail, outputArgs, requiredOptions});
return '';
}
}