#!/usr/bin/env node // TODO: // - building a structured output // - testing function Arg({ name = 'Flag', shortFlag = null, longFlag = null, requiresValue=false, optional=false }) { this.name = name; this.flags = { short: shortFlag, long: longFlag }; this.requiresValue = requiresValue; this.optional = optional; }; function Arguments(argumentsObject=[]) { this.args = argumentsObject; this.add = (...a) => a.forEach((x) => argumentsObject.push(new Arg(x))); this.parse = function() { const argsRequiringValues = this.args.filter((a) => a.requiresValue); const requiredArgs = this.args.filter((a) => !a.optional); let argv = process.argv.slice(2); // Split up grouped short flags let argvSplit = [].concat(...argv.map((x) => { if (x.startsWith('-') && !x.startsWith('--')) { // short flags let arr = x.substring(1).split(''); arr = arr.map((y) => '-' + y); return arr; } return x; })); // Check if all the required flags have been included requiredArgs.forEach((a) => { if (!argvSplit.includes('-'+a.flags.short) && !argvSplit.includes('-'+a.flags.long)) { let long = (a.flags.long) ? `--${a.flags.long}, ` : ''; throw new Error(`${a.name} flag (-${a.flags.short}${long}) is required`); } }); // Validate... argvSplit.forEach((av, index) => { // Check for attempts to use --flags that don't exist let valid = true; if (av.startsWith('--')) { // TODO: this may be wrong: valid = this.args.filter((a) => a.flags.long === av.substring(2)).length > 0; } else if (av.startsWith('-')) { // TODO: this may be wrong: valid = this.args.filter((a) => a.flags.short === av.substring(1)).length > 0; } if (!valid) { throw new Error(`There is no ${av} option`); } // Check if it requires a value... // and if it does, do a cursory check to see if one is likely to be there let shouldCheckValue = argsRequiringValues.filter((a) => { let noDash = av.substring(1); return (a.flags.short === noDash || a.flags.long === noDash); }).length > 0; if (shouldCheckValue) { let errorMessage = `Value required for ${av}`; // If there's nothing after this flag, error; // Or if the next item is a flag... error: if (typeof argvSplit[index + 1] === 'undefined') { throw new Error(errorMessage); } else if (argvSplit[index + 1].startsWith('-')) { throw new Error(errorMessage); }; } // TODO return something useful }); } } module.exports = { Arguments: Arguments, }