import IOption from './interfaces/IOption'; import IState from './interfaces/IState'; import verifyAndStoreOptionValue from './verifyAndStoreOptionValue'; export default function parseArgument( { spec, outputArgs, requiredOptions, shortToLongLookup }: { spec: { [key: string]: IOption }, outputArgs: IState['outputArgs'], requiredOptions: IState['requiredOptions'], shortToLongLookup: IState['shortToLongLookup'], }, 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 === '--') { throw new Error(`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) { throw new Error(`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, 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) { throw new Error(`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, outputArgs, requiredOptions}); return ''; } return option; } else { throw new Error(`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, outputArgs, requiredOptions}); return ''; } }