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 ''; } }