Skip to content

Instantly share code, notes, and snippets.

@thybzi
Created April 26, 2019 10:51
Show Gist options
  • Save thybzi/6ae844debf6099dd63d09c3ae38f3154 to your computer and use it in GitHub Desktop.
Save thybzi/6ae844debf6099dd63d09c3ae38f3154 to your computer and use it in GitHub Desktop.
/**
* Convert cli-style arguments to reasonable key-value hashmap object
* @param {string[]} args Raw cli args
* @param {boolean} dropFirstTwo Useful for nodejs (drops two leading args)
* @returns Object<string|number|boolean>
* @example
* yargify(['--foo=bar', '--qux="hello world", '--fred', '-x=42', '-y=false'])
* // => {foo: 'bar', qux: 'hello world', fred: true, x: 42, y: false}
*/
function yargify(args, dropFirstTwo=true) {
const valueDelimiter = '=';
const shortKeyRe = /^-([^-])$/;
const longKeyRe = /^--([^-]{2,})$/;
const quotedRe = /^"[\s\S]*"$/;
const numberRe = /^(\n+)|(\n*\.\n+)$/;
const booleanRe = /^true|false$/i;
if (dropFirstTwo) {
args = args.slice(2);
}
return args.reduce((result, item) => {
const parts = item.split(valueDelimiter);
let key;
let value;
switch (parts.length) {
case 1:
key = parts[0];
value = true;
break;
case 2:
key = parts[0];
value = parts[1];
break;
default:
key = parts.shift();
value = parts.join(valueDelimiter);
break;
}
if (shortKeyRe.test(key)) {
key = key.replace(shortKeyRe, '$1');
} else if (longKeyRe.test(key)) {
key = key.replace(longKeyRe, '$1');
}
if ((typeof value === 'string') && (quotedRe.test(value) || numberRe.test(value) || booleanRe.test(value))) {
value = JSON.parse(value);
}
result[key] = value;
return result;
}, {});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment