Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F103704875
option.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Mar 4, 03:52
Size
4 KB
Mime Type
text/x-c++
Expires
Thu, Mar 6, 03:52 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
24649730
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
option.js
View Options
const
{
InvalidArgumentError
}
=
require
(
'./error.js'
);
// @ts-check
class
Option
{
/**
* Initialize a new `Option` with the given `flags` and `description`.
*
* @param {string} flags
* @param {string} [description]
*/
constructor
(
flags
,
description
)
{
this
.
flags
=
flags
;
this
.
description
=
description
||
''
;
this
.
required
=
flags
.
includes
(
'<'
);
// A value must be supplied when the option is specified.
this
.
optional
=
flags
.
includes
(
'['
);
// A value is optional when the option is specified.
// variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument
this
.
variadic
=
/\w\.\.\.[>\]]$/
.
test
(
flags
);
// The option can take multiple values.
this
.
mandatory
=
false
;
// The option must have a value after parsing, which usually means it must be specified on command line.
const
optionFlags
=
splitOptionFlags
(
flags
);
this
.
short
=
optionFlags
.
shortFlag
;
this
.
long
=
optionFlags
.
longFlag
;
this
.
negate
=
false
;
if
(
this
.
long
)
{
this
.
negate
=
this
.
long
.
startsWith
(
'--no-'
);
}
this
.
defaultValue
=
undefined
;
this
.
defaultValueDescription
=
undefined
;
this
.
envVar
=
undefined
;
this
.
parseArg
=
undefined
;
this
.
hidden
=
false
;
this
.
argChoices
=
undefined
;
}
/**
* Set the default value, and optionally supply the description to be displayed in the help.
*
* @param {any} value
* @param {string} [description]
* @return {Option}
*/
default
(
value
,
description
)
{
this
.
defaultValue
=
value
;
this
.
defaultValueDescription
=
description
;
return
this
;
};
/**
* Set environment variable to check for option value.
* Priority order of option values is default < env < cli
*
* @param {string} name
* @return {Option}
*/
env
(
name
)
{
this
.
envVar
=
name
;
return
this
;
};
/**
* Set the custom handler for processing CLI option arguments into option values.
*
* @param {Function} [fn]
* @return {Option}
*/
argParser
(
fn
)
{
this
.
parseArg
=
fn
;
return
this
;
};
/**
* Whether the option is mandatory and must have a value after parsing.
*
* @param {boolean} [mandatory=true]
* @return {Option}
*/
makeOptionMandatory
(
mandatory
=
true
)
{
this
.
mandatory
=
!!
mandatory
;
return
this
;
};
/**
* Hide option in help.
*
* @param {boolean} [hide=true]
* @return {Option}
*/
hideHelp
(
hide
=
true
)
{
this
.
hidden
=
!!
hide
;
return
this
;
};
/**
* @api private
*/
_concatValue
(
value
,
previous
)
{
if
(
previous
===
this
.
defaultValue
||
!
Array
.
isArray
(
previous
))
{
return
[
value
];
}
return
previous
.
concat
(
value
);
}
/**
* Only allow option value to be one of choices.
*
* @param {string[]} values
* @return {Option}
*/
choices
(
values
)
{
this
.
argChoices
=
values
;
this
.
parseArg
=
(
arg
,
previous
)
=>
{
if
(
!
values
.
includes
(
arg
))
{
throw
new
InvalidArgumentError
(
`
Allowed
choices
are
$
{
values
.
join
(
', '
)}.
`
);
}
if
(
this
.
variadic
)
{
return
this
.
_concatValue
(
arg
,
previous
);
}
return
arg
;
};
return
this
;
};
/**
* Return option name.
*
* @return {string}
*/
name
()
{
if
(
this
.
long
)
{
return
this
.
long
.
replace
(
/^--/
,
''
);
}
return
this
.
short
.
replace
(
/^-/
,
''
);
};
/**
* Return option name, in a camelcase format that can be used
* as a object attribute key.
*
* @return {string}
* @api private
*/
attributeName
()
{
return
camelcase
(
this
.
name
().
replace
(
/^no-/
,
''
));
};
/**
* Check if `arg` matches the short or long flag.
*
* @param {string} arg
* @return {boolean}
* @api private
*/
is
(
arg
)
{
return
this
.
short
===
arg
||
this
.
long
===
arg
;
};
}
/**
* Convert string from kebab-case to camelCase.
*
* @param {string} str
* @return {string}
* @api private
*/
function
camelcase
(
str
)
{
return
str
.
split
(
'-'
).
reduce
((
str
,
word
)
=>
{
return
str
+
word
[
0
].
toUpperCase
()
+
word
.
slice
(
1
);
});
}
/**
* Split the short and long flag out of something like '-m,--mixed <value>'
*
* @api private
*/
function
splitOptionFlags
(
flags
)
{
let
shortFlag
;
let
longFlag
;
// Use original very loose parsing to maintain backwards compatibility for now,
// which allowed for example unintended `-sw, --short-word` [sic].
const
flagParts
=
flags
.
split
(
/[ |,]+/
);
if
(
flagParts
.
length
>
1
&&
!
/^[[<]/
.
test
(
flagParts
[
1
]))
shortFlag
=
flagParts
.
shift
();
longFlag
=
flagParts
.
shift
();
// Add support for lone short flag without significantly changing parsing!
if
(
!
shortFlag
&&
/^-[^-]$/
.
test
(
longFlag
))
{
shortFlag
=
longFlag
;
longFlag
=
undefined
;
}
return
{
shortFlag
,
longFlag
};
}
exports
.
Option
=
Option
;
exports
.
splitOptionFlags
=
splitOptionFlags
;
Event Timeline
Log In to Comment