diff --git a/README.md b/README.md index 9801f7a..d690525 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![Gihub repo dependents](https://badgen.net/github/dependents-repo/75lb/command-line-args)](https://github.com/75lb/command-line-args/network/dependents?dependent_type=REPOSITORY) [![Gihub package dependents](https://badgen.net/github/dependents-pkg/75lb/command-line-args)](https://github.com/75lb/command-line-args/network/dependents?dependent_type=PACKAGE) [![Node.js CI](https://github.com/75lb/command-line-args/actions/workflows/node.js.yml/badge.svg)](https://github.com/75lb/command-line-args/actions/workflows/node.js.yml) -[![Coverage Status](https://coveralls.io/repos/github/75lb/command-line-args/badge.svg)](https://coveralls.io/github/75lb/command-line-args) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/feross/standard) ***Upgraders, please read the [release notes](https://github.com/75lb/command-line-args/releases)*** diff --git a/dist/index.cjs b/dist/index.cjs new file mode 100644 index 0000000..4ffd609 --- /dev/null +++ b/dist/index.cjs @@ -0,0 +1,1976 @@ +'use strict'; + +/** + * Takes any input and guarantees an array back. + * + * - Converts array-like objects (e.g. `arguments`, `Set`) to a real array. + * - Converts `undefined` to an empty array. + * - Converts any another other, singular value (including `null`, objects and iterables other than `Set`) into an array containing that value. + * - Ignores input which is already an array. + * + * @module array-back + * @example + * > const arrayify = require('array-back') + * + * > arrayify(undefined) + * [] + * + * > arrayify(null) + * [ null ] + * + * > arrayify(0) + * [ 0 ] + * + * > arrayify([ 1, 2 ]) + * [ 1, 2 ] + * + * > arrayify(new Set([ 1, 2 ])) + * [ 1, 2 ] + * + * > function f(){ return arrayify(arguments); } + * > f(1,2,3) + * [ 1, 2, 3 ] + */ + +function isObject$1 (input) { + return typeof input === 'object' && input !== null +} + +function isArrayLike$1 (input) { + return isObject$1(input) && typeof input.length === 'number' +} + +/** + * @param {*} - The input value to convert to an array + * @returns {Array} + * @alias module:array-back + */ +function arrayify (input) { + if (Array.isArray(input)) { + return input + } else if (input === undefined) { + return [] + } else if (isArrayLike$1(input) || input instanceof Set) { + return Array.from(input) + } else { + return [input] + } +} + +/** + * @module find-replace + */ + +/** + * @param {array} - The input array + * @param {function} - A predicate function which, if returns `true` causes the current item to be operated on. + * @param [replaceWith] {...any} - If not specified, each found value will be removed. If specified, each found value will be replaced with this value. If the `replaceWith` value is a function, it will be invoked with the found value and its result used as the replace value. If the `replaceWith` function returns an array, the found value will be replaced with each item in the array (not replaced with the array itself). + * @returns {array} + * @alias module:find-replace + */ +function findReplace (array, findFn, ...replaceWiths) { + const found = []; + if (!Array.isArray(array)) { + throw new Error('Input must be an array') + } + + for (const [index, value] of array.entries()) { + let expanded = []; + replaceWiths.forEach(replaceWith => { + if (typeof replaceWith === 'function') { + expanded = expanded.concat(replaceWith(value)); + } else { + expanded.push(replaceWith); + } + }); + + if (findFn(value)) { + found.push({ + index: index, + replaceWithValue: expanded + }); + } + } + + for (const item of found.reverse()) { + const spliceArgs = [item.index, 1].concat(item.replaceWithValue); + array.splice.apply(array, spliceArgs); + } + + return array +} + +/** + * Some useful tools for working with `process.argv`. + * + * @module argv-tools + * @typicalName argvTools + * @example + * const argvTools = require('argv-tools') + */ + +/** + * Regular expressions for matching option formats. + * @static + */ +const re = { + short: /^-([^\d-])$/, + long: /^--(\S+)/, + combinedShort: /^-[^\d-]{2,}$/, + optEquals: /^(--\S+?)=(.*)/ +}; + +/** + * Array subclass encapsulating common operations on `process.argv`. + * @static + */ +class ArgvArray extends Array { + /** + * Clears the array has loads the supplied input. + * @param {string[]} argv - The argv list to load. Defaults to `process.argv`. + */ + load (argv) { + this.clear(); + if (argv && argv !== process.argv) { + argv = arrayify(argv); + } else { + /* if no argv supplied, assume we are parsing process.argv */ + argv = process.argv.slice(0); + const deleteCount = process.execArgv.some(isExecArg) ? 1 : 2; + argv.splice(0, deleteCount); + } + argv.forEach(arg => this.push(String(arg))); + } + + /** + * Clear the array. + */ + clear () { + this.length = 0; + } + + /** + * expand ``--option=value` style args. + */ + expandOptionEqualsNotation () { + if (this.some(arg => re.optEquals.test(arg))) { + const expandedArgs = []; + this.forEach(arg => { + const matches = arg.match(re.optEquals); + if (matches) { + expandedArgs.push(matches[1], matches[2]); + } else { + expandedArgs.push(arg); + } + }); + this.clear(); + this.load(expandedArgs); + } + } + + /** + * expand getopt-style combinedShort options. + */ + expandGetoptNotation () { + if (this.hasCombinedShortOptions()) { + findReplace(this, re.combinedShort, expandCombinedShortArg); + } + } + + /** + * Returns true if the array contains combined short options (e.g. `-ab`). + * @returns {boolean} + */ + hasCombinedShortOptions () { + return this.some(arg => re.combinedShort.test(arg)) + } + + static from (argv) { + const result = new this(); + result.load(argv); + return result + } +} + +/** + * Expand a combined short option. + * @param {string} - the string to expand, e.g. `-ab` + * @returns {string[]} + * @static + */ +function expandCombinedShortArg (arg) { + /* remove initial hypen */ + arg = arg.slice(1); + return arg.split('').map(letter => '-' + letter) +} + +/** + * Returns true if the supplied arg matches `--option=value` notation. + * @param {string} - the arg to test, e.g. `--one=something` + * @returns {boolean} + * @static + */ +function isOptionEqualsNotation (arg) { + return re.optEquals.test(arg) +} + +/** + * Returns true if the supplied arg is in either long (`--one`) or short (`-o`) format. + * @param {string} - the arg to test, e.g. `--one` + * @returns {boolean} + * @static + */ +function isOption (arg) { + return (re.short.test(arg) || re.long.test(arg)) && !re.optEquals.test(arg) +} + +/** + * Returns true if the supplied arg is in long (`--one`) format. + * @param {string} - the arg to test, e.g. `--one` + * @returns {boolean} + * @static + */ +function isLongOption (arg) { + return re.long.test(arg) && !isOptionEqualsNotation(arg) +} + +/** + * Returns the name from a long, short or `--options=value` arg. + * @param {string} - the arg to inspect, e.g. `--one` + * @returns {string} + * @static + */ +function getOptionName (arg) { + if (re.short.test(arg)) { + return arg.match(re.short)[1] + } else if (isLongOption(arg)) { + return arg.match(re.long)[1] + } else if (isOptionEqualsNotation(arg)) { + return arg.match(re.optEquals)[1].replace(/^--/, '') + } else { + return null + } +} + +function isValue (arg) { + return !(isOption(arg) || re.combinedShort.test(arg) || re.optEquals.test(arg)) +} + +function isExecArg (arg) { + return ['--eval', '-e'].indexOf(arg) > -1 || arg.startsWith('--eval=') +} + +/** + * Isomorphic, functional type-checking for Javascript. + * @module typical + * @typicalname t + * @example + * import * as t from 'typical' + * const allDefined = array.every(t.isDefined) + */ + +/** + * Returns true if input is a number (including infinity). It is a more reasonable alternative to `typeof n` which returns `number` for `NaN`. + * + * @param {*} n - The input to test + * @returns {boolean} `true` if input is a number + * @static + * @example + * > t.isNumber(0) + * true + * > t.isNumber(1) + * true + * > t.isNumber(1.1) + * true + * > t.isNumber(0xff) + * true + * > t.isNumber(0644) + * true + * > t.isNumber(6.2e5) + * true + * > t.isNumber(NaN) + * false + * > t.isNumber(Infinity) + * true + */ +function isNumber (n) { + return !isNaN(parseFloat(n)) +} + +/** + * Returns true if input is a finite number. Identical to `isNumber` beside excluding infinity. + * + * @param {*} n - The input to test + * @returns {boolean} + * @static + * @example + * > t.isFiniteNumber(0) + * true + * > t.isFiniteNumber(1) + * true + * > t.isFiniteNumber(1.1) + * true + * > t.isFiniteNumber(0xff) + * true + * > t.isFiniteNumber(0644) + * true + * > t.isFiniteNumber(6.2e5) + * true + * > t.isFiniteNumber(NaN) + * false + * > t.isFiniteNumber(Infinity) + * false + */ +function isFiniteNumber (n) { + return !isNaN(parseFloat(n)) && isFinite(n) +} + +/** + * A plain object is a simple object literal, it is not an instance of a class. Returns true if the input `typeof` is `object` and directly decends from `Object`. + * + * @param {*} input - The input to test + * @returns {boolean} + * @static + * @example + * > t.isPlainObject({ something: 'one' }) + * true + * > t.isPlainObject(new Date()) + * false + * > t.isPlainObject([ 0, 1 ]) + * false + * > t.isPlainObject(/test/) + * false + * > t.isPlainObject(1) + * false + * > t.isPlainObject('one') + * false + * > t.isPlainObject(null) + * false + * > t.isPlainObject((function * () {})()) + * false + * > t.isPlainObject(function * () {}) + * false + */ +function isPlainObject (input) { + return input !== null && typeof input === 'object' && input.constructor === Object +} + +/** + * An array-like value has all the properties of an array yet is not an array instance. An example is the `arguments` object. Returns `true`` if the input value is an object, not `null`` and has a `length` property set with a numeric value. + * + * @param {*} input - The input to test + * @returns {boolean} + * @static + * @example + * function sum(x, y){ + * console.log(t.isArrayLike(arguments)) + * // prints `true` + * } + */ +function isArrayLike (input) { + return isObject(input) && typeof input.length === 'number' +} + +/** + * Returns true if the typeof input is `'object'` but not null. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isObject (input) { + return typeof input === 'object' && input !== null +} + +/** + * Returns true if the input value is defined. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isDefined (input) { + return typeof input !== 'undefined' +} + +/** + * Returns true if the input value is undefined. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isUndefined (input) { + return !isDefined(input) +} + +/** + * Returns true if the input value is null. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isNull (input) { + return input === null +} + +/** + * Returns true if the input value is not one of `undefined`, `null`, or `NaN`. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isDefinedValue (input) { + return isDefined(input) && !isNull(input) && !Number.isNaN(input) +} + +/** + * Returns true if the input value is an ES2015 `class`. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isClass (input) { + if (typeof input === 'function') { + return /^class /.test(Function.prototype.toString.call(input)) + } else { + return false + } +} + +/** + * Returns true if the input is a string, number, symbol, boolean, null or undefined value. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isPrimitive (input) { + if (input === null) return true + switch (typeof input) { + case 'string': + case 'number': + case 'symbol': + case 'undefined': + case 'boolean': + return true + default: + return false + } +} + +/** + * Returns true if the input is a Promise. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isPromise (input) { + if (input) { + const isPromise = isDefined(Promise) && input instanceof Promise; + const isThenable = input.then && typeof input.then === 'function'; + return !!(isPromise || isThenable) + } else { + return false + } +} + +/** + * Returns true if the input is an iterable (`Map`, `Set`, `Array`, Generator etc.). + * @param {*} input - The input to test + * @returns {boolean} + * @static + * @example + * > t.isIterable('string') + * true + * > t.isIterable(new Map()) + * true + * > t.isIterable([]) + * true + * > t.isIterable((function * () {})()) + * true + * > t.isIterable(Promise.resolve()) + * false + * > t.isIterable(Promise) + * false + * > t.isIterable(true) + * false + * > t.isIterable({}) + * false + * > t.isIterable(0) + * false + * > t.isIterable(1.1) + * false + * > t.isIterable(NaN) + * false + * > t.isIterable(Infinity) + * false + * > t.isIterable(function () {}) + * false + * > t.isIterable(Date) + * false + * > t.isIterable() + * false + * > t.isIterable({ then: function () {} }) + * false + */ +function isIterable (input) { + if (input === null || !isDefined(input)) { + return false + } else { + return ( + typeof input[Symbol.iterator] === 'function' || + typeof input[Symbol.asyncIterator] === 'function' + ) + } +} + +/** + * Returns true if the input value is a string. The equivalent of `typeof input === 'string'` for use in funcitonal contexts. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isString (input) { + return typeof input === 'string' +} + +/** + * Returns true if the input value is a function. The equivalent of `typeof input === 'function'` for use in funcitonal contexts. + * @param {*} input - The input to test + * @returns {boolean} + * @static + */ +function isFunction (input) { + return typeof input === 'function' +} + +var t = { + isNumber, + isFiniteNumber, + isPlainObject, + isArrayLike, + isObject, + isDefined, + isUndefined, + isNull, + isDefinedValue, + isClass, + isPrimitive, + isPromise, + isIterable, + isString, + isFunction +}; + +/** + * @module option-definition + */ + +/** + * Describes a command-line option. Additionally, if generating a usage guide with [command-line-usage](https://github.com/75lb/command-line-usage) you could optionally add `description` and `typeLabel` properties to each definition. + * + * @alias module:option-definition + * @typicalname option + */ +class OptionDefinition { + constructor (definition) { + /** + * The only required definition property is `name`, so the simplest working example is + * ```js + * const optionDefinitions = [ + * { name: 'file' }, + * { name: 'depth' } + * ] + * ``` + * + * Where a `type` property is not specified it will default to `String`. + * + * | # | argv input | commandLineArgs() output | + * | --- | -------------------- | ------------ | + * | 1 | `--file` | `{ file: null }` | + * | 2 | `--file lib.js` | `{ file: 'lib.js' }` | + * | 3 | `--depth 2` | `{ depth: '2' }` | + * + * Unicode option names and aliases are valid, for example: + * ```js + * const optionDefinitions = [ + * { 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. + * + * The most common values used are `String` (the default), `Number` and `Boolean` but you can use a custom function, for example: + * + * ```js + * const fs = require('fs') + * + * class FileDetails { + * constructor (filename) { + * this.filename = filename + * this.exists = fs.existsSync(filename) + * } + * } + * + * const cli = commandLineArgs([ + * { name: 'file', type: filename => new FileDetails(filename) }, + * { name: 'depth', type: Number } + * ]) + * ``` + * + * | # | argv input | commandLineArgs() 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`. + * + * | # | argv input | commandLineArgs() 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 hyphen. + * + * ```js + * const optionDefinitions = [ + * { name: 'hot', alias: 'h', type: Boolean }, + * { name: 'discount', alias: 'd', type: Boolean }, + * { name: 'courses', alias: 'c' , type: Number } + * ] + * ``` + * + * | # | argv input | commandLineArgs() 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 + * const optionDefinitions = [ + * { name: 'files', type: String, multiple: true } + * ] + * ``` + * + * Note, examples 1 and 3 below demonstrate "greedy" parsing which can be disabled by using `lazyMultiple`. + * + * | # | argv input | commandLineArgs() 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; + + /** + * Identical to `multiple` but with greedy parsing disabled. + * + * ```js + * const optionDefinitions = [ + * { name: 'files', lazyMultiple: true }, + * { name: 'verbose', alias: 'v', type: Boolean, lazyMultiple: true } + * ] + * ``` + * + * | # | argv input | commandLineArgs() output | + * | --- | ------------ | ------------ | + * | 1 | `--files one.js --files two.js` | `{ files: [ 'one.js', 'two.js' ] }` | + * | 2 | `-vvv` | `{ verbose: [ true, true, true ] }` | + * + * @type {boolean} + */ + this.lazyMultiple = definition.lazyMultiple; + + /** + * Any values unaccounted for by an option definition will be set on the `defaultOption`. This flag is typically set on the most commonly-used option to make for more concise usage (i.e. `$ example *.js` instead of `$ example --files *.js`). + * + * ```js + * const optionDefinitions = [ + * { name: 'files', multiple: true, defaultOption: true } + * ] + * ``` + * + * | # | argv input | commandLineArgs() 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 + * const optionDefinitions = [ + * { name: 'files', multiple: true, defaultValue: [ 'one.js' ] }, + * { name: 'max', type: Number, defaultValue: 3 } + * ] + * ``` + * + * | # | argv input | commandLineArgs() 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 + * const optionDefinitions = [ + * { name: 'verbose', group: 'standard' }, + * { name: 'help', group: [ 'standard', 'main' ] }, + * { name: 'compress', group: [ 'server', 'main' ] }, + * { name: 'static', group: 'server' }, + * { name: 'debug' } + * ] + * ``` + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
#Command LinecommandLineArgs() output
1--verbose

+    *{
+    *  _all: { verbose: true },
+    *  standard: { verbose: true }
+    *}
+    *
2--debug

+    *{
+    *  _all: { debug: true },
+    *  _none: { debug: true }
+    *}
+    *
3--verbose --debug --compress

+    *{
+    *  _all: {
+    *    verbose: true,
+    *    debug: true,
+    *    compress: true
+    *  },
+    *  standard: { verbose: true },
+    *  server: { compress: true },
+    *  main: { compress: true },
+    *  _none: { debug: true }
+    *}
+    *
4--compress

+    *{
+    *  _all: { compress: true },
+    *  server: { compress: true },
+    *  main: { compress: true }
+    *}
+    *
+ * + * @type {string|string[]} + */ + this.group = definition.group; + + /* pick up any remaining properties */ + for (const prop in definition) { + if (!this[prop]) this[prop] = definition[prop]; + } + } + + isBoolean () { + return this.type === Boolean || (t.isFunction(this.type) && this.type.name === 'Boolean') + } + + isMultiple () { + return this.multiple || this.lazyMultiple + } + + static create (def) { + const result = new this(def); + return result + } +} + +/** + * @module option-definitions + */ + +/** + * @alias module:option-definitions + */ +class Definitions extends Array { + /** + * validate option definitions + * @param {boolean} [caseInsensitive=false] - whether arguments will be parsed in a case insensitive manner + * @returns {string} + */ + validate (caseInsensitive) { + const someHaveNoName = this.some(def => !def.name); + if (someHaveNoName) { + halt( + 'INVALID_DEFINITIONS', + '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_DEFINITIONS', + '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_DEFINITIONS', + '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_DEFINITIONS', + 'Invalid option definition: an alias must be a single character' + ); + } + + const hypenAlias = this.some(def => { + invalidOption = def; + return def.alias === '-' + }); + if (hypenAlias) { + halt( + 'INVALID_DEFINITIONS', + 'Invalid option definition: an alias cannot be "-"' + ); + } + + const duplicateName = hasDuplicates(this.map(def => caseInsensitive ? def.name.toLowerCase() : def.name)); + if (duplicateName) { + halt( + 'INVALID_DEFINITIONS', + 'Two or more option definitions have the same name' + ); + } + + const duplicateAlias = hasDuplicates(this.map(def => caseInsensitive && t.isDefined(def.alias) ? def.alias.toLowerCase() : def.alias)); + if (duplicateAlias) { + halt( + 'INVALID_DEFINITIONS', + 'Two or more option definitions have the same alias' + ); + } + + const duplicateDefaultOption = this.filter(def => def.defaultOption === true).length > 1; + if (duplicateDefaultOption) { + halt( + 'INVALID_DEFINITIONS', + 'Only one option definition can be the defaultOption' + ); + } + + const defaultBoolean = this.some(def => { + invalidOption = def; + return def.isBoolean() && def.defaultOption + }); + if (defaultBoolean) { + halt( + 'INVALID_DEFINITIONS', + `A boolean option ["${invalidOption.name}"] can not also be the defaultOption.` + ); + } + } + + /** + * Get definition by option arg (e.g. `--one` or `-o`) + * @param {string} [arg] the argument name to get the definition for + * @param {boolean} [caseInsensitive] whether to use case insensitive comparisons when finding the appropriate definition + * @returns {Definition} + */ + get (arg, caseInsensitive) { + if (isOption(arg)) { + if (re.short.test(arg)) { + const shortOptionName = getOptionName(arg); + if (caseInsensitive) { + const lowercaseShortOptionName = shortOptionName.toLowerCase(); + return this.find(def => t.isDefined(def.alias) && def.alias.toLowerCase() === lowercaseShortOptionName) + } else { + return this.find(def => def.alias === shortOptionName) + } + } else { + const optionName = getOptionName(arg); + if (caseInsensitive) { + const lowercaseOptionName = optionName.toLowerCase(); + return this.find(def => def.name.toLowerCase() === lowercaseOptionName) + } else { + return this.find(def => def.name === optionName) + } + } + } else { + return this.find(def => def.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)) + } + + whereDefaultValueSet () { + return this.filter(def => t.isDefined(def.defaultValue)) + } + + static from (definitions, caseInsensitive) { + if (definitions instanceof this) return definitions + const result = super.from(arrayify(definitions), def => OptionDefinition.create(def)); + result.validate(caseInsensitive); + return result + } +} + +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 argv-parser + */ + +/** + * @alias module:argv-parser + */ +class ArgvParser { + /** + * @param {OptionDefinitions} - Definitions array + * @param {object} [options] - Options + * @param {string[]} [options.argv] - Overrides `process.argv` + * @param {boolean} [options.stopAtFirstUnknown] - + * @param {boolean} [options.caseInsensitive] - Arguments will be parsed in a case insensitive manner. Defaults to false. + */ + constructor (definitions, options) { + this.options = Object.assign({}, options); + /** + * Option Definitions + */ + this.definitions = Definitions.from(definitions, this.options.caseInsensitive); + + /** + * Argv + */ + this.argv = ArgvArray.from(this.options.argv); + if (this.argv.hasCombinedShortOptions()) { + findReplace(this.argv, re.combinedShort.test.bind(re.combinedShort), arg => { + arg = arg.slice(1); + return arg.split('').map(letter => ({ origArg: `-${arg}`, arg: '-' + letter })) + }); + } + } + + /** + * Yields one `{ event, name, value, arg, def }` argInfo object for each arg in `process.argv` (or `options.argv`). + */ + * [Symbol.iterator] () { + const definitions = this.definitions; + + let def; + let value; + let name; + let event; + let singularDefaultSet = false; + let unknownFound = false; + let origArg; + + for (let arg of this.argv) { + if (t.isPlainObject(arg)) { + origArg = arg.origArg; + arg = arg.arg; + } + + if (unknownFound && this.options.stopAtFirstUnknown) { + yield { event: 'unknown_value', arg, name: '_unknown', value: undefined }; + continue + } + + /* handle long or short option */ + if (isOption(arg)) { + def = definitions.get(arg, this.options.caseInsensitive); + value = undefined; + if (def) { + value = def.isBoolean() ? true : null; + event = 'set'; + } else { + event = 'unknown_option'; + } + + /* handle --option-value notation */ + } else if (isOptionEqualsNotation(arg)) { + const matches = arg.match(re.optEquals); + def = definitions.get(matches[1], this.options.caseInsensitive); + if (def) { + if (def.isBoolean()) { + yield { event: 'unknown_value', arg, name: '_unknown', value, def }; + event = 'set'; + value = true; + } else { + event = 'set'; + value = matches[2]; + } + } else { + event = 'unknown_option'; + } + + /* handle value */ + } else if (isValue(arg)) { + if (def) { + value = arg; + event = 'set'; + } else { + /* get the defaultOption */ + def = this.definitions.getDefault(); + if (def && !singularDefaultSet) { + value = arg; + event = 'set'; + } else { + event = 'unknown_value'; + def = undefined; + } + } + } + + name = def ? def.name : '_unknown'; + const argInfo = { event, arg, name, value, def }; + if (origArg) { + argInfo.subArg = arg; + argInfo.arg = origArg; + } + yield argInfo; + + /* unknownFound logic */ + if (name === '_unknown') unknownFound = true; + + /* singularDefaultSet logic */ + if (def && def.defaultOption && !def.isMultiple() && event === 'set') singularDefaultSet = true; + + /* reset values once consumed and yielded */ + if (def && def.isBoolean()) def = undefined; + /* reset the def if it's a singular which has been set */ + if (def && !def.multiple && t.isDefined(value) && value !== null) { + def = undefined; + } + value = undefined; + event = undefined; + name = undefined; + origArg = undefined; + } + } +} + +const _value = new WeakMap(); + +/** + * Encapsulates behaviour (defined by an OptionDefinition) when setting values + */ +class Option { + constructor (definition) { + this.definition = new OptionDefinition(definition); + this.state = null; /* set or default */ + this.resetToDefault(); + } + + get () { + return _value.get(this) + } + + set (val) { + this._set(val, 'set'); + } + + _set (val, state) { + const def = this.definition; + if (def.isMultiple()) { + /* don't add null or undefined to a multiple */ + if (val !== null && val !== undefined) { + const arr = this.get(); + if (this.state === 'default') arr.length = 0; + arr.push(def.type(val)); + this.state = state; + } + } else { + /* throw if already set on a singlar defaultOption */ + if (!def.isMultiple() && this.state === 'set') { + const err = new Error(`Singular option already set [${this.definition.name}=${this.get()}]`); + err.name = 'ALREADY_SET'; + err.value = val; + err.optionName = def.name; + throw err + } else if (val === null || val === undefined) { + _value.set(this, val); + // /* required to make 'partial: defaultOption with value equal to defaultValue 2' pass */ + // if (!(def.defaultOption && !def.isMultiple())) { + // this.state = state + // } + } else { + _value.set(this, def.type(val)); + this.state = state; + } + } + } + + resetToDefault () { + if (t.isDefined(this.definition.defaultValue)) { + if (this.definition.isMultiple()) { + _value.set(this, arrayify(this.definition.defaultValue).slice()); + } else { + _value.set(this, this.definition.defaultValue); + } + } else { + if (this.definition.isMultiple()) { + _value.set(this, []); + } else { + _value.set(this, null); + } + } + this.state = 'default'; + } + + static create (definition) { + definition = new OptionDefinition(definition); + if (definition.isBoolean()) { + return FlagOption.create(definition) + } else { + return new this(definition) + } + } +} + +class FlagOption extends Option { + set (val) { + super.set(true); + } + + static create (def) { + return new this(def) + } +} + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used to match words composed of alphanumeric characters. */ +var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + +/** Used to match Latin Unicode letters (excluding mathematical operators). */ +var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = '\\u2000-\\u206f', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + +/** Used to compose unicode capture groups. */ +var rsApos = "['\u2019]", + rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', + rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match apostrophes. */ +var reApos = RegExp(rsApos, 'g'); + +/** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ +var reComboMark = RegExp(rsCombo, 'g'); + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** Used to match complex or compound words. */ +var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', + rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr, + rsUpper + '+' + rsOptUpperContr, + rsDigits, + rsEmoji +].join('|'), 'g'); + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/** Used to detect strings that need a more robust regexp to match words. */ +var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + +/** Used to map Latin Unicode letters to basic Latin letters. */ +var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 'ss' +}; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function asciiToArray(string) { + return string.split(''); +} + +/** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ +function asciiWords(string) { + return string.match(reAsciiWord) || []; +} + +/** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; +} + +/** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ +var deburrLetter = basePropertyOf(deburredLetters); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ +function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); +} + +/** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); +} + +/** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function unicodeToArray(string) { + return string.match(reUnicode) || []; +} + +/** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ +function unicodeWords(string) { + return string.match(reUnicodeWord) || []; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var Symbol$1 = root.Symbol; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ +function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); +} + +/** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ +function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); + + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); + + return chr[methodName]() + trailing; + }; +} + +/** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ +function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} + +/** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ +var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); +}); + +/** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ +function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); +} + +/** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ +function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); +} + +/** + * Converts the first character of `string` to upper case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.upperFirst('fred'); + * // => 'Fred' + * + * _.upperFirst('FRED'); + * // => 'FRED' + */ +var upperFirst = createCaseFirst('toUpperCase'); + +/** + * Splits `string` into an array of its words. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {RegExp|string} [pattern] The pattern to match words. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the words of `string`. + * @example + * + * _.words('fred, barney, & pebbles'); + * // => ['fred', 'barney', 'pebbles'] + * + * _.words('fred, barney, & pebbles', /[^, ]+/g); + * // => ['fred', 'barney', '&', 'pebbles'] + */ +function words(string, pattern, guard) { + string = toString(string); + pattern = pattern; + + if (pattern === undefined) { + return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string); + } + return string.match(pattern) || []; +} + +var lodash_camelcase = camelCase; + +var camelCase$1 = /*@__PURE__*/getDefaultExportFromCjs(lodash_camelcase); + +/** + * A map of { DefinitionNameString: Option }. By default, an Output has an `_unknown` property and any options with defaultValues. + */ +class Output extends Map { + constructor (definitions) { + super(); + /** + * @type {OptionDefinitions} + */ + this.definitions = Definitions.from(definitions); + + /* by default, an Output has an `_unknown` property and any options with defaultValues */ + this.set('_unknown', Option.create({ name: '_unknown', multiple: true })); + for (const def of this.definitions.whereDefaultValueSet()) { + this.set(def.name, Option.create(def)); + } + } + + toObject (options) { + options = options || {}; + const output = {}; + for (const item of this) { + const name = options.camelCase && item[0] !== '_unknown' ? camelCase$1(item[0]) : item[0]; + const option = item[1]; + if (name === '_unknown' && !option.get().length) continue + output[name] = option.get(); + } + + if (options.skipUnknown) delete output._unknown; + return output + } +} + +class GroupedOutput extends Output { + toObject (options) { + const superOutputNoCamel = super.toObject({ skipUnknown: options.skipUnknown }); + const superOutput = super.toObject(options); + const unknown = superOutput._unknown; + delete superOutput._unknown; + const grouped = { + _all: superOutput + }; + if (unknown && unknown.length) grouped._unknown = unknown; + + this.definitions.whereGrouped().forEach(def => { + const name = options.camelCase ? camelCase$1(def.name) : def.name; + const outputValue = superOutputNoCamel[def.name]; + for (const groupName of arrayify(def.group)) { + grouped[groupName] = grouped[groupName] || {}; + if (t.isDefined(outputValue)) { + grouped[groupName][name] = outputValue; + } + } + }); + + this.definitions.whereNotGrouped().forEach(def => { + const name = options.camelCase ? camelCase$1(def.name) : def.name; + const outputValue = superOutputNoCamel[def.name]; + if (t.isDefined(outputValue)) { + if (!grouped._none) grouped._none = {}; + grouped._none[name] = outputValue; + } + }); + return grouped + } +} + +/** + * @module command-line-args + */ + +/** + * Returns an object containing all option values set on the command line. By default it parses the global [`process.argv`](https://nodejs.org/api/process.html#process_process_argv) array. + * + * Parsing is strict by default - an exception is thrown if the user sets a singular option more than once or sets an unknown value or option (one without a valid [definition](https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md)). To be more permissive, enabling [partial](https://github.com/75lb/command-line-args/wiki/Partial-mode-example) or [stopAtFirstUnknown](https://github.com/75lb/command-line-args/wiki/stopAtFirstUnknown) modes will return known options in the usual manner while collecting unknown arguments in a separate `_unknown` property. + * + * @param {Array} - An array of [OptionDefinition](https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md) objects + * @param {object} [options] - Options. + * @param {string[]} [options.argv] - An array of strings which, if present will be parsed instead of `process.argv`. + * @param {boolean} [options.partial] - If `true`, an array of unknown arguments is returned in the `_unknown` property of the output. + * @param {boolean} [options.stopAtFirstUnknown] - If `true`, parsing will stop at the first unknown argument and the remaining arguments returned in `_unknown`. When set, `partial: true` is also implied. + * @param {boolean} [options.camelCase] - If `true`, options with hypenated names (e.g. `move-to`) will be returned in camel-case (e.g. `moveTo`). + * @param {boolean} [options.caseInsensitive] - If `true`, the case of each option name or alias parsed is insignificant. In other words, both `--Verbose` and `--verbose`, `-V` and `-v` would be equivalent. Defaults to false. + * @returns {object} + * @throws `UNKNOWN_OPTION` If `options.partial` is false and the user set an undefined option. The `err.optionName` property contains the arg that specified an unknown option, e.g. `--one`. + * @throws `UNKNOWN_VALUE` If `options.partial` is false and the user set a value unaccounted for by an option definition. The `err.value` property contains the unknown value, e.g. `5`. + * @throws `ALREADY_SET` If a user sets a singular, non-multiple option more than once. The `err.optionName` property contains the option name that has already been set, e.g. `one`. + * @throws `INVALID_DEFINITIONS` + * - If an option definition is missing the required `name` property + * - If an option definition has a `type` value that's not a function + * - If an alias is numeric, a hyphen or a length other than 1 + * - If an option definition name was used more than once + * - If an option definition alias was used more than once + * - If more than one option definition has `defaultOption: true` + * - If a `Boolean` option is also set as the `defaultOption`. + * @alias module:command-line-args + */ +function commandLineArgs (optionDefinitions, options) { + options = options || {}; + if (options.stopAtFirstUnknown) options.partial = true; + optionDefinitions = Definitions.from(optionDefinitions, options.caseInsensitive); + + const parser = new ArgvParser(optionDefinitions, { + argv: options.argv, + stopAtFirstUnknown: options.stopAtFirstUnknown, + caseInsensitive: options.caseInsensitive + }); + + const OutputClass = optionDefinitions.isGrouped() ? GroupedOutput : Output; + const output = new OutputClass(optionDefinitions); + + /* Iterate the parser setting each known value to the output. Optionally, throw on unknowns. */ + for (const argInfo of parser) { + const arg = argInfo.subArg || argInfo.arg; + if (!options.partial) { + if (argInfo.event === 'unknown_value') { + const err = new Error(`Unknown value: ${arg}`); + err.name = 'UNKNOWN_VALUE'; + err.value = arg; + throw err + } else if (argInfo.event === 'unknown_option') { + const err = new Error(`Unknown option: ${arg}`); + err.name = 'UNKNOWN_OPTION'; + err.optionName = arg; + throw err + } + } + + let option; + if (output.has(argInfo.name)) { + option = output.get(argInfo.name); + } else { + option = Option.create(argInfo.def); + output.set(argInfo.name, option); + } + + if (argInfo.name === '_unknown') { + option.set(arg); + } else { + option.set(argInfo.value); + } + } + + return output.toObject({ skipUnknown: !options.partial, camelCase: options.camelCase }) +} + +module.exports = commandLineArgs; diff --git a/package-lock.json b/package-lock.json index 6ddd790..59e1c90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,13 +15,15 @@ "typical": "^7.1.1" }, "devDependencies": { + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", "coveralls": "^3.1.1", "jsdoc-to-markdown": "^8.0.1", "rollup": "~4.18.0", "test-runner": "^0.10.1" }, "engines": { - "node": ">=4.0.0" + "node": ">=12.20" } }, "node_modules/@babel/parser": { @@ -37,6 +39,31 @@ "node": ">=6.0.0" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "license": "MIT" + }, "node_modules/@jsdoc/salty": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", @@ -50,6 +77,142 @@ "node": ">=v12.0.0" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz", + "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^10.4.1", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=16.0.0 || 14 >= 14.17" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", @@ -434,6 +597,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -589,6 +759,19 @@ "concat-map": "0.0.1" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cache-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz", @@ -836,6 +1019,13 @@ "node": ">=8" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, "node_modules/composite-class": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/composite-class/-/composite-class-2.0.1.tgz", @@ -906,6 +1096,21 @@ "node": ">=10" } }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/current-module-paths": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.1.tgz", @@ -937,6 +1142,16 @@ "node": ">=4.0.0" } }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -970,6 +1185,13 @@ "node": ">=12" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -980,6 +1202,13 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1016,6 +1245,13 @@ "node": ">=4" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -1079,6 +1315,23 @@ "node": ">=14" } }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1148,6 +1401,16 @@ "node": ">=14" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1241,6 +1504,19 @@ "node": ">=4" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -1275,18 +1551,103 @@ "dev": true, "license": "ISC" }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -1515,6 +1876,26 @@ "node": ">=0.8.6" } }, + "node_modules/lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -1611,6 +1992,16 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -1684,6 +2075,13 @@ "wrappy": "1" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1694,12 +2092,59 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -1900,6 +2345,24 @@ "lodash": "^4.17.21" } }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/rollup": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", @@ -1962,7 +2425,43 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/sort-array": { + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sort-array": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.5.tgz", "integrity": "sha512-Ya4peoS1fgFN42RN1REk2FgdNOeLIEMKFGJvs7VTP3OklF8+kl2SkpVliZ4tk/PurWsrWRsdNdU+tgyOBkB9sA==", @@ -2097,6 +2596,70 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -2113,6 +2676,30 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2139,6 +2726,19 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", @@ -2451,6 +3051,22 @@ "node": ">=12.17" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -2486,6 +3102,137 @@ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", "dev": true }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -2508,6 +3255,26 @@ "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "@jsdoc/salty": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", @@ -2517,6 +3284,86 @@ "lodash": "^4.17.21" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@rollup/plugin-commonjs": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz", + "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^10.4.1", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + } + }, + "@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, "@rollup/rollup-android-arm-eabi": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", @@ -2757,6 +3604,12 @@ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, + "@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2879,6 +3732,12 @@ "concat-map": "0.0.1" } }, + "builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true + }, "cache-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz", @@ -3072,6 +3931,12 @@ "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "composite-class": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/composite-class/-/composite-class-2.0.1.tgz", @@ -3126,6 +3991,17 @@ "integrity": "sha512-LkdMqnWT9LaqBN4huqpUnMz56Yr1mVSoCduAd2xXefgH/YZP2sXCMAyztXjk4q8hTF/TlcDa+zQW2aTgGdjjKQ==", "dev": true }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "current-module-paths": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.1.tgz", @@ -3147,6 +4023,12 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3173,6 +4055,12 @@ "walk-back": "^5.1.0" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -3183,6 +4071,12 @@ "safer-buffer": "^2.1.0" } }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, "entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -3201,6 +4095,12 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3251,6 +4151,16 @@ "array-back": "^6.2.2" } }, + "foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3297,6 +4207,12 @@ "obso": "^0.7.0" } }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3361,6 +4277,15 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3388,18 +4313,73 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "requires": { + "builtin-modules": "^3.3.0" + } + }, + "is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -3585,6 +4565,21 @@ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, + "lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "dev": true + }, + "magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -3656,6 +4651,12 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -3707,18 +4708,52 @@ "wrappy": "1" } }, + "package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -3870,6 +4905,17 @@ "lodash": "^4.17.21" } }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, "rollup": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", @@ -3908,6 +4954,27 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, "sort-array": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.5.tgz", @@ -4003,6 +5070,51 @@ "strip-ansi": "^7.0.1" } }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -4012,6 +5124,23 @@ "ansi-regex": "^6.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + } + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4027,6 +5156,12 @@ "has-flag": "^3.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", @@ -4264,6 +5399,15 @@ "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", "dev": true }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -4294,6 +5438,94 @@ } } }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + } + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 548d85e..918d705 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,11 @@ "description": "A mature, feature-complete library to parse command-line options.", "repository": "https://github.com/75lb/command-line-args", "scripts": { - "test": "test-runner test/**/*.js", + "test": "npm run dist && npm run test:ci", + "test:ci": "test-runner 'test/**/*.js' 'test/**/*.cjs'", "docs": "jsdoc2md index.js > doc/API.md && jsdoc2md lib/option-definition.js > doc/option-definition.md", "cover": "nyc --reporter=text-lcov test-runner test/*.js test/internals/*.js | coveralls", - "dist": "rollup index.mjs -f cjs -e 'lodash.camelcase' -o dist/index.js && rollup index.mjs -f esm -e 'lodash.camelcase' -o dist/index.mjs && rollup test/tests.mjs -f cjs -e 'test-runner,assert,lodash.camelcase' -o dist/tests.js" + "dist": "rollup -c" }, "type": "module", "exports": { @@ -39,6 +40,8 @@ "dist/index.mjs" ], "devDependencies": { + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", "coveralls": "^3.1.1", "jsdoc-to-markdown": "^8.0.1", "rollup": "~4.18.0", diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..b966b53 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,15 @@ +import { nodeResolve } from '@rollup/plugin-node-resolve' +import commonJs from '@rollup/plugin-commonjs' + +export default [ + { + input: 'index.js', + output: { + file: 'dist/index.cjs', + format: 'cjs', + exports: 'auto' + }, + external: [], + plugins: [nodeResolve({ preferBuiltins: true }), commonJs()] + } +] diff --git a/test/alias-cluster.js b/test/alias-cluster.js index 4a7f2d6..a4ee221 100644 --- a/test/alias-cluster.js +++ b/test/alias-cluster.js @@ -1,75 +1,51 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' const tom = new TestRunner.Tom() -tom.test('two flags, one option, nothing set', function () { - const optionDefinitions = [ - { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'recursive', alias: 'r', type: Boolean }, - { name: 'file', alias: 'f' } - ] - - const argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), {}) -}) - tom.test('two flags, one option', function () { const optionDefinitions = [ - { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'recursive', alias: 'r', type: Boolean }, - { name: 'file', alias: 'f' } + { name: 'flagA', alias: 'a', type: Boolean }, + { name: 'flagB', alias: 'b', type: Boolean }, + { name: 'three', alias: 'c' } ] - const argv = ['-vrf', 'yeah'] + const argv = ['-abc', 'yeah'] a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - verbose: true, - recursive: true, - file: 'yeah' + flagA: true, + flagB: true, + three: 'yeah' }) }) tom.test('two flags, one option 2', function () { const optionDefinitions = [ - { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'recursive', alias: 'r', type: Boolean }, - { name: 'file', alias: 'f' } + { name: 'flagA', alias: 'a', type: Boolean }, + { name: 'flagB', alias: 'b', type: Boolean }, + { name: 'three', alias: 'c' } ] - const argv = ['-f', 'yeah', '-vr'] + const argv = ['-c', 'yeah', '-ab'] a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - verbose: true, - recursive: true, - file: 'yeah' + flagA: true, + flagB: true, + three: 'yeah' }) }) tom.test('three string options', function () { const optionDefinitions = [ - { name: 'plugin', alias: 'p' }, - { name: 'depth', alias: 'd' }, - { name: 'file', alias: 'f' } + { name: 'flagA', alias: 'a' }, + { name: 'flagB', alias: 'b' }, + { name: 'three', alias: 'c' } ] - const argv = ['-pdf', 'yeah'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - /UNKNOWN_VALUE/ - ) -}) - -tom.test('three string options, partial', function () { - const optionDefinitions = [ - { name: 'plugin', alias: 'p' }, - { name: 'depth', alias: 'd' }, - { name: 'file', alias: 'f' } - ] - - const argv = ['-pdf', 'yeah'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv, partial: true }), { - plugin: 'df', - _unknown: ['yeah'] + const argv = ['-abc', 'yeah'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + flagA: null, + flagB: null, + three: 'yeah' }) }) diff --git a/test/alias-whitespace.js b/test/alias-whitespace.js deleted file mode 100644 index f787108..0000000 --- a/test/alias-whitespace.js +++ /dev/null @@ -1,51 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' -import a from 'assert' - -const tom = new TestRunner.Tom() - -tom.test('with space after option', function () { - const optionDefinitions = [ - { name: 'file', alias: 'f' } - ] - const argv = ['-f', 'one'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - file: 'one' - }) -}) - -tom.test('without space after option', function () { - const optionDefinitions = [ - { name: 'file', alias: 'f' } - ] - const argv = ['-fone'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - file: 'one' - }) -}) - -tom.test('with space after option in cluster', function () { - const optionDefinitions = [ - { name: 'file', alias: 'f' }, - { name: 'verbose', alias: 'v', type: Boolean } - ] - const argv = ['-vf', 'one'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - verbose: true, - file: 'one' - }) -}) - -tom.test('without space after option in cluster', function () { - const optionDefinitions = [ - { name: 'file', alias: 'f' }, - { name: 'verbose', alias: 'v', type: Boolean } - ] - const argv = ['-vfone'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - verbose: true, - file: 'one' - }) -}) - -export default tom diff --git a/test/alias.js b/test/alias.js index ab2742f..3a93c1c 100644 --- a/test/alias.js +++ b/test/alias.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('alias') +const tom = new TestRunner.Tom() tom.test('one string alias', function () { const optionDefinitions = [ diff --git a/test/bad-input-ambiguous.js b/test/ambiguous-input.js similarity index 57% rename from test/bad-input-ambiguous.js rename to test/ambiguous-input.js index ff9749f..4f87d94 100644 --- a/test/bad-input-ambiguous.js +++ b/test/ambiguous-input.js @@ -1,22 +1,21 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('bad-input-ambiguous') +const tom = new TestRunner.Tom() tom.test('value looks like an option 1', function () { const optionDefinitions = [ - { name: 'colour', alias: 'c' } + { name: 'colour', type: String, alias: 'c' } ] - const argv = ['-c', 'red'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['-c', 'red'] }), { colour: 'red' }) }) tom.test('value looks like an option 2', function () { const optionDefinitions = [ - { name: 'colour', alias: 'c' } + { name: 'colour', type: String, alias: 'c' } ] const argv = ['--colour', '--red'] a.throws( @@ -27,20 +26,18 @@ tom.test('value looks like an option 2', function () { tom.test('value looks like an option 3', function () { const optionDefinitions = [ - { name: 'colour', alias: 'c' } + { name: 'colour', type: String, alias: 'c' } ] - const argv = ['--colour=--red'] a.doesNotThrow(function () { - commandLineArgs(optionDefinitions, { argv }) + commandLineArgs(optionDefinitions, { argv: ['--colour=--red'] }) }) }) tom.test('value looks like an option 4', function () { const optionDefinitions = [ - { name: 'colour', alias: 'c' } + { name: 'colour', type: String, alias: 'c' } ] - const argv = ['--colour=--red'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour=--red'] }), { colour: '--red' }) }) diff --git a/test/bad-input-empty-string.js b/test/bad-input-empty-string.js deleted file mode 100644 index 8559db6..0000000 --- a/test/bad-input-empty-string.js +++ /dev/null @@ -1,61 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' -import a from 'assert' - -const tom = new TestRunner.Tom('bad-input-empty-string') - -tom.test('empty string', function () { - const optionDefinitions = [ - { name: 'one' } - ] - const argv = ['--one', ''] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - one: '' - }) -}) - -tom.test('empty string, option cluster', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o', type: Boolean }, - { name: 'two', alias: 't' } - ] - const argv = ['-ot', ''] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - one: true, - two: '' - }) -}) - -tom.test('empty string, --option=', function () { - const optionDefinitions = [ - { name: 'one' } - ] - const argv = ['--one='] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - one: '' - }) -}) - -tom.test('empty string unknown value', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean } - ] - const argv = ['--one', ''] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - /UNKNOWN_VALUE/ - ) -}) - -tom.test('empty string added to unknown values', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean } - ] - const argv = ['--one', ''] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv, partial: true }), { - one: true, - _unknown: [''] - }) -}) - -export default tom diff --git a/test/bad-input.js b/test/bad-input.js index f28cd44..2972473 100644 --- a/test/bad-input.js +++ b/test/bad-input.js @@ -1,36 +1,18 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('bad-input') - -tom.test('an unset option should not be defined', function () { - const optionDefinitions = [ - { name: 'colour' } - ] - const argv = [] - const result = commandLineArgs(optionDefinitions, { argv }) - a.strictEqual(result.colour, undefined) -}) +const tom = new TestRunner.Tom() tom.test('missing option value should be null', function () { const optionDefinitions = [ - { name: 'colour' }, + { name: 'colour', type: String }, { name: 'files' } ] - const argv = ['--colour'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour'] }), { colour: null }) -}) - -tom.test('missing option value should be null 2', function () { - const optionDefinitions = [ - { name: 'colour' }, - { name: 'files' } - ] - const argv = ['--colour', '--files', 'yeah'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour', '--files', 'yeah'] }), { colour: null, files: 'yeah' }) @@ -38,7 +20,7 @@ tom.test('missing option value should be null 2', function () { tom.test('handles arrays with relative paths', function () { const optionDefinitions = [ - { name: 'colours', multiple: true } + { name: 'colours', type: String, multiple: true } ] const argv = ['--colours', '../what', '../ever'] a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { @@ -46,6 +28,28 @@ tom.test('handles arrays with relative paths', function () { }) }) +tom.test('empty string added to unknown values', function () { + const optionDefinitions = [ + { name: 'one', type: String }, + { name: 'two', type: Number }, + { name: 'three', type: Number, multiple: true }, + { name: 'four', type: String }, + { name: 'five', type: Boolean } + ] + const argv = ['--one', '', '', '--two', '0', '--three=', '', '--four=', '--five='] + a.throws(() => { + commandLineArgs(optionDefinitions, { argv }) + }) + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv, partial: true }), { + one: '', + two: 0, + three: [0, 0], + four: '', + five: true, + _unknown: ['', '--five='] + }) +}) + tom.test('non-strings in argv', function () { const optionDefinitions = [ { name: 'one', type: Number } diff --git a/test/camel-case.js b/test/camel-case.js index 8e74240..006166c 100644 --- a/test/camel-case.js +++ b/test/camel-case.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('camel-case') +const tom = new TestRunner.Tom() tom.test('regular', function () { const optionDefinitions = [ diff --git a/test/case-insensitive.js b/test/case-insensitive.js new file mode 100644 index 0000000..78e31ba --- /dev/null +++ b/test/case-insensitive.js @@ -0,0 +1,74 @@ +import TestRunner from 'test-runner' +import commandLineArgs from 'command-line-args' +import a from 'assert' + +const tom = new TestRunner.Tom() + +tom.test('disabled', function () { + const optionDefinitions = [ + { name: 'dryRun', type: Boolean, alias: 'd' }] + + a.throws( + () => commandLineArgs(optionDefinitions, { argv: ['--DRYrun'] }), + err => err.name === 'UNKNOWN_OPTION' && err.optionName === '--DRYrun' + ) + a.throws( + () => commandLineArgs(optionDefinitions, { argv: ['-D'] }), + err => err.name === 'UNKNOWN_OPTION' && err.optionName === '-D' + ) +}) + +tom.test('option no value', function () { + const optionDefinitions = [ + { name: 'dryRun', type: Boolean }] + const argv = ['--DRYrun'] + const result = commandLineArgs(optionDefinitions, { argv, caseInsensitive: true }) + a.deepStrictEqual(result, { + dryRun: true + }) +}) + +tom.test('option with value', function () { + const optionDefinitions = [ + { name: 'colour', type: String } + ] + const argv = ['--coLour', 'red'] + const result = commandLineArgs(optionDefinitions, { argv, caseInsensitive: true }) + a.deepStrictEqual(result, { + colour: 'red' + }) +}) + +tom.test('alias', function () { + const optionDefinitions = [ + { name: 'dryRun', type: Boolean, alias: 'd' }] + const argv = ['-D'] + const result = commandLineArgs(optionDefinitions, { argv, caseInsensitive: true }) + a.deepStrictEqual(result, { + dryRun: true + }) +}) + +tom.test('multiple', function () { + const optionDefinitions = [ + { name: 'colour', type: String, multiple: true } + ] + const argv = ['--colour=red', '--COLOUR', 'green', '--colOUR', 'blue'] + const result = commandLineArgs(optionDefinitions, { argv, caseInsensitive: true }) + a.deepStrictEqual(result, { + colour: ['red', 'green', 'blue'] + }) +}) + +tom.test('camelCase', function () { + const optionDefinitions = [ + { name: 'dry-run', type: Boolean } + ] + const argv = ['--dry-RUN'] + const result = commandLineArgs(optionDefinitions, { argv, camelCase: true, caseInsensitive: true }) + a.deepStrictEqual(result, { + dryRun: true + }) +}) + +export default tom diff --git a/test/common-js.cjs b/test/common-js.cjs new file mode 100644 index 0000000..5004c0a --- /dev/null +++ b/test/common-js.cjs @@ -0,0 +1,25 @@ +const TestRunner = require('test-runner') +const commandLineArgs = require('command-line-args') +const a = require('assert') + +const tom = new TestRunner.Tom() + +tom.test('CommonJS build works correctly', function () { + const optionDefinitions = [ + { name: 'one', type: String } + ] + a.deepStrictEqual( + commandLineArgs(optionDefinitions, { argv: ['--one', 'yeah'] }), + { one: 'yeah' } + ) + a.deepStrictEqual( + commandLineArgs(optionDefinitions, { argv: ['--one'] }), + { one: null } + ) + a.deepStrictEqual( + commandLineArgs(optionDefinitions, { argv: ['--one', '3'] }), + { one: '3' } + ) +}) + +module.exports = tom diff --git a/test/default-option-multiple.js b/test/default-option-multiple.js deleted file mode 100644 index 83307e6..0000000 --- a/test/default-option-multiple.js +++ /dev/null @@ -1,60 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' -import a from 'assert' - -const tom = new TestRunner.Tom('default-option-multiple') - -tom.test('multiple string', function () { - const optionDefinitions = [ - { name: 'files', defaultOption: true, multiple: true } - ] - const argv = ['file1', 'file2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - files: ['file1', 'file2'] - }) -}) - -tom.test('multiple-defaultOption values spread out', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' }, - { name: 'files', defaultOption: true, multiple: true } - ] - const argv = ['--one', '1', 'file1', 'file2', '--two', '2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - one: '1', - two: '2', - files: ['file1', 'file2'] - }) -}) - -tom.test('multiple-defaultOption values spread out 2', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean }, - { name: 'two' }, - { name: 'files', defaultOption: true, multiple: true } - ] - const argv = ['file0', '--one', 'file1', '--files', 'file2', '--two', '2', 'file3'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - one: true, - two: '2', - files: ['file0', 'file1', 'file2', 'file3'] - }) -}) - -tom.test('multiple with --option=value', function () { - const definitions = [ - { name: 'files', defaultOption: true, multiple: true }, - { name: 'one', type: Boolean }, - { name: 'two', alias: 't', defaultValue: 2 } - ] - const argv = ['file1', '--one', 'file2', '-t', '--two=3', 'file3'] - const options = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(options, { - files: ['file1', 'file2', 'file3'], - two: '3', - one: true - }) -}) - -export default tom diff --git a/test/default-option-single.js b/test/default-option-single.js deleted file mode 100644 index e29982c..0000000 --- a/test/default-option-single.js +++ /dev/null @@ -1,51 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' -import a from 'assert' - -const tom = new TestRunner.Tom('default-option-single') - -tom.test('after a boolean', function () { - const definitions = [ - { name: 'one', type: Boolean }, - { name: 'two', defaultOption: true } - ] - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['--one', 'sfsgf'] }), - { one: true, two: 'sfsgf' } - ) -}) - -tom.test('value equal to defaultValue', function () { - const definitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['file1'] - const options = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(options, { - file: 'file1' - }) -}) - -tom.test('string value can be set by argv only once', function () { - const definitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['--file', '--file=file2'] - const options = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(options, { - file: 'file2' - }) -}) - -tom.test('string value cannot be set by argv twice', function () { - const definitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['--file', '--file=file2', 'file3'] - a.throws( - () => commandLineArgs(definitions, { argv }), - /UNKNOWN_VALUE/ - ) -}) - -export default tom diff --git a/test/default-option.js b/test/default-option.js index a486b60..b96eaa7 100644 --- a/test/default-option.js +++ b/test/default-option.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('default-option') +const tom = new TestRunner.Tom() tom.test('multiple string', function () { const optionDefinitions = [ @@ -14,6 +14,17 @@ tom.test('multiple string', function () { }) }) +tom.test('after a boolean', function () { + const definitions = [ + { name: 'one', type: Boolean }, + { name: 'two', defaultOption: true } + ] + a.deepStrictEqual( + commandLineArgs(definitions, { argv: ['--one', 'sfsgf'] }), + { one: true, two: 'sfsgf' } + ) +}) + tom.test('multiple-defaultOption values spread out', function () { const optionDefinitions = [ { name: 'one' }, @@ -28,6 +39,20 @@ tom.test('multiple-defaultOption values spread out', function () { }) }) +tom.test('can be false', function () { + const optionDefinitions = [ + { name: 'one', defaultOption: false }, + { name: 'two', defaultOption: false }, + { name: 'files', defaultOption: true, multiple: true } + ] + const argv = ['--one', '1', 'file1', 'file2', '--two', '2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + one: '1', + two: '2', + files: ['file1', 'file2'] + }) +}) + tom.test('multiple-defaultOption values spread out 2', function () { const optionDefinitions = [ { name: 'one', type: Boolean }, @@ -42,19 +67,4 @@ tom.test('multiple-defaultOption values spread out 2', function () { }) }) -tom.test('multiple with --option=value', function () { - const definitions = [ - { name: 'files', defaultOption: true, multiple: true }, - { name: 'one', type: Boolean }, - { name: 'two', alias: 't', defaultValue: 2 } - ] - const argv = ['file1', '--one', 'file2', '-t', '--two=3', 'file3'] - const options = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(options, { - files: ['file1', 'file2', 'file3'], - two: '3', - one: true - }) -}) - export default tom diff --git a/test/default-value.js b/test/default-value.js index d3c8334..2ecdb18 100644 --- a/test/default-value.js +++ b/test/default-value.js @@ -1,159 +1,153 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('default-value') +const tom = new TestRunner.Tom() tom.test('default value', function () { - const optionDefinitions = [ + const defs = [ { name: 'one' }, { name: 'two', defaultValue: 'two' } ] const argv = ['--one', '1'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { one: '1', two: 'two' }) }) tom.test('default value 2', function () { - const optionDefinitions = [ - { name: 'two', defaultValue: 'two' } - ] + const defs = [{ name: 'two', defaultValue: 'two' }] const argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: 'two' }) + a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: 'two' }) }) tom.test('default value 3', function () { - const optionDefinitions = [ - { name: 'two', defaultValue: 'two' } - ] + const defs = [{ name: 'two', defaultValue: 'two' }] const argv = ['--two', 'zwei'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: 'zwei' }) + a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: 'zwei' }) }) tom.test('default value 4', function () { - const optionDefinitions = [ - { name: 'two', multiple: true, defaultValue: ['two', 'zwei'] } - ] + const defs = [{ name: 'two', multiple: true, defaultValue: ['two', 'zwei'] }] const argv = ['--two', 'duo'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: ['duo'] }) + a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: ['duo'] }) }) tom.test('default value 5', function () { - const optionDefinitions = [ + const defs = [ { name: 'two', multiple: true, defaultValue: ['two', 'zwei'] } ] const argv = [] - const result = commandLineArgs(optionDefinitions, { argv }) + const result = commandLineArgs(defs, { argv }) a.deepStrictEqual(result, { two: ['two', 'zwei'] }) }) -tom.test('array as defaultOption', function () { - const optionDefinitions = [ +tom.test('default value: array as defaultOption', function () { + const defs = [ { name: 'two', multiple: true, defaultValue: ['two', 'zwei'], defaultOption: true } ] const argv = ['duo'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: ['duo'] }) + a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: ['duo'] }) }) -tom.test('falsy default values', function () { - const optionDefinitions = [ +tom.test('default value: falsy default values', function () { + const defs = [ { name: 'one', defaultValue: 0 }, { name: 'two', defaultValue: false } ] const argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { one: 0, two: false }) }) -tom.test('is arrayifed if multiple set', function () { - const optionDefinitions = [ +tom.test('default value: is arrayifed if multiple set', function () { + const defs = [ { name: 'one', defaultValue: 0, multiple: true } ] let argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { one: [0] }) argv = ['--one', '2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { one: ['2'] }) }) -tom.test('combined with defaultOption', function () { - const optionDefinitions = [ +tom.test('default value: combined with defaultOption', function () { + const defs = [ { name: 'path', defaultOption: true, defaultValue: './' } ] let argv = ['--path', 'test'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: 'test' }) argv = ['test'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: 'test' }) argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: './' }) }) -tom.test('combined with multiple and defaultOption', function () { - const optionDefinitions = [ +tom.test('default value: combined with multiple and defaultOption', function () { + const defs = [ { name: 'path', multiple: true, defaultOption: true, defaultValue: './' } ] let argv = ['--path', 'test1', 'test2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test1', 'test2'] }) argv = ['--path', 'test'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test'] }) argv = ['test1', 'test2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test1', 'test2'] }) argv = ['test'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test'] }) argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['./'] }) }) -tom.test('array default combined with multiple and defaultOption', function () { - const optionDefinitions = [ +tom.test('default value: array default combined with multiple and defaultOption', function () { + const defs = [ { name: 'path', multiple: true, defaultOption: true, defaultValue: ['./'] } ] let argv = ['--path', 'test1', 'test2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test1', 'test2'] }) argv = ['--path', 'test'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test'] }) argv = ['test1', 'test2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test1', 'test2'] }) argv = ['test'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['test'] }) argv = [] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + a.deepStrictEqual(commandLineArgs(defs, { argv }), { path: ['./'] }) }) diff --git a/test/detect-process-argv.js b/test/detect-process-argv.js index 69eebe7..34b1500 100644 --- a/test/detect-process-argv.js +++ b/test/detect-process-argv.js @@ -1,35 +1,26 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('detect-process-argv') +const tom = new TestRunner.Tom() tom.test('should automatically remove first two argv items', function () { - const optionDefinitions = [ - { name: 'one' } - ] process.argv = ['node', 'filename', '--one', 'eins'] - a.deepStrictEqual(commandLineArgs(optionDefinitions), { + a.deepStrictEqual(commandLineArgs({ name: 'one' }), { one: 'eins' }) }) tom.test('should automatically remove first two argv items 2', function () { - const optionDefinitions = [ - { name: 'one' } - ] process.argv = ['node', 'filename', '--one', 'eins'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: process.argv }), { + a.deepStrictEqual(commandLineArgs({ name: 'one' }, { argv: process.argv }), { one: 'eins' }) }) tom.test('process.argv is left untouched', function () { - const optionDefinitions = [ - { name: 'one' } - ] process.argv = ['node', 'filename', '--one', 'eins'] - a.deepStrictEqual(commandLineArgs(optionDefinitions), { + a.deepStrictEqual(commandLineArgs({ name: 'one' }), { one: 'eins' }) a.deepStrictEqual(process.argv, ['node', 'filename', '--one', 'eins']) diff --git a/test/detect-process-execArgv.js b/test/detect-process-execArgv.js index 5271d46..1ca137d 100644 --- a/test/detect-process-execArgv.js +++ b/test/detect-process-execArgv.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('detect-process-execArgv') +const tom = new TestRunner.Tom() tom.test('should automatically remove first argv items', function () { const origArgv = process.argv diff --git a/test/exceptions-already-set.js b/test/exceptions-already-set.js index 1230c65..3c7ec04 100644 --- a/test/exceptions-already-set.js +++ b/test/exceptions-already-set.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('exceptions-already-set') +const tom = new TestRunner.Tom() tom.test('long option', function () { const optionDefinitions = [ @@ -48,26 +48,4 @@ tom.test('combined short option', function () { ) }) -tom.test('alias then long', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' } - ] - const argv = ['-o', '1', '--one', '1'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'ALREADY_SET' && err.optionName === 'one' - ) -}) - -tom.test('alias then --option=value', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' } - ] - const argv = ['-o', '1', '--one=1'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'ALREADY_SET' && err.optionName === 'one' - ) -}) - export default tom diff --git a/test/exceptions-invalid-definition.js b/test/exceptions-invalid-definition.js index e857767..dedec8a 100644 --- a/test/exceptions-invalid-definition.js +++ b/test/exceptions-invalid-definition.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('exceptions-invalid-definition') +const tom = new TestRunner.Tom() tom.test('throws when no definition.name specified', function () { const optionDefinitions = [ @@ -94,6 +94,30 @@ tom.test('duplicate name', function () { ) }) +tom.test('duplicate name caused by case insensitivity', function () { + const optionDefinitions = [ + { name: 'colours' }, + { name: 'coloURS' } + ] + const argv = ['--colours', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv, caseInsensitive: true }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('case sensitive names in different case', function () { + const optionDefinitions = [ + { name: 'colours' }, + { name: 'coloURS' } + ] + const argv = ['--colours', 'red', '--coloURS', 'green'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + colours: 'red', + coloURS: 'green' + }) +}) + tom.test('duplicate alias', function () { const optionDefinitions = [ { name: 'one', alias: 'a' }, @@ -106,6 +130,29 @@ tom.test('duplicate alias', function () { ) }) +tom.test('duplicate alias caused by case insensitivity', function () { + const optionDefinitions = [ + { name: 'one', alias: 'a' }, + { name: 'two', alias: 'A' } + ] + const argv = ['-a', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv, caseInsensitive: true }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('case sensitive aliases in different case', function () { + const optionDefinitions = [ + { name: 'one', alias: 'a' }, + { name: 'two', alias: 'A' } + ] + const argv = ['-a', 'red'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + one: 'red' + }) +}) + tom.test('multiple defaultOption', function () { const optionDefinitions = [ { name: 'one', defaultOption: true }, @@ -118,7 +165,21 @@ tom.test('multiple defaultOption', function () { ) }) -tom.test('err-invalid-defaultOption: defaultOption on a Boolean type', function () { +tom.test('multiple defaultOptions 2', function () { + const optionDefinitions = [ + { name: 'one', defaultOption: undefined }, + { name: 'two', defaultOption: false }, + { name: 'files', defaultOption: true, multiple: true }, + { name: 'files2', defaultOption: true } + ] + const argv = ['--one', '1', 'file1', 'file2', '--two', '2'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('defaultOption on a Boolean type', function () { const optionDefinitions = [ { name: 'one', type: Boolean, defaultOption: true } ] diff --git a/test/exceptions-unknowns.js b/test/exceptions-unknowns.js index 93ea0ef..cacada4 100644 --- a/test/exceptions-unknowns.js +++ b/test/exceptions-unknowns.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('exceptions-unknowns') +const tom = new TestRunner.Tom() tom.test('unknown option', function () { const optionDefinitions = [ @@ -38,9 +38,8 @@ tom.test('unknown combined aliases', function () { const optionDefinitions = [ { name: 'one', type: Number } ] - const argv = ['-sdf'] a.throws( - () => commandLineArgs(optionDefinitions, { argv }), + () => commandLineArgs(optionDefinitions, { argv: ['-sdf'] }), err => err.name === 'UNKNOWN_OPTION' && err.optionName === '-s' ) }) diff --git a/test/output-grouping.js b/test/grouping.js similarity index 97% rename from test/output-grouping.js rename to test/grouping.js index 9698b0d..1a42820 100644 --- a/test/output-grouping.js +++ b/test/grouping.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('output-grouping') +const tom = new TestRunner.Tom() tom.test('groups', function () { const definitions = [ diff --git a/test/internals/argv-parser.js b/test/internals/argv-parser.js index efebd6f..ab18705 100644 --- a/test/internals/argv-parser.js +++ b/test/internals/argv-parser.js @@ -2,7 +2,7 @@ import TestRunner from 'test-runner' import a from 'assert' import ArgvParser from '../../lib/argv-parser.js' -const tom = new TestRunner.Tom('argv-parser') +const tom = new TestRunner.Tom() tom.test('long option, string', function () { const optionDefinitions = [ @@ -365,49 +365,4 @@ tom.test('combined short option, one unknown', function () { ]) }) -tom.skip('expandCluster, no whitespace value', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' } - ] - const argv = ['-oone'] - const parser = new ArgvParser(optionDefinitions, { argv }) - a.strictEqual(parser.argv.length, 2) - a.deepStrictEqual(parser.argv[0], { origArg: '-oone', arg: '-o' }) - a.deepStrictEqual(parser.argv[1], { origArg: '-oone', arg: 'one' }) -}) - -tom.test('expandCluster, flags', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o', type: Boolean }, - { name: 'two', alias: 't', type: Boolean } - ] - const argv = ['-ot'] - const parser = new ArgvParser(optionDefinitions, { argv }) - a.strictEqual(parser.argv.length, 2) - a.deepStrictEqual(parser.argv[0], { origArg: '-ot', arg: '-o' }) - a.deepStrictEqual(parser.argv[1], { origArg: '-ot', arg: '-t' }) -}) - -tom.test('expandCluster, mix', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o', type: Boolean }, - { name: 'two', alias: 't' } - ] - const argv = ['-ot'] - const parser = new ArgvParser(optionDefinitions, { argv }) - a.strictEqual(parser.argv.length, 2) - a.deepStrictEqual(parser.argv[0], { origArg: '-ot', arg: '-o' }) - a.deepStrictEqual(parser.argv[1], { origArg: '-ot', arg: '-t' }) -}) - -tom.test('expand a cluster of short options with no definition', function () { - const optionDefinitions = [] - const argv = ['-abc'] - const parser = new ArgvParser(optionDefinitions, { argv }) - a.strictEqual(parser.argv.length, 3) - a.deepStrictEqual(parser.argv[0], { origArg: '-abc', arg: '-a' }) - a.deepStrictEqual(parser.argv[1], { origArg: '-abc', arg: '-b' }) - a.deepStrictEqual(parser.argv[2], { origArg: '-abc', arg: '-c' }) -}) - export default tom diff --git a/test/internals/option-default.js b/test/internals/option-default.js index 82b3ea5..ca84624 100644 --- a/test/internals/option-default.js +++ b/test/internals/option-default.js @@ -2,7 +2,7 @@ import TestRunner from 'test-runner' import a from 'assert' import Option from '../../lib/option.js' -const tom = new TestRunner.Tom('option-default') +const tom = new TestRunner.Tom() tom.test('defaultValue', function () { const option = new Option({ name: 'two', defaultValue: 'two' }) diff --git a/test/internals/option-definitions.js b/test/internals/option-definitions.js index b8939bf..bdb1186 100644 --- a/test/internals/option-definitions.js +++ b/test/internals/option-definitions.js @@ -2,7 +2,7 @@ import TestRunner from 'test-runner' import a from 'assert' import Definitions from '../../lib/option-definitions.js' -const tom = new TestRunner.Tom('option-definitions') +const tom = new TestRunner.Tom() tom.test('.get(long option)', function () { const definitions = Definitions.from([{ name: 'one' }]) diff --git a/test/internals/option-flag.js b/test/internals/option-flag.js index 23bf6ed..db6e29f 100644 --- a/test/internals/option-flag.js +++ b/test/internals/option-flag.js @@ -2,23 +2,23 @@ import TestRunner from 'test-runner' import a from 'assert' import FlagOption from '../../lib/option-flag.js' -const tom = new TestRunner.Tom('option-flag') +const tom = new TestRunner.Tom() -tom.test('type-boolean: single set', function () { +tom.test('single set', function () { const option = new FlagOption({ name: 'one', type: Boolean }) option.set(undefined) a.strictEqual(option.get(), true) }) -tom.test('type-boolean: single set 2', function () { +tom.test('single set 2', function () { const option = new FlagOption({ name: 'one', type: Boolean }) option.set('true') a.strictEqual(option.get(), true) }) -tom.test('type-boolean: set twice', function () { +tom.test('set twice', function () { const option = new FlagOption({ name: 'one', type: Boolean }) option.set(undefined) @@ -32,7 +32,7 @@ tom.test('type-boolean: set twice', function () { const origBoolean = Boolean /* test in contexts which override the standard global Boolean constructor */ -tom.test('type-boolean: global Boolean overridden', function () { +tom.test('global Boolean overridden', function () { function Boolean () { return origBoolean.apply(origBoolean, arguments) } diff --git a/test/internals/option.js b/test/internals/option.js index 017f251..b9442e5 100644 --- a/test/internals/option.js +++ b/test/internals/option.js @@ -2,7 +2,7 @@ import TestRunner from 'test-runner' import a from 'assert' import Option from '../../lib/option.js' -const tom = new TestRunner.Tom('option') +const tom = new TestRunner.Tom() tom.test('simple set string', function () { const option = Option.create({ name: 'two' }) @@ -60,7 +60,7 @@ tom.test('string multiple', function () { a.strictEqual(option.state, 'set') }) -tom.test('lazyMultiple', function () { +tom.test('option.set: lazyMultiple', function () { const option = Option.create({ name: 'one', lazyMultiple: true }) a.deepStrictEqual(option.get(), []) a.strictEqual(option.state, 'default') diff --git a/test/internals/output.js b/test/internals/output.js index c22d133..19842d7 100644 --- a/test/internals/output.js +++ b/test/internals/output.js @@ -3,16 +3,16 @@ import a from 'assert' import Output from '../../lib/output.js' import Option from '../../lib/option.js' -const tom = new TestRunner.Tom('output') +const tom = new TestRunner.Tom() -tom.test('output.toObject(): no defs set', function () { +tom.test('no defs set', function () { const output = new Output([ { name: 'one' } ]) a.deepStrictEqual(output.toObject(), {}) }) -tom.test('output.toObject(): one def set', function () { +tom.test('one def set', function () { const output = new Output([ { name: 'one' } ]) diff --git a/test/multiple-lazy.js b/test/multiple-lazy.js index e73c690..2eda6e2 100644 --- a/test/multiple-lazy.js +++ b/test/multiple-lazy.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('multiple-lazy') +const tom = new TestRunner.Tom() tom.test('string', function () { const argv = ['--one', 'a', '--one', 'b', '--one', 'd'] diff --git a/test/multiple.js b/test/multiple.js index 26d7437..aac7b51 100644 --- a/test/multiple.js +++ b/test/multiple.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('multiple') +const tom = new TestRunner.Tom() tom.test('empty argv', function () { const optionDefinitions = [ diff --git a/test/name-alias-mix.js b/test/name-alias-mix.js new file mode 100644 index 0000000..c5386cd --- /dev/null +++ b/test/name-alias-mix.js @@ -0,0 +1,22 @@ +import TestRunner from 'test-runner' +import commandLineArgs from 'command-line-args' +import a from 'assert' + +const tom = new TestRunner.Tom() + +tom.test('one of each', function () { + const optionDefinitions = [ + { name: 'one', alias: 'o' }, + { name: 'two', alias: 't' }, + { name: 'three', alias: 'h' }, + { name: 'four', alias: 'f' } + ] + const argv = ['--one', '-t', '--three'] + const result = commandLineArgs(optionDefinitions, { argv }) + a.strictEqual(result.one, null) + a.strictEqual(result.two, null) + a.strictEqual(result.three, null) + a.strictEqual(result.four, undefined) +}) + +export default tom diff --git a/test/name-unicode.js b/test/name-unicode.js new file mode 100644 index 0000000..7fad0f2 --- /dev/null +++ b/test/name-unicode.js @@ -0,0 +1,20 @@ +import TestRunner from 'test-runner' +import commandLineArgs from 'command-line-args' +import a from 'assert' + +const tom = new TestRunner.Tom() + +tom.test('unicode names and aliases are permitted', function () { + const optionDefinitions = [ + { name: 'один' }, + { name: '两' }, + { name: 'три', alias: 'т' } + ] + const argv = ['--один', '1', '--两', '2', '-т', '3'] + const result = commandLineArgs(optionDefinitions, { argv }) + a.strictEqual(result.один, '1') + a.strictEqual(result.两, '2') + a.strictEqual(result.три, '3') +}) + +export default tom diff --git a/test/name.js b/test/name.js deleted file mode 100644 index cfd1afb..0000000 --- a/test/name.js +++ /dev/null @@ -1,35 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' -import a from 'assert' - -const tom = new TestRunner.Tom('name') - -tom.test('name-unicode: unicode names and aliases are permitted', function () { - const optionDefinitions = [ - { name: 'один' }, - { name: '两' }, - { name: 'три', alias: 'т' } - ] - const argv = ['--один', '1', '--两', '2', '-т', '3'] - const result = commandLineArgs(optionDefinitions, { argv }) - a.strictEqual(result.один, '1') - a.strictEqual(result.两, '2') - a.strictEqual(result.три, '3') -}) - -tom.test('name-alias-mix: one of each', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' }, - { name: 'three', alias: 'h' }, - { name: 'four', alias: 'f' } - ] - const argv = ['--one', '-t', '--three'] - const result = commandLineArgs(optionDefinitions, { argv }) - a.strictEqual(result.one, null) - a.strictEqual(result.two, null) - a.strictEqual(result.three, null) - a.strictEqual(result.four, undefined) -}) - -export default tom diff --git a/test/option-value-notation.js b/test/option=value-notation.js similarity index 91% rename from test/option-value-notation.js rename to test/option=value-notation.js index b41586f..db6b16c 100644 --- a/test/option-value-notation.js +++ b/test/option=value-notation.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('option=value-notation') +const tom = new TestRunner.Tom() tom.test('two plus a regular notation', function () { const optionDefinitions = [ diff --git a/test/output-camel-case.js b/test/output-camel-case.js deleted file mode 100644 index 609de3f..0000000 --- a/test/output-camel-case.js +++ /dev/null @@ -1,79 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' -import a from 'assert' - -const tom = new TestRunner.Tom('output-camel-case') - -tom.test('regular', function () { - const optionDefinitions = [ - { name: 'one-two' }, - { name: 'three', type: Boolean } - ] - const argv = ['--one-two', '1', '--three'] - const result = commandLineArgs(optionDefinitions, { argv, camelCase: true }) - a.deepStrictEqual(result, { - oneTwo: '1', - three: true - }) -}) - -tom.test('grouped', function () { - const optionDefinitions = [ - { name: 'one-one', group: 'a' }, - { name: 'two-two', group: 'a' }, - { name: 'three-three', group: 'b', type: Boolean }, - { name: 'four-four' } - ] - const argv = ['--one-one', '1', '--two-two', '2', '--three-three', '--four-four', '4'] - const result = commandLineArgs(optionDefinitions, { argv, camelCase: true }) - a.deepStrictEqual(result, { - a: { - oneOne: '1', - twoTwo: '2' - }, - b: { - threeThree: true - }, - _all: { - oneOne: '1', - twoTwo: '2', - threeThree: true, - fourFour: '4' - }, - _none: { - fourFour: '4' - } - }) -}) - -tom.test('grouped with unknowns', function () { - const optionDefinitions = [ - { name: 'one-one', group: 'a' }, - { name: 'two-two', group: 'a' }, - { name: 'three-three', group: 'b', type: Boolean }, - { name: 'four-four' } - ] - const argv = ['--one-one', '1', '--two-two', '2', '--three-three', '--four-four', '4', '--five'] - const result = commandLineArgs(optionDefinitions, { argv, camelCase: true, partial: true }) - a.deepStrictEqual(result, { - a: { - oneOne: '1', - twoTwo: '2' - }, - b: { - threeThree: true - }, - _all: { - oneOne: '1', - twoTwo: '2', - threeThree: true, - fourFour: '4' - }, - _none: { - fourFour: '4' - }, - _unknown: ['--five'] - }) -}) - -export default tom diff --git a/test/partial.js b/test/partial.js index 17e48ec..24375dc 100644 --- a/test/partial.js +++ b/test/partial.js @@ -1,15 +1,15 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('partial') +const tom = new TestRunner.Tom() tom.test('simple', function () { - const optionDefinitions = [ + const definitions = [ { name: 'one', type: Boolean } ] const argv = ['--two', 'two', '--one', 'two'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { one: true, _unknown: ['--two', 'two', 'two'] @@ -17,11 +17,11 @@ tom.test('simple', function () { }) tom.test('defaultOption', function () { - const optionDefinitions = [ - { name: 'files', defaultOption: true, multiple: true } + const definitions = [ + { name: 'files', type: String, defaultOption: true, multiple: true } ] const argv = ['--files', 'file1', '--one', 'file2'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { files: ['file1', 'file2'], _unknown: ['--one'] @@ -29,12 +29,11 @@ tom.test('defaultOption', function () { }) tom.test('defaultOption: floating args present but no defaultOption', function () { - const optionDefinitions = [ + const definitions = [ { name: 'one', type: Boolean } ] - const argv = ['aaa', '--one', 'aaa', 'aaa'] a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv, partial: true }), + commandLineArgs(definitions, { argv: ['aaa', '--one', 'aaa', 'aaa'], partial: true }), { one: true, _unknown: ['aaa', 'aaa', 'aaa'] @@ -43,42 +42,38 @@ tom.test('defaultOption: floating args present but no defaultOption', function ( }) tom.test('combined short option, both unknown', function () { - const optionDefinitions = [ + const definitions = [ { name: 'one', alias: 'o' }, { name: 'two', alias: 't' } ] const argv = ['-ab'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) - /* could also have meant - _unknown: [ '-a', 'b' ] - but better to leave untouched as - _unknown: [ '-ab' ] - */ + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { _unknown: ['-a', '-b'] }) }) tom.test('combined short option, one known, one unknown', function () { - const optionDefinitions = [ + const definitions = [ { name: 'one', alias: 'o' }, { name: 'two', alias: 't' } ] const argv = ['-ob'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { - one: 'b' + one: null, + _unknown: ['-b'] }) }) tom.test('defaultOption with --option=value and combined short options', function () { - const optionDefinitions = [ - { name: 'files', defaultOption: true, multiple: true }, + const definitions = [ + { name: 'files', type: String, defaultOption: true, multiple: true }, { name: 'one', type: Boolean }, { name: 'two', alias: 't', defaultValue: 2 } ] const argv = ['file1', '--one', 'file2', '-t', '--two=3', 'file3', '-ab'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { files: ['file1', 'file2', 'file3'], two: '3', @@ -88,11 +83,11 @@ tom.test('defaultOption with --option=value and combined short options', functio }) tom.test('defaultOption with value equal to defaultValue', function () { - const optionDefinitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } + const definitions = [ + { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } ] const argv = ['file1', '--two=3', '--four', '5'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { file: 'file1', _unknown: ['--two=3', '--four', '5'] @@ -100,11 +95,11 @@ tom.test('defaultOption with value equal to defaultValue', function () { }) tom.test('string defaultOption can be set by argv once', function () { - const optionDefinitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } + const definitions = [ + { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } ] const argv = ['--file', '--file=file2', '--two=3', '--four', '5'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { file: 'file2', _unknown: ['--two=3', '--four', '5'] @@ -112,11 +107,11 @@ tom.test('string defaultOption can be set by argv once', function () { }) tom.test('string defaultOption can not be set by argv twice', function () { - const optionDefinitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } + const definitions = [ + { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } ] const argv = ['--file', '--file=file2', '--two=3', '--four', '5', 'file3'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { file: 'file2', _unknown: ['--two=3', '--four', '5', 'file3'] @@ -124,11 +119,11 @@ tom.test('string defaultOption can not be set by argv twice', function () { }) tom.test('defaultOption with value equal to defaultValue 3', function () { - const optionDefinitions = [ - { name: 'file', defaultOption: true, defaultValue: 'file1' } + const definitions = [ + { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } ] const argv = ['file1', 'file2', '--two=3', '--four', '5'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { file: 'file1', _unknown: ['file2', '--two=3', '--four', '5'] @@ -136,11 +131,11 @@ tom.test('defaultOption with value equal to defaultValue 3', function () { }) tom.test('multiple', function () { - const optionDefinitions = [ - { name: 'files', multiple: true } + const definitions = [ + { name: 'files', type: String, multiple: true } ] const argv = ['file1', '--files', 'file2', '-t', '--two=3', 'file3', '-ab', '--files=file4'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { files: ['file2', 'file4'], _unknown: ['file1', '-t', '--two=3', 'file3', '-a', '-b'] @@ -148,13 +143,13 @@ tom.test('multiple', function () { }) tom.test('unknown options: rejected defaultOption values end up in _unknown', function () { - const optionDefinitions = [ - { name: 'foo' }, + const definitions = [ + { name: 'foo', type: String }, { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'libs', defaultOption: true } + { name: 'libs', type: String, defaultOption: true } ] const argv = ['--foo', 'bar', '-v', 'libfn', '--libarg', 'val1', '-r'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { foo: 'bar', verbose: true, @@ -164,11 +159,11 @@ tom.test('unknown options: rejected defaultOption values end up in _unknown', fu }) tom.test('defaultOption with --option=value notation', function () { - const optionDefinitions = [ - { name: 'files', multiple: true, defaultOption: true } + const definitions = [ + { name: 'files', type: String, multiple: true, defaultOption: true } ] const argv = ['file1', 'file2', '--unknown=something'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { files: ['file1', 'file2'], _unknown: ['--unknown=something'] @@ -176,11 +171,11 @@ tom.test('defaultOption with --option=value notation', function () { }) tom.test('defaultOption with --option=value notation 2', function () { - const optionDefinitions = [ - { name: 'files', multiple: true, defaultOption: true } + const definitions = [ + { name: 'files', type: String, multiple: true, defaultOption: true } ] const argv = ['file1', 'file2', '--unknown=something', '--files', 'file3', '--files=file4'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { files: ['file1', 'file2', 'file3', 'file4'], _unknown: ['--unknown=something'] @@ -188,11 +183,11 @@ tom.test('defaultOption with --option=value notation 2', function () { }) tom.test('defaultOption with --option=value notation 3', function () { - const optionDefinitions = [ - { name: 'files', multiple: true, defaultOption: true } + const definitions = [ + { name: 'files', type: String, multiple: true, defaultOption: true } ] const argv = ['--unknown', 'file1', '--another', 'something', 'file2', '--unknown=something', '--files', 'file3', '--files=file4'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { files: ['file1', 'something', 'file2', 'file3', 'file4'], _unknown: ['--unknown', '--another', '--unknown=something'] @@ -200,11 +195,11 @@ tom.test('defaultOption with --option=value notation 3', function () { }) tom.test('mulitple unknowns with same name', function () { - const optionDefinitions = [ + const definitions = [ { name: 'file' } ] const argv = ['--unknown', '--unknown=something', '--file=file1', '--unknown'] - const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + const options = commandLineArgs(definitions, { argv, partial: true }) a.deepStrictEqual(options, { file: 'file1', _unknown: ['--unknown', '--unknown=something', '--unknown'] diff --git a/test/stop-at-first-unknown.js b/test/stop-at-first-unknown.js index db8cdcc..4375486 100644 --- a/test/stop-at-first-unknown.js +++ b/test/stop-at-first-unknown.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('stop-at-first-unknown') +const tom = new TestRunner.Tom() -tom.test('simple', function () { +tom.test('stopAtFirstUnknown', function () { const optionDefinitions = [ { name: 'one', type: Boolean }, { name: 'two', type: Boolean } diff --git a/test/type-boolean.js b/test/type-boolean.js index 1fadc49..8aa0f19 100644 --- a/test/type-boolean.js +++ b/test/type-boolean.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('type-boolean') +const tom = new TestRunner.Tom() -tom.test('simple', function () { +tom.test('type-boolean: simple', function () { const optionDefinitions = [ { name: 'one', type: Boolean } ] @@ -18,16 +18,17 @@ tom.test('simple', function () { const origBoolean = Boolean /* test in contexts which override the standard global Boolean constructor */ -tom.test('global Boolean overridden', function () { +tom.test('type-boolean: global Boolean overridden', function () { function Boolean () { return origBoolean.apply(origBoolean, arguments) } + const optionDefinitions = [ { name: 'one', type: Boolean } ] - const argv = ['--one'] + a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv }), + commandLineArgs(optionDefinitions, { argv: ['--one'] }), { one: true } ) }) diff --git a/test/type-none.js b/test/type-none.js index 63cae7d..49ddfa2 100644 --- a/test/type-none.js +++ b/test/type-none.js @@ -1,26 +1,23 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('type-none') +const tom = new TestRunner.Tom() + +const definitions = [ + { name: 'one' }, + { name: 'two' } +] tom.test('no argv values', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' } - ] const argv = [] - const result = commandLineArgs(optionDefinitions, { argv }) + const result = commandLineArgs(definitions, { argv }) a.deepStrictEqual(result, {}) }) tom.test('just names, no values', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' } - ] const argv = ['--one', '--two'] - const result = commandLineArgs(optionDefinitions, { argv }) + const result = commandLineArgs(definitions, { argv }) a.deepStrictEqual(result, { one: null, two: null @@ -28,12 +25,8 @@ tom.test('just names, no values', function () { }) tom.test('just names, one value, one unpassed value', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' } - ] const argv = ['--one', 'one', '--two'] - const result = commandLineArgs(optionDefinitions, { argv }) + const result = commandLineArgs(definitions, { argv }) a.deepStrictEqual(result, { one: 'one', two: null @@ -41,12 +34,8 @@ tom.test('just names, one value, one unpassed value', function () { }) tom.test('just names, two values', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' } - ] const argv = ['--one', 'one', '--two', 'two'] - const result = commandLineArgs(optionDefinitions, { argv }) + const result = commandLineArgs(definitions, { argv }) a.deepStrictEqual(result, { one: 'one', two: 'two' diff --git a/test/type-number.js b/test/type-number.js index 6a7d9ef..81ccc9e 100644 --- a/test/type-number.js +++ b/test/type-number.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('type-number') +const tom = new TestRunner.Tom() tom.test('different values', function () { const optionDefinitions = [ diff --git a/test/type-other.js b/test/type-other.js index 9572b23..ce1f4f1 100644 --- a/test/type-other.js +++ b/test/type-other.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('type-other') +const tom = new TestRunner.Tom() tom.test('different values', function () { const definitions = [ @@ -38,7 +38,7 @@ tom.test('broken custom type function', function () { }) }) -tom.test('type-other-multiple: different values', function () { +tom.test('multiple: different values', function () { const definitions = [ { name: 'file', diff --git a/test/type-string.js b/test/type-string.js index 922239b..f1d3f19 100644 --- a/test/type-string.js +++ b/test/type-string.js @@ -1,8 +1,8 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.js' +import commandLineArgs from 'command-line-args' import a from 'assert' -const tom = new TestRunner.Tom('type-string') +const tom = new TestRunner.Tom() tom.test('different values', function () { const optionDefinitions = [