diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index fa3fdd8..9495035 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,10 +1,10 @@ -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions +# See: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs name: Node.js CI on: push: - branches: [ master ] + branches: [ master, next ] pull_request: branches: [ master ] @@ -15,14 +15,15 @@ jobs: strategy: matrix: - node-version: [4, 6, 8, 10, 12, 14, 16, 17] + node-version: [12, 14, 16, 18, 20, 22] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm install - - run: npm run test:ci + - name: Run tests + run: npm run test diff --git a/LICENSE b/LICENSE index 07fadb4..2200cb4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-22 Lloyd Brookes <75pound@gmail.com> +Copyright (c) 2014-24 Lloyd Brookes <75pound@gmail.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d7003b8..9801f7a 100644 --- a/README.md +++ b/README.md @@ -102,4 +102,4 @@ $ npm install command-line-args --save * * * -© 2014-22 Lloyd Brookes \<75pound@gmail.com\>. Documented by [jsdoc-to-markdown](https://github.com/75lb/jsdoc-to-markdown). +© 2014-24 Lloyd Brookes \<75pound@gmail.com\>. Documented by [jsdoc-to-markdown](https://github.com/75lb/jsdoc-to-markdown). diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 90a0c5e..0000000 --- a/dist/index.js +++ /dev/null @@ -1,1399 +0,0 @@ -'use strict'; - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var camelCase = _interopDefault(require('lodash.camelcase')); - -/** - * 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 (input) { - return typeof input === 'object' && input !== null -} - -function isArrayLike (input) { - return isObject(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 - } - - if (input === undefined) { - return [] - } - - if (isArrayLike(input) || input instanceof Set) { - return Array.from(input) - } - - return [ input ] -} - -/** - * Takes any input and guarantees an array back. - * - * - converts array-like objects (e.g. `arguments`) to a real array - * - converts `undefined` to an empty array - * - converts any another other, singular value (including `null`) 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 ] - * - * > 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$1 (input) { - if (Array.isArray(input)) { - return input - } else { - if (input === undefined) { - return [] - } else if (isArrayLike$1(input)) { - return Array.prototype.slice.call(input) - } else { - return [ input ] - } - } -} - -/** - * Find and either replace or remove items in an array. - * - * @module find-replace - * @example - * > const findReplace = require('find-replace') - * > const numbers = [ 1, 2, 3] - * - * > findReplace(numbers, n => n === 2, 'two') - * [ 1, 'two', 3 ] - * - * > findReplace(numbers, n => n === 2, [ 'two', 'zwei' ]) - * [ 1, [ 'two', 'zwei' ], 3 ] - * - * > findReplace(numbers, n => n === 2, 'two', 'zwei') - * [ 1, 'two', 'zwei', 3 ] - * - * > findReplace(numbers, n => n === 2) // no replacement, so remove - * [ 1, 3 ] - */ - -/** - * @param {array} - The input array - * @param {testFn} - A predicate function which, if returning `true` causes the current item to be operated on. - * @param [replaceWith] {...any} - If specified, found values will be replaced with these values, else removed. - * @returns {array} - * @alias module:find-replace - */ -function findReplace (array, testFn) { - const found = []; - const replaceWiths = arrayify$1(arguments); - replaceWiths.splice(0, 2); - - arrayify$1(array).forEach((value, index) => { - let expanded = []; - replaceWiths.forEach(replaceWith => { - if (typeof replaceWith === 'function') { - expanded = expanded.concat(replaceWith(value)); - } else { - expanded.push(replaceWith); - } - }); - - if (testFn(value)) { - found.push({ - index: index, - replaceWithValue: expanded - }); - } - }); - - found.reverse().forEach(item => { - 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=') -} - -/** - * For type-checking Javascript values. - * @module typical - * @typicalname t - * @example - * const t = require('typical') - */ - -/** - * Returns true if input is a number - * @param {*} - the input to test - * @returns {boolean} - * @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) - * false - */ -function isNumber (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 {*} - 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, but is not an array instance. Examples in the `arguments` object. Returns true if the input value is an object, not null and has a `length` property with a numeric value. - * - * @param {*} - the input to test - * @returns {boolean} - * @static - * @example - * function sum(x, y){ - * console.log(t.isArrayLike(arguments)) - * // prints `true` - * } - */ -function isArrayLike$2 (input) { - return isObject$2(input) && typeof input.length === 'number' -} - -/** - * returns true if the typeof input is `'object'`, but not null! - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isObject$2 (input) { - return typeof input === 'object' && input !== null -} - -/** - * Returns true if the input value is defined - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isDefined (input) { - return typeof input !== 'undefined' -} - -/** - * Returns true if the input value is a string - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isString (input) { - return typeof input === 'string' -} - -/** - * Returns true if the input value is a boolean - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isBoolean (input) { - return typeof input === 'boolean' -} - -/** - * Returns true if the input value is a function - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isFunction (input) { - return typeof input === 'function' -} - -/** - * Returns true if the input value is an es2015 `class`. - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isClass (input) { - if (isFunction(input)) { - 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 {*} - 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 {*} - 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 {*} - 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' - ) - } -} - -var t = { - isNumber, - isString, - isBoolean, - isPlainObject, - isArrayLike: isArrayLike$2, - isObject: isObject$2, - isDefined, - isFunction, - isClass, - isPrimitive, - isPromise, - isIterable -}; - -/** - * @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) - } -} - -/** - * 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(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(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(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/dist/index.mjs b/dist/index.mjs deleted file mode 100644 index 00683e4..0000000 --- a/dist/index.mjs +++ /dev/null @@ -1,1395 +0,0 @@ -import camelCase from 'lodash.camelcase'; - -/** - * 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 (input) { - return typeof input === 'object' && input !== null -} - -function isArrayLike (input) { - return isObject(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 - } - - if (input === undefined) { - return [] - } - - if (isArrayLike(input) || input instanceof Set) { - return Array.from(input) - } - - return [ input ] -} - -/** - * Takes any input and guarantees an array back. - * - * - converts array-like objects (e.g. `arguments`) to a real array - * - converts `undefined` to an empty array - * - converts any another other, singular value (including `null`) 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 ] - * - * > 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$1 (input) { - if (Array.isArray(input)) { - return input - } else { - if (input === undefined) { - return [] - } else if (isArrayLike$1(input)) { - return Array.prototype.slice.call(input) - } else { - return [ input ] - } - } -} - -/** - * Find and either replace or remove items in an array. - * - * @module find-replace - * @example - * > const findReplace = require('find-replace') - * > const numbers = [ 1, 2, 3] - * - * > findReplace(numbers, n => n === 2, 'two') - * [ 1, 'two', 3 ] - * - * > findReplace(numbers, n => n === 2, [ 'two', 'zwei' ]) - * [ 1, [ 'two', 'zwei' ], 3 ] - * - * > findReplace(numbers, n => n === 2, 'two', 'zwei') - * [ 1, 'two', 'zwei', 3 ] - * - * > findReplace(numbers, n => n === 2) // no replacement, so remove - * [ 1, 3 ] - */ - -/** - * @param {array} - The input array - * @param {testFn} - A predicate function which, if returning `true` causes the current item to be operated on. - * @param [replaceWith] {...any} - If specified, found values will be replaced with these values, else removed. - * @returns {array} - * @alias module:find-replace - */ -function findReplace (array, testFn) { - const found = []; - const replaceWiths = arrayify$1(arguments); - replaceWiths.splice(0, 2); - - arrayify$1(array).forEach((value, index) => { - let expanded = []; - replaceWiths.forEach(replaceWith => { - if (typeof replaceWith === 'function') { - expanded = expanded.concat(replaceWith(value)); - } else { - expanded.push(replaceWith); - } - }); - - if (testFn(value)) { - found.push({ - index: index, - replaceWithValue: expanded - }); - } - }); - - found.reverse().forEach(item => { - 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=') -} - -/** - * For type-checking Javascript values. - * @module typical - * @typicalname t - * @example - * const t = require('typical') - */ - -/** - * Returns true if input is a number - * @param {*} - the input to test - * @returns {boolean} - * @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) - * false - */ -function isNumber (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 {*} - 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, but is not an array instance. Examples in the `arguments` object. Returns true if the input value is an object, not null and has a `length` property with a numeric value. - * - * @param {*} - the input to test - * @returns {boolean} - * @static - * @example - * function sum(x, y){ - * console.log(t.isArrayLike(arguments)) - * // prints `true` - * } - */ -function isArrayLike$2 (input) { - return isObject$2(input) && typeof input.length === 'number' -} - -/** - * returns true if the typeof input is `'object'`, but not null! - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isObject$2 (input) { - return typeof input === 'object' && input !== null -} - -/** - * Returns true if the input value is defined - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isDefined (input) { - return typeof input !== 'undefined' -} - -/** - * Returns true if the input value is a string - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isString (input) { - return typeof input === 'string' -} - -/** - * Returns true if the input value is a boolean - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isBoolean (input) { - return typeof input === 'boolean' -} - -/** - * Returns true if the input value is a function - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isFunction (input) { - return typeof input === 'function' -} - -/** - * Returns true if the input value is an es2015 `class`. - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isClass (input) { - if (isFunction(input)) { - 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 {*} - 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 {*} - 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 {*} - 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' - ) - } -} - -var t = { - isNumber, - isString, - isBoolean, - isPlainObject, - isArrayLike: isArrayLike$2, - isObject: isObject$2, - isDefined, - isFunction, - isClass, - isPrimitive, - isPromise, - isIterable -}; - -/** - * @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) - } -} - -/** - * 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(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(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(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 }) -} - -export default commandLineArgs; diff --git a/dist/tests.js b/dist/tests.js deleted file mode 100644 index 996cc72..0000000 --- a/dist/tests.js +++ /dev/null @@ -1,3755 +0,0 @@ -'use strict'; - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var TestRunner = _interopDefault(require('test-runner')); -var a = _interopDefault(require('assert')); -var camelCase = _interopDefault(require('lodash.camelcase')); - -/** - * 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 (input) { - return typeof input === 'object' && input !== null -} - -function isArrayLike (input) { - return isObject(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 - } - - if (input === undefined) { - return [] - } - - if (isArrayLike(input) || input instanceof Set) { - return Array.from(input) - } - - return [ input ] -} - -/** - * Takes any input and guarantees an array back. - * - * - converts array-like objects (e.g. `arguments`) to a real array - * - converts `undefined` to an empty array - * - converts any another other, singular value (including `null`) 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 ] - * - * > 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$1 (input) { - if (Array.isArray(input)) { - return input - } else { - if (input === undefined) { - return [] - } else if (isArrayLike$1(input)) { - return Array.prototype.slice.call(input) - } else { - return [ input ] - } - } -} - -/** - * Find and either replace or remove items in an array. - * - * @module find-replace - * @example - * > const findReplace = require('find-replace') - * > const numbers = [ 1, 2, 3] - * - * > findReplace(numbers, n => n === 2, 'two') - * [ 1, 'two', 3 ] - * - * > findReplace(numbers, n => n === 2, [ 'two', 'zwei' ]) - * [ 1, [ 'two', 'zwei' ], 3 ] - * - * > findReplace(numbers, n => n === 2, 'two', 'zwei') - * [ 1, 'two', 'zwei', 3 ] - * - * > findReplace(numbers, n => n === 2) // no replacement, so remove - * [ 1, 3 ] - */ - -/** - * @param {array} - The input array - * @param {testFn} - A predicate function which, if returning `true` causes the current item to be operated on. - * @param [replaceWith] {...any} - If specified, found values will be replaced with these values, else removed. - * @returns {array} - * @alias module:find-replace - */ -function findReplace (array, testFn) { - const found = []; - const replaceWiths = arrayify$1(arguments); - replaceWiths.splice(0, 2); - - arrayify$1(array).forEach((value, index) => { - let expanded = []; - replaceWiths.forEach(replaceWith => { - if (typeof replaceWith === 'function') { - expanded = expanded.concat(replaceWith(value)); - } else { - expanded.push(replaceWith); - } - }); - - if (testFn(value)) { - found.push({ - index: index, - replaceWithValue: expanded - }); - } - }); - - found.reverse().forEach(item => { - 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=') -} - -/** - * For type-checking Javascript values. - * @module typical - * @typicalname t - * @example - * const t = require('typical') - */ - -/** - * Returns true if input is a number - * @param {*} - the input to test - * @returns {boolean} - * @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) - * false - */ -function isNumber (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 {*} - 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, but is not an array instance. Examples in the `arguments` object. Returns true if the input value is an object, not null and has a `length` property with a numeric value. - * - * @param {*} - the input to test - * @returns {boolean} - * @static - * @example - * function sum(x, y){ - * console.log(t.isArrayLike(arguments)) - * // prints `true` - * } - */ -function isArrayLike$2 (input) { - return isObject$2(input) && typeof input.length === 'number' -} - -/** - * returns true if the typeof input is `'object'`, but not null! - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isObject$2 (input) { - return typeof input === 'object' && input !== null -} - -/** - * Returns true if the input value is defined - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isDefined (input) { - return typeof input !== 'undefined' -} - -/** - * Returns true if the input value is a string - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isString (input) { - return typeof input === 'string' -} - -/** - * Returns true if the input value is a boolean - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isBoolean (input) { - return typeof input === 'boolean' -} - -/** - * Returns true if the input value is a function - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isFunction (input) { - return typeof input === 'function' -} - -/** - * Returns true if the input value is an es2015 `class`. - * @param {*} - the input to test - * @returns {boolean} - * @static - */ -function isClass (input) { - if (isFunction(input)) { - 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 {*} - 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 {*} - 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 {*} - 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' - ) - } -} - -var t = { - isNumber, - isString, - isBoolean, - isPlainObject, - isArrayLike: isArrayLike$2, - isObject: isObject$2, - isDefined, - isFunction, - isClass, - isPrimitive, - isPromise, - isIterable -}; - -/** - * @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 runner = new TestRunner(); - -runner.test('argv-parser: long option, string', function () { - const optionDefinitions = [ - { name: 'one' } - ]; - const argv = ['--one', '1']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' } - ]); -}); - -runner.test('argv-parser: long option, string repeated', function () { - const optionDefinitions = [ - { name: 'one' } - ]; - const argv = ['--one', '1', '--one', '2']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - a.ok(result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '2', name: 'one', value: '2' } - ]); -}); - -runner.test('argv-parser: long option, string multiple', function () { - const optionDefinitions = [ - { name: 'one', multiple: true } - ]; - const argv = ['--one', '1', '2']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'set', arg: '2', name: 'one', value: '2' } - ]); -}); - -runner.test('argv-parser: long option, string multiple then boolean', function () { - const optionDefinitions = [ - { name: 'one', multiple: true }, - { name: 'two', type: Boolean } - ]; - const argv = ['--one', '1', '2', '--two']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - a.ok(result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'set', arg: '2', name: 'one', value: '2' }, - { event: 'set', arg: '--two', name: 'two', value: true } - ]); -}); - -runner.test('argv-parser: long option, boolean', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean } - ]; - const argv = ['--one', '1']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(!result[1].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: true }, - { event: 'unknown_value', arg: '1', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: simple, with unknown values', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - const argv = ['clive', '--one', '1', 'yeah']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(!result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - a.ok(!result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'unknown_value', arg: 'clive', name: '_unknown', value: undefined }, - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'unknown_value', arg: 'yeah', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: simple, with singular defaultOption', function () { - const optionDefinitions = [ - { name: 'one', type: Number }, - { name: 'two', defaultOption: true } - ]; - const argv = ['clive', '--one', '1', 'yeah']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - a.ok(!result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: 'clive', name: 'two', value: 'clive' }, - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'unknown_value', arg: 'yeah', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: simple, with multiple defaultOption', function () { - const optionDefinitions = [ - { name: 'one', type: Number }, - { name: 'two', defaultOption: true, multiple: true } - ]; - const argv = ['clive', '--one', '1', 'yeah']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - a.ok(result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: 'clive', name: 'two', value: 'clive' }, - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'set', arg: 'yeah', name: 'two', value: 'yeah' } - ]); -}); - -runner.test('argv-parser: long option, string lazyMultiple bad', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one', '1', '2']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(!result[2].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'unknown_value', arg: '2', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: long option, string lazyMultiple good', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one', '1', '--one', '2']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - a.ok(result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '2', name: 'one', value: '2' } - ]); -}); - -runner.test('argv-parser: long option, stopAtFirstUnknown', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' } - ]; - const argv = ['--one', '1', 'asdf', '--two', '2']; - const parser = new ArgvParser(optionDefinitions, { argv, stopAtFirstUnknown: true }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(!result[2].def); - a.ok(!result[3].def); - a.ok(!result[4].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'unknown_value', arg: 'asdf', name: '_unknown', value: undefined }, - { event: 'unknown_value', arg: '--two', name: '_unknown', value: undefined }, - { event: 'unknown_value', arg: '2', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: long option, stopAtFirstUnknown with defaultOption', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true }, - { name: 'two' } - ]; - const argv = ['1', 'asdf', '--two', '2']; - const parser = new ArgvParser(optionDefinitions, { argv, stopAtFirstUnknown: true }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(!result[1].def); - a.ok(!result[2].def); - a.ok(!result[3].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'unknown_value', arg: 'asdf', name: '_unknown', value: undefined }, - { event: 'unknown_value', arg: '--two', name: '_unknown', value: undefined }, - { event: 'unknown_value', arg: '2', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: long option, stopAtFirstUnknown with defaultOption 2', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true }, - { name: 'two' } - ]; - const argv = ['--one', '1', '--', '--two', '2']; - const parser = new ArgvParser(optionDefinitions, { argv, stopAtFirstUnknown: true }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(!result[2].def); - a.ok(!result[3].def); - a.ok(!result[4].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' }, - { event: 'unknown_value', arg: '--', name: '_unknown', value: undefined }, - { event: 'unknown_value', arg: '--two', name: '_unknown', value: undefined }, - { event: 'unknown_value', arg: '2', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: --option=value', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' } - ]; - const argv = ['--one=1', '--two=2', '--two=']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '--one=1', name: 'one', value: '1' }, - { event: 'set', arg: '--two=2', name: 'two', value: '2' }, - { event: 'set', arg: '--two=', name: 'two', value: '' } - ]); -}); - -runner.test('argv-parser: --option=value, unknown option', function () { - const optionDefinitions = [ - { name: 'one' } - ]; - const argv = ['--three=3']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(!result[0].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'unknown_option', arg: '--three=3', name: '_unknown', value: undefined } - ]); -}); - -runner.test('argv-parser: --option=value where option is boolean', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean } - ]; - const argv = ['--one=1']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'unknown_value', arg: '--one=1', name: '_unknown', value: undefined }, - { event: 'set', arg: '--one=1', name: 'one', value: true } - ]); -}); - -runner.test('argv-parser: short option, string', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' } - ]; - const argv = ['-o', '1']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '-o', name: 'one', value: null }, - { event: 'set', arg: '1', name: 'one', value: '1' } - ]); -}); - -runner.test('argv-parser: combined short option, string', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' } - ]; - const argv = ['-ot', '1']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'set', arg: '-ot', subArg: '-o', name: 'one', value: null }, - { event: 'set', arg: '-ot', subArg: '-t', name: 'two', value: null }, - { event: 'set', arg: '1', name: 'two', value: '1' } - ]); -}); - -runner.test('argv-parser: combined short option, one unknown', function () { - const optionDefinitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' } - ]; - const argv = ['-xt', '1']; - const parser = new ArgvParser(optionDefinitions, { argv }); - const result = Array.from(parser); - a.ok(!result[0].def); - a.ok(result[1].def); - a.ok(result[2].def); - result.forEach(r => delete r.def); - a.deepStrictEqual(result, [ - { event: 'unknown_option', arg: '-xt', subArg: '-x', name: '_unknown', value: undefined }, - { event: 'set', arg: '-xt', subArg: '-t', name: 'two', value: null }, - { event: 'set', arg: '1', name: 'two', value: '1' } - ]); -}); - -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) - } -} - -const runner$1 = new TestRunner(); - -runner$1.test('option.set(): defaultValue', function () { - const option = new Option({ name: 'two', defaultValue: 'two' }); - a.strictEqual(option.get(), 'two'); - option.set('zwei'); - a.strictEqual(option.get(), 'zwei'); -}); - -runner$1.test('option.set(): multiple defaultValue', function () { - const option = new Option({ name: 'two', multiple: true, defaultValue: ['two', 'zwei'] }); - a.deepStrictEqual(option.get(), ['two', 'zwei']); - option.set('duo'); - a.deepStrictEqual(option.get(), ['duo']); -}); - -runner$1.test('option.set(): falsy defaultValue', function () { - const option = new Option({ name: 'one', defaultValue: 0 }); - a.strictEqual(option.get(), 0); -}); - -runner$1.test('option.set(): falsy defaultValue 2', function () { - const option = new Option({ name: 'two', defaultValue: false }); - a.strictEqual(option.get(), false); -}); - -runner$1.test('option.set(): falsy defaultValue multiple', function () { - const option = new Option({ name: 'one', defaultValue: 0, multiple: true }); - a.deepStrictEqual(option.get(), [0]); -}); - -const runner$2 = new TestRunner(); - -runner$2.test('.get(long option)', function () { - const definitions = Definitions.from([{ name: 'one' }]); - a.strictEqual(definitions.get('--one').name, 'one'); -}); - -runner$2.test('.get(short option)', function () { - const definitions = Definitions.from([{ name: 'one', alias: 'o' }]); - a.strictEqual(definitions.get('-o').name, 'one'); -}); - -runner$2.test('.get(name)', function () { - const definitions = Definitions.from([{ name: 'one' }]); - a.strictEqual(definitions.get('one').name, 'one'); -}); - -runner$2.test('.validate()', function () { - a.throws(function () { - const definitions = new Definitions(); - definitions.load([{ name: 'one' }, { name: 'one' }]); - }); -}); - -class FlagOption$1 extends Option { - set (val) { - super.set(true); - } - - static create (def) { - return new this(def) - } -} - -const runner$3 = new TestRunner(); - -runner$3.test('type-boolean: single set', function () { - const option = new FlagOption$1({ name: 'one', type: Boolean }); - - option.set(undefined); - a.strictEqual(option.get(), true); -}); - -runner$3.test('type-boolean: single set 2', function () { - const option = new FlagOption$1({ name: 'one', type: Boolean }); - - option.set('true'); - a.strictEqual(option.get(), true); -}); - -runner$3.test('type-boolean: set twice', function () { - const option = new FlagOption$1({ name: 'one', type: Boolean }); - - option.set(undefined); - a.strictEqual(option.get(), true); - a.throws( - () => option.set('true'), - err => err.name === 'ALREADY_SET' - ); -}); - -const origBoolean = Boolean; - -/* test in contexts which override the standard global Boolean constructor */ -runner$3.test('type-boolean: global Boolean overridden', function () { - function Boolean () { - return origBoolean.apply(origBoolean, arguments) - } - - const option = new FlagOption$1({ name: 'one', type: Boolean }); - - option.set(); - a.strictEqual(option.get(), true); -}); - -runner$3.test('type-boolean-multiple: 1', function () { - const option = new FlagOption$1({ name: 'one', type: Boolean, multiple: true }); - - option.set(undefined); - option.set(undefined); - option.set(undefined); - - a.deepStrictEqual(option.get(), [true, true, true]); -}); - -const runner$4 = new TestRunner(); - -runner$4.test('option.set(): simple set string', function () { - const option = Option.create({ name: 'two' }); - a.strictEqual(option.get(), null); - a.strictEqual(option.state, 'default'); - option.set('zwei'); - a.strictEqual(option.get(), 'zwei'); - a.strictEqual(option.state, 'set'); -}); - -runner$4.test('option.set(): simple set boolean', function () { - const option = Option.create({ name: 'two', type: Boolean }); - a.strictEqual(option.get(), null); - a.strictEqual(option.state, 'default'); - option.set(); - a.strictEqual(option.get(), true); - a.strictEqual(option.state, 'set'); -}); - -runner$4.test('option.set(): simple set string twice', function () { - const option = Option.create({ name: 'two' }); - a.strictEqual(option.get(), null); - a.strictEqual(option.state, 'default'); - option.set('zwei'); - a.strictEqual(option.get(), 'zwei'); - a.strictEqual(option.state, 'set'); - a.throws( - () => option.set('drei'), - err => err.name === 'ALREADY_SET' - ); -}); - -runner$4.test('option.set(): simple set boolean twice', function () { - const option = Option.create({ name: 'two', type: Boolean }); - a.strictEqual(option.get(), null); - a.strictEqual(option.state, 'default'); - option.set(); - a.strictEqual(option.get(), true); - a.strictEqual(option.state, 'set'); - a.throws( - () => option.set(), - err => err.name === 'ALREADY_SET' - ); -}); - -runner$4.test('option.set(): string multiple', function () { - const option = Option.create({ name: 'two', multiple: true }); - a.deepStrictEqual(option.get(), []); - a.strictEqual(option.state, 'default'); - option.set('1'); - a.deepStrictEqual(option.get(), ['1']); - a.strictEqual(option.state, 'set'); - option.set('2'); - a.deepStrictEqual(option.get(), ['1', '2']); - a.strictEqual(option.state, 'set'); -}); - -runner$4.test('option.set: lazyMultiple', function () { - const option = Option.create({ name: 'one', lazyMultiple: true }); - a.deepStrictEqual(option.get(), []); - a.strictEqual(option.state, 'default'); - option.set('1'); - a.deepStrictEqual(option.get(), ['1']); - a.strictEqual(option.state, 'set'); - option.set('2'); - a.deepStrictEqual(option.get(), ['1', '2']); - a.strictEqual(option.state, 'set'); -}); - -runner$4.test('option.set(): string multiple defaultOption', function () { - const option = Option.create({ name: 'two', multiple: true, defaultOption: true }); - a.deepStrictEqual(option.get(), []); - a.strictEqual(option.state, 'default'); - option.set('1'); - a.deepStrictEqual(option.get(), ['1']); - a.strictEqual(option.state, 'set'); - option.set('2'); - a.deepStrictEqual(option.get(), ['1', '2']); - a.strictEqual(option.state, 'set'); -}); - -runner$4.test('option.set: lazyMultiple defaultOption', function () { - const option = Option.create({ name: 'one', lazyMultiple: true, defaultOption: true }); - a.deepStrictEqual(option.get(), []); - a.strictEqual(option.state, 'default'); - option.set('1'); - a.deepStrictEqual(option.get(), ['1']); - a.strictEqual(option.state, 'set'); - option.set('2'); - a.deepStrictEqual(option.get(), ['1', '2']); - a.strictEqual(option.state, 'set'); -}); - -/** - * 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(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 - } -} - -const runner$5 = new TestRunner(); - -runner$5.test('output.toObject(): no defs set', function () { - const output = new Output([ - { name: 'one' } - ]); - a.deepStrictEqual(output.toObject(), {}); -}); - -runner$5.test('output.toObject(): one def set', function () { - const output = new Output([ - { name: 'one' } - ]); - const option = Option.create({ name: 'one' }); - option.set('yeah'); - output.set('one', option); - a.deepStrictEqual(output.toObject(), { - one: 'yeah' - }); -}); - -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(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(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 }) -} - -const runner$6 = new TestRunner(); - -runner$6.test('alias-cluster: two flags, one option', function () { - const optionDefinitions = [ - { name: 'flagA', alias: 'a', type: Boolean }, - { name: 'flagB', alias: 'b', type: Boolean }, - { name: 'three', alias: 'c' } - ]; - - const argv = ['-abc', 'yeah']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - flagA: true, - flagB: true, - three: 'yeah' - }); -}); - -runner$6.test('alias-cluster: two flags, one option 2', function () { - const optionDefinitions = [ - { name: 'flagA', alias: 'a', type: Boolean }, - { name: 'flagB', alias: 'b', type: Boolean }, - { name: 'three', alias: 'c' } - ]; - - const argv = ['-c', 'yeah', '-ab']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - flagA: true, - flagB: true, - three: 'yeah' - }); -}); - -runner$6.test('alias-cluster: three string options', function () { - const optionDefinitions = [ - { name: 'flagA', alias: 'a' }, - { name: 'flagB', alias: 'b' }, - { name: 'three', alias: 'c' } - ]; - - const argv = ['-abc', 'yeah']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - flagA: null, - flagB: null, - three: 'yeah' - }); -}); - -const runner$7 = new TestRunner(); - -runner$7.test('alias: one string alias', function () { - const optionDefinitions = [ - { name: 'verbose', alias: 'v' } - ]; - const argv = ['-v']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - verbose: null - }); -}); - -runner$7.test('alias: one boolean alias', function () { - const optionDefinitions = [ - { name: 'dry-run', alias: 'd', type: Boolean } - ]; - const argv = ['-d']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - 'dry-run': true - }); -}); - -runner$7.test('alias: one boolean, one string', function () { - const optionDefinitions = [ - { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'colour', alias: 'c' } - ]; - const argv = ['-v', '-c']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - verbose: true, - colour: null - }); -}); - -const runner$8 = new TestRunner(); - -runner$8.test('ambiguous input: value looks like an option 1', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ]; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['-c', 'red'] }), { - colour: 'red' - }); -}); - -runner$8.test('ambiguous input: value looks like an option 2', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ]; - const argv = ['--colour', '--red']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_OPTION' - ); -}); - -runner$8.test('ambiguous input: value looks like an option 3', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ]; - a.doesNotThrow(function () { - commandLineArgs(optionDefinitions, { argv: ['--colour=--red'] }); - }); -}); - -runner$8.test('ambiguous input: value looks like an option 4', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ]; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour=--red'] }), { - colour: '--red' - }); -}); - -const runner$9 = new TestRunner(); - -runner$9.test('bad-input: missing option value should be null', function () { - const optionDefinitions = [ - { name: 'colour', type: String }, - { name: 'files' } - ]; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour'] }), { - colour: null - }); - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour', '--files', 'yeah'] }), { - colour: null, - files: 'yeah' - }); -}); - -runner$9.test('bad-input: handles arrays with relative paths', function () { - const optionDefinitions = [ - { name: 'colours', type: String, multiple: true } - ]; - const argv = ['--colours', '../what', '../ever']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - colours: ['../what', '../ever'] - }); -}); - -runner$9.test('bad-input: 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='] - }); -}); - -runner$9.test('bad-input: non-strings in argv', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - const argv = ['--one', 1]; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { one: 1 }); -}); - -const runner$a = new TestRunner(); - -runner$a.test('camel-case: 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 - }); -}); - -runner$a.test('camel-case: 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' - } - }); -}); - -runner$a.test('camel-case: 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'] - }); -}); - -const runner$b = new TestRunner(); - -runner$b.test('case-insensitive: 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' - ); -}); - -runner$b.test('case-insensitive: 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 - }); -}); - -runner$b.test('case-insensitive: 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' - }); -}); - -runner$b.test('case-insensitive: 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 - }); -}); - -runner$b.test('case-insensitive: 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'] - }); -}); - -runner$b.test('case-insensitive: 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 - }); -}); - -const runner$c = new TestRunner(); - -runner$c.test('defaultOption: multiple string', function () { - const optionDefinitions = [ - { name: 'files', defaultOption: true, multiple: true } - ]; - const argv = ['file1', 'file2']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - files: ['file1', 'file2'] - }); -}); - -runner$c.test('defaultOption: 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' } - ); -}); - -runner$c.test('defaultOption: 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'] - }); -}); - -runner$c.test('defaultOption: 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'] - }); -}); - -runner$c.test('defaultOption: 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'] - }); -}); - -const runner$d = new TestRunner(); - -runner$d.test('default value', function () { - const defs = [ - { name: 'one' }, - { name: 'two', defaultValue: 'two' } - ]; - const argv = ['--one', '1']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: '1', - two: 'two' - }); -}); - -runner$d.test('default value 2', function () { - const defs = [{ name: 'two', defaultValue: 'two' }]; - const argv = []; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: 'two' }); -}); - -runner$d.test('default value 3', function () { - const defs = [{ name: 'two', defaultValue: 'two' }]; - const argv = ['--two', 'zwei']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: 'zwei' }); -}); - -runner$d.test('default value 4', function () { - const defs = [{ name: 'two', multiple: true, defaultValue: ['two', 'zwei'] }]; - const argv = ['--two', 'duo']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: ['duo'] }); -}); - -runner$d.test('default value 5', function () { - const defs = [ - { name: 'two', multiple: true, defaultValue: ['two', 'zwei'] } - ]; - const argv = []; - const result = commandLineArgs(defs, { argv }); - a.deepStrictEqual(result, { two: ['two', 'zwei'] }); -}); - -runner$d.test('default value: array as defaultOption', function () { - const defs = [ - { name: 'two', multiple: true, defaultValue: ['two', 'zwei'], defaultOption: true } - ]; - const argv = ['duo']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: ['duo'] }); -}); - -runner$d.test('default value: falsy default values', function () { - const defs = [ - { name: 'one', defaultValue: 0 }, - { name: 'two', defaultValue: false } - ]; - - const argv = []; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: 0, - two: false - }); -}); - -runner$d.test('default value: is arrayifed if multiple set', function () { - const defs = [ - { name: 'one', defaultValue: 0, multiple: true } - ]; - - let argv = []; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: [0] - }); - argv = ['--one', '2']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: ['2'] - }); -}); - -runner$d.test('default value: combined with defaultOption', function () { - const defs = [ - { name: 'path', defaultOption: true, defaultValue: './' } - ]; - - let argv = ['--path', 'test']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: 'test' - }); - argv = ['test']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: 'test' - }); - argv = []; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: './' - }); -}); - -runner$d.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(defs, { argv }), { - path: ['test1', 'test2'] - }); - argv = ['--path', 'test']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }); - argv = ['test1', 'test2']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test1', 'test2'] - }); - argv = ['test']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }); - argv = []; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['./'] - }); -}); - -runner$d.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(defs, { argv }), { - path: ['test1', 'test2'] - }); - argv = ['--path', 'test']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }); - argv = ['test1', 'test2']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test1', 'test2'] - }); - argv = ['test']; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }); - argv = []; - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['./'] - }); -}); - -const runner$e = new TestRunner(); - -runner$e.test('detect process.argv: should automatically remove first two argv items', function () { - process.argv = ['node', 'filename', '--one', 'eins']; - a.deepStrictEqual(commandLineArgs({ name: 'one' }), { - one: 'eins' - }); -}); - -runner$e.test('detect process.argv: should automatically remove first two argv items 2', function () { - process.argv = ['node', 'filename', '--one', 'eins']; - a.deepStrictEqual(commandLineArgs({ name: 'one' }, { argv: process.argv }), { - one: 'eins' - }); -}); - -runner$e.test('process.argv is left untouched', function () { - process.argv = ['node', 'filename', '--one', 'eins']; - a.deepStrictEqual(commandLineArgs({ name: 'one' }), { - one: 'eins' - }); - a.deepStrictEqual(process.argv, ['node', 'filename', '--one', 'eins']); -}); - -const runner$f = new TestRunner(); - -runner$f.test('detect process.execArgv: should automatically remove first argv items', function () { - const origArgv = process.argv; - const origExecArgv = process.execArgv; - process.argv = ['node', '--one', 'eins']; - process.execArgv = ['-e', 'something']; - a.deepStrictEqual(commandLineArgs({ name: 'one' }), { - one: 'eins' - }); - process.argv = origArgv; - process.execArgv = origExecArgv; -}); - -const runner$g = new TestRunner(); - -runner$g.test('exceptions-already-set: long option', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean } - ]; - const argv = ['--one', '--one']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'ALREADY_SET' && err.optionName === 'one' - ); -}); - -runner$g.test('exceptions-already-set: short option', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean, alias: 'o' } - ]; - const argv = ['--one', '-o']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'ALREADY_SET' && err.optionName === 'one' - ); -}); - -runner$g.test('exceptions-already-set: --option=value', function () { - const optionDefinitions = [ - { name: 'one' } - ]; - const argv = ['--one=1', '--one=1']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'ALREADY_SET' && err.optionName === 'one' - ); -}); - -runner$g.test('exceptions-already-set: combined short option', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean, alias: 'o' } - ]; - const argv = ['-oo']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'ALREADY_SET' && err.optionName === 'one' - ); -}); - -const runner$h = new TestRunner(); - -runner$h.test('err-invalid-definition: throws when no definition.name specified', function () { - const optionDefinitions = [ - { something: 'one' }, - { something: 'two' } - ]; - const argv = ['--one', '--two']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: throws if dev set a numeric alias', function () { - const optionDefinitions = [ - { name: 'colours', alias: '1' } - ]; - const argv = ['--colours', 'red']; - - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: throws if dev set an alias of "-"', function () { - const optionDefinitions = [ - { name: 'colours', alias: '-' } - ]; - const argv = ['--colours', 'red']; - - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: multi-character alias', function () { - const optionDefinitions = [ - { name: 'one', alias: 'aa' } - ]; - const argv = ['--one', 'red']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: invalid type values 1', function () { - const argv = ['--one', 'something']; - a.throws( - () => commandLineArgs([{ name: 'one', type: 'string' }], { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: invalid type values 2', function () { - const argv = ['--one', 'something']; - a.throws( - () => commandLineArgs([{ name: 'one', type: 234 }], { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: invalid type values 3', function () { - const argv = ['--one', 'something']; - a.throws( - () => commandLineArgs([{ name: 'one', type: {} }], { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: invalid type values 4', function () { - const argv = ['--one', 'something']; - a.doesNotThrow(function () { - commandLineArgs([{ name: 'one', type: function () {} }], { argv }); - }, /invalid/i); -}); - -runner$h.test('err-invalid-definition: duplicate name', function () { - const optionDefinitions = [ - { name: 'colours' }, - { name: 'colours' } - ]; - const argv = ['--colours', 'red']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: 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' - ); -}); - -runner$h.test('err-invalid-definition: 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' - }); -}); - -runner$h.test('err-invalid-definition: duplicate alias', function () { - const optionDefinitions = [ - { name: 'one', alias: 'a' }, - { name: 'two', alias: 'a' } - ]; - const argv = ['--one', 'red']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: 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' - ); -}); - -runner$h.test('err-invalid-definition: 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' - }); -}); - -runner$h.test('err-invalid-definition: multiple defaultOption', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true }, - { name: 'two', defaultOption: true } - ]; - const argv = ['--one', 'red']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -runner$h.test('err-invalid-definition: 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' - ); -}); - -runner$h.test('err-invalid-defaultOption: defaultOption on a Boolean type', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean, defaultOption: true } - ]; - const argv = ['--one', 'red']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ); -}); - -const runner$i = new TestRunner(); - -runner$i.test('exceptions-unknowns: unknown option', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - a.throws( - () => commandLineArgs(optionDefinitions, { argv: ['--one', '--two'] }), - err => err.name === 'UNKNOWN_OPTION' && err.optionName === '--two' - ); -}); - -runner$i.test('exceptions-unknowns: 1 unknown option, 1 unknown value', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - a.throws( - () => commandLineArgs(optionDefinitions, { argv: ['--one', '2', '--two', 'two'] }), - err => err.name === 'UNKNOWN_OPTION' && err.optionName === '--two' - ); -}); - -runner$i.test('exceptions-unknowns: unknown alias', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - a.throws( - () => commandLineArgs(optionDefinitions, { argv: ['-a', '2'] }), - err => err.name === 'UNKNOWN_OPTION' && err.optionName === '-a' - ); -}); - -runner$i.test('exceptions-unknowns: unknown combined aliases', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - a.throws( - () => commandLineArgs(optionDefinitions, { argv: ['-sdf'] }), - err => err.name === 'UNKNOWN_OPTION' && err.optionName === '-s' - ); -}); - -runner$i.test('exceptions-unknowns: unknown value', function () { - const optionDefinitions = [ - { name: 'one' } - ]; - const argv = ['--one', 'arg1', 'arg2']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_VALUE' && err.value === 'arg2' - ); -}); - -runner$i.test('exceptions-unknowns: unknown value with singular defaultOption', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true } - ]; - const argv = ['arg1', 'arg2']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_VALUE' && err.value === 'arg2' - ); -}); - -runner$i.test('exceptions-unknowns: no unknown value exception with multiple defaultOption', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true, multiple: true } - ]; - const argv = ['arg1', 'arg2']; - a.doesNotThrow(() => { - commandLineArgs(optionDefinitions, { argv }); - }); -}); - -runner$i.test('exceptions-unknowns: non-multiple defaultOption should take first value 2', function () { - const optionDefinitions = [ - { name: 'file', defaultOption: true }, - { name: 'one', type: Boolean }, - { name: 'two', type: Boolean } - ]; - const argv = ['--two', 'file1', '--one', 'file2']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_VALUE' && err.value === 'file2' - ); -}); - -const runner$j = new TestRunner(); - -runner$j.test('groups', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three', group: 'b' } - ]; - const argv = ['--one', '1', '--two', '2', '--three', '3']; - const output = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(output, { - a: { - one: '1', - two: '2' - }, - b: { - three: '3' - }, - _all: { - one: '1', - two: '2', - three: '3' - } - }); -}); - -runner$j.test('groups: multiple and _none', function () { - const definitions = [ - { name: 'one', group: ['a', 'f'] }, - { name: 'two', group: ['a', 'g'] }, - { name: 'three' } - ]; - - a.deepStrictEqual(commandLineArgs(definitions, { argv: ['--one', '1', '--two', '2', '--three', '3'] }), { - a: { - one: '1', - two: '2' - }, - f: { - one: '1' - }, - g: { - two: '2' - }, - _none: { - three: '3' - }, - _all: { - one: '1', - two: '2', - three: '3' - } - }); -}); - -runner$j.test('groups: nothing set', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three', group: 'b' } - ]; - const argv = []; - const output = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(output, { - a: {}, - b: {}, - _all: {} - }); -}); - -runner$j.test('groups: nothing set with one ungrouped', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three' } - ]; - const argv = []; - const output = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(output, { - a: {}, - _all: {} - }); -}); - -runner$j.test('groups: two ungrouped, one set', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three' }, - { name: 'four' } - ]; - const argv = ['--three', '3']; - const output = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(output, { - a: {}, - _all: { three: '3' }, - _none: { three: '3' } - }); -}); - -runner$j.test('groups: two ungrouped, both set', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three' }, - { name: 'four' } - ]; - const argv = ['--three', '3', '--four', '4']; - const output = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(output, { - a: {}, - _all: { three: '3', four: '4' }, - _none: { three: '3', four: '4' } - }); -}); - -runner$j.test('groups: with partial', function () { - const definitions = [ - { name: 'one', group: 'a' }, - { name: 'two', group: 'a' }, - { name: 'three', group: 'b' } - ]; - const argv = ['--one', '1', '--two', '2', '--three', '3', 'ham', '--cheese']; - a.deepStrictEqual(commandLineArgs(definitions, { argv, partial: true }), { - a: { - one: '1', - two: '2' - }, - b: { - three: '3' - }, - _all: { - one: '1', - two: '2', - three: '3' - }, - _unknown: ['ham', '--cheese'] - }); -}); - -runner$j.test('partial: with partial, multiple groups and _none', function () { - const definitions = [ - { name: 'one', group: ['a', 'f'] }, - { name: 'two', group: ['a', 'g'] }, - { name: 'three' } - ]; - const argv = ['--cheese', '--one', '1', 'ham', '--two', '2', '--three', '3', '-c']; - a.deepStrictEqual(commandLineArgs(definitions, { argv, partial: true }), { - a: { - one: '1', - two: '2' - }, - f: { - one: '1' - }, - g: { - two: '2' - }, - _none: { - three: '3' - }, - _all: { - one: '1', - two: '2', - three: '3' - }, - _unknown: ['--cheese', 'ham', '-c'] - }); -}); - -const runner$k = new TestRunner(); - -runner$k.test('lazy multiple: string', function () { - const argv = ['--one', 'a', '--one', 'b', '--one', 'd']; - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['a', 'b', 'd'] - }); -}); - -runner$k.test('lazy multiple: string unset with defaultValue', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true, defaultValue: 1 } - ]; - const argv = []; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { one: [1] }); -}); - -runner$k.test('lazy multiple: string, --option=value', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one=1', '--one=2']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2'] - }); -}); - -runner$k.test('lazy multiple: string, --option=value mix', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one=1', '--one=2', '--one', '3']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2', '3'] - }); -}); - -runner$k.test('lazy multiple: string, defaultOption', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true, defaultOption: true } - ]; - const argv = ['1', '2']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2'] - }); -}); - -runner$k.test('lazy multiple: greedy style, string', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one', '1', '2']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_VALUE' && err.value === '2' - ); -}); - -runner$k.test('lazy multiple: greedy style, string, --option=value', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one=1', '--one=2']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2'] - }); -}); - -runner$k.test('lazy multiple: greedy style, string, --option=value mix', function () { - const optionDefinitions = [ - { name: 'one', lazyMultiple: true } - ]; - const argv = ['--one=1', '--one=2', '3']; - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_VALUE' && err.value === '3' - ); -}); - -const runner$l = new TestRunner(); - -runner$l.test('multiple: empty argv', function () { - const optionDefinitions = [ - { name: 'one', multiple: true } - ]; - const argv = []; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, {}); -}); - -runner$l.test('multiple: boolean, empty argv', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean, multiple: true } - ]; - const argv = []; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { }); -}); - -runner$l.test('multiple: string unset with defaultValue', function () { - const optionDefinitions = [ - { name: 'one', multiple: true, defaultValue: 1 } - ]; - const argv = []; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { one: [1] }); -}); - -runner$l.test('multiple: string', function () { - const optionDefinitions = [ - { name: 'one', multiple: true } - ]; - const argv = ['--one', '1', '2']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2'] - }); -}); - -runner$l.test('multiple: string, --option=value', function () { - const optionDefinitions = [ - { name: 'one', multiple: true } - ]; - const argv = ['--one=1', '--one=2']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2'] - }); -}); - -runner$l.test('multiple: string, --option=value mix', function () { - const optionDefinitions = [ - { name: 'one', multiple: true } - ]; - const argv = ['--one=1', '--one=2', '3']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2', '3'] - }); -}); - -runner$l.test('multiple: string, defaultOption', function () { - const optionDefinitions = [ - { name: 'one', multiple: true, defaultOption: true } - ]; - const argv = ['1', '2']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - one: ['1', '2'] - }); -}); - -const runner$m = new TestRunner(); - -runner$m.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); -}); - -const runner$n = new TestRunner(); - -runner$n.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'); -}); - -const runner$o = new TestRunner(); - -runner$o.test('--option=value notation: two plus a regular notation', function () { - const optionDefinitions = [ - { name: 'one' }, - { name: 'two' }, - { name: 'three' } - ]; - - const argv = ['--one=1', '--two', '2', '--three=3']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.strictEqual(result.one, '1'); - a.strictEqual(result.two, '2'); - a.strictEqual(result.three, '3'); -}); - -runner$o.test('--option=value notation: value contains "="', function () { - const optionDefinitions = [ - { name: 'url' }, - { name: 'two' }, - { name: 'three' } - ]; - - let result = commandLineArgs(optionDefinitions, { argv: ['--url=my-url?q=123', '--two', '2', '--three=3'] }); - a.strictEqual(result.url, 'my-url?q=123'); - a.strictEqual(result.two, '2'); - a.strictEqual(result.three, '3'); - - result = commandLineArgs(optionDefinitions, { argv: ['--url=my-url?q=123=1'] }); - a.strictEqual(result.url, 'my-url?q=123=1'); - - result = commandLineArgs({ name: 'my-url' }, { argv: ['--my-url=my-url?q=123=1'] }); - a.strictEqual(result['my-url'], 'my-url?q=123=1'); -}); - -const runner$p = new TestRunner(); - -runner$p.test('partial: simple', function () { - const definitions = [ - { name: 'one', type: Boolean } - ]; - const argv = ['--two', 'two', '--one', 'two']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - one: true, - _unknown: ['--two', 'two', 'two'] - }); -}); - -runner$p.test('partial: defaultOption', function () { - const definitions = [ - { name: 'files', type: String, defaultOption: true, multiple: true } - ]; - const argv = ['--files', 'file1', '--one', 'file2']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - files: ['file1', 'file2'], - _unknown: ['--one'] - }); -}); - -runner$p.test('defaultOption: floating args present but no defaultOption', function () { - const definitions = [ - { name: 'one', type: Boolean } - ]; - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['aaa', '--one', 'aaa', 'aaa'], partial: true }), - { - one: true, - _unknown: ['aaa', 'aaa', 'aaa'] - } - ); -}); - -runner$p.test('partial: combined short option, both unknown', function () { - const definitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' } - ]; - const argv = ['-ab']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - _unknown: ['-a', '-b'] - }); -}); - -runner$p.test('partial: combined short option, one known, one unknown', function () { - const definitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' } - ]; - const argv = ['-ob']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - one: null, - _unknown: ['-b'] - }); -}); - -runner$p.test('partial: defaultOption with --option=value and combined short options', function () { - 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(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - files: ['file1', 'file2', 'file3'], - two: '3', - one: true, - _unknown: ['-a', '-b'] - }); -}); - -runner$p.test('partial: defaultOption with value equal to defaultValue', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ]; - const argv = ['file1', '--two=3', '--four', '5']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - file: 'file1', - _unknown: ['--two=3', '--four', '5'] - }); -}); - -runner$p.test('partial: string defaultOption can be set by argv once', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ]; - const argv = ['--file', '--file=file2', '--two=3', '--four', '5']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - file: 'file2', - _unknown: ['--two=3', '--four', '5'] - }); -}); - -runner$p.test('partial: string defaultOption can not be set by argv twice', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ]; - const argv = ['--file', '--file=file2', '--two=3', '--four', '5', 'file3']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - file: 'file2', - _unknown: ['--two=3', '--four', '5', 'file3'] - }); -}); - -runner$p.test('partial: defaultOption with value equal to defaultValue 3', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ]; - const argv = ['file1', 'file2', '--two=3', '--four', '5']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - file: 'file1', - _unknown: ['file2', '--two=3', '--four', '5'] - }); -}); - -runner$p.test('partial: multiple', function () { - const definitions = [ - { name: 'files', type: String, multiple: true } - ]; - const argv = ['file1', '--files', 'file2', '-t', '--two=3', 'file3', '-ab', '--files=file4']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - files: ['file2', 'file4'], - _unknown: ['file1', '-t', '--two=3', 'file3', '-a', '-b'] - }); -}); - -runner$p.test('unknown options: rejected defaultOption values end up in _unknown', function () { - const definitions = [ - { name: 'foo', type: String }, - { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'libs', type: String, defaultOption: true } - ]; - const argv = ['--foo', 'bar', '-v', 'libfn', '--libarg', 'val1', '-r']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - foo: 'bar', - verbose: true, - libs: 'libfn', - _unknown: ['--libarg', 'val1', '-r'] - }); -}); - -runner$p.test('partial: defaultOption with --option=value notation', function () { - const definitions = [ - { name: 'files', type: String, multiple: true, defaultOption: true } - ]; - const argv = ['file1', 'file2', '--unknown=something']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - files: ['file1', 'file2'], - _unknown: ['--unknown=something'] - }); -}); - -runner$p.test('partial: defaultOption with --option=value notation 2', function () { - const definitions = [ - { name: 'files', type: String, multiple: true, defaultOption: true } - ]; - const argv = ['file1', 'file2', '--unknown=something', '--files', 'file3', '--files=file4']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - files: ['file1', 'file2', 'file3', 'file4'], - _unknown: ['--unknown=something'] - }); -}); - -runner$p.test('partial: defaultOption with --option=value notation 3', function () { - 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(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - files: ['file1', 'something', 'file2', 'file3', 'file4'], - _unknown: ['--unknown', '--another', '--unknown=something'] - }); -}); - -runner$p.test('partial: mulitple unknowns with same name', function () { - const definitions = [ - { name: 'file' } - ]; - const argv = ['--unknown', '--unknown=something', '--file=file1', '--unknown']; - const options = commandLineArgs(definitions, { argv, partial: true }); - a.deepStrictEqual(options, { - file: 'file1', - _unknown: ['--unknown', '--unknown=something', '--unknown'] - }); -}); - -runner$p.test('defaultOption: single string', function () { - const optionDefinitions = [ - { name: 'files', defaultOption: true } - ]; - const argv = ['file1', 'file2']; - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv, partial: true }), { - files: 'file1', - _unknown: ['file2'] - }); -}); - -const runner$q = new TestRunner(); - -runner$q.test('stopAtFirstUnknown', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean }, - { name: 'two', type: Boolean } - ]; - const argv = ['--one', 'a', '--two']; - const result = commandLineArgs(optionDefinitions, { argv, stopAtFirstUnknown: true, partial: true }); - a.deepStrictEqual(result, { - one: true, - _unknown: ['a', '--two'] - }); -}); - -runner$q.test('stopAtFirstUnknown: with a singlular defaultOption', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true }, - { name: 'two' } - ]; - const argv = ['--one', '1', '--', '--two', '2']; - const result = commandLineArgs(optionDefinitions, { argv, stopAtFirstUnknown: true }); - a.deepStrictEqual(result, { - one: '1', - _unknown: ['--', '--two', '2'] - }); -}); - -runner$q.test('stopAtFirstUnknown: with a singlular defaultOption and partial', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true }, - { name: 'two' } - ]; - const argv = ['--one', '1', '--', '--two', '2']; - const result = commandLineArgs(optionDefinitions, { argv, stopAtFirstUnknown: true, partial: true }); - a.deepStrictEqual(result, { - one: '1', - _unknown: ['--', '--two', '2'] - }); -}); - -const runner$r = new TestRunner(); - -runner$r.test('type-boolean: simple', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean } - ]; - - a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv: ['--one'] }), - { one: true } - ); -}); - -const origBoolean$1 = Boolean; - -/* test in contexts which override the standard global Boolean constructor */ -runner$r.test('type-boolean: global Boolean overridden', function () { - function Boolean () { - return origBoolean$1.apply(origBoolean$1, arguments) - } - - const optionDefinitions = [ - { name: 'one', type: Boolean } - ]; - - a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv: ['--one'] }), - { one: true } - ); -}); - -runner$r.test('type-boolean-multiple: 1', function () { - const optionDefinitions = [ - { name: 'array', type: Boolean, multiple: true } - ]; - const argv = ['--array', '--array', '--array']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - array: [true, true, true] - }); -}); - -const runner$s = new TestRunner(); - -const definitions = [ - { name: 'one' }, - { name: 'two' } -]; - -runner$s.test('name: no argv values', function () { - const argv = []; - const result = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(result, {}); -}); - -runner$s.test('name: just names, no values', function () { - const argv = ['--one', '--two']; - const result = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(result, { - one: null, - two: null - }); -}); - -runner$s.test('name: just names, one value, one unpassed value', function () { - const argv = ['--one', 'one', '--two']; - const result = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(result, { - one: 'one', - two: null - }); -}); - -runner$s.test('name: just names, two values', function () { - const argv = ['--one', 'one', '--two', 'two']; - const result = commandLineArgs(definitions, { argv }); - a.deepStrictEqual(result, { - one: 'one', - two: 'two' - }); -}); - -const runner$t = new TestRunner(); - -runner$t.test('type-number: different values', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ]; - a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv: ['--one', '1'] }), - { one: 1 } - ); - a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv: ['--one'] }), - { one: null } - ); - a.deepStrictEqual( - commandLineArgs(optionDefinitions, { argv: ['--one', '-1'] }), - { one: -1 } - ); - const result = commandLineArgs(optionDefinitions, { argv: ['--one', 'asdf'] }); - a.ok(isNaN(result.one)); -}); - -runner$t.test('number multiple: 1', function () { - const optionDefinitions = [ - { name: 'array', type: Number, multiple: true } - ]; - const argv = ['--array', '1', '2', '3']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - array: [1, 2, 3] - }); - a.notDeepStrictEqual(result, { - array: ['1', '2', '3'] - }); -}); - -runner$t.test('number multiple: 2', function () { - const optionDefinitions = [ - { name: 'array', type: Number, multiple: true } - ]; - const argv = ['--array', '1', '--array', '2', '--array', '3']; - const result = commandLineArgs(optionDefinitions, { argv }); - a.deepStrictEqual(result, { - array: [1, 2, 3] - }); - a.notDeepStrictEqual(result, { - array: ['1', '2', '3'] - }); -}); - -const runner$u = new TestRunner(); - -runner$u.test('type-other: different values', function () { - const definitions = [ - { - name: 'file', - type: function (file) { - return file - } - } - ]; - - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['--file', 'one.js'] }), - { file: 'one.js' } - ); - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['--file'] }), - { file: null } - ); -}); - -runner$u.test('type-other: broken custom type function', function () { - const definitions = [ - { - name: 'file', - type: function (file) { - throw new Error('broken') - } - } - ]; - a.throws(function () { - commandLineArgs(definitions, { argv: ['--file', 'one.js'] }); - }); -}); - -runner$u.test('type-other-multiple: different values', function () { - const definitions = [ - { - name: 'file', - multiple: true, - type: function (file) { - return file - } - } - ]; - - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['--file', 'one.js'] }), - { file: ['one.js'] } - ); - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['--file', 'one.js', 'two.js'] }), - { file: ['one.js', 'two.js'] } - ); - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['--file'] }), - { file: [] } - ); -}); - -const runner$v = new TestRunner(); - -runner$v.test('type-string: different values', 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' } - ); -}); diff --git a/index.mjs b/index.js similarity index 95% rename from index.mjs rename to index.js index 4ce4dea..9871c52 100644 --- a/index.mjs +++ b/index.js @@ -1,8 +1,8 @@ -import Definitions from './lib/option-definitions.mjs' -import ArgvParser from './lib/argv-parser.mjs' -import Option from './lib/option.mjs' -import OutputGrouped from './lib/output-grouped.mjs' -import Output from './lib/output.mjs' +import Definitions from './lib/option-definitions.js' +import ArgvParser from './lib/argv-parser.js' +import Option from './lib/option.js' +import OutputGrouped from './lib/output-grouped.js' +import Output from './lib/output.js' /** * @module command-line-args diff --git a/jsdoc.conf b/jsdoc.conf deleted file mode 100644 index 15d1b97..0000000 --- a/jsdoc.conf +++ /dev/null @@ -1,5 +0,0 @@ -{ - "source": { - "includePattern": ".+\\.(js(doc|x)?|mjs)$" - } -} diff --git a/lib/argv-parser.mjs b/lib/argv-parser.js similarity index 94% rename from lib/argv-parser.mjs rename to lib/argv-parser.js index a2335d3..78c3328 100644 --- a/lib/argv-parser.mjs +++ b/lib/argv-parser.js @@ -1,7 +1,7 @@ -import * as argvTools from './argv-tools.mjs' -import Definitions from './option-definitions.mjs' -import findReplace from '../node_modules/find-replace/dist/index.mjs' -import t from '../node_modules/typical/index.mjs' +import * as argvTools from './argv-tools.js' +import Definitions from './option-definitions.js' +import findReplace from 'find-replace' +import t from 'typical' /** * @module argv-parser diff --git a/lib/argv-tools.mjs b/lib/argv-tools.js similarity index 96% rename from lib/argv-tools.mjs rename to lib/argv-tools.js index 7a0e426..3da5890 100644 --- a/lib/argv-tools.mjs +++ b/lib/argv-tools.js @@ -1,5 +1,5 @@ -import arrayify from '../node_modules/array-back/index.mjs' -import findReplace from '../node_modules/find-replace/dist/index.mjs' +import arrayify from 'array-back' +import findReplace from 'find-replace' /** * Some useful tools for working with `process.argv`. diff --git a/lib/option-definition.mjs b/lib/option-definition.js similarity index 99% rename from lib/option-definition.mjs rename to lib/option-definition.js index eb2e65c..f75b580 100644 --- a/lib/option-definition.mjs +++ b/lib/option-definition.js @@ -1,4 +1,4 @@ -import t from '../node_modules/typical/index.mjs' +import t from 'typical' /** * @module option-definition diff --git a/lib/option-definitions.mjs b/lib/option-definitions.js similarity index 95% rename from lib/option-definitions.mjs rename to lib/option-definitions.js index 0bc879c..a69f15f 100644 --- a/lib/option-definitions.mjs +++ b/lib/option-definitions.js @@ -1,7 +1,7 @@ -import arrayify from '../node_modules/array-back/index.mjs' -import * as argvTools from './argv-tools.mjs' -import t from '../node_modules/typical/index.mjs' -import Definition from './option-definition.mjs' +import arrayify from 'array-back' +import * as argvTools from './argv-tools.js' +import t from 'typical' +import Definition from './option-definition.js' /** * @module option-definitions @@ -84,7 +84,7 @@ class Definitions extends Array { ) } - const duplicateDefaultOption = this.filter(def => def.defaultOption === true).length > 1; + const duplicateDefaultOption = this.filter(def => def.defaultOption === true).length > 1 if (duplicateDefaultOption) { halt( 'INVALID_DEFINITIONS', diff --git a/lib/option-flag.mjs b/lib/option-flag.js similarity index 82% rename from lib/option-flag.mjs rename to lib/option-flag.js index 4bbf0c8..0bedb6f 100644 --- a/lib/option-flag.mjs +++ b/lib/option-flag.js @@ -1,4 +1,4 @@ -import Option from './option.mjs' +import Option from './option.js' class FlagOption extends Option { set (val) { diff --git a/lib/option.mjs b/lib/option.js similarity index 93% rename from lib/option.mjs rename to lib/option.js index eca9013..ac956fd 100644 --- a/lib/option.mjs +++ b/lib/option.js @@ -1,6 +1,6 @@ -import arrayify from '../node_modules/array-back/index.mjs' -import t from '../node_modules/typical/index.mjs' -import Definition from './option-definition.mjs' +import arrayify from 'array-back' +import t from 'typical' +import Definition from './option-definition.js' const _value = new WeakMap() /** diff --git a/lib/output-grouped.mjs b/lib/output-grouped.js similarity index 89% rename from lib/output-grouped.mjs rename to lib/output-grouped.js index ed78b1d..407beb2 100644 --- a/lib/output-grouped.mjs +++ b/lib/output-grouped.js @@ -1,6 +1,6 @@ -import Output from './output.mjs' -import arrayify from '../node_modules/array-back/index.mjs' -import t from '../node_modules/typical/index.mjs' +import Output from './output.js' +import arrayify from 'array-back' +import t from 'typical' import camelCase from 'lodash.camelcase' class GroupedOutput extends Output { diff --git a/lib/output.mjs b/lib/output.js similarity index 92% rename from lib/output.mjs rename to lib/output.js index f52a091..2d9c8c4 100644 --- a/lib/output.mjs +++ b/lib/output.js @@ -1,5 +1,5 @@ -import Option from './option.mjs' -import Definitions from './option-definitions.mjs' +import Option from './option.js' +import Definitions from './option-definitions.js' import camelCase from 'lodash.camelcase' /** diff --git a/package-lock.json b/package-lock.json index 57d93ed..6ddd790 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,26 +9,27 @@ "version": "5.2.1", "license": "MIT", "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", + "array-back": "^6.2.2", + "find-replace": "^5.0.1", "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" + "typical": "^7.1.1" }, "devDependencies": { "coveralls": "^3.1.1", - "jsdoc-to-markdown": "^7.1.1", - "rollup": "~1.7.4", - "test-runner": "^0.5.1" + "jsdoc-to-markdown": "^8.0.1", + "rollup": "~4.18.0", + "test-runner": "^0.10.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/@babel/parser": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", - "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -36,52 +37,403 @@ "node": ">=6.0.0" } }, - "node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true + "node_modules/@jsdoc/salty": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", + "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } }, - "node_modules/@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", - "dev": 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", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@test-runner/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@test-runner/core/-/core-0.10.0.tgz", + "integrity": "sha512-1m+DowKsEa4IAShyvwj58b9AfbCgZxf9ynPRGixsIzUY03zSEdNB2ItfjMtDPNmoPgbZVxX0DgTgbNfgwRrJQA==", + "dev": true, + "license": "MIT", "dependencies": { - "@types/linkify-it": "*", - "@types/mdurl": "*" + "@test-runner/tom": "^0.8.0", + "fsm-base": "^0.7.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", - "dev": true + "node_modules/@test-runner/core/node_modules/@test-runner/tom": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@test-runner/tom/-/tom-0.8.1.tgz", + "integrity": "sha512-MbQsG8V5R+yU+O9gkL3oidbxk1PNp/j/ctpAXAvbLOdpD+GMan//MBRstFBzLl+n7R9UNvfW3U8eKlnlQ7SNcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "composite-class": "^2.0.1", + "create-mixin": "^3.0.0", + "fsm-base": "^0.7.0", + "race-timeout-anywhere": "^2.0.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.17" + } }, - "node_modules/@types/node": { - "version": "11.15.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.15.54.tgz", - "integrity": "sha512-1RWYiq+5UfozGsU6MwJyFX6BtktcT10XRjvcAQmskCtMcW3tPske88lM/nHv7BQG1w9KBXI1zPGuu5PnNCX14g==", - "dev": true + "node_modules/@test-runner/default-view": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@test-runner/default-view/-/default-view-0.6.1.tgz", + "integrity": "sha512-/yuHQe+kdtYDnppGg/wc80KQal/3Ril4JOTUUA9esskjZaEpcA6xQ9Cop21rpWhrbmxLqsX1Q48MccunA3/T4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escape-sequences": "^6.2.0" + }, + "engines": { + "node": ">=12.17" + } }, - "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "node_modules/@test-runner/default-view/node_modules/ansi-escape-sequences": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", + "integrity": "sha512-mBPG9BZy4dMOJQ9BehU6ph8IKslvVppbqZ8APHnpfP+Hsx/hGow5PY46lSQL1vPPi1F5XTtO6p3GcH8O9c0cUg==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2" }, "engines": { - "node": ">=0.4.0" + "node": ">=12.17" } }, + "node_modules/@test-runner/live-view": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@test-runner/live-view/-/live-view-0.2.1.tgz", + "integrity": "sha512-JnCPfxP4v9cMnFbyVaCp9Oa2bufM842MY24g8EIXmkkhO8UKMc2dH3K9tHX48D1s4kIty2UdT92kb4nxexOC4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escape-sequences": "^6.2.0" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@test-runner/live-view/node_modules/ansi-escape-sequences": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", + "integrity": "sha512-mBPG9BZy4dMOJQ9BehU6ph8IKslvVppbqZ8APHnpfP+Hsx/hGow5PY46lSQL1vPPi1F5XTtO6p3GcH8O9c0cUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@test-runner/oneline-view": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@test-runner/oneline-view/-/oneline-view-0.2.0.tgz", + "integrity": "sha512-A0Q3D/V/71vrZjlMu0nCYVjrcI/7q7KD/AVRNCsMysSbalKJh4AcwEeGHPDtUhio7V3Eux4VjJl9HVtgst0Mcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@test-runner/default-view": "^0.6.1", + "ansi-escape-sequences": "^6.2.0", + "string-length": "^5.0.1" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@test-runner/oneline-view/node_modules/ansi-escape-sequences": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", + "integrity": "sha512-mBPG9BZy4dMOJQ9BehU6ph8IKslvVppbqZ8APHnpfP+Hsx/hGow5PY46lSQL1vPPi1F5XTtO6p3GcH8O9c0cUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@test-runner/tom": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@test-runner/tom/-/tom-0.9.1.tgz", + "integrity": "sha512-kkr+2AcUCsMANLghAiLdWOF8clUe6a3hhsHeDdPyrPVZNMuooqOl/d5bQm1/YK3D0Xm1aiCs3NIPimZcQhzk+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "composite-class": "^2.0.1", + "create-mixin": "^3.0.0", + "fsm-base": "^0.7.0", + "race-timeout-anywhere": "^2.0.0", + "typical": "^7.1.1" + }, + "engines": { + "node": ">=12.17" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -110,6 +462,42 @@ "node": ">=8.0.0" } }, + "node_modules/ansi-escape-sequences/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -120,11 +508,12 @@ } }, "node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12.17" } }, "node_modules/asn1": { @@ -170,7 +559,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -185,13 +575,15 @@ "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -202,6 +594,7 @@ "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-2.0.0.tgz", "integrity": "sha512-4gkeHlFpSKgm3vm2gJN5sPqfmijYRFYCQ6tv5cLw0xVmT6r1z1vd4FNnpuOREco3cBs1G709sZ72LdgddKvL5w==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^4.0.1", "fs-then-native": "^2.0.0", @@ -216,6 +609,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -231,6 +625,7 @@ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, + "license": "MIT", "dependencies": { "lodash": "^4.17.15" }, @@ -238,11 +633,47 @@ "node": ">= 10" } }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, "node_modules/collect-all": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", "dev": true, + "license": "MIT", "dependencies": { "stream-connect": "^1.0.2", "stream-via": "^1.0.4" @@ -251,6 +682,23 @@ "node": ">=0.10.0" } }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -278,6 +726,39 @@ "node": ">=4.0.0" } }, + "node_modules/command-line-args/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/command-line-args/node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-args/node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/command-line-tool": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", @@ -350,15 +831,27 @@ "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/composite-class": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/composite-class/-/composite-class-2.0.1.tgz", + "integrity": "sha512-zEUaKe0wIkAMonjQPZPm4w7aylosaMjqGpHynYT2V05q02I93CWfBxp3kV2iB7anvc/aDvCJN36FzFco3c788A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, "node_modules/config-master": { "version": "3.1.0", @@ -403,6 +896,26 @@ "node": ">=6" } }, + "node_modules/create-mixin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/create-mixin/-/create-mixin-3.0.0.tgz", + "integrity": "sha512-LkdMqnWT9LaqBN4huqpUnMz56Yr1mVSoCduAd2xXefgH/YZP2sXCMAyztXjk4q8hTF/TlcDa+zQW2aTgGdjjKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/current-module-paths": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.1.tgz", + "integrity": "sha512-8Ga5T8oMXBaSsHq9Gj+bddX7kHSaJKsl2vaAd3ep51eQLkr4W18eFEmEZM5bLo1zrz8tt3jE1U8QK9QGhaLR4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -434,17 +947,18 @@ } }, "node_modules/dmd": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.1.0.tgz", - "integrity": "sha512-0zQIJ873gay1scCTFZvHPWM9mVJBnaylB2NQDI8O9u8O32m00Jb6uxDKexZm8hjTRM7RiWe0FJ32pExHoXdwoQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.2.0.tgz", + "integrity": "sha512-uXWxLF1H7TkUAuoHK59/h/ts5cKavm2LnhrIgJWisip4BVzPoXavlwyoprFFn2CzcahKYgvkfaebS6oxzgflkg==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^6.2.2", "cache-point": "^2.0.0", "common-sequence": "^2.0.2", "file-set": "^4.0.2", "handlebars": "^4.7.7", - "marked": "^4.0.12", + "marked": "^4.2.3", "object-get": "^2.1.1", "reduce-flatten": "^3.0.1", "reduce-unique": "^2.0.1", @@ -456,15 +970,6 @@ "node": ">=12" } }, - "node_modules/dmd/node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true, - "engines": { - "node": ">=12.17" - } - }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -476,10 +981,14 @@ } }, "node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -489,6 +998,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -538,6 +1048,7 @@ "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.2.tgz", "integrity": "sha512-fuxEgzk4L8waGXaAkd8cMr73Pm0FxOVkn8hztzUW7BAHhOGH90viQNXbiOsnecCWmfInqU6YmAMwxRMdKETceQ==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^5.0.0", "glob": "^7.1.6" @@ -551,19 +1062,21 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.1.tgz", + "integrity": "sha512-o5/Y8HrCNRuFF5rdNTkX8Vhv6kTFTV0t1zIoigwlCdbkA9qaapRzxvWPND2VvlFa9LBI05Q1i8ml/saMqkOJUQ==", + "license": "MIT", "dependencies": { - "array-back": "^3.0.1" + "array-back": "^6.2.2" }, "engines": { - "node": ">=4.0.0" + "node": ">=14" } }, "node_modules/forever-agent": { @@ -592,8 +1105,9 @@ "node_modules/fs-then-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", - "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=", + "integrity": "sha512-X712jAOaWXkemQCAmWeg5rOT2i+KOpWz1Z/txk/cW0qlOu2oQ9H61vc5w3X/iyuUEfq/OyaFJ78/cZAQD1/bgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -601,8 +1115,38 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fsm-base": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/fsm-base/-/fsm-base-0.7.0.tgz", + "integrity": "sha512-qL/cAOixPK0DmwmZzwzSXPJ8fcetM5iuXF47g7OovQHPGE9gfZdPQklXY47gNZUIjDKan5P27GK5Jk0GC+4wDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^6.1.1", + "obso": "^0.7.0" + }, + "engines": { + "node": ">=14" + } }, "node_modules/getpass": { "version": "0.1.7", @@ -614,15 +1158,17 @@ } }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -633,14 +1179,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, @@ -677,6 +1231,16 @@ "node": ">=6" } }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -695,8 +1259,10 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -706,7 +1272,8 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/is-typedarray": { "version": "1.0.0", @@ -738,6 +1305,7 @@ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "xmlcreate": "^2.0.4" } @@ -749,46 +1317,48 @@ "dev": true }, "node_modules/jsdoc": { - "version": "3.6.10", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz", - "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.3.tgz", + "integrity": "sha512-Nu7Sf35kXJ1MWDZIMAuATRQTg1iIPdzh7tqJ6jjvaU/GfDf+qi5UV8zJR3Mo+/pYFvm8mzay4+6O5EWigaQBQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/parser": "^7.9.4", - "@types/markdown-it": "^12.2.3", + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^14.1.1", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", - "klaw": "^4.0.1", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", + "klaw": "^3.0.0", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", "underscore": "~1.13.2" }, "bin": { "jsdoc": "jsdoc.js" }, "engines": { - "node": ">=8.15.0" + "node": ">=12.0.0" } }, "node_modules/jsdoc-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-7.1.1.tgz", - "integrity": "sha512-0pkuPCzVXiqsDAsVrNFXCkHzlyNepBIDVtwwehry4RJAnZmXtlAz7rh8F9FRz53u3NeynGbex+bpYWwi8lE66A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-8.0.0.tgz", + "integrity": "sha512-Rnhor0suB1Ds1abjmFkFfKeD+kSMRN9oHMTMZoJVUrmtCGDwXty+sWMA9sa4xbe4UyxuPjhC7tavZ40mDKK6QQ==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^6.2.2", "cache-point": "^2.0.0", "collect-all": "^1.0.4", "file-set": "^4.0.2", "fs-then-native": "^2.0.0", - "jsdoc": "^3.6.10", + "jsdoc": "^4.0.0", "object-to-spawn-args": "^2.0.1", "temp-path": "^1.0.0", "walk-back": "^5.1.0" @@ -797,53 +1367,36 @@ "node": ">=12.17" } }, - "node_modules/jsdoc-api/node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true, - "engines": { - "node": ">=12.17" - } - }, "node_modules/jsdoc-parse": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.1.0.tgz", - "integrity": "sha512-n/hDGQJa69IBun1yZAjqzV4gVR41+flZ3bIlm9fKvNe2Xjsd1/+zCo2+R9ls8LxtePgIWbpA1jU7xkB2lRdLLg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.2.1.tgz", + "integrity": "sha512-9viGRUUtWOk/G4V0+nQ6rfLucz5plxh5I74WbNSNm9h9NWugCDVX4jbG8hZP9QqKGpdTPDE+qJXzaYNos3wqTA==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^6.2.2", "lodash.omit": "^4.5.0", - "lodash.pick": "^4.4.0", "reduce-extract": "^1.0.0", - "sort-array": "^4.1.4", + "sort-array": "^4.1.5", "test-value": "^3.0.0" }, "engines": { "node": ">=12" } }, - "node_modules/jsdoc-parse/node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true, - "engines": { - "node": ">=12.17" - } - }, "node_modules/jsdoc-to-markdown": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-7.1.1.tgz", - "integrity": "sha512-CI86d63xAVNO+ENumWwmJ034lYe5iGU5GwjtTA11EuphP9tpnoi4hrKgR/J8uME0D+o4KUpVfwX1fjZhc8dEtg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-8.0.1.tgz", + "integrity": "sha512-qJfNJhkq2C26UYoOdj8L1yheTJlk1veCsxwRejRmj07XZKCn7oSkuPErx6+JoNi8afCaUKdIM5oUu0uF2/T8iw==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^6.2.2", "command-line-tool": "^0.8.0", "config-master": "^3.1.0", - "dmd": "^6.1.0", - "jsdoc-api": "^7.1.1", - "jsdoc-parse": "^6.1.0", + "dmd": "^6.2.0", + "jsdoc-api": "^8.0.0", + "jsdoc-parse": "^6.2.1", "walk-back": "^5.1.0" }, "bin": { @@ -853,15 +1406,6 @@ "node": ">=12.17" } }, - "node_modules/jsdoc-to-markdown/node_modules/array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true, - "engines": { - "node": ">=12.17" - } - }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -896,12 +1440,13 @@ } }, "node_modules/klaw": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz", - "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, - "engines": { - "node": ">=14.14.0" + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.9" } }, "node_modules/lcov-parse": { @@ -914,19 +1459,34 @@ } }, "node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, + "license": "MIT", "dependencies": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" + } + }, + "node_modules/load-module": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/load-module/-/load-module-4.2.1.tgz", + "integrity": "sha512-Sbfg6R4LjvyThJpqUoADHMjyoI2+cL4msbCQeZ9kkY/CqP/TT2938eftKm7x4I2gd4/A+DEe6nePkbfWYbXwSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^6.2.0" + }, + "engines": { + "node": ">=12.17" } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -936,8 +1496,9 @@ "node_modules/lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", - "dev": true + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", + "dev": true, + "license": "MIT" }, "node_modules/lodash.padend": { "version": "4.6.1", @@ -945,12 +1506,6 @@ "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", "dev": true }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", - "dev": true - }, "node_modules/log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -961,26 +1516,29 @@ } }, "node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "bin": { - "markdown-it": "bin/markdown-it.js" + "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/markdown-it-anchor": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.4.1.tgz", - "integrity": "sha512-sLODeRetZ/61KkKLJElaU3NuU2z7MhXf12Ml1WJMSdwpngeofneCRF+JBbat8HiSqhniOMuTemXMrsI7hA6XyA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", "dev": true, + "license": "Unlicense", "peerDependencies": { "@types/markdown-it": "*", "markdown-it": "*" @@ -990,13 +1548,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/marked": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", - "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -1005,10 +1565,11 @@ } }, "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" }, "node_modules/mime-db": { "version": "1.51.0", @@ -1032,10 +1593,11 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1054,6 +1616,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -1065,13 +1628,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.5.tgz", "integrity": "sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/oauth-sign": { "version": "0.9.0", @@ -1086,22 +1651,35 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz", "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/object-to-spawn-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz", "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } }, + "node_modules/obso": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/obso/-/obso-0.7.0.tgz", + "integrity": "sha512-iNEHV1r9hFfemR0jFUIxFxqkR9rcvY10C7U/LtKM2w5wS3nSLZEqRnfGY/P8cYzCXHTzTefxMYfnIJkssDhmAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -1109,8 +1687,9 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1136,6 +1715,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", @@ -1145,11 +1734,22 @@ "node": ">=0.6" } }, + "node_modules/race-timeout-anywhere": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/race-timeout-anywhere/-/race-timeout-anywhere-2.0.0.tgz", + "integrity": "sha512-kFE+ZL9Esq2JVcHp+ygSI8bTSAfJuXi8nQCDVAD2zLYJ/TMzObyLLbVaXA99JFVtsibIF7A1IqJRfiC4H+muxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/reduce-extract": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", - "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=", + "integrity": "sha512-QF8vjWx3wnRSL5uFMyCjDeDc5EBMiryoT9tz94VvgjKfzecHAVnqmXAwQDcr7X4JmLc2cjkjFGCVzhMqDjgR9g==", "dev": true, + "license": "MIT", "dependencies": { "test-value": "^1.0.1" }, @@ -1160,8 +1760,9 @@ "node_modules/reduce-extract/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, + "license": "MIT", "dependencies": { "typical": "^2.6.0" }, @@ -1172,8 +1773,9 @@ "node_modules/reduce-extract/node_modules/test-value": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", - "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=", + "integrity": "sha512-wrsbRo7qP+2Je8x8DsK8ovCGyxe3sYfQwOraIY/09A2gFXU9DYKiTF14W4ki/01AEh56kMzAmlj9CaHGDDUBJA==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^1.0.2", "typical": "^2.4.2" @@ -1185,14 +1787,16 @@ "node_modules/reduce-extract/node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", + "dev": true, + "license": "MIT" }, "node_modules/reduce-flatten": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz", "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1202,6 +1806,7 @@ "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz", "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1209,8 +1814,9 @@ "node_modules/reduce-without": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", - "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=", + "integrity": "sha512-zQv5y/cf85sxvdrKPlfcRzlDn/OqKFThNimYmsS3flmkioKvkUGn2Qg9cJVoQiEvdxFGLE0MQER/9fZ9sUqdxg==", "dev": true, + "license": "MIT", "dependencies": { "test-value": "^2.0.0" }, @@ -1221,8 +1827,9 @@ "node_modules/reduce-without/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, + "license": "MIT", "dependencies": { "typical": "^2.6.0" }, @@ -1233,8 +1840,9 @@ "node_modules/reduce-without/node_modules/test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^1.0.3", "typical": "^2.6.0" @@ -1246,8 +1854,9 @@ "node_modules/reduce-without/node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", + "dev": true, + "license": "MIT" }, "node_modules/request": { "version": "2.88.2", @@ -1282,26 +1891,49 @@ } }, "node_modules/requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", "dev": true, + "license": "MIT", "dependencies": { - "lodash": "^4.17.14" + "lodash": "^4.17.21" } }, "node_modules/rollup": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.7.4.tgz", - "integrity": "sha512-nc86fETLHdozhRWlW/uNVIQ7ODuA1vU2/L8znAxP9TNMx1NA6GTth3llqoxxCle2kkyui+OfGzbKaQxD60NJjA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "0.0.39", - "@types/node": "^11.11.6", - "acorn": "^6.1.1" + "@types/estree": "1.0.5" }, "bin": { - "rollup": "bin/rollup" + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" } }, "node_modules/safe-buffer": { @@ -1331,10 +1963,11 @@ "dev": true }, "node_modules/sort-array": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.4.tgz", - "integrity": "sha512-GVFN6Y1sHKrWaSYOJTk9093ZnrBMc9sP3nuhANU44S4xg3rE6W5Z5WyamuT8VpMBbssnetx5faKCua0LEmUnSw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.5.tgz", + "integrity": "sha512-Ya4peoS1fgFN42RN1REk2FgdNOeLIEMKFGJvs7VTP3OklF8+kl2SkpVliZ4tk/PurWsrWRsdNdU+tgyOBkB9sA==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^5.0.0", "typical": "^6.0.1" @@ -1348,6 +1981,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -1357,6 +1991,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-6.0.1.tgz", "integrity": "sha512-+g3NEp7fJLe9DPa1TArHm9QAA7YciZmWnfAqEaFrBihQ7epOv9i99rjtgb6Iz0wh3WuQDjsCTDfgRoGnmHN81A==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -1366,6 +2001,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1404,8 +2040,9 @@ "node_modules/stream-connect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", - "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=", + "integrity": "sha512-68Kl+79cE0RGKemKkhxTSg8+6AGrqBt+cbZAXevg2iJ6Y3zX4JhA/sZeGzLpxW9cXhmqAcE7KnJCisUmIUfnFQ==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^1.0.2" }, @@ -1416,8 +2053,9 @@ "node_modules/stream-connect/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, + "license": "MIT", "dependencies": { "typical": "^2.6.0" }, @@ -1428,23 +2066,59 @@ "node_modules/stream-connect/node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", + "dev": true, + "license": "MIT" }, "node_modules/stream-via": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -1452,6 +2126,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", @@ -1486,92 +2173,145 @@ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", "dev": true }, - "node_modules/taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, "node_modules/temp-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", - "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=", - "dev": true + "integrity": "sha512-TvmyH7kC6ZVTYkqCODjJIbgvu0FKiwQpZ4D1aknE7xpcDf/qEOB8KZEK5ef2pfbVoiBhNWs3yx4y+ESMtNYmlg==", + "dev": true, + "license": "MIT" }, "node_modules/test-runner": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/test-runner/-/test-runner-0.5.1.tgz", - "integrity": "sha512-xZA5KZcZvPAdthhrhEKLjnSyx4i9/7jeENu5EqUnKWc7auwJDuTdvYD4MbnG/RCSoPTS5pun0j6QLrmmKPxTcA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/test-runner/-/test-runner-0.10.1.tgz", + "integrity": "sha512-0eQ7u3a4NFa//+SP6MUZX+s2614XTvRRLCTdNAzjMS/zub4ImIMSys7oS+rkBZ9tU+mgyAUJdkrg90MwSPm9qg==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escape-sequences": "^4.0.0", - "array-back": "^2.0.0", - "command-line-args": "^5.0.2", - "command-line-usage": "^4.1.0", - "file-set": "^1.1.1", - "reduce-flatten": "^1.0.1" + "@test-runner/core": "^0.10.0", + "@test-runner/default-view": "^0.6.1", + "@test-runner/live-view": "^0.2.1", + "@test-runner/oneline-view": "^0.2.0", + "@test-runner/tom": "^0.9.1", + "command-line-args": "^5.2.0", + "command-line-usage": "^6.1.1", + "current-module-paths": "^1.1.0", + "file-set": "^5.1.2", + "load-module": "^4.2.1", + "walk-back": "^5.1.0" }, "bin": { "test-runner": "bin/cli.js" }, "engines": { - "node": ">=4" + "node": ">=12.17" } }, - "node_modules/test-runner/node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "node_modules/test-runner/node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", "dev": true, + "license": "MIT", "dependencies": { - "typical": "^2.6.1" + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" }, "engines": { - "node": ">=4" + "node": ">=8.0.0" + } + }, + "node_modules/test-runner/node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/test-runner/node_modules/file-set": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/file-set/-/file-set-1.1.2.tgz", - "integrity": "sha512-xDXI09w+l+mXxWDym7dQXy3PLdo7DygHlAtRnQ6XIMa0iY/qX6+1J75jjwCArCd48yCiMx2+fRn50BTFd45+jQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/file-set/-/file-set-5.1.3.tgz", + "integrity": "sha512-mQ6dqz+z59on3B50IGF3ujNGbZmY1TAeLHpNfhLEeNM6Lky31w3RUlbCyqZWQs0DuZJQU4R2qDuVd9ojyzadcg==", "dev": true, + "license": "MIT", "dependencies": { - "array-back": "^1.0.3", - "glob": "^7.1.0" + "array-back": "^6.2.2", + "glob": "^7.2.0" + }, + "engines": { + "node": ">=12.17" } }, - "node_modules/test-runner/node_modules/file-set/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "node_modules/test-runner/node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/test-runner/node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", "dev": true, + "license": "MIT", "dependencies": { - "typical": "^2.6.0" + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" }, "engines": { - "node": ">=0.12.0" + "node": ">=8.0.0" } }, - "node_modules/test-runner/node_modules/reduce-flatten": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", - "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "node_modules/test-runner/node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/test-runner/node_modules/typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/test-runner/node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "license": "MIT", + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } }, "node_modules/test-value": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", "dev": true, + "license": "MIT", "dependencies": { "array-back": "^2.0.0", "typical": "^2.6.1" @@ -1585,6 +2325,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, + "license": "MIT", "dependencies": { "typical": "^2.6.1" }, @@ -1595,8 +2336,9 @@ "node_modules/test-value/node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", + "dev": true, + "license": "MIT" }, "node_modules/tough-cookie": { "version": "2.5.0", @@ -1630,24 +2372,27 @@ "dev": true }, "node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12.17" } }, "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" }, "node_modules/uglify-js": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.0.tgz", - "integrity": "sha512-x+xdeDWq7FiORDvyIJ0q/waWd4PhjBNOm5dQUOq2AKC0IEjxOS66Ha9tctiVDGcRQuh69K7fgU5oRuTK4cysSg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", "dev": true, + "license": "BSD-2-Clause", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -1657,10 +2402,11 @@ } }, "node_modules/underscore": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", - "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", - "dev": true + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true, + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", @@ -1700,102 +2446,315 @@ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.0.tgz", "integrity": "sha512-Uhxps5yZcVNbLEAnb+xaEEMdgTXl9qAQDzKYejG2AZ7qPwRQ81lozY9ECDbjLPNWm7YsO1IK5rsP1KoQzXAcGA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.17" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "node_modules/wordwrapjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", - "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wordwrapjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", + "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", + "dev": true, + "dependencies": { + "reduce-flatten": "^1.0.1", + "typical": "^2.6.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/reduce-flatten": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", + "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", + "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true, + "license": "Apache-2.0" + } + }, + "dependencies": { + "@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true + }, + "@jsdoc/salty": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", + "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, + "@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", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "dev": true, + "optional": true + }, + "@test-runner/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@test-runner/core/-/core-0.10.0.tgz", + "integrity": "sha512-1m+DowKsEa4IAShyvwj58b9AfbCgZxf9ynPRGixsIzUY03zSEdNB2ItfjMtDPNmoPgbZVxX0DgTgbNfgwRrJQA==", + "dev": true, + "requires": { + "@test-runner/tom": "^0.8.0", + "fsm-base": "^0.7.0" + }, + "dependencies": { + "@test-runner/tom": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@test-runner/tom/-/tom-0.8.1.tgz", + "integrity": "sha512-MbQsG8V5R+yU+O9gkL3oidbxk1PNp/j/ctpAXAvbLOdpD+GMan//MBRstFBzLl+n7R9UNvfW3U8eKlnlQ7SNcw==", + "dev": true, + "requires": { + "composite-class": "^2.0.1", + "create-mixin": "^3.0.0", + "fsm-base": "^0.7.0", + "race-timeout-anywhere": "^2.0.0", + "typical": "^7.1.1" + } + } + } + }, + "@test-runner/default-view": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@test-runner/default-view/-/default-view-0.6.1.tgz", + "integrity": "sha512-/yuHQe+kdtYDnppGg/wc80KQal/3Ril4JOTUUA9esskjZaEpcA6xQ9Cop21rpWhrbmxLqsX1Q48MccunA3/T4w==", + "dev": true, + "requires": { + "ansi-escape-sequences": "^6.2.0" + }, + "dependencies": { + "ansi-escape-sequences": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", + "integrity": "sha512-mBPG9BZy4dMOJQ9BehU6ph8IKslvVppbqZ8APHnpfP+Hsx/hGow5PY46lSQL1vPPi1F5XTtO6p3GcH8O9c0cUg==", + "dev": true, + "requires": { + "array-back": "^6.2.2" + } + } + } + }, + "@test-runner/live-view": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@test-runner/live-view/-/live-view-0.2.1.tgz", + "integrity": "sha512-JnCPfxP4v9cMnFbyVaCp9Oa2bufM842MY24g8EIXmkkhO8UKMc2dH3K9tHX48D1s4kIty2UdT92kb4nxexOC4w==", "dev": true, - "dependencies": { - "reduce-flatten": "^1.0.1", - "typical": "^2.6.1" + "requires": { + "ansi-escape-sequences": "^6.2.0" }, - "engines": { - "node": ">=4.0.0" + "dependencies": { + "ansi-escape-sequences": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", + "integrity": "sha512-mBPG9BZy4dMOJQ9BehU6ph8IKslvVppbqZ8APHnpfP+Hsx/hGow5PY46lSQL1vPPi1F5XTtO6p3GcH8O9c0cUg==", + "dev": true, + "requires": { + "array-back": "^6.2.2" + } + } } }, - "node_modules/wordwrapjs/node_modules/reduce-flatten": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", - "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", + "@test-runner/oneline-view": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@test-runner/oneline-view/-/oneline-view-0.2.0.tgz", + "integrity": "sha512-A0Q3D/V/71vrZjlMu0nCYVjrcI/7q7KD/AVRNCsMysSbalKJh4AcwEeGHPDtUhio7V3Eux4VjJl9HVtgst0Mcw==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@test-runner/default-view": "^0.6.1", + "ansi-escape-sequences": "^6.2.0", + "string-length": "^5.0.1" + }, + "dependencies": { + "ansi-escape-sequences": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-6.2.2.tgz", + "integrity": "sha512-mBPG9BZy4dMOJQ9BehU6ph8IKslvVppbqZ8APHnpfP+Hsx/hGow5PY46lSQL1vPPi1F5XTtO6p3GcH8O9c0cUg==", + "dev": true, + "requires": { + "array-back": "^6.2.2" + } + } } }, - "node_modules/wordwrapjs/node_modules/typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - } - }, - "dependencies": { - "@babel/parser": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", - "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", - "dev": true + "@test-runner/tom": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@test-runner/tom/-/tom-0.9.1.tgz", + "integrity": "sha512-kkr+2AcUCsMANLghAiLdWOF8clUe6a3hhsHeDdPyrPVZNMuooqOl/d5bQm1/YK3D0Xm1aiCs3NIPimZcQhzk+g==", + "dev": true, + "requires": { + "composite-class": "^2.0.1", + "create-mixin": "^3.0.0", + "fsm-base": "^0.7.0", + "race-timeout-anywhere": "^2.0.0", + "typical": "^7.1.1" + } }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, "@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==", "dev": true, "requires": { - "@types/linkify-it": "*", - "@types/mdurl": "*" + "@types/linkify-it": "^5", + "@types/mdurl": "^2" } }, "@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", - "dev": true - }, - "@types/node": { - "version": "11.15.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.15.54.tgz", - "integrity": "sha512-1RWYiq+5UfozGsU6MwJyFX6BtktcT10XRjvcAQmskCtMcW3tPske88lM/nHv7BQG1w9KBXI1zPGuu5PnNCX14g==", - "dev": true - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", "dev": true }, "ajv": { @@ -1817,6 +2776,29 @@ "dev": true, "requires": { "array-back": "^3.0.1" + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" } }, "argparse": { @@ -1829,9 +2811,9 @@ } }, "array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==" + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==" }, "asn1": { "version": "0.2.6", @@ -1931,6 +2913,31 @@ "lodash": "^4.17.15" } }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + } + } + }, + "char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "dev": true + }, "collect-all": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", @@ -1941,6 +2948,21 @@ "stream-via": "^1.0.4" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1960,6 +2982,29 @@ "find-replace": "^3.0.0", "lodash.camelcase": "^4.3.0", "typical": "^4.0.0" + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + } + }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true + } } }, "command-line-tool": { @@ -2027,10 +3072,16 @@ "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", "dev": true }, + "composite-class": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/composite-class/-/composite-class-2.0.1.tgz", + "integrity": "sha512-zEUaKe0wIkAMonjQPZPm4w7aylosaMjqGpHynYT2V05q02I93CWfBxp3kV2iB7anvc/aDvCJN36FzFco3c788A==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "config-master": { @@ -2069,6 +3120,18 @@ "request": "^2.88.2" } }, + "create-mixin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/create-mixin/-/create-mixin-3.0.0.tgz", + "integrity": "sha512-LkdMqnWT9LaqBN4huqpUnMz56Yr1mVSoCduAd2xXefgH/YZP2sXCMAyztXjk4q8hTF/TlcDa+zQW2aTgGdjjKQ==", + "dev": true + }, + "current-module-paths": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.1.tgz", + "integrity": "sha512-8Ga5T8oMXBaSsHq9Gj+bddX7kHSaJKsl2vaAd3ep51eQLkr4W18eFEmEZM5bLo1zrz8tt3jE1U8QK9QGhaLR4g==", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2091,9 +3154,9 @@ "dev": true }, "dmd": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.1.0.tgz", - "integrity": "sha512-0zQIJ873gay1scCTFZvHPWM9mVJBnaylB2NQDI8O9u8O32m00Jb6uxDKexZm8hjTRM7RiWe0FJ32pExHoXdwoQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dmd/-/dmd-6.2.0.tgz", + "integrity": "sha512-uXWxLF1H7TkUAuoHK59/h/ts5cKavm2LnhrIgJWisip4BVzPoXavlwyoprFFn2CzcahKYgvkfaebS6oxzgflkg==", "dev": true, "requires": { "array-back": "^6.2.2", @@ -2101,21 +3164,13 @@ "common-sequence": "^2.0.2", "file-set": "^4.0.2", "handlebars": "^4.7.7", - "marked": "^4.0.12", + "marked": "^4.2.3", "object-get": "^2.1.1", "reduce-flatten": "^3.0.1", "reduce-unique": "^2.0.1", "reduce-without": "^1.0.1", "test-value": "^3.0.0", "walk-back": "^5.1.0" - }, - "dependencies": { - "array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true - } } }, "ecc-jsbn": { @@ -2129,9 +3184,9 @@ } }, "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true }, "escape-string-regexp": { @@ -2189,11 +3244,11 @@ } }, "find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.1.tgz", + "integrity": "sha512-o5/Y8HrCNRuFF5rdNTkX8Vhv6kTFTV0t1zIoigwlCdbkA9qaapRzxvWPND2VvlFa9LBI05Q1i8ml/saMqkOJUQ==", "requires": { - "array-back": "^3.0.1" + "array-back": "^6.2.2" } }, "forever-agent": { @@ -2216,15 +3271,32 @@ "fs-then-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", - "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=", + "integrity": "sha512-X712jAOaWXkemQCAmWeg5rOT2i+KOpWz1Z/txk/cW0qlOu2oQ9H61vc5w3X/iyuUEfq/OyaFJ78/cZAQD1/bgA==", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "fsm-base": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/fsm-base/-/fsm-base-0.7.0.tgz", + "integrity": "sha512-qL/cAOixPK0DmwmZzwzSXPJ8fcetM5iuXF47g7OovQHPGE9gfZdPQklXY47gNZUIjDKan5P27GK5Jk0GC+4wDQ==", + "dev": true, + "requires": { + "array-back": "^6.1.1", + "obso": "^0.7.0" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -2235,27 +3307,33 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "requires": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" @@ -2277,6 +3355,12 @@ "har-schema": "^2.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2291,7 +3375,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -2342,32 +3426,32 @@ "dev": true }, "jsdoc": { - "version": "3.6.10", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz", - "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.3.tgz", + "integrity": "sha512-Nu7Sf35kXJ1MWDZIMAuATRQTg1iIPdzh7tqJ6jjvaU/GfDf+qi5UV8zJR3Mo+/pYFvm8mzay4+6O5EWigaQBQw==", "dev": true, "requires": { - "@babel/parser": "^7.9.4", - "@types/markdown-it": "^12.2.3", + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^14.1.1", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.2", - "klaw": "^4.0.1", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", + "klaw": "^3.0.0", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", "marked": "^4.0.10", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", "underscore": "~1.13.2" } }, "jsdoc-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-7.1.1.tgz", - "integrity": "sha512-0pkuPCzVXiqsDAsVrNFXCkHzlyNepBIDVtwwehry4RJAnZmXtlAz7rh8F9FRz53u3NeynGbex+bpYWwi8lE66A==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-8.0.0.tgz", + "integrity": "sha512-Rnhor0suB1Ds1abjmFkFfKeD+kSMRN9oHMTMZoJVUrmtCGDwXty+sWMA9sa4xbe4UyxuPjhC7tavZ40mDKK6QQ==", "dev": true, "requires": { "array-back": "^6.2.2", @@ -2375,63 +3459,38 @@ "collect-all": "^1.0.4", "file-set": "^4.0.2", "fs-then-native": "^2.0.0", - "jsdoc": "^3.6.10", + "jsdoc": "^4.0.0", "object-to-spawn-args": "^2.0.1", "temp-path": "^1.0.0", "walk-back": "^5.1.0" - }, - "dependencies": { - "array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true - } } }, "jsdoc-parse": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.1.0.tgz", - "integrity": "sha512-n/hDGQJa69IBun1yZAjqzV4gVR41+flZ3bIlm9fKvNe2Xjsd1/+zCo2+R9ls8LxtePgIWbpA1jU7xkB2lRdLLg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.2.1.tgz", + "integrity": "sha512-9viGRUUtWOk/G4V0+nQ6rfLucz5plxh5I74WbNSNm9h9NWugCDVX4jbG8hZP9QqKGpdTPDE+qJXzaYNos3wqTA==", "dev": true, "requires": { "array-back": "^6.2.2", "lodash.omit": "^4.5.0", - "lodash.pick": "^4.4.0", "reduce-extract": "^1.0.0", - "sort-array": "^4.1.4", + "sort-array": "^4.1.5", "test-value": "^3.0.0" - }, - "dependencies": { - "array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true - } } }, "jsdoc-to-markdown": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-7.1.1.tgz", - "integrity": "sha512-CI86d63xAVNO+ENumWwmJ034lYe5iGU5GwjtTA11EuphP9tpnoi4hrKgR/J8uME0D+o4KUpVfwX1fjZhc8dEtg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-8.0.1.tgz", + "integrity": "sha512-qJfNJhkq2C26UYoOdj8L1yheTJlk1veCsxwRejRmj07XZKCn7oSkuPErx6+JoNi8afCaUKdIM5oUu0uF2/T8iw==", "dev": true, "requires": { "array-back": "^6.2.2", "command-line-tool": "^0.8.0", "config-master": "^3.1.0", - "dmd": "^6.1.0", - "jsdoc-api": "^7.1.1", - "jsdoc-parse": "^6.1.0", + "dmd": "^6.2.0", + "jsdoc-api": "^8.0.0", + "jsdoc-parse": "^6.2.1", "walk-back": "^5.1.0" - }, - "dependencies": { - "array-back": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", - "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", - "dev": true - } } }, "json-schema": { @@ -2465,10 +3524,13 @@ } }, "klaw": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz", - "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } }, "lcov-parse": { "version": "1.0.0", @@ -2477,12 +3539,21 @@ "dev": true }, "linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "requires": { + "uc.micro": "^2.0.0" + } + }, + "load-module": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/load-module/-/load-module-4.2.1.tgz", + "integrity": "sha512-Sbfg6R4LjvyThJpqUoADHMjyoI2+cL4msbCQeZ9kkY/CqP/TT2938eftKm7x4I2gd4/A+DEe6nePkbfWYbXwSw==", "dev": true, "requires": { - "uc.micro": "^1.0.1" + "array-back": "^6.2.0" } }, "lodash": { @@ -2499,7 +3570,7 @@ "lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", "dev": true }, "lodash.padend": { @@ -2508,12 +3579,6 @@ "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", "dev": true }, - "lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", - "dev": true - }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -2521,16 +3586,17 @@ "dev": true }, "markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "requires": { "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "dependencies": { "argparse": { @@ -2542,22 +3608,22 @@ } }, "markdown-it-anchor": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.4.1.tgz", - "integrity": "sha512-sLODeRetZ/61KkKLJElaU3NuU2z7MhXf12Ml1WJMSdwpngeofneCRF+JBbat8HiSqhniOMuTemXMrsI7hA6XyA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", "dev": true, "requires": {} }, "marked": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz", - "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true }, "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, "mime-db": { @@ -2576,9 +3642,9 @@ } }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -2626,10 +3692,16 @@ "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==", "dev": true }, + "obso": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/obso/-/obso-0.7.0.tgz", + "integrity": "sha512-iNEHV1r9hFfemR0jFUIxFxqkR9rcvY10C7U/LtKM2w5wS3nSLZEqRnfGY/P8cYzCXHTzTefxMYfnIJkssDhmAg==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -2638,7 +3710,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "performance-now": { @@ -2659,16 +3731,28 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true + }, "qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, + "race-timeout-anywhere": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/race-timeout-anywhere/-/race-timeout-anywhere-2.0.0.tgz", + "integrity": "sha512-kFE+ZL9Esq2JVcHp+ygSI8bTSAfJuXi8nQCDVAD2zLYJ/TMzObyLLbVaXA99JFVtsibIF7A1IqJRfiC4H+muxQ==", + "dev": true + }, "reduce-extract": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", - "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=", + "integrity": "sha512-QF8vjWx3wnRSL5uFMyCjDeDc5EBMiryoT9tz94VvgjKfzecHAVnqmXAwQDcr7X4JmLc2cjkjFGCVzhMqDjgR9g==", "dev": true, "requires": { "test-value": "^1.0.1" @@ -2677,7 +3761,7 @@ "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { "typical": "^2.6.0" @@ -2686,7 +3770,7 @@ "test-value": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", - "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=", + "integrity": "sha512-wrsbRo7qP+2Je8x8DsK8ovCGyxe3sYfQwOraIY/09A2gFXU9DYKiTF14W4ki/01AEh56kMzAmlj9CaHGDDUBJA==", "dev": true, "requires": { "array-back": "^1.0.2", @@ -2696,7 +3780,7 @@ "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true } } @@ -2716,7 +3800,7 @@ "reduce-without": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", - "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=", + "integrity": "sha512-zQv5y/cf85sxvdrKPlfcRzlDn/OqKFThNimYmsS3flmkioKvkUGn2Qg9cJVoQiEvdxFGLE0MQER/9fZ9sUqdxg==", "dev": true, "requires": { "test-value": "^2.0.0" @@ -2725,7 +3809,7 @@ "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { "typical": "^2.6.0" @@ -2734,7 +3818,7 @@ "test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", + "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", "dev": true, "requires": { "array-back": "^1.0.3", @@ -2744,7 +3828,7 @@ "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true } } @@ -2778,23 +3862,38 @@ } }, "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", "dev": true, "requires": { - "lodash": "^4.17.14" + "lodash": "^4.17.21" } }, "rollup": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.7.4.tgz", - "integrity": "sha512-nc86fETLHdozhRWlW/uNVIQ7ODuA1vU2/L8znAxP9TNMx1NA6GTth3llqoxxCle2kkyui+OfGzbKaQxD60NJjA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, "requires": { - "@types/estree": "0.0.39", - "@types/node": "^11.11.6", - "acorn": "^6.1.1" + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "@types/estree": "1.0.5", + "fsevents": "~2.3.2" } }, "safe-buffer": { @@ -2810,9 +3909,9 @@ "dev": true }, "sort-array": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.4.tgz", - "integrity": "sha512-GVFN6Y1sHKrWaSYOJTk9093ZnrBMc9sP3nuhANU44S4xg3rE6W5Z5WyamuT8VpMBbssnetx5faKCua0LEmUnSw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.5.tgz", + "integrity": "sha512-Ya4peoS1fgFN42RN1REk2FgdNOeLIEMKFGJvs7VTP3OklF8+kl2SkpVliZ4tk/PurWsrWRsdNdU+tgyOBkB9sA==", "dev": true, "requires": { "array-back": "^5.0.0", @@ -2865,7 +3964,7 @@ "stream-connect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", - "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=", + "integrity": "sha512-68Kl+79cE0RGKemKkhxTSg8+6AGrqBt+cbZAXevg2iJ6Y3zX4JhA/sZeGzLpxW9cXhmqAcE7KnJCisUmIUfnFQ==", "dev": true, "requires": { "array-back": "^1.0.2" @@ -2874,7 +3973,7 @@ "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", + "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", "dev": true, "requires": { "typical": "^2.6.0" @@ -2883,7 +3982,7 @@ "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true } } @@ -2894,12 +3993,40 @@ "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", "dev": true }, + "string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dev": true, + "requires": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, "table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", @@ -2930,73 +4057,102 @@ } } }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, "temp-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", - "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=", + "integrity": "sha512-TvmyH7kC6ZVTYkqCODjJIbgvu0FKiwQpZ4D1aknE7xpcDf/qEOB8KZEK5ef2pfbVoiBhNWs3yx4y+ESMtNYmlg==", "dev": true }, "test-runner": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/test-runner/-/test-runner-0.5.1.tgz", - "integrity": "sha512-xZA5KZcZvPAdthhrhEKLjnSyx4i9/7jeENu5EqUnKWc7auwJDuTdvYD4MbnG/RCSoPTS5pun0j6QLrmmKPxTcA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/test-runner/-/test-runner-0.10.1.tgz", + "integrity": "sha512-0eQ7u3a4NFa//+SP6MUZX+s2614XTvRRLCTdNAzjMS/zub4ImIMSys7oS+rkBZ9tU+mgyAUJdkrg90MwSPm9qg==", "dev": true, "requires": { - "ansi-escape-sequences": "^4.0.0", - "array-back": "^2.0.0", - "command-line-args": "^5.0.2", - "command-line-usage": "^4.1.0", - "file-set": "^1.1.1", - "reduce-flatten": "^1.0.1" + "@test-runner/core": "^0.10.0", + "@test-runner/default-view": "^0.6.1", + "@test-runner/live-view": "^0.2.1", + "@test-runner/oneline-view": "^0.2.0", + "@test-runner/tom": "^0.9.1", + "command-line-args": "^5.2.0", + "command-line-usage": "^6.1.1", + "current-module-paths": "^1.1.0", + "file-set": "^5.1.2", + "load-module": "^4.2.1", + "walk-back": "^5.1.0" }, "dependencies": { - "array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", + "command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", "dev": true, "requires": { - "typical": "^2.6.1" + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "dependencies": { + "array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true + } } }, "file-set": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/file-set/-/file-set-1.1.2.tgz", - "integrity": "sha512-xDXI09w+l+mXxWDym7dQXy3PLdo7DygHlAtRnQ6XIMa0iY/qX6+1J75jjwCArCd48yCiMx2+fRn50BTFd45+jQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/file-set/-/file-set-5.1.3.tgz", + "integrity": "sha512-mQ6dqz+z59on3B50IGF3ujNGbZmY1TAeLHpNfhLEeNM6Lky31w3RUlbCyqZWQs0DuZJQU4R2qDuVd9ojyzadcg==", "dev": true, "requires": { - "array-back": "^1.0.3", - "glob": "^7.1.0" + "array-back": "^6.2.2", + "glob": "^7.2.0" + } + }, + "reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "dev": true + }, + "table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dev": true, + "requires": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" }, "dependencies": { "array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", - "dev": true, - "requires": { - "typical": "^2.6.0" - } + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "dev": true } } }, - "reduce-flatten": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", - "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", - "dev": true - }, "typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", "dev": true + }, + "wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dev": true, + "requires": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + } } } }, @@ -3022,7 +4178,7 @@ "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", + "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", "dev": true } } @@ -3053,27 +4209,27 @@ "dev": true }, "typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz", + "integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==" }, "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, "uglify-js": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.0.tgz", - "integrity": "sha512-x+xdeDWq7FiORDvyIJ0q/waWd4PhjBNOm5dQUOq2AKC0IEjxOS66Ha9tctiVDGcRQuh69K7fgU5oRuTK4cysSg==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", "dev": true, "optional": true }, "underscore": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", - "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, "uri-js": { @@ -3111,7 +4267,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, "wordwrapjs": { @@ -3141,7 +4297,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "xmlcreate": { diff --git a/package.json b/package.json index 7431e10..548d85e 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,16 @@ "description": "A mature, feature-complete library to parse command-line options.", "repository": "https://github.com/75lb/command-line-args", "scripts": { - "test": "npm run dist && npm run test:js && npm run test:mjs", - "test:js": "node dist/tests.js", - "test:mjs": "node --experimental-modules test/tests.mjs", - "test:ci": "npm run test:js", - "docs": "jsdoc2md -c jsdoc.conf index.mjs > doc/API.md && jsdoc2md -c jsdoc.conf lib/option-definition.mjs > doc/option-definition.md", + "test": "test-runner test/**/*.js", + "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" }, - "main": "dist/index.js", + "type": "module", + "exports": { + "import": "./index.js", + "require": "./dist/index.cjs" + }, "keywords": [ "argv", "parse", @@ -29,25 +30,25 @@ "author": "Lloyd Brookes <75pound@gmail.com>", "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": ">=12.20" }, "files": [ - "index.mjs", + "index.js", "lib", "dist/index.js", "dist/index.mjs" ], "devDependencies": { "coveralls": "^3.1.1", - "jsdoc-to-markdown": "^7.1.1", - "rollup": "~1.7.4", - "test-runner": "^0.5.1" + "jsdoc-to-markdown": "^8.0.1", + "rollup": "~4.18.0", + "test-runner": "^0.10.1" }, "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", + "array-back": "^6.2.2", + "find-replace": "^5.0.1", "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" + "typical": "^7.1.1" }, "standard": { "ignore": [ diff --git a/test/alias-cluster.js b/test/alias-cluster.js new file mode 100644 index 0000000..4a7f2d6 --- /dev/null +++ b/test/alias-cluster.js @@ -0,0 +1,76 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +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' } + ] + + const argv = ['-vrf', 'yeah'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + verbose: true, + recursive: true, + file: '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' } + ] + + const argv = ['-f', 'yeah', '-vr'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + verbose: true, + recursive: true, + file: 'yeah' + }) +}) + +tom.test('three string options', function () { + const optionDefinitions = [ + { name: 'plugin', alias: 'p' }, + { name: 'depth', alias: 'd' }, + { name: 'file', alias: 'f' } + ] + + 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'] + }) +}) + +export default tom diff --git a/test/alias-cluster.mjs b/test/alias-cluster.mjs deleted file mode 100644 index 4eb8671..0000000 --- a/test/alias-cluster.mjs +++ /dev/null @@ -1,50 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('alias-cluster: two flags, one option', function () { - const optionDefinitions = [ - { name: 'flagA', alias: 'a', type: Boolean }, - { name: 'flagB', alias: 'b', type: Boolean }, - { name: 'three', alias: 'c' } - ] - - const argv = ['-abc', 'yeah'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - flagA: true, - flagB: true, - three: 'yeah' - }) -}) - -runner.test('alias-cluster: two flags, one option 2', function () { - const optionDefinitions = [ - { name: 'flagA', alias: 'a', type: Boolean }, - { name: 'flagB', alias: 'b', type: Boolean }, - { name: 'three', alias: 'c' } - ] - - const argv = ['-c', 'yeah', '-ab'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - flagA: true, - flagB: true, - three: 'yeah' - }) -}) - -runner.test('alias-cluster: three string options', function () { - const optionDefinitions = [ - { name: 'flagA', alias: 'a' }, - { name: 'flagB', alias: 'b' }, - { name: 'three', alias: 'c' } - ] - - 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 new file mode 100644 index 0000000..f787108 --- /dev/null +++ b/test/alias-whitespace.js @@ -0,0 +1,51 @@ +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.mjs b/test/alias.js similarity index 74% rename from test/alias.mjs rename to test/alias.js index 5a9663f..ab2742f 100644 --- a/test/alias.mjs +++ b/test/alias.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('alias') -runner.test('alias: one string alias', function () { +tom.test('one string alias', function () { const optionDefinitions = [ { name: 'verbose', alias: 'v' } ] @@ -14,7 +14,7 @@ runner.test('alias: one string alias', function () { }) }) -runner.test('alias: one boolean alias', function () { +tom.test('one boolean alias', function () { const optionDefinitions = [ { name: 'dry-run', alias: 'd', type: Boolean } ] @@ -24,7 +24,7 @@ runner.test('alias: one boolean alias', function () { }) }) -runner.test('alias: one boolean, one string', function () { +tom.test('one boolean, one string', function () { const optionDefinitions = [ { name: 'verbose', alias: 'v', type: Boolean }, { name: 'colour', alias: 'c' } @@ -35,3 +35,5 @@ runner.test('alias: one boolean, one string', function () { colour: null }) }) + +export default tom diff --git a/test/ambiguous-input.mjs b/test/ambiguous-input.mjs deleted file mode 100644 index 5eaa274..0000000 --- a/test/ambiguous-input.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('ambiguous input: value looks like an option 1', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['-c', 'red'] }), { - colour: 'red' - }) -}) - -runner.test('ambiguous input: value looks like an option 2', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ] - const argv = ['--colour', '--red'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'UNKNOWN_OPTION' - ) -}) - -runner.test('ambiguous input: value looks like an option 3', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ] - a.doesNotThrow(function () { - commandLineArgs(optionDefinitions, { argv: ['--colour=--red'] }) - }) -}) - -runner.test('ambiguous input: value looks like an option 4', function () { - const optionDefinitions = [ - { name: 'colour', type: String, alias: 'c' } - ] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour=--red'] }), { - colour: '--red' - }) -}) diff --git a/test/bad-input-ambiguous.js b/test/bad-input-ambiguous.js new file mode 100644 index 0000000..ff9749f --- /dev/null +++ b/test/bad-input-ambiguous.js @@ -0,0 +1,48 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('bad-input-ambiguous') + +tom.test('value looks like an option 1', function () { + const optionDefinitions = [ + { name: 'colour', alias: 'c' } + ] + const argv = ['-c', 'red'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + colour: 'red' + }) +}) + +tom.test('value looks like an option 2', function () { + const optionDefinitions = [ + { name: 'colour', alias: 'c' } + ] + const argv = ['--colour', '--red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'UNKNOWN_OPTION' + ) +}) + +tom.test('value looks like an option 3', function () { + const optionDefinitions = [ + { name: 'colour', alias: 'c' } + ] + const argv = ['--colour=--red'] + a.doesNotThrow(function () { + commandLineArgs(optionDefinitions, { argv }) + }) +}) + +tom.test('value looks like an option 4', function () { + const optionDefinitions = [ + { name: 'colour', alias: 'c' } + ] + const argv = ['--colour=--red'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + colour: '--red' + }) +}) + +export default tom diff --git a/test/bad-input-empty-string.js b/test/bad-input-empty-string.js new file mode 100644 index 0000000..8559db6 --- /dev/null +++ b/test/bad-input-empty-string.js @@ -0,0 +1,61 @@ +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 new file mode 100644 index 0000000..f28cd44 --- /dev/null +++ b/test/bad-input.js @@ -0,0 +1,58 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +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) +}) + +tom.test('missing option value should be null', function () { + const optionDefinitions = [ + { name: 'colour' }, + { name: 'files' } + ] + const argv = ['--colour'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + 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 }), { + colour: null, + files: 'yeah' + }) +}) + +tom.test('handles arrays with relative paths', function () { + const optionDefinitions = [ + { name: 'colours', multiple: true } + ] + const argv = ['--colours', '../what', '../ever'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + colours: ['../what', '../ever'] + }) +}) + +tom.test('non-strings in argv', function () { + const optionDefinitions = [ + { name: 'one', type: Number } + ] + const argv = ['--one', 1] + const result = commandLineArgs(optionDefinitions, { argv }) + a.deepStrictEqual(result, { one: 1 }) +}) + +export default tom diff --git a/test/bad-input.mjs b/test/bad-input.mjs deleted file mode 100644 index 048bad6..0000000 --- a/test/bad-input.mjs +++ /dev/null @@ -1,60 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('bad-input: missing option value should be null', function () { - const optionDefinitions = [ - { name: 'colour', type: String }, - { name: 'files' } - ] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour'] }), { - colour: null - }) - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv: ['--colour', '--files', 'yeah'] }), { - colour: null, - files: 'yeah' - }) -}) - -runner.test('bad-input: handles arrays with relative paths', function () { - const optionDefinitions = [ - { name: 'colours', type: String, multiple: true } - ] - const argv = ['--colours', '../what', '../ever'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { - colours: ['../what', '../ever'] - }) -}) - -runner.test('bad-input: 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='] - }) -}) - -runner.test('bad-input: non-strings in argv', function () { - const optionDefinitions = [ - { name: 'one', type: Number } - ] - const argv = ['--one', 1] - const result = commandLineArgs(optionDefinitions, { argv }) - a.deepStrictEqual(result, { one: 1 }) -}) diff --git a/test/camel-case.mjs b/test/camel-case.js similarity index 87% rename from test/camel-case.mjs rename to test/camel-case.js index 814e4d6..8e74240 100644 --- a/test/camel-case.mjs +++ b/test/camel-case.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('camel-case') -runner.test('camel-case: regular', function () { +tom.test('regular', function () { const optionDefinitions = [ { name: 'one-two' }, { name: 'three', type: Boolean } @@ -17,7 +17,7 @@ runner.test('camel-case: regular', function () { }) }) -runner.test('camel-case: grouped', function () { +tom.test('grouped', function () { const optionDefinitions = [ { name: 'one-one', group: 'a' }, { name: 'two-two', group: 'a' }, @@ -46,7 +46,7 @@ runner.test('camel-case: grouped', function () { }) }) -runner.test('camel-case: grouped with unknowns', function () { +tom.test('grouped with unknowns', function () { const optionDefinitions = [ { name: 'one-one', group: 'a' }, { name: 'two-two', group: 'a' }, @@ -75,3 +75,5 @@ runner.test('camel-case: grouped with unknowns', function () { _unknown: ['--five'] }) }) + +export default tom diff --git a/test/case-insensitive.mjs b/test/case-insensitive.mjs deleted file mode 100644 index 5e60175..0000000 --- a/test/case-insensitive.mjs +++ /dev/null @@ -1,72 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('case-insensitive: 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' - ) -}) - -runner.test('case-insensitive: 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 - }) -}) - -runner.test('case-insensitive: 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' - }) -}) - -runner.test('case-insensitive: 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 - }) -}) - -runner.test('case-insensitive: 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'] - }) -}) - -runner.test('case-insensitive: 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 - }) -}) diff --git a/test/default-option.mjs b/test/default-option-multiple.js similarity index 53% rename from test/default-option.mjs rename to test/default-option-multiple.js index 9c1c8d0..83307e6 100644 --- a/test/default-option.mjs +++ b/test/default-option-multiple.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('default-option-multiple') -runner.test('defaultOption: multiple string', function () { +tom.test('multiple string', function () { const optionDefinitions = [ { name: 'files', defaultOption: true, multiple: true } ] @@ -14,18 +14,7 @@ runner.test('defaultOption: multiple string', function () { }) }) -runner.test('defaultOption: 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' } - ) -}) - -runner.test('defaultOption: multiple-defaultOption values spread out', function () { +tom.test('multiple-defaultOption values spread out', function () { const optionDefinitions = [ { name: 'one' }, { name: 'two' }, @@ -39,21 +28,7 @@ runner.test('defaultOption: multiple-defaultOption values spread out', function }) }) -runner.test('defaultOption: 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'] - }) -}) - -runner.test('defaultOption: multiple-defaultOption values spread out 2', function () { +tom.test('multiple-defaultOption values spread out 2', function () { const optionDefinitions = [ { name: 'one', type: Boolean }, { name: 'two' }, @@ -66,3 +41,20 @@ runner.test('defaultOption: multiple-defaultOption values spread out 2', functio 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 new file mode 100644 index 0000000..e29982c --- /dev/null +++ b/test/default-option-single.js @@ -0,0 +1,51 @@ +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 new file mode 100644 index 0000000..a486b60 --- /dev/null +++ b/test/default-option.js @@ -0,0 +1,60 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('default-option') + +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-value.js b/test/default-value.js new file mode 100644 index 0000000..d3c8334 --- /dev/null +++ b/test/default-value.js @@ -0,0 +1,161 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('default-value') + +tom.test('default value', function () { + const optionDefinitions = [ + { name: 'one' }, + { name: 'two', defaultValue: 'two' } + ] + const argv = ['--one', '1'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + one: '1', + two: 'two' + }) +}) + +tom.test('default value 2', function () { + const optionDefinitions = [ + { name: 'two', defaultValue: 'two' } + ] + const argv = [] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: 'two' }) +}) + +tom.test('default value 3', function () { + const optionDefinitions = [ + { name: 'two', defaultValue: 'two' } + ] + const argv = ['--two', 'zwei'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: 'zwei' }) +}) + +tom.test('default value 4', function () { + const optionDefinitions = [ + { name: 'two', multiple: true, defaultValue: ['two', 'zwei'] } + ] + const argv = ['--two', 'duo'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: ['duo'] }) +}) + +tom.test('default value 5', function () { + const optionDefinitions = [ + { name: 'two', multiple: true, defaultValue: ['two', 'zwei'] } + ] + const argv = [] + const result = commandLineArgs(optionDefinitions, { argv }) + a.deepStrictEqual(result, { two: ['two', 'zwei'] }) +}) + +tom.test('array as defaultOption', function () { + const optionDefinitions = [ + { name: 'two', multiple: true, defaultValue: ['two', 'zwei'], defaultOption: true } + ] + const argv = ['duo'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { two: ['duo'] }) +}) + +tom.test('falsy default values', function () { + const optionDefinitions = [ + { name: 'one', defaultValue: 0 }, + { name: 'two', defaultValue: false } + ] + + const argv = [] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + one: 0, + two: false + }) +}) + +tom.test('is arrayifed if multiple set', function () { + const optionDefinitions = [ + { name: 'one', defaultValue: 0, multiple: true } + ] + + let argv = [] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + one: [0] + }) + argv = ['--one', '2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + one: ['2'] + }) +}) + +tom.test('combined with defaultOption', function () { + const optionDefinitions = [ + { name: 'path', defaultOption: true, defaultValue: './' } + ] + + let argv = ['--path', 'test'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: 'test' + }) + argv = ['test'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: 'test' + }) + argv = [] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: './' + }) +}) + +tom.test('combined with multiple and defaultOption', function () { + const optionDefinitions = [ + { name: 'path', multiple: true, defaultOption: true, defaultValue: './' } + ] + + let argv = ['--path', 'test1', 'test2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test1', 'test2'] + }) + argv = ['--path', 'test'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test'] + }) + argv = ['test1', 'test2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test1', 'test2'] + }) + argv = ['test'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test'] + }) + argv = [] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['./'] + }) +}) + +tom.test('array default combined with multiple and defaultOption', function () { + const optionDefinitions = [ + { name: 'path', multiple: true, defaultOption: true, defaultValue: ['./'] } + ] + + let argv = ['--path', 'test1', 'test2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test1', 'test2'] + }) + argv = ['--path', 'test'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test'] + }) + argv = ['test1', 'test2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test1', 'test2'] + }) + argv = ['test'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['test'] + }) + argv = [] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv }), { + path: ['./'] + }) +}) + +export default tom diff --git a/test/default-value.mjs b/test/default-value.mjs deleted file mode 100644 index c7923f9..0000000 --- a/test/default-value.mjs +++ /dev/null @@ -1,153 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('default value', function () { - const defs = [ - { name: 'one' }, - { name: 'two', defaultValue: 'two' } - ] - const argv = ['--one', '1'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: '1', - two: 'two' - }) -}) - -runner.test('default value 2', function () { - const defs = [{ name: 'two', defaultValue: 'two' }] - const argv = [] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: 'two' }) -}) - -runner.test('default value 3', function () { - const defs = [{ name: 'two', defaultValue: 'two' }] - const argv = ['--two', 'zwei'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: 'zwei' }) -}) - -runner.test('default value 4', function () { - const defs = [{ name: 'two', multiple: true, defaultValue: ['two', 'zwei'] }] - const argv = ['--two', 'duo'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: ['duo'] }) -}) - -runner.test('default value 5', function () { - const defs = [ - { name: 'two', multiple: true, defaultValue: ['two', 'zwei'] } - ] - const argv = [] - const result = commandLineArgs(defs, { argv }) - a.deepStrictEqual(result, { two: ['two', 'zwei'] }) -}) - -runner.test('default value: array as defaultOption', function () { - const defs = [ - { name: 'two', multiple: true, defaultValue: ['two', 'zwei'], defaultOption: true } - ] - const argv = ['duo'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { two: ['duo'] }) -}) - -runner.test('default value: falsy default values', function () { - const defs = [ - { name: 'one', defaultValue: 0 }, - { name: 'two', defaultValue: false } - ] - - const argv = [] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: 0, - two: false - }) -}) - -runner.test('default value: is arrayifed if multiple set', function () { - const defs = [ - { name: 'one', defaultValue: 0, multiple: true } - ] - - let argv = [] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: [0] - }) - argv = ['--one', '2'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - one: ['2'] - }) -}) - -runner.test('default value: combined with defaultOption', function () { - const defs = [ - { name: 'path', defaultOption: true, defaultValue: './' } - ] - - let argv = ['--path', 'test'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: 'test' - }) - argv = ['test'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: 'test' - }) - argv = [] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: './' - }) -}) - -runner.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(defs, { argv }), { - path: ['test1', 'test2'] - }) - argv = ['--path', 'test'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }) - argv = ['test1', 'test2'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test1', 'test2'] - }) - argv = ['test'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }) - argv = [] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['./'] - }) -}) - -runner.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(defs, { argv }), { - path: ['test1', 'test2'] - }) - argv = ['--path', 'test'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }) - argv = ['test1', 'test2'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test1', 'test2'] - }) - argv = ['test'] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['test'] - }) - argv = [] - a.deepStrictEqual(commandLineArgs(defs, { argv }), { - path: ['./'] - }) -}) diff --git a/test/detect-process-argv.js b/test/detect-process-argv.js new file mode 100644 index 0000000..69eebe7 --- /dev/null +++ b/test/detect-process-argv.js @@ -0,0 +1,38 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('detect-process-argv') + +tom.test('should automatically remove first two argv items', function () { + const optionDefinitions = [ + { name: 'one' } + ] + process.argv = ['node', 'filename', '--one', 'eins'] + a.deepStrictEqual(commandLineArgs(optionDefinitions), { + 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 }), { + one: 'eins' + }) +}) + +tom.test('process.argv is left untouched', function () { + const optionDefinitions = [ + { name: 'one' } + ] + process.argv = ['node', 'filename', '--one', 'eins'] + a.deepStrictEqual(commandLineArgs(optionDefinitions), { + one: 'eins' + }) + a.deepStrictEqual(process.argv, ['node', 'filename', '--one', 'eins']) +}) + +export default tom diff --git a/test/detect-process-argv.mjs b/test/detect-process-argv.mjs deleted file mode 100644 index 6f34182..0000000 --- a/test/detect-process-argv.mjs +++ /dev/null @@ -1,27 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('detect process.argv: should automatically remove first two argv items', function () { - process.argv = ['node', 'filename', '--one', 'eins'] - a.deepStrictEqual(commandLineArgs({ name: 'one' }), { - one: 'eins' - }) -}) - -runner.test('detect process.argv: should automatically remove first two argv items 2', function () { - process.argv = ['node', 'filename', '--one', 'eins'] - a.deepStrictEqual(commandLineArgs({ name: 'one' }, { argv: process.argv }), { - one: 'eins' - }) -}) - -runner.test('process.argv is left untouched', function () { - process.argv = ['node', 'filename', '--one', 'eins'] - a.deepStrictEqual(commandLineArgs({ name: 'one' }), { - one: 'eins' - }) - a.deepStrictEqual(process.argv, ['node', 'filename', '--one', 'eins']) -}) diff --git a/test/detect-process-execArgv.mjs b/test/detect-process-execArgv.js similarity index 65% rename from test/detect-process-execArgv.mjs rename to test/detect-process-execArgv.js index 26e1b2b..5271d46 100644 --- a/test/detect-process-execArgv.mjs +++ b/test/detect-process-execArgv.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('detect-process-execArgv') -runner.test('detect process.execArgv: should automatically remove first argv items', function () { +tom.test('should automatically remove first argv items', function () { const origArgv = process.argv const origExecArgv = process.execArgv process.argv = ['node', '--one', 'eins'] @@ -15,3 +15,5 @@ runner.test('detect process.execArgv: should automatically remove first argv ite process.argv = origArgv process.execArgv = origExecArgv }) + +export default tom diff --git a/test/exceptions-already-set.mjs b/test/exceptions-already-set.js similarity index 54% rename from test/exceptions-already-set.mjs rename to test/exceptions-already-set.js index 1e79ba4..1230c65 100644 --- a/test/exceptions-already-set.mjs +++ b/test/exceptions-already-set.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('exceptions-already-set') -runner.test('exceptions-already-set: long option', function () { +tom.test('long option', function () { const optionDefinitions = [ { name: 'one', type: Boolean } ] @@ -15,7 +15,7 @@ runner.test('exceptions-already-set: long option', function () { ) }) -runner.test('exceptions-already-set: short option', function () { +tom.test('short option', function () { const optionDefinitions = [ { name: 'one', type: Boolean, alias: 'o' } ] @@ -26,7 +26,7 @@ runner.test('exceptions-already-set: short option', function () { ) }) -runner.test('exceptions-already-set: --option=value', function () { +tom.test('--option=value', function () { const optionDefinitions = [ { name: 'one' } ] @@ -37,7 +37,7 @@ runner.test('exceptions-already-set: --option=value', function () { ) }) -runner.test('exceptions-already-set: combined short option', function () { +tom.test('combined short option', function () { const optionDefinitions = [ { name: 'one', type: Boolean, alias: 'o' } ] @@ -47,3 +47,27 @@ runner.test('exceptions-already-set: combined short option', function () { err => err.name === 'ALREADY_SET' && err.optionName === 'one' ) }) + +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 new file mode 100644 index 0000000..e857767 --- /dev/null +++ b/test/exceptions-invalid-definition.js @@ -0,0 +1,132 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('exceptions-invalid-definition') + +tom.test('throws when no definition.name specified', function () { + const optionDefinitions = [ + { something: 'one' }, + { something: 'two' } + ] + const argv = ['--one', '--two'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('throws if dev set a numeric alias', function () { + const optionDefinitions = [ + { name: 'colours', alias: '1' } + ] + const argv = ['--colours', 'red'] + + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('throws if dev set an alias of "-"', function () { + const optionDefinitions = [ + { name: 'colours', alias: '-' } + ] + const argv = ['--colours', 'red'] + + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('multi-character alias', function () { + const optionDefinitions = [ + { name: 'one', alias: 'aa' } + ] + const argv = ['--one', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('invalid type values 1', function () { + const argv = ['--one', 'something'] + a.throws( + () => commandLineArgs([{ name: 'one', type: 'string' }], { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('invalid type values 2', function () { + const argv = ['--one', 'something'] + a.throws( + () => commandLineArgs([{ name: 'one', type: 234 }], { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('invalid type values 3', function () { + const argv = ['--one', 'something'] + a.throws( + () => commandLineArgs([{ name: 'one', type: {} }], { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('invalid type values 4', function () { + const argv = ['--one', 'something'] + a.doesNotThrow(function () { + commandLineArgs([{ name: 'one', type: function () {} }], { argv }) + }, /invalid/i) +}) + +tom.test('duplicate name', function () { + const optionDefinitions = [ + { name: 'colours' }, + { name: 'colours' } + ] + const argv = ['--colours', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('duplicate alias', function () { + const optionDefinitions = [ + { name: 'one', alias: 'a' }, + { name: 'two', alias: 'a' } + ] + const argv = ['--one', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('multiple defaultOption', function () { + const optionDefinitions = [ + { name: 'one', defaultOption: true }, + { name: 'two', defaultOption: true } + ] + const argv = ['--one', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +tom.test('err-invalid-defaultOption: defaultOption on a Boolean type', function () { + const optionDefinitions = [ + { name: 'one', type: Boolean, defaultOption: true } + ] + const argv = ['--one', 'red'] + a.throws( + () => commandLineArgs(optionDefinitions, { argv }), + err => err.name === 'INVALID_DEFINITIONS' + ) +}) + +export default tom diff --git a/test/exceptions-invalid-definition.mjs b/test/exceptions-invalid-definition.mjs deleted file mode 100644 index a47e32b..0000000 --- a/test/exceptions-invalid-definition.mjs +++ /dev/null @@ -1,191 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('err-invalid-definition: throws when no definition.name specified', function () { - const optionDefinitions = [ - { something: 'one' }, - { something: 'two' } - ] - const argv = ['--one', '--two'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: throws if dev set a numeric alias', function () { - const optionDefinitions = [ - { name: 'colours', alias: '1' } - ] - const argv = ['--colours', 'red'] - - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: throws if dev set an alias of "-"', function () { - const optionDefinitions = [ - { name: 'colours', alias: '-' } - ] - const argv = ['--colours', 'red'] - - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: multi-character alias', function () { - const optionDefinitions = [ - { name: 'one', alias: 'aa' } - ] - const argv = ['--one', 'red'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: invalid type values 1', function () { - const argv = ['--one', 'something'] - a.throws( - () => commandLineArgs([{ name: 'one', type: 'string' }], { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: invalid type values 2', function () { - const argv = ['--one', 'something'] - a.throws( - () => commandLineArgs([{ name: 'one', type: 234 }], { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: invalid type values 3', function () { - const argv = ['--one', 'something'] - a.throws( - () => commandLineArgs([{ name: 'one', type: {} }], { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: invalid type values 4', function () { - const argv = ['--one', 'something'] - a.doesNotThrow(function () { - commandLineArgs([{ name: 'one', type: function () {} }], { argv }) - }, /invalid/i) -}) - -runner.test('err-invalid-definition: duplicate name', function () { - const optionDefinitions = [ - { name: 'colours' }, - { name: 'colours' } - ] - const argv = ['--colours', 'red'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: 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' - ) -}) - -runner.test('err-invalid-definition: 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' - }) -}) - -runner.test('err-invalid-definition: duplicate alias', function () { - const optionDefinitions = [ - { name: 'one', alias: 'a' }, - { name: 'two', alias: 'a' } - ] - const argv = ['--one', 'red'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: 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' - ) -}) - -runner.test('err-invalid-definition: 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' - }) -}) - -runner.test('err-invalid-definition: multiple defaultOption', function () { - const optionDefinitions = [ - { name: 'one', defaultOption: true }, - { name: 'two', defaultOption: true } - ] - const argv = ['--one', 'red'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) - -runner.test('err-invalid-definition: 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' - ) -}) - -runner.test('err-invalid-defaultOption: defaultOption on a Boolean type', function () { - const optionDefinitions = [ - { name: 'one', type: Boolean, defaultOption: true } - ] - const argv = ['--one', 'red'] - a.throws( - () => commandLineArgs(optionDefinitions, { argv }), - err => err.name === 'INVALID_DEFINITIONS' - ) -}) diff --git a/test/exceptions-unknowns.mjs b/test/exceptions-unknowns.js similarity index 71% rename from test/exceptions-unknowns.mjs rename to test/exceptions-unknowns.js index d9dc930..93ea0ef 100644 --- a/test/exceptions-unknowns.mjs +++ b/test/exceptions-unknowns.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('exceptions-unknowns') -runner.test('exceptions-unknowns: unknown option', function () { +tom.test('unknown option', function () { const optionDefinitions = [ { name: 'one', type: Number } ] @@ -14,7 +14,7 @@ runner.test('exceptions-unknowns: unknown option', function () { ) }) -runner.test('exceptions-unknowns: 1 unknown option, 1 unknown value', function () { +tom.test('1 unknown option, 1 unknown value', function () { const optionDefinitions = [ { name: 'one', type: Number } ] @@ -24,7 +24,7 @@ runner.test('exceptions-unknowns: 1 unknown option, 1 unknown value', function ( ) }) -runner.test('exceptions-unknowns: unknown alias', function () { +tom.test('unknown alias', function () { const optionDefinitions = [ { name: 'one', type: Number } ] @@ -34,17 +34,18 @@ runner.test('exceptions-unknowns: unknown alias', function () { ) }) -runner.test('exceptions-unknowns: unknown combined aliases', function () { +tom.test('unknown combined aliases', function () { const optionDefinitions = [ { name: 'one', type: Number } ] + const argv = ['-sdf'] a.throws( - () => commandLineArgs(optionDefinitions, { argv: ['-sdf'] }), + () => commandLineArgs(optionDefinitions, { argv }), err => err.name === 'UNKNOWN_OPTION' && err.optionName === '-s' ) }) -runner.test('exceptions-unknowns: unknown value', function () { +tom.test('unknown value', function () { const optionDefinitions = [ { name: 'one' } ] @@ -55,7 +56,7 @@ runner.test('exceptions-unknowns: unknown value', function () { ) }) -runner.test('exceptions-unknowns: unknown value with singular defaultOption', function () { +tom.test('unknown value with singular defaultOption', function () { const optionDefinitions = [ { name: 'one', defaultOption: true } ] @@ -66,7 +67,7 @@ runner.test('exceptions-unknowns: unknown value with singular defaultOption', fu ) }) -runner.test('exceptions-unknowns: no unknown value exception with multiple defaultOption', function () { +tom.test('no unknown value exception with multiple defaultOption', function () { const optionDefinitions = [ { name: 'one', defaultOption: true, multiple: true } ] @@ -76,7 +77,7 @@ runner.test('exceptions-unknowns: no unknown value exception with multiple defau }) }) -runner.test('exceptions-unknowns: non-multiple defaultOption should take first value 2', function () { +tom.test('non-multiple defaultOption should take first value 2', function () { const optionDefinitions = [ { name: 'file', defaultOption: true }, { name: 'one', type: Boolean }, @@ -88,3 +89,5 @@ runner.test('exceptions-unknowns: non-multiple defaultOption should take first v err => err.name === 'UNKNOWN_VALUE' && err.value === 'file2' ) }) + +export default tom diff --git a/test/internals/argv-parser.mjs b/test/internals/argv-parser.js similarity index 79% rename from test/internals/argv-parser.mjs rename to test/internals/argv-parser.js index 0ceeaa7..efebd6f 100644 --- a/test/internals/argv-parser.mjs +++ b/test/internals/argv-parser.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' import a from 'assert' -import ArgvParser from '../../lib/argv-parser.mjs' +import ArgvParser from '../../lib/argv-parser.js' -const runner = new TestRunner() +const tom = new TestRunner.Tom('argv-parser') -runner.test('argv-parser: long option, string', function () { +tom.test('long option, string', function () { const optionDefinitions = [ { name: 'one' } ] @@ -20,7 +20,7 @@ runner.test('argv-parser: long option, string', function () { ]) }) -runner.test('argv-parser: long option, string repeated', function () { +tom.test('long option, string repeated', function () { const optionDefinitions = [ { name: 'one' } ] @@ -40,7 +40,7 @@ runner.test('argv-parser: long option, string repeated', function () { ]) }) -runner.test('argv-parser: long option, string multiple', function () { +tom.test('long option, string multiple', function () { const optionDefinitions = [ { name: 'one', multiple: true } ] @@ -58,7 +58,7 @@ runner.test('argv-parser: long option, string multiple', function () { ]) }) -runner.test('argv-parser: long option, string multiple then boolean', function () { +tom.test('long option, string multiple then boolean', function () { const optionDefinitions = [ { name: 'one', multiple: true }, { name: 'two', type: Boolean } @@ -79,7 +79,7 @@ runner.test('argv-parser: long option, string multiple then boolean', function ( ]) }) -runner.test('argv-parser: long option, boolean', function () { +tom.test('long option, boolean', function () { const optionDefinitions = [ { name: 'one', type: Boolean } ] @@ -95,7 +95,7 @@ runner.test('argv-parser: long option, boolean', function () { ]) }) -runner.test('argv-parser: simple, with unknown values', function () { +tom.test('simple, with unknown values', function () { const optionDefinitions = [ { name: 'one', type: Number } ] @@ -115,7 +115,7 @@ runner.test('argv-parser: simple, with unknown values', function () { ]) }) -runner.test('argv-parser: simple, with singular defaultOption', function () { +tom.test('simple, with singular defaultOption', function () { const optionDefinitions = [ { name: 'one', type: Number }, { name: 'two', defaultOption: true } @@ -136,7 +136,7 @@ runner.test('argv-parser: simple, with singular defaultOption', function () { ]) }) -runner.test('argv-parser: simple, with multiple defaultOption', function () { +tom.test('simple, with multiple defaultOption', function () { const optionDefinitions = [ { name: 'one', type: Number }, { name: 'two', defaultOption: true, multiple: true } @@ -157,7 +157,7 @@ runner.test('argv-parser: simple, with multiple defaultOption', function () { ]) }) -runner.test('argv-parser: long option, string lazyMultiple bad', function () { +tom.test('long option, string lazyMultiple bad', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -175,7 +175,7 @@ runner.test('argv-parser: long option, string lazyMultiple bad', function () { ]) }) -runner.test('argv-parser: long option, string lazyMultiple good', function () { +tom.test('long option, string lazyMultiple good', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -195,7 +195,7 @@ runner.test('argv-parser: long option, string lazyMultiple good', function () { ]) }) -runner.test('argv-parser: long option, stopAtFirstUnknown', function () { +tom.test('long option, stopAtFirstUnknown', function () { const optionDefinitions = [ { name: 'one' }, { name: 'two' } @@ -218,7 +218,7 @@ runner.test('argv-parser: long option, stopAtFirstUnknown', function () { ]) }) -runner.test('argv-parser: long option, stopAtFirstUnknown with defaultOption', function () { +tom.test('long option, stopAtFirstUnknown with defaultOption', function () { const optionDefinitions = [ { name: 'one', defaultOption: true }, { name: 'two' } @@ -239,7 +239,7 @@ runner.test('argv-parser: long option, stopAtFirstUnknown with defaultOption', f ]) }) -runner.test('argv-parser: long option, stopAtFirstUnknown with defaultOption 2', function () { +tom.test('long option, stopAtFirstUnknown with defaultOption 2', function () { const optionDefinitions = [ { name: 'one', defaultOption: true }, { name: 'two' } @@ -262,7 +262,7 @@ runner.test('argv-parser: long option, stopAtFirstUnknown with defaultOption 2', ]) }) -runner.test('argv-parser: --option=value', function () { +tom.test('--option=value', function () { const optionDefinitions = [ { name: 'one' }, { name: 'two' } @@ -281,7 +281,7 @@ runner.test('argv-parser: --option=value', function () { ]) }) -runner.test('argv-parser: --option=value, unknown option', function () { +tom.test('--option=value, unknown option', function () { const optionDefinitions = [ { name: 'one' } ] @@ -295,7 +295,7 @@ runner.test('argv-parser: --option=value, unknown option', function () { ]) }) -runner.test('argv-parser: --option=value where option is boolean', function () { +tom.test('--option=value where option is boolean', function () { const optionDefinitions = [ { name: 'one', type: Boolean } ] @@ -311,7 +311,7 @@ runner.test('argv-parser: --option=value where option is boolean', function () { ]) }) -runner.test('argv-parser: short option, string', function () { +tom.test('short option, string', function () { const optionDefinitions = [ { name: 'one', alias: 'o' } ] @@ -327,7 +327,7 @@ runner.test('argv-parser: short option, string', function () { ]) }) -runner.test('argv-parser: combined short option, string', function () { +tom.test('combined short option, string', function () { const optionDefinitions = [ { name: 'one', alias: 'o' }, { name: 'two', alias: 't' } @@ -346,7 +346,7 @@ runner.test('argv-parser: combined short option, string', function () { ]) }) -runner.test('argv-parser: combined short option, one unknown', function () { +tom.test('combined short option, one unknown', function () { const optionDefinitions = [ { name: 'one', alias: 'o' }, { name: 'two', alias: 't' } @@ -364,3 +364,50 @@ runner.test('argv-parser: combined short option, one unknown', function () { { event: 'set', arg: '1', name: 'two', value: '1' } ]) }) + +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.mjs b/test/internals/option-default.js similarity index 66% rename from test/internals/option-default.mjs rename to test/internals/option-default.js index c8a80fe..82b3ea5 100644 --- a/test/internals/option-default.mjs +++ b/test/internals/option-default.js @@ -1,34 +1,36 @@ import TestRunner from 'test-runner' import a from 'assert' -import Option from '../../lib/option.mjs' +import Option from '../../lib/option.js' -const runner = new TestRunner() +const tom = new TestRunner.Tom('option-default') -runner.test('option.set(): defaultValue', function () { +tom.test('defaultValue', function () { const option = new Option({ name: 'two', defaultValue: 'two' }) a.strictEqual(option.get(), 'two') option.set('zwei') a.strictEqual(option.get(), 'zwei') }) -runner.test('option.set(): multiple defaultValue', function () { +tom.test('multiple defaultValue', function () { const option = new Option({ name: 'two', multiple: true, defaultValue: ['two', 'zwei'] }) a.deepStrictEqual(option.get(), ['two', 'zwei']) option.set('duo') a.deepStrictEqual(option.get(), ['duo']) }) -runner.test('option.set(): falsy defaultValue', function () { +tom.test('falsy defaultValue', function () { const option = new Option({ name: 'one', defaultValue: 0 }) a.strictEqual(option.get(), 0) }) -runner.test('option.set(): falsy defaultValue 2', function () { +tom.test('falsy defaultValue 2', function () { const option = new Option({ name: 'two', defaultValue: false }) a.strictEqual(option.get(), false) }) -runner.test('option.set(): falsy defaultValue multiple', function () { +tom.test('falsy defaultValue multiple', function () { const option = new Option({ name: 'one', defaultValue: 0, multiple: true }) a.deepStrictEqual(option.get(), [0]) }) + +export default tom diff --git a/test/internals/option-definitions.mjs b/test/internals/option-definitions.js similarity index 65% rename from test/internals/option-definitions.mjs rename to test/internals/option-definitions.js index 1b47193..b8939bf 100644 --- a/test/internals/option-definitions.mjs +++ b/test/internals/option-definitions.js @@ -1,27 +1,29 @@ import TestRunner from 'test-runner' import a from 'assert' -import Definitions from '../../lib/option-definitions.mjs' +import Definitions from '../../lib/option-definitions.js' -const runner = new TestRunner() +const tom = new TestRunner.Tom('option-definitions') -runner.test('.get(long option)', function () { +tom.test('.get(long option)', function () { const definitions = Definitions.from([{ name: 'one' }]) a.strictEqual(definitions.get('--one').name, 'one') }) -runner.test('.get(short option)', function () { +tom.test('.get(short option)', function () { const definitions = Definitions.from([{ name: 'one', alias: 'o' }]) a.strictEqual(definitions.get('-o').name, 'one') }) -runner.test('.get(name)', function () { +tom.test('.get(name)', function () { const definitions = Definitions.from([{ name: 'one' }]) a.strictEqual(definitions.get('one').name, 'one') }) -runner.test('.validate()', function () { +tom.test('.validate()', function () { a.throws(function () { const definitions = new Definitions() definitions.load([{ name: 'one' }, { name: 'one' }]) }) }) + +export default tom diff --git a/test/internals/option-flag.mjs b/test/internals/option-flag.js similarity index 73% rename from test/internals/option-flag.mjs rename to test/internals/option-flag.js index 99d35ef..23bf6ed 100644 --- a/test/internals/option-flag.mjs +++ b/test/internals/option-flag.js @@ -1,24 +1,24 @@ import TestRunner from 'test-runner' import a from 'assert' -import FlagOption from '../../lib/option-flag.mjs' +import FlagOption from '../../lib/option-flag.js' -const runner = new TestRunner() +const tom = new TestRunner.Tom('option-flag') -runner.test('type-boolean: single set', function () { +tom.test('type-boolean: single set', function () { const option = new FlagOption({ name: 'one', type: Boolean }) option.set(undefined) a.strictEqual(option.get(), true) }) -runner.test('type-boolean: single set 2', function () { +tom.test('type-boolean: single set 2', function () { const option = new FlagOption({ name: 'one', type: Boolean }) option.set('true') a.strictEqual(option.get(), true) }) -runner.test('type-boolean: set twice', function () { +tom.test('type-boolean: set twice', function () { const option = new FlagOption({ name: 'one', type: Boolean }) option.set(undefined) @@ -32,7 +32,7 @@ runner.test('type-boolean: set twice', function () { const origBoolean = Boolean /* test in contexts which override the standard global Boolean constructor */ -runner.test('type-boolean: global Boolean overridden', function () { +tom.test('type-boolean: global Boolean overridden', function () { function Boolean () { return origBoolean.apply(origBoolean, arguments) } @@ -43,7 +43,7 @@ runner.test('type-boolean: global Boolean overridden', function () { a.strictEqual(option.get(), true) }) -runner.test('type-boolean-multiple: 1', function () { +tom.test('type-boolean-multiple: 1', function () { const option = new FlagOption({ name: 'one', type: Boolean, multiple: true }) option.set(undefined) @@ -52,3 +52,5 @@ runner.test('type-boolean-multiple: 1', function () { a.deepStrictEqual(option.get(), [true, true, true]) }) + +export default tom diff --git a/test/internals/option.mjs b/test/internals/option.js similarity index 81% rename from test/internals/option.mjs rename to test/internals/option.js index 3f3718a..017f251 100644 --- a/test/internals/option.mjs +++ b/test/internals/option.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' import a from 'assert' -import Option from '../../lib/option.mjs' +import Option from '../../lib/option.js' -const runner = new TestRunner() +const tom = new TestRunner.Tom('option') -runner.test('option.set(): simple set string', function () { +tom.test('simple set string', function () { const option = Option.create({ name: 'two' }) a.strictEqual(option.get(), null) a.strictEqual(option.state, 'default') @@ -13,7 +13,7 @@ runner.test('option.set(): simple set string', function () { a.strictEqual(option.state, 'set') }) -runner.test('option.set(): simple set boolean', function () { +tom.test('simple set boolean', function () { const option = Option.create({ name: 'two', type: Boolean }) a.strictEqual(option.get(), null) a.strictEqual(option.state, 'default') @@ -22,7 +22,7 @@ runner.test('option.set(): simple set boolean', function () { a.strictEqual(option.state, 'set') }) -runner.test('option.set(): simple set string twice', function () { +tom.test('simple set string twice', function () { const option = Option.create({ name: 'two' }) a.strictEqual(option.get(), null) a.strictEqual(option.state, 'default') @@ -35,7 +35,7 @@ runner.test('option.set(): simple set string twice', function () { ) }) -runner.test('option.set(): simple set boolean twice', function () { +tom.test('simple set boolean twice', function () { const option = Option.create({ name: 'two', type: Boolean }) a.strictEqual(option.get(), null) a.strictEqual(option.state, 'default') @@ -48,7 +48,7 @@ runner.test('option.set(): simple set boolean twice', function () { ) }) -runner.test('option.set(): string multiple', function () { +tom.test('string multiple', function () { const option = Option.create({ name: 'two', multiple: true }) a.deepStrictEqual(option.get(), []) a.strictEqual(option.state, 'default') @@ -60,7 +60,7 @@ runner.test('option.set(): string multiple', function () { a.strictEqual(option.state, 'set') }) -runner.test('option.set: lazyMultiple', function () { +tom.test('lazyMultiple', function () { const option = Option.create({ name: 'one', lazyMultiple: true }) a.deepStrictEqual(option.get(), []) a.strictEqual(option.state, 'default') @@ -72,7 +72,7 @@ runner.test('option.set: lazyMultiple', function () { a.strictEqual(option.state, 'set') }) -runner.test('option.set(): string multiple defaultOption', function () { +tom.test('string multiple defaultOption', function () { const option = Option.create({ name: 'two', multiple: true, defaultOption: true }) a.deepStrictEqual(option.get(), []) a.strictEqual(option.state, 'default') @@ -84,7 +84,7 @@ runner.test('option.set(): string multiple defaultOption', function () { a.strictEqual(option.state, 'set') }) -runner.test('option.set: lazyMultiple defaultOption', function () { +tom.test('lazyMultiple defaultOption', function () { const option = Option.create({ name: 'one', lazyMultiple: true, defaultOption: true }) a.deepStrictEqual(option.get(), []) a.strictEqual(option.state, 'default') @@ -95,3 +95,5 @@ runner.test('option.set: lazyMultiple defaultOption', function () { a.deepStrictEqual(option.get(), ['1', '2']) a.strictEqual(option.state, 'set') }) + +export default tom diff --git a/test/internals/output.mjs b/test/internals/output.js similarity index 59% rename from test/internals/output.mjs rename to test/internals/output.js index 8f3efaa..c22d133 100644 --- a/test/internals/output.mjs +++ b/test/internals/output.js @@ -1,18 +1,18 @@ import TestRunner from 'test-runner' import a from 'assert' -import Output from '../../lib/output.mjs' -import Option from '../../lib/option.mjs' +import Output from '../../lib/output.js' +import Option from '../../lib/option.js' -const runner = new TestRunner() +const tom = new TestRunner.Tom('output') -runner.test('output.toObject(): no defs set', function () { +tom.test('output.toObject(): no defs set', function () { const output = new Output([ { name: 'one' } ]) a.deepStrictEqual(output.toObject(), {}) }) -runner.test('output.toObject(): one def set', function () { +tom.test('output.toObject(): one def set', function () { const output = new Output([ { name: 'one' } ]) @@ -23,3 +23,5 @@ runner.test('output.toObject(): one def set', function () { one: 'yeah' }) }) + +export default tom diff --git a/test/multiple-lazy.mjs b/test/multiple-lazy.js similarity index 75% rename from test/multiple-lazy.mjs rename to test/multiple-lazy.js index dbe9610..e73c690 100644 --- a/test/multiple-lazy.mjs +++ b/test/multiple-lazy.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('multiple-lazy') -runner.test('lazy multiple: string', function () { +tom.test('string', function () { const argv = ['--one', 'a', '--one', 'b', '--one', 'd'] const optionDefinitions = [ { name: 'one', lazyMultiple: true } @@ -15,7 +15,7 @@ runner.test('lazy multiple: string', function () { }) }) -runner.test('lazy multiple: string unset with defaultValue', function () { +tom.test('string unset with defaultValue', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true, defaultValue: 1 } ] @@ -24,7 +24,7 @@ runner.test('lazy multiple: string unset with defaultValue', function () { a.deepStrictEqual(result, { one: [1] }) }) -runner.test('lazy multiple: string, --option=value', function () { +tom.test('string, --option=value', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -35,7 +35,7 @@ runner.test('lazy multiple: string, --option=value', function () { }) }) -runner.test('lazy multiple: string, --option=value mix', function () { +tom.test('string, --option=value mix', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -46,7 +46,7 @@ runner.test('lazy multiple: string, --option=value mix', function () { }) }) -runner.test('lazy multiple: string, defaultOption', function () { +tom.test('string, defaultOption', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true, defaultOption: true } ] @@ -57,7 +57,7 @@ runner.test('lazy multiple: string, defaultOption', function () { }) }) -runner.test('lazy multiple: greedy style, string', function () { +tom.test('greedy style, string', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -68,7 +68,7 @@ runner.test('lazy multiple: greedy style, string', function () { ) }) -runner.test('lazy multiple: greedy style, string, --option=value', function () { +tom.test('greedy style, string, --option=value', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -79,7 +79,7 @@ runner.test('lazy multiple: greedy style, string, --option=value', function () { }) }) -runner.test('lazy multiple: greedy style, string, --option=value mix', function () { +tom.test('greedy style, string, --option=value mix', function () { const optionDefinitions = [ { name: 'one', lazyMultiple: true } ] @@ -89,3 +89,5 @@ runner.test('lazy multiple: greedy style, string, --option=value mix', function err => err.name === 'UNKNOWN_VALUE' && err.value === '3' ) }) + +export default tom diff --git a/test/multiple.mjs b/test/multiple.js similarity index 76% rename from test/multiple.mjs rename to test/multiple.js index 835579a..26d7437 100644 --- a/test/multiple.mjs +++ b/test/multiple.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('multiple') -runner.test('multiple: empty argv', function () { +tom.test('empty argv', function () { const optionDefinitions = [ { name: 'one', multiple: true } ] @@ -13,7 +13,7 @@ runner.test('multiple: empty argv', function () { a.deepStrictEqual(result, {}) }) -runner.test('multiple: boolean, empty argv', function () { +tom.test('boolean, empty argv', function () { const optionDefinitions = [ { name: 'one', type: Boolean, multiple: true } ] @@ -22,7 +22,7 @@ runner.test('multiple: boolean, empty argv', function () { a.deepStrictEqual(result, { }) }) -runner.test('multiple: string unset with defaultValue', function () { +tom.test('string unset with defaultValue', function () { const optionDefinitions = [ { name: 'one', multiple: true, defaultValue: 1 } ] @@ -31,7 +31,7 @@ runner.test('multiple: string unset with defaultValue', function () { a.deepStrictEqual(result, { one: [1] }) }) -runner.test('multiple: string', function () { +tom.test('string', function () { const optionDefinitions = [ { name: 'one', multiple: true } ] @@ -42,7 +42,7 @@ runner.test('multiple: string', function () { }) }) -runner.test('multiple: string, --option=value', function () { +tom.test('string, --option=value', function () { const optionDefinitions = [ { name: 'one', multiple: true } ] @@ -53,7 +53,7 @@ runner.test('multiple: string, --option=value', function () { }) }) -runner.test('multiple: string, --option=value mix', function () { +tom.test('string, --option=value mix', function () { const optionDefinitions = [ { name: 'one', multiple: true } ] @@ -64,7 +64,7 @@ runner.test('multiple: string, --option=value mix', function () { }) }) -runner.test('multiple: string, defaultOption', function () { +tom.test('string, defaultOption', function () { const optionDefinitions = [ { name: 'one', multiple: true, defaultOption: true } ] @@ -74,3 +74,5 @@ runner.test('multiple: string, defaultOption', function () { one: ['1', '2'] }) }) + +export default tom diff --git a/test/name-alias-mix.mjs b/test/name-alias-mix.mjs deleted file mode 100644 index a1db5d0..0000000 --- a/test/name-alias-mix.mjs +++ /dev/null @@ -1,20 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.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) -}) diff --git a/test/name-unicode.mjs b/test/name-unicode.mjs deleted file mode 100644 index b21d12a..0000000 --- a/test/name-unicode.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.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') -}) diff --git a/test/name.js b/test/name.js new file mode 100644 index 0000000..cfd1afb --- /dev/null +++ b/test/name.js @@ -0,0 +1,35 @@ +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.mjs b/test/option-value-notation.js similarity index 80% rename from test/option=value-notation.mjs rename to test/option-value-notation.js index f9a7ba1..b41586f 100644 --- a/test/option=value-notation.mjs +++ b/test/option-value-notation.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('option=value-notation') -runner.test('--option=value notation: two plus a regular notation', function () { +tom.test('two plus a regular notation', function () { const optionDefinitions = [ { name: 'one' }, { name: 'two' }, @@ -18,7 +18,7 @@ runner.test('--option=value notation: two plus a regular notation', function () a.strictEqual(result.three, '3') }) -runner.test('--option=value notation: value contains "="', function () { +tom.test('value contains "="', function () { const optionDefinitions = [ { name: 'url' }, { name: 'two' }, @@ -36,3 +36,5 @@ runner.test('--option=value notation: value contains "="', function () { result = commandLineArgs({ name: 'my-url' }, { argv: ['--my-url=my-url?q=123=1'] }) a.strictEqual(result['my-url'], 'my-url?q=123=1') }) + +export default tom diff --git a/test/output-camel-case.js b/test/output-camel-case.js new file mode 100644 index 0000000..609de3f --- /dev/null +++ b/test/output-camel-case.js @@ -0,0 +1,79 @@ +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/grouping.mjs b/test/output-grouping.js similarity index 85% rename from test/grouping.mjs rename to test/output-grouping.js index 86b5570..9698b0d 100644 --- a/test/grouping.mjs +++ b/test/output-grouping.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('output-grouping') -runner.test('groups', function () { +tom.test('groups', function () { const definitions = [ { name: 'one', group: 'a' }, { name: 'two', group: 'a' }, @@ -28,7 +28,7 @@ runner.test('groups', function () { }) }) -runner.test('groups: multiple and _none', function () { +tom.test('multiple and _none', function () { const definitions = [ { name: 'one', group: ['a', 'f'] }, { name: 'two', group: ['a', 'g'] }, @@ -57,7 +57,7 @@ runner.test('groups: multiple and _none', function () { }) }) -runner.test('groups: nothing set', function () { +tom.test('nothing set', function () { const definitions = [ { name: 'one', group: 'a' }, { name: 'two', group: 'a' }, @@ -72,7 +72,7 @@ runner.test('groups: nothing set', function () { }) }) -runner.test('groups: nothing set with one ungrouped', function () { +tom.test('nothing set with one ungrouped', function () { const definitions = [ { name: 'one', group: 'a' }, { name: 'two', group: 'a' }, @@ -86,7 +86,7 @@ runner.test('groups: nothing set with one ungrouped', function () { }) }) -runner.test('groups: two ungrouped, one set', function () { +tom.test('two ungrouped, one set', function () { const definitions = [ { name: 'one', group: 'a' }, { name: 'two', group: 'a' }, @@ -102,7 +102,7 @@ runner.test('groups: two ungrouped, one set', function () { }) }) -runner.test('groups: two ungrouped, both set', function () { +tom.test('two ungrouped, both set', function () { const definitions = [ { name: 'one', group: 'a' }, { name: 'two', group: 'a' }, @@ -118,7 +118,7 @@ runner.test('groups: two ungrouped, both set', function () { }) }) -runner.test('groups: with partial', function () { +tom.test('with partial', function () { const definitions = [ { name: 'one', group: 'a' }, { name: 'two', group: 'a' }, @@ -142,7 +142,7 @@ runner.test('groups: with partial', function () { }) }) -runner.test('partial: with partial, multiple groups and _none', function () { +tom.test('partial: with partial, multiple groups and _none', function () { const definitions = [ { name: 'one', group: ['a', 'f'] }, { name: 'two', group: ['a', 'g'] }, @@ -171,3 +171,5 @@ runner.test('partial: with partial, multiple groups and _none', function () { _unknown: ['--cheese', 'ham', '-c'] }) }) + +export default tom diff --git a/test/partial.js b/test/partial.js new file mode 100644 index 0000000..17e48ec --- /dev/null +++ b/test/partial.js @@ -0,0 +1,225 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('partial') + +tom.test('simple', function () { + const optionDefinitions = [ + { name: 'one', type: Boolean } + ] + const argv = ['--two', 'two', '--one', 'two'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + one: true, + _unknown: ['--two', 'two', 'two'] + }) +}) + +tom.test('defaultOption', function () { + const optionDefinitions = [ + { name: 'files', defaultOption: true, multiple: true } + ] + const argv = ['--files', 'file1', '--one', 'file2'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + files: ['file1', 'file2'], + _unknown: ['--one'] + }) +}) + +tom.test('defaultOption: floating args present but no defaultOption', function () { + const optionDefinitions = [ + { name: 'one', type: Boolean } + ] + const argv = ['aaa', '--one', 'aaa', 'aaa'] + a.deepStrictEqual( + commandLineArgs(optionDefinitions, { argv, partial: true }), + { + one: true, + _unknown: ['aaa', 'aaa', 'aaa'] + } + ) +}) + +tom.test('combined short option, both unknown', function () { + const optionDefinitions = [ + { 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' ] + */ + a.deepStrictEqual(options, { + _unknown: ['-a', '-b'] + }) +}) + +tom.test('combined short option, one known, one unknown', function () { + const optionDefinitions = [ + { name: 'one', alias: 'o' }, + { name: 'two', alias: 't' } + ] + const argv = ['-ob'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + one: 'b' + }) +}) + +tom.test('defaultOption with --option=value and combined short options', function () { + const optionDefinitions = [ + { 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', '-ab'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + files: ['file1', 'file2', 'file3'], + two: '3', + one: true, + _unknown: ['-a', '-b'] + }) +}) + +tom.test('defaultOption with value equal to defaultValue', function () { + const optionDefinitions = [ + { name: 'file', defaultOption: true, defaultValue: 'file1' } + ] + const argv = ['file1', '--two=3', '--four', '5'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + file: 'file1', + _unknown: ['--two=3', '--four', '5'] + }) +}) + +tom.test('string defaultOption can be set by argv once', function () { + const optionDefinitions = [ + { name: 'file', defaultOption: true, defaultValue: 'file1' } + ] + const argv = ['--file', '--file=file2', '--two=3', '--four', '5'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + file: 'file2', + _unknown: ['--two=3', '--four', '5'] + }) +}) + +tom.test('string defaultOption can not be set by argv twice', function () { + const optionDefinitions = [ + { name: 'file', defaultOption: true, defaultValue: 'file1' } + ] + const argv = ['--file', '--file=file2', '--two=3', '--four', '5', 'file3'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + file: 'file2', + _unknown: ['--two=3', '--four', '5', 'file3'] + }) +}) + +tom.test('defaultOption with value equal to defaultValue 3', function () { + const optionDefinitions = [ + { name: 'file', defaultOption: true, defaultValue: 'file1' } + ] + const argv = ['file1', 'file2', '--two=3', '--four', '5'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + file: 'file1', + _unknown: ['file2', '--two=3', '--four', '5'] + }) +}) + +tom.test('multiple', function () { + const optionDefinitions = [ + { name: 'files', multiple: true } + ] + const argv = ['file1', '--files', 'file2', '-t', '--two=3', 'file3', '-ab', '--files=file4'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + files: ['file2', 'file4'], + _unknown: ['file1', '-t', '--two=3', 'file3', '-a', '-b'] + }) +}) + +tom.test('unknown options: rejected defaultOption values end up in _unknown', function () { + const optionDefinitions = [ + { name: 'foo' }, + { name: 'verbose', alias: 'v', type: Boolean }, + { name: 'libs', defaultOption: true } + ] + const argv = ['--foo', 'bar', '-v', 'libfn', '--libarg', 'val1', '-r'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + foo: 'bar', + verbose: true, + libs: 'libfn', + _unknown: ['--libarg', 'val1', '-r'] + }) +}) + +tom.test('defaultOption with --option=value notation', function () { + const optionDefinitions = [ + { name: 'files', multiple: true, defaultOption: true } + ] + const argv = ['file1', 'file2', '--unknown=something'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + files: ['file1', 'file2'], + _unknown: ['--unknown=something'] + }) +}) + +tom.test('defaultOption with --option=value notation 2', function () { + const optionDefinitions = [ + { name: 'files', multiple: true, defaultOption: true } + ] + const argv = ['file1', 'file2', '--unknown=something', '--files', 'file3', '--files=file4'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + files: ['file1', 'file2', 'file3', 'file4'], + _unknown: ['--unknown=something'] + }) +}) + +tom.test('defaultOption with --option=value notation 3', function () { + const optionDefinitions = [ + { name: 'files', multiple: true, defaultOption: true } + ] + const argv = ['--unknown', 'file1', '--another', 'something', 'file2', '--unknown=something', '--files', 'file3', '--files=file4'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + files: ['file1', 'something', 'file2', 'file3', 'file4'], + _unknown: ['--unknown', '--another', '--unknown=something'] + }) +}) + +tom.test('mulitple unknowns with same name', function () { + const optionDefinitions = [ + { name: 'file' } + ] + const argv = ['--unknown', '--unknown=something', '--file=file1', '--unknown'] + const options = commandLineArgs(optionDefinitions, { argv, partial: true }) + a.deepStrictEqual(options, { + file: 'file1', + _unknown: ['--unknown', '--unknown=something', '--unknown'] + }) +}) + +tom.test('defaultOption: single string', function () { + const optionDefinitions = [ + { name: 'files', defaultOption: true } + ] + const argv = ['file1', 'file2'] + a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv, partial: true }), { + files: 'file1', + _unknown: ['file2'] + }) +}) + +export default tom diff --git a/test/partial.mjs b/test/partial.mjs deleted file mode 100644 index bfc97a9..0000000 --- a/test/partial.mjs +++ /dev/null @@ -1,218 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -runner.test('partial: simple', function () { - const definitions = [ - { name: 'one', type: Boolean } - ] - const argv = ['--two', 'two', '--one', 'two'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - one: true, - _unknown: ['--two', 'two', 'two'] - }) -}) - -runner.test('partial: defaultOption', function () { - const definitions = [ - { name: 'files', type: String, defaultOption: true, multiple: true } - ] - const argv = ['--files', 'file1', '--one', 'file2'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - files: ['file1', 'file2'], - _unknown: ['--one'] - }) -}) - -runner.test('defaultOption: floating args present but no defaultOption', function () { - const definitions = [ - { name: 'one', type: Boolean } - ] - a.deepStrictEqual( - commandLineArgs(definitions, { argv: ['aaa', '--one', 'aaa', 'aaa'], partial: true }), - { - one: true, - _unknown: ['aaa', 'aaa', 'aaa'] - } - ) -}) - -runner.test('partial: combined short option, both unknown', function () { - const definitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' } - ] - const argv = ['-ab'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - _unknown: ['-a', '-b'] - }) -}) - -runner.test('partial: combined short option, one known, one unknown', function () { - const definitions = [ - { name: 'one', alias: 'o' }, - { name: 'two', alias: 't' } - ] - const argv = ['-ob'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - one: null, - _unknown: ['-b'] - }) -}) - -runner.test('partial: defaultOption with --option=value and combined short options', function () { - 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(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - files: ['file1', 'file2', 'file3'], - two: '3', - one: true, - _unknown: ['-a', '-b'] - }) -}) - -runner.test('partial: defaultOption with value equal to defaultValue', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['file1', '--two=3', '--four', '5'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - file: 'file1', - _unknown: ['--two=3', '--four', '5'] - }) -}) - -runner.test('partial: string defaultOption can be set by argv once', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['--file', '--file=file2', '--two=3', '--four', '5'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - file: 'file2', - _unknown: ['--two=3', '--four', '5'] - }) -}) - -runner.test('partial: string defaultOption can not be set by argv twice', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['--file', '--file=file2', '--two=3', '--four', '5', 'file3'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - file: 'file2', - _unknown: ['--two=3', '--four', '5', 'file3'] - }) -}) - -runner.test('partial: defaultOption with value equal to defaultValue 3', function () { - const definitions = [ - { name: 'file', type: String, defaultOption: true, defaultValue: 'file1' } - ] - const argv = ['file1', 'file2', '--two=3', '--four', '5'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - file: 'file1', - _unknown: ['file2', '--two=3', '--four', '5'] - }) -}) - -runner.test('partial: multiple', function () { - const definitions = [ - { name: 'files', type: String, multiple: true } - ] - const argv = ['file1', '--files', 'file2', '-t', '--two=3', 'file3', '-ab', '--files=file4'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - files: ['file2', 'file4'], - _unknown: ['file1', '-t', '--two=3', 'file3', '-a', '-b'] - }) -}) - -runner.test('unknown options: rejected defaultOption values end up in _unknown', function () { - const definitions = [ - { name: 'foo', type: String }, - { name: 'verbose', alias: 'v', type: Boolean }, - { name: 'libs', type: String, defaultOption: true } - ] - const argv = ['--foo', 'bar', '-v', 'libfn', '--libarg', 'val1', '-r'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - foo: 'bar', - verbose: true, - libs: 'libfn', - _unknown: ['--libarg', 'val1', '-r'] - }) -}) - -runner.test('partial: defaultOption with --option=value notation', function () { - const definitions = [ - { name: 'files', type: String, multiple: true, defaultOption: true } - ] - const argv = ['file1', 'file2', '--unknown=something'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - files: ['file1', 'file2'], - _unknown: ['--unknown=something'] - }) -}) - -runner.test('partial: defaultOption with --option=value notation 2', function () { - const definitions = [ - { name: 'files', type: String, multiple: true, defaultOption: true } - ] - const argv = ['file1', 'file2', '--unknown=something', '--files', 'file3', '--files=file4'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - files: ['file1', 'file2', 'file3', 'file4'], - _unknown: ['--unknown=something'] - }) -}) - -runner.test('partial: defaultOption with --option=value notation 3', function () { - 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(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - files: ['file1', 'something', 'file2', 'file3', 'file4'], - _unknown: ['--unknown', '--another', '--unknown=something'] - }) -}) - -runner.test('partial: mulitple unknowns with same name', function () { - const definitions = [ - { name: 'file' } - ] - const argv = ['--unknown', '--unknown=something', '--file=file1', '--unknown'] - const options = commandLineArgs(definitions, { argv, partial: true }) - a.deepStrictEqual(options, { - file: 'file1', - _unknown: ['--unknown', '--unknown=something', '--unknown'] - }) -}) - -runner.test('defaultOption: single string', function () { - const optionDefinitions = [ - { name: 'files', defaultOption: true } - ] - const argv = ['file1', 'file2'] - a.deepStrictEqual(commandLineArgs(optionDefinitions, { argv, partial: true }), { - files: 'file1', - _unknown: ['file2'] - }) -}) diff --git a/test/stop-at-first-unknown.mjs b/test/stop-at-first-unknown.js similarity index 78% rename from test/stop-at-first-unknown.mjs rename to test/stop-at-first-unknown.js index 01f3ff5..db8cdcc 100644 --- a/test/stop-at-first-unknown.mjs +++ b/test/stop-at-first-unknown.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('stop-at-first-unknown') -runner.test('stopAtFirstUnknown', function () { +tom.test('simple', function () { const optionDefinitions = [ { name: 'one', type: Boolean }, { name: 'two', type: Boolean } @@ -17,7 +17,7 @@ runner.test('stopAtFirstUnknown', function () { }) }) -runner.test('stopAtFirstUnknown: with a singlular defaultOption', function () { +tom.test('with a singlular defaultOption', function () { const optionDefinitions = [ { name: 'one', defaultOption: true }, { name: 'two' } @@ -30,7 +30,7 @@ runner.test('stopAtFirstUnknown: with a singlular defaultOption', function () { }) }) -runner.test('stopAtFirstUnknown: with a singlular defaultOption and partial', function () { +tom.test('with a singlular defaultOption and partial', function () { const optionDefinitions = [ { name: 'one', defaultOption: true }, { name: 'two' } @@ -42,3 +42,5 @@ runner.test('stopAtFirstUnknown: with a singlular defaultOption and partial', fu _unknown: ['--', '--two', '2'] }) }) + +export default tom diff --git a/test/tests.mjs b/test/tests.mjs deleted file mode 100644 index 56cb75c..0000000 --- a/test/tests.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import './internals/argv-parser.mjs' -import './internals/option-default.mjs' -import './internals/option-definitions.mjs' -import './internals/option-flag.mjs' -import './internals/option.mjs' -import './internals/output.mjs' -import './alias-cluster.mjs' -import './alias.mjs' -import './ambiguous-input.mjs' -import './bad-input.mjs' -import './camel-case.mjs' -import './case-insensitive.mjs' -import './default-option.mjs' -import './default-value.mjs' -import './detect-process-argv.mjs' -import './detect-process-execArgv.mjs' -import './exceptions-already-set.mjs' -import './exceptions-invalid-definition.mjs' -import './exceptions-unknowns.mjs' -import './grouping.mjs' -import './multiple-lazy.mjs' -import './multiple.mjs' -import './name-alias-mix.mjs' -import './name-unicode.mjs' -import './option=value-notation.mjs' -import './partial.mjs' -import './stop-at-first-unknown.mjs' -import './type-boolean.mjs' -import './type-none.mjs' -import './type-number.mjs' -import './type-other.mjs' -import './type-string.mjs' diff --git a/test/type-boolean.mjs b/test/type-boolean.js similarity index 71% rename from test/type-boolean.mjs rename to test/type-boolean.js index 1b3ea28..1fadc49 100644 --- a/test/type-boolean.mjs +++ b/test/type-boolean.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('type-boolean') -runner.test('type-boolean: simple', function () { +tom.test('simple', function () { const optionDefinitions = [ { name: 'one', type: Boolean } ] @@ -18,22 +18,21 @@ runner.test('type-boolean: simple', function () { const origBoolean = Boolean /* test in contexts which override the standard global Boolean constructor */ -runner.test('type-boolean: global Boolean overridden', function () { +tom.test('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: ['--one'] }), + commandLineArgs(optionDefinitions, { argv }), { one: true } ) }) -runner.test('type-boolean-multiple: 1', function () { +tom.test('type-boolean-multiple: 1', function () { const optionDefinitions = [ { name: 'array', type: Boolean, multiple: true } ] @@ -43,3 +42,5 @@ runner.test('type-boolean-multiple: 1', function () { array: [true, true, true] }) }) + +export default tom diff --git a/test/type-none.js b/test/type-none.js new file mode 100644 index 0000000..63cae7d --- /dev/null +++ b/test/type-none.js @@ -0,0 +1,56 @@ +import TestRunner from 'test-runner' +import commandLineArgs from '../index.js' +import a from 'assert' + +const tom = new TestRunner.Tom('type-none') + +tom.test('no argv values', function () { + const optionDefinitions = [ + { name: 'one' }, + { name: 'two' } + ] + const argv = [] + const result = commandLineArgs(optionDefinitions, { 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 }) + a.deepStrictEqual(result, { + one: null, + two: null + }) +}) + +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 }) + a.deepStrictEqual(result, { + one: 'one', + two: null + }) +}) + +tom.test('just names, two values', function () { + const optionDefinitions = [ + { name: 'one' }, + { name: 'two' } + ] + const argv = ['--one', 'one', '--two', 'two'] + const result = commandLineArgs(optionDefinitions, { argv }) + a.deepStrictEqual(result, { + one: 'one', + two: 'two' + }) +}) + +export default tom diff --git a/test/type-none.mjs b/test/type-none.mjs deleted file mode 100644 index f3b0c51..0000000 --- a/test/type-none.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' -import a from 'assert' - -const runner = new TestRunner() - -const definitions = [ - { name: 'one' }, - { name: 'two' } -] - -runner.test('name: no argv values', function () { - const argv = [] - const result = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(result, {}) -}) - -runner.test('name: just names, no values', function () { - const argv = ['--one', '--two'] - const result = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(result, { - one: null, - two: null - }) -}) - -runner.test('name: just names, one value, one unpassed value', function () { - const argv = ['--one', 'one', '--two'] - const result = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(result, { - one: 'one', - two: null - }) -}) - -runner.test('name: just names, two values', function () { - const argv = ['--one', 'one', '--two', 'two'] - const result = commandLineArgs(definitions, { argv }) - a.deepStrictEqual(result, { - one: 'one', - two: 'two' - }) -}) diff --git a/test/type-number.mjs b/test/type-number.js similarity index 83% rename from test/type-number.mjs rename to test/type-number.js index 6096ed5..6a7d9ef 100644 --- a/test/type-number.mjs +++ b/test/type-number.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('type-number') -runner.test('type-number: different values', function () { +tom.test('different values', function () { const optionDefinitions = [ { name: 'one', type: Number } ] @@ -24,7 +24,7 @@ runner.test('type-number: different values', function () { a.ok(isNaN(result.one)) }) -runner.test('number multiple: 1', function () { +tom.test('number multiple: 1', function () { const optionDefinitions = [ { name: 'array', type: Number, multiple: true } ] @@ -38,7 +38,7 @@ runner.test('number multiple: 1', function () { }) }) -runner.test('number multiple: 2', function () { +tom.test('number multiple: 2', function () { const optionDefinitions = [ { name: 'array', type: Number, multiple: true } ] @@ -51,3 +51,5 @@ runner.test('number multiple: 2', function () { array: ['1', '2', '3'] }) }) + +export default tom diff --git a/test/type-other.mjs b/test/type-other.js similarity index 80% rename from test/type-other.mjs rename to test/type-other.js index cfd413a..9572b23 100644 --- a/test/type-other.mjs +++ b/test/type-other.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('type-other') -runner.test('type-other: different values', function () { +tom.test('different values', function () { const definitions = [ { name: 'file', @@ -24,7 +24,7 @@ runner.test('type-other: different values', function () { ) }) -runner.test('type-other: broken custom type function', function () { +tom.test('broken custom type function', function () { const definitions = [ { name: 'file', @@ -38,7 +38,7 @@ runner.test('type-other: broken custom type function', function () { }) }) -runner.test('type-other-multiple: different values', function () { +tom.test('type-other-multiple: different values', function () { const definitions = [ { name: 'file', @@ -62,3 +62,5 @@ runner.test('type-other-multiple: different values', function () { { file: [] } ) }) + +export default tom diff --git a/test/type-string.mjs b/test/type-string.js similarity index 75% rename from test/type-string.mjs rename to test/type-string.js index 3178f46..922239b 100644 --- a/test/type-string.mjs +++ b/test/type-string.js @@ -1,10 +1,10 @@ import TestRunner from 'test-runner' -import commandLineArgs from '../index.mjs' +import commandLineArgs from '../index.js' import a from 'assert' -const runner = new TestRunner() +const tom = new TestRunner.Tom('type-string') -runner.test('type-string: different values', function () { +tom.test('different values', function () { const optionDefinitions = [ { name: 'one', type: String } ] @@ -21,3 +21,5 @@ runner.test('type-string: different values', function () { { one: '3' } ) }) + +export default tom