-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
76 lines (63 loc) · 2.66 KB
/
index.js
File metadata and controls
76 lines (63 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Converts an array of arguments into a key value object
// Convenience helper function to find embedded number value in key
function getEmbeddedKeyValue( key ) {
const index = key.search( /[0-9]/ );
return index === -1 ? null : {
key: key.slice( 0, index ),
value: key.slice( index )
};
}
module.exports = function( {
booleanKeys = [],
allowKeyGrouping = false,
allowEmbeddedValues = false,
args = process.argv.slice(2)
} = {} ) {
return args.reduce( ( argsObjInReduction, arg, index, args ) => {
const isArgKey = arg.length > 0 && arg[0] === '-';
let isArgValue = false;
// Replace any previously undefined values for arg keys with current arg key and value,
// or true if the current arg also starts with a dash and is presumed to be another key.
argsObjInReduction = Object.keys( argsObjInReduction ).reduce( ( argsObjInUndefinedReplacement, argKey ) => {
let argValue = argsObjInReduction[ argKey ];
if( argValue === undefined ) {
argValue = isArgKey ? true : arg ;
isArgValue = !isArgKey ;
}
return Object.assign( {}, argsObjInUndefinedReplacement, { [ argKey ] : argValue } );
}, {} );
// If argument is not a key and not used as a value for previous key, collect it as an extra arg.
if( !isArgKey && !isArgValue) {
argsObjInReduction = Object.assign( {}, argsObjInReduction, {
_args : ( argsObjInReduction._args || [] ).concat( arg )
});
}
// If argument is a key, check to see if it has an embedded value.
// If no embedded value, check to see if it's the last arg, or a group of keys, or a boolean key, and if so, set to true.
// Otherwise set its value temporarily to undefined to be replaced later with next arg or true.
if( isArgKey ) {
const isArgGroupKey = allowKeyGrouping && arg.length > 2 && arg[0] === '-' && arg[1] !== '-';
let trimmedKey = arg // remove leading dashes, trim space, and convert any embedded dashes or spaces to camelCase
.replace( /^-*/g, '' )
.trim()
.replace(/(-+|\s+)\w/g, g => g[g.length - 1].toUpperCase() );
let value ;
const embeddedValueObject = allowEmbeddedValues && getEmbeddedKeyValue( trimmedKey );
if( embeddedValueObject ) {
trimmedKey = embeddedValueObject.key ;
value = embeddedValueObject.value ;
} else if( index === args.length - 1 || isArgGroupKey || booleanKeys.indexOf( trimmedKey ) !== -1 ) {
value = true ;
} else {
value = undefined ;
}
const keys = trimmedKey ? isArgGroupKey ? Array.from( trimmedKey ) : [ trimmedKey ] : [] ;
keys.forEach( key => {
argsObjInReduction = Object.assign( {}, argsObjInReduction, {
[ key ] : value
});
});
}
return argsObjInReduction ;
}, { _args: [] } );
};