change approach again
This commit is contained in:
96
node_modules/command-line-args/lib/argv.js
generated
vendored
Normal file
96
node_modules/command-line-args/lib/argv.js
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
'use strict'
|
||||
const arrayify = require('array-back')
|
||||
const option = require('./option')
|
||||
|
||||
/**
|
||||
* Handles parsing different argv notations
|
||||
*
|
||||
* @module argv
|
||||
* @private
|
||||
*/
|
||||
|
||||
class Argv extends Array {
|
||||
load (argv) {
|
||||
if (argv) {
|
||||
argv = arrayify(argv)
|
||||
} else {
|
||||
/* if no argv supplied, assume we are parsing process.argv */
|
||||
argv = process.argv.slice(0)
|
||||
argv.splice(0, 2)
|
||||
}
|
||||
argv.forEach(arg => this.push(String(arg)))
|
||||
}
|
||||
|
||||
clear () {
|
||||
this.length = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* expand --option=value style args. The value is clearly marked to indicate it is definitely a value (which would otherwise be unclear if the value is `--value`, which would be parsed as an option). The special marker is removed in parsing phase.
|
||||
*/
|
||||
expandOptionEqualsNotation () {
|
||||
const optEquals = option.optEquals
|
||||
if (this.some(optEquals.test.bind(optEquals))) {
|
||||
const expandedArgs = []
|
||||
this.forEach(arg => {
|
||||
const matches = arg.match(optEquals)
|
||||
if (matches) {
|
||||
expandedArgs.push(matches[1], option.VALUE_MARKER + matches[2])
|
||||
} else {
|
||||
expandedArgs.push(arg)
|
||||
}
|
||||
})
|
||||
this.clear()
|
||||
this.load(expandedArgs)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* expand getopt-style combined options
|
||||
*/
|
||||
expandGetoptNotation () {
|
||||
const findReplace = require('find-replace')
|
||||
const combinedArg = option.combined
|
||||
const hasGetopt = this.some(combinedArg.test.bind(combinedArg))
|
||||
if (hasGetopt) {
|
||||
findReplace(this, combinedArg, arg => {
|
||||
arg = arg.slice(1)
|
||||
return arg.split('').map(letter => '-' + letter)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspect the user-supplied options for validation issues.
|
||||
* @throws `UNKNOWN_OPTION`
|
||||
*/
|
||||
validate (definitions, options) {
|
||||
options = options || {}
|
||||
let invalidOption
|
||||
|
||||
if (!options.partial) {
|
||||
const optionWithoutDefinition = this
|
||||
.filter(arg => option.isOption(arg))
|
||||
.some(arg => {
|
||||
if (definitions.get(arg) === undefined) {
|
||||
invalidOption = arg
|
||||
return true
|
||||
}
|
||||
})
|
||||
if (optionWithoutDefinition) {
|
||||
halt(
|
||||
'UNKNOWN_OPTION',
|
||||
'Unknown option: ' + invalidOption
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function halt (name, message) {
|
||||
const err = new Error(message)
|
||||
err.name = name
|
||||
throw err
|
||||
}
|
||||
|
||||
module.exports = Argv
|
58
node_modules/command-line-args/lib/command-line-args.js
generated
vendored
Normal file
58
node_modules/command-line-args/lib/command-line-args.js
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @module command-line-args
|
||||
*/
|
||||
module.exports = commandLineArgs
|
||||
|
||||
/**
|
||||
* Returns an object containing all options set on the command line. By default it parses the global [`process.argv`](https://nodejs.org/api/process.html#process_process_argv) array.
|
||||
*
|
||||
* By default, an exception is thrown if the user sets an unknown option (one without a valid [definition](#exp_module_definition--OptionDefinition)). To enable __partial parsing__, invoke `commandLineArgs` with the `partial` option - all unknown arguments will be returned in the `_unknown` property.
|
||||
*
|
||||
*
|
||||
* @param {module:definition[]} - An array of [OptionDefinition](#exp_module_definition--OptionDefinition) objects
|
||||
* @param [options] {object} - Options.
|
||||
* @param [options.argv] {string[]} - An array of strings, which if passed will be parsed instead of `process.argv`.
|
||||
* @param [options.partial] {boolean} - If `true`, an array of unknown arguments is returned in the `_unknown` property of the output.
|
||||
* @returns {object}
|
||||
* @throws `UNKNOWN_OPTION` if `options.partial` is false and the user set an undefined option
|
||||
* @throws `NAME_MISSING` if an option definition is missing the required `name` property
|
||||
* @throws `INVALID_TYPE` if an option definition has a `type` value that's not a function
|
||||
* @throws `INVALID_ALIAS` if an alias is numeric, a hyphen or a length other than 1
|
||||
* @throws `DUPLICATE_NAME` if an option definition name was used more than once
|
||||
* @throws `DUPLICATE_ALIAS` if an option definition alias was used more than once
|
||||
* @throws `DUPLICATE_DEFAULT_OPTION` if more than one option definition has `defaultOption: true`
|
||||
* @alias module:command-line-args
|
||||
*/
|
||||
function commandLineArgs (optionDefinitions, options) {
|
||||
options = options || {}
|
||||
const Definitions = require('./definitions')
|
||||
const Argv = require('./argv')
|
||||
const definitions = new Definitions()
|
||||
definitions.load(optionDefinitions)
|
||||
const argv = new Argv()
|
||||
argv.load(options.argv)
|
||||
argv.expandOptionEqualsNotation()
|
||||
argv.expandGetoptNotation()
|
||||
argv.validate(definitions, options)
|
||||
|
||||
const OutputClass = definitions.isGrouped() ? require('./grouped-output') : require('./output')
|
||||
const output = new OutputClass(definitions, options)
|
||||
let optionName
|
||||
|
||||
const option = require('./option')
|
||||
for (const arg of argv) {
|
||||
if (option.isOption(arg)) {
|
||||
optionName = output.setFlag(arg) ? undefined : arg
|
||||
} else {
|
||||
if (optionName) {
|
||||
optionName = output.setOptionValue(optionName, arg) ? undefined : optionName
|
||||
} else {
|
||||
optionName = output.setValue(arg) ? undefined : optionName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output.toObject()
|
||||
}
|
236
node_modules/command-line-args/lib/definition.js
generated
vendored
Normal file
236
node_modules/command-line-args/lib/definition.js
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
'use strict'
|
||||
const t = require('typical')
|
||||
|
||||
/**
|
||||
* @module definition
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes a command-line option. Additionally, you can add `description` and `typeLabel` properties and make use of [command-line-usage](https://github.com/75lb/command-line-usage).
|
||||
* @alias module:definition
|
||||
* @typicalname option
|
||||
*/
|
||||
class OptionDefinition {
|
||||
constructor (definition) {
|
||||
/**
|
||||
* The only required definition property is `name`, so the simplest working example is
|
||||
* ```js
|
||||
* [
|
||||
* { name: "file" },
|
||||
* { name: "verbose" },
|
||||
* { name: "depth"}
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* In this case, the value of each option will be either a Boolean or string.
|
||||
*
|
||||
* | # | Command line args | .parse() output |
|
||||
* | --- | -------------------- | ------------ |
|
||||
* | 1 | `--file` | `{ file: true }` |
|
||||
* | 2 | `--file lib.js --verbose` | `{ file: "lib.js", verbose: true }` |
|
||||
* | 3 | `--verbose very` | `{ verbose: "very" }` |
|
||||
* | 4 | `--depth 2` | `{ depth: "2" }` |
|
||||
*
|
||||
* Unicode option names and aliases are valid, for example:
|
||||
* ```js
|
||||
* [
|
||||
* { name: 'один' },
|
||||
* { name: '两' },
|
||||
* { name: 'три', alias: 'т' }
|
||||
* ]
|
||||
* ```
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = definition.name
|
||||
|
||||
/**
|
||||
* The `type` value is a setter function (you receive the output from this), enabling you to be specific about the type and value received.
|
||||
*
|
||||
* You can use a class, if you like:
|
||||
*
|
||||
* ```js
|
||||
* const fs = require('fs')
|
||||
*
|
||||
* function FileDetails(filename){
|
||||
* if (!(this instanceof FileDetails)) return new FileDetails(filename)
|
||||
* this.filename = filename
|
||||
* this.exists = fs.existsSync(filename)
|
||||
* }
|
||||
*
|
||||
* const cli = commandLineArgs([
|
||||
* { name: 'file', type: FileDetails },
|
||||
* { name: 'depth', type: Number }
|
||||
* ])
|
||||
* ```
|
||||
*
|
||||
* | # | Command line args| .parse() output |
|
||||
* | --- | ----------------- | ------------ |
|
||||
* | 1 | `--file asdf.txt` | `{ file: { filename: 'asdf.txt', exists: false } }` |
|
||||
*
|
||||
* The `--depth` option expects a `Number`. If no value was set, you will receive `null`.
|
||||
*
|
||||
* | # | Command line args | .parse() output |
|
||||
* | --- | ----------------- | ------------ |
|
||||
* | 2 | `--depth` | `{ depth: null }` |
|
||||
* | 3 | `--depth 2` | `{ depth: 2 }` |
|
||||
*
|
||||
* @type {function}
|
||||
* @default String
|
||||
*/
|
||||
this.type = definition.type || String
|
||||
|
||||
/**
|
||||
* getopt-style short option names. Can be any single character (unicode included) except a digit or hypen.
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* { name: "hot", alias: "h", type: Boolean },
|
||||
* { name: "discount", alias: "d", type: Boolean },
|
||||
* { name: "courses", alias: "c" , type: Number }
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* | # | Command line | .parse() output |
|
||||
* | --- | ------------ | ------------ |
|
||||
* | 1 | `-hcd` | `{ hot: true, courses: null, discount: true }` |
|
||||
* | 2 | `-hdc 3` | `{ hot: true, discount: true, courses: 3 }` |
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
this.alias = definition.alias
|
||||
|
||||
/**
|
||||
* Set this flag if the option takes a list of values. You will receive an array of values, each passed through the `type` function (if specified).
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* { name: "files", type: String, multiple: true }
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* | # | Command line | .parse() output |
|
||||
* | --- | ------------ | ------------ |
|
||||
* | 1 | `--files one.js two.js` | `{ files: [ 'one.js', 'two.js' ] }` |
|
||||
* | 2 | `--files one.js --files two.js` | `{ files: [ 'one.js', 'two.js' ] }` |
|
||||
* | 3 | `--files *` | `{ files: [ 'one.js', 'two.js' ] }` |
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.multiple = definition.multiple
|
||||
|
||||
/**
|
||||
* Any unclaimed command-line args will be set on this option. This flag is typically set on the most commonly-used option to make for more concise usage (i.e. `$ myapp *.js` instead of `$ myapp --files *.js`).
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* { name: "files", type: String, multiple: true, defaultOption: true }
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* | # | Command line | .parse() output |
|
||||
* | --- | ------------ | ------------ |
|
||||
* | 1 | `--files one.js two.js` | `{ files: [ 'one.js', 'two.js' ] }` |
|
||||
* | 2 | `one.js two.js` | `{ files: [ 'one.js', 'two.js' ] }` |
|
||||
* | 3 | `*` | `{ files: [ 'one.js', 'two.js' ] }` |
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.defaultOption = definition.defaultOption
|
||||
|
||||
/**
|
||||
* An initial value for the option.
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* { name: "files", type: String, multiple: true, defaultValue: [ "one.js" ] },
|
||||
* { name: "max", type: Number, defaultValue: 3 }
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* | # | Command line | .parse() output |
|
||||
* | --- | ------------ | ------------ |
|
||||
* | 1 | | `{ files: [ 'one.js' ], max: 3 }` |
|
||||
* | 2 | `--files two.js` | `{ files: [ 'two.js' ], max: 3 }` |
|
||||
* | 3 | `--max 4` | `{ files: [ 'one.js' ], max: 4 }` |
|
||||
*
|
||||
* @type {*}
|
||||
*/
|
||||
this.defaultValue = definition.defaultValue
|
||||
|
||||
/**
|
||||
* When your app has a large amount of options it makes sense to organise them in groups.
|
||||
*
|
||||
* There are two automatic groups: `_all` (contains all options) and `_none` (contains options without a `group` specified in their definition).
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* { name: "verbose", group: "standard" },
|
||||
* { name: "help", group: [ "standard", "main" ] },
|
||||
* { name: "compress", group: [ "server", "main" ] },
|
||||
* { name: "static", group: "server" },
|
||||
* { name: "debug" }
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
*<table>
|
||||
* <tr>
|
||||
* <th>#</th><th>Command Line</th><th>.parse() output</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td><td><code>--verbose</code></td><td><pre><code>
|
||||
*{
|
||||
* _all: { verbose: true },
|
||||
* standard: { verbose: true }
|
||||
*}
|
||||
*</code></pre></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>2</td><td><code>--debug</code></td><td><pre><code>
|
||||
*{
|
||||
* _all: { debug: true },
|
||||
* _none: { debug: true }
|
||||
*}
|
||||
*</code></pre></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>3</td><td><code>--verbose --debug --compress</code></td><td><pre><code>
|
||||
*{
|
||||
* _all: {
|
||||
* verbose: true,
|
||||
* debug: true,
|
||||
* compress: true
|
||||
* },
|
||||
* standard: { verbose: true },
|
||||
* server: { compress: true },
|
||||
* main: { compress: true },
|
||||
* _none: { debug: true }
|
||||
*}
|
||||
*</code></pre></td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>4</td><td><code>--compress</code></td><td><pre><code>
|
||||
*{
|
||||
* _all: { compress: true },
|
||||
* server: { compress: true },
|
||||
* main: { compress: true }
|
||||
*}
|
||||
*</code></pre></td>
|
||||
* </tr>
|
||||
*</table>
|
||||
*
|
||||
* @type {string|string[]}
|
||||
*/
|
||||
this.group = definition.group
|
||||
|
||||
/* pick up any remaining properties */
|
||||
for (let prop in definition) {
|
||||
if (!this[prop]) this[prop] = definition[prop]
|
||||
}
|
||||
}
|
||||
|
||||
isBoolean (value) {
|
||||
return this.type === Boolean || (t.isFunction(this.type) && this.type.name === 'Boolean')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OptionDefinition
|
155
node_modules/command-line-args/lib/definitions.js
generated
vendored
Normal file
155
node_modules/command-line-args/lib/definitions.js
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
'use strict'
|
||||
const arrayify = require('array-back')
|
||||
const option = require('./option')
|
||||
const Definition = require('./definition')
|
||||
const t = require('typical')
|
||||
|
||||
/**
|
||||
* @module definitions
|
||||
* @private
|
||||
*/
|
||||
|
||||
/**
|
||||
* @alias module:definitions
|
||||
*/
|
||||
class Definitions extends Array {
|
||||
load (definitions) {
|
||||
this.clear()
|
||||
arrayify(definitions).forEach(def => this.push(new Definition(def)))
|
||||
this.validate()
|
||||
}
|
||||
|
||||
clear () {
|
||||
this.length = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* validate option definitions
|
||||
* @returns {string}
|
||||
*/
|
||||
validate (argv) {
|
||||
const someHaveNoName = this.some(def => !def.name)
|
||||
if (someHaveNoName) {
|
||||
halt(
|
||||
'NAME_MISSING',
|
||||
'Invalid option definitions: the `name` property is required on each definition'
|
||||
)
|
||||
}
|
||||
|
||||
const someDontHaveFunctionType = this.some(def => def.type && typeof def.type !== 'function')
|
||||
if (someDontHaveFunctionType) {
|
||||
halt(
|
||||
'INVALID_TYPE',
|
||||
'Invalid option definitions: the `type` property must be a setter fuction (default: `Boolean`)'
|
||||
)
|
||||
}
|
||||
|
||||
let invalidOption
|
||||
|
||||
const numericAlias = this.some(def => {
|
||||
invalidOption = def
|
||||
return t.isDefined(def.alias) && t.isNumber(def.alias)
|
||||
})
|
||||
if (numericAlias) {
|
||||
halt(
|
||||
'INVALID_ALIAS',
|
||||
'Invalid option definition: to avoid ambiguity an alias cannot be numeric [--' + invalidOption.name + ' alias is -' + invalidOption.alias + ']'
|
||||
)
|
||||
}
|
||||
|
||||
const multiCharacterAlias = this.some(def => {
|
||||
invalidOption = def
|
||||
return t.isDefined(def.alias) && def.alias.length !== 1
|
||||
})
|
||||
if (multiCharacterAlias) {
|
||||
halt(
|
||||
'INVALID_ALIAS',
|
||||
'Invalid option definition: an alias must be a single character'
|
||||
)
|
||||
}
|
||||
|
||||
const hypenAlias = this.some(def => {
|
||||
invalidOption = def
|
||||
return def.alias === '-'
|
||||
})
|
||||
if (hypenAlias) {
|
||||
halt(
|
||||
'INVALID_ALIAS',
|
||||
'Invalid option definition: an alias cannot be "-"'
|
||||
)
|
||||
}
|
||||
|
||||
const duplicateName = hasDuplicates(this.map(def => def.name))
|
||||
if (duplicateName) {
|
||||
halt(
|
||||
'DUPLICATE_NAME',
|
||||
'Two or more option definitions have the same name'
|
||||
)
|
||||
}
|
||||
|
||||
const duplicateAlias = hasDuplicates(this.map(def => def.alias))
|
||||
if (duplicateAlias) {
|
||||
halt(
|
||||
'DUPLICATE_ALIAS',
|
||||
'Two or more option definitions have the same alias'
|
||||
)
|
||||
}
|
||||
|
||||
const duplicateDefaultOption = hasDuplicates(this.map(def => def.defaultOption))
|
||||
if (duplicateDefaultOption) {
|
||||
halt(
|
||||
'DUPLICATE_DEFAULT_OPTION',
|
||||
'Only one option definition can be the defaultOption'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string}
|
||||
* @returns {Definition}
|
||||
*/
|
||||
get (arg) {
|
||||
return option.short.test(arg)
|
||||
? this.find(def => def.alias === option.short.name(arg))
|
||||
: this.find(def => def.name === option.long.name(arg))
|
||||
}
|
||||
|
||||
getDefault () {
|
||||
return this.find(def => def.defaultOption === true)
|
||||
}
|
||||
|
||||
isGrouped () {
|
||||
return this.some(def => def.group)
|
||||
}
|
||||
|
||||
whereGrouped () {
|
||||
return this.filter(containsValidGroup)
|
||||
}
|
||||
whereNotGrouped () {
|
||||
return this.filter(def => !containsValidGroup(def))
|
||||
}
|
||||
}
|
||||
|
||||
function halt (name, message) {
|
||||
const err = new Error(message)
|
||||
err.name = name
|
||||
throw err
|
||||
}
|
||||
|
||||
function containsValidGroup (def) {
|
||||
return arrayify(def.group).some(group => group)
|
||||
}
|
||||
|
||||
function hasDuplicates (array) {
|
||||
const items = {}
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const value = array[i]
|
||||
if (items[value]) {
|
||||
return true
|
||||
} else {
|
||||
if (t.isDefined(value)) items[value] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Definitions
|
35
node_modules/command-line-args/lib/grouped-output.js
generated
vendored
Normal file
35
node_modules/command-line-args/lib/grouped-output.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
const arrayify = require('array-back')
|
||||
const Output = require('./output')
|
||||
|
||||
class GroupedOutput extends Output {
|
||||
toObject () {
|
||||
const superOutput = super.toObject()
|
||||
delete superOutput._unknown
|
||||
const grouped = {
|
||||
_all: superOutput
|
||||
}
|
||||
if (this.unknown.length) grouped._unknown = this.unknown
|
||||
|
||||
this.definitions.whereGrouped().forEach(def => {
|
||||
const outputValue = this.output[def.name]
|
||||
for (const groupName of arrayify(def.group)) {
|
||||
grouped[groupName] = grouped[groupName] || {}
|
||||
if (outputValue && outputValue.isDefined()) {
|
||||
grouped[groupName][def.name] = outputValue.value
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.definitions.whereNotGrouped().forEach(def => {
|
||||
const outputValue = this.output[def.name]
|
||||
if (outputValue && outputValue.isDefined()) {
|
||||
if (!grouped._none) grouped._none = {}
|
||||
grouped._none[def.name] = outputValue.value
|
||||
}
|
||||
})
|
||||
return grouped
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GroupedOutput
|
14
node_modules/command-line-args/lib/option.js
generated
vendored
Normal file
14
node_modules/command-line-args/lib/option.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
class ArgRegExp extends RegExp {
|
||||
name (arg) {
|
||||
return arg.match(this)[1]
|
||||
}
|
||||
}
|
||||
|
||||
exports.short = new ArgRegExp('^-([^\\d-])$')
|
||||
exports.long = new ArgRegExp('^--(\\S+)')
|
||||
exports.combined = new ArgRegExp('^-([^\\d-]{2,})$')
|
||||
exports.isOption = arg => exports.short.test(arg) || exports.long.test(arg)
|
||||
exports.optEquals = new ArgRegExp('^(--\\S+?)=(.*)')
|
||||
exports.VALUE_MARKER = '552f3a31-14cd-4ced-bd67-656a659e9efb' // must be unique
|
152
node_modules/command-line-args/lib/output.js
generated
vendored
Normal file
152
node_modules/command-line-args/lib/output.js
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
'use strict'
|
||||
const t = require('typical')
|
||||
const arrayify = require('array-back')
|
||||
|
||||
class OutputValue {
|
||||
constructor (value) {
|
||||
this.value = value
|
||||
this.hasDefaultArrayValue = false
|
||||
this.valueSource = 'unknown'
|
||||
}
|
||||
|
||||
isDefined () {
|
||||
return t.isDefined(this.value)
|
||||
}
|
||||
}
|
||||
|
||||
class Output {
|
||||
constructor (definitions, options) {
|
||||
this.options = options || {}
|
||||
this.output = {}
|
||||
this.unknown = []
|
||||
this.definitions = definitions
|
||||
this._assignDefaultValues()
|
||||
}
|
||||
|
||||
_assignDefaultValues () {
|
||||
this.definitions.forEach(def => {
|
||||
if (t.isDefined(def.defaultValue)) {
|
||||
if (def.multiple) {
|
||||
this.output[def.name] = new OutputValue(arrayify(def.defaultValue))
|
||||
this.output[def.name].hasDefaultArrayValue = true
|
||||
} else {
|
||||
this.output[def.name] = new OutputValue(def.defaultValue)
|
||||
}
|
||||
this.output[def.name].valueSource = 'default'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setFlag (optionArg) {
|
||||
const def = this.definitions.get(optionArg)
|
||||
|
||||
if (def) {
|
||||
this.output[def.name] = this.output[def.name] || new OutputValue()
|
||||
const outputValue = this.output[def.name]
|
||||
|
||||
if (def.multiple) outputValue.value = outputValue.value || []
|
||||
|
||||
/* for boolean types, set value to `true`. For all other types run value through setter function. */
|
||||
if (def.isBoolean()) {
|
||||
if (Array.isArray(outputValue.value)) {
|
||||
outputValue.value.push(true)
|
||||
} else {
|
||||
outputValue.value = true
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
if (!Array.isArray(outputValue.value) && outputValue.valueSource === 'unknown') outputValue.value = null
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
this.unknown.push(optionArg)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
setOptionValue (optionArg, value) {
|
||||
const ValueArg = require('./value-arg')
|
||||
const valueArg = new ValueArg(value)
|
||||
|
||||
const def = this.definitions.get(optionArg)
|
||||
|
||||
this.output[def.name] = this.output[def.name] || new OutputValue()
|
||||
const outputValue = this.output[def.name]
|
||||
|
||||
if (def.multiple) outputValue.value = outputValue.value || []
|
||||
|
||||
/* run value through setter function. */
|
||||
valueArg.value = def.type(valueArg.value)
|
||||
outputValue.valueSource = 'argv'
|
||||
if (Array.isArray(outputValue.value)) {
|
||||
if (outputValue.hasDefaultArrayValue) {
|
||||
outputValue.value = [ valueArg.value ]
|
||||
outputValue.hasDefaultArrayValue = false
|
||||
} else {
|
||||
outputValue.value.push(valueArg.value)
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
outputValue.value = valueArg.value
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return `true` when an option value was set and is not a multiple. Return `false` if option was a multiple or if a value was not yet set.
|
||||
*/
|
||||
setValue (value) {
|
||||
const ValueArg = require('./value-arg')
|
||||
const valueArg = new ValueArg(value)
|
||||
|
||||
/* use the defaultOption */
|
||||
const def = this.definitions.getDefault()
|
||||
|
||||
/* handle unknown values in the case a value was already set on a defaultOption */
|
||||
if (def) {
|
||||
const currentValue = this.output[def.name]
|
||||
if (valueArg.isDefined() && currentValue && t.isDefined(currentValue.value)) {
|
||||
if (def.multiple) {
|
||||
/* in the case we're setting an --option=value value on a multiple defaultOption, tag the value onto the previous unknown */
|
||||
if (valueArg.isOptionValueNotationValue && this.unknown.length) {
|
||||
this.unknown[this.unknown.length - 1] += `=${valueArg.value}`
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
/* currentValue has already been set by argv,log this value as unknown and move on */
|
||||
if (currentValue.valueSource === 'argv') {
|
||||
this.unknown.push(valueArg.value)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.setOptionValue(`--${def.name}`, value)
|
||||
} else {
|
||||
if (valueArg.isOptionValueNotationValue) {
|
||||
this.unknown[this.unknown.length - 1] += `=${valueArg.value}`
|
||||
} else {
|
||||
this.unknown.push(valueArg.value)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
get (name) {
|
||||
return this.output[name] && this.output[name].value
|
||||
}
|
||||
|
||||
toObject () {
|
||||
let output = Object.assign({}, this.output)
|
||||
if (this.options.partial && this.unknown.length) {
|
||||
output._unknown = this.unknown
|
||||
}
|
||||
for (const prop in output) {
|
||||
if (prop !== '_unknown') {
|
||||
output[prop] = output[prop].value
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Output
|
36
node_modules/command-line-args/lib/output2.js
generated
vendored
Normal file
36
node_modules/command-line-args/lib/output2.js
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
class FlagOption {}
|
||||
class SingleValueOption {
|
||||
constructor (definition) {
|
||||
this.definition = definition
|
||||
}
|
||||
|
||||
set value (val) {
|
||||
this._val = this.definition.type(val)
|
||||
}
|
||||
get value () {
|
||||
return this._val
|
||||
}
|
||||
}
|
||||
class MultipleValueOption {}
|
||||
|
||||
|
||||
|
||||
class Output extends Map {
|
||||
constructor (definitions) {
|
||||
this.definitions = definitions
|
||||
}
|
||||
|
||||
set (key, value) {
|
||||
const def = this.definitions.get(key)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const optionDefinitions = [
|
||||
{ name: 'one' }
|
||||
]
|
||||
const output = new Output(optionDefinitions)
|
||||
output.set('one', 'something')
|
||||
console.log(output)
|
||||
output.set('one', 'something2')
|
||||
console.log(output)
|
18
node_modules/command-line-args/lib/value-arg.js
generated
vendored
Normal file
18
node_modules/command-line-args/lib/value-arg.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict'
|
||||
const t = require('typical')
|
||||
const option = require('./option')
|
||||
const reBeginsWithValueMarker = new RegExp('^' + option.VALUE_MARKER)
|
||||
|
||||
class ValueArg {
|
||||
constructor (value) {
|
||||
this.isOptionValueNotationValue = reBeginsWithValueMarker.test(value)
|
||||
/* if the value marker is present at the value beginning, strip it */
|
||||
this.value = value ? value.replace(reBeginsWithValueMarker, '') : value
|
||||
}
|
||||
|
||||
isDefined () {
|
||||
return t.isDefined(this.value)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ValueArg
|
Reference in New Issue
Block a user