command-line-args
Advanced tools
+1976
| 'use strict'; | ||
| /** | ||
| * Takes any input and guarantees an array back. | ||
| * | ||
| * - Converts array-like objects (e.g. `arguments`, `Set`) to a real array. | ||
| * - Converts `undefined` to an empty array. | ||
| * - Converts any another other, singular value (including `null`, objects and iterables other than `Set`) into an array containing that value. | ||
| * - Ignores input which is already an array. | ||
| * | ||
| * @module array-back | ||
| * @example | ||
| * > const arrayify = require('array-back') | ||
| * | ||
| * > arrayify(undefined) | ||
| * [] | ||
| * | ||
| * > arrayify(null) | ||
| * [ null ] | ||
| * | ||
| * > arrayify(0) | ||
| * [ 0 ] | ||
| * | ||
| * > arrayify([ 1, 2 ]) | ||
| * [ 1, 2 ] | ||
| * | ||
| * > arrayify(new Set([ 1, 2 ])) | ||
| * [ 1, 2 ] | ||
| * | ||
| * > function f(){ return arrayify(arguments); } | ||
| * > f(1,2,3) | ||
| * [ 1, 2, 3 ] | ||
| */ | ||
| function isObject$1 (input) { | ||
| return typeof input === 'object' && input !== null | ||
| } | ||
| function isArrayLike$1 (input) { | ||
| return isObject$1(input) && typeof input.length === 'number' | ||
| } | ||
| /** | ||
| * @param {*} - The input value to convert to an array | ||
| * @returns {Array} | ||
| * @alias module:array-back | ||
| */ | ||
| function arrayify (input) { | ||
| if (Array.isArray(input)) { | ||
| return input | ||
| } else if (input === undefined) { | ||
| return [] | ||
| } else if (isArrayLike$1(input) || input instanceof Set) { | ||
| return Array.from(input) | ||
| } else { | ||
| return [input] | ||
| } | ||
| } | ||
| /** | ||
| * @module find-replace | ||
| */ | ||
| /** | ||
| * @param {array} - The input array | ||
| * @param {function} - A predicate function which, if returns `true` causes the current item to be operated on. | ||
| * @param [replaceWith] {...any} - If not specified, each found value will be removed. If specified, each found value will be replaced with this value. If the `replaceWith` value is a function, it will be invoked with the found value and its result used as the replace value. If the `replaceWith` function returns an array, the found value will be replaced with each item in the array (not replaced with the array itself). | ||
| * @returns {array} | ||
| * @alias module:find-replace | ||
| */ | ||
| function findReplace (array, findFn, ...replaceWiths) { | ||
| const found = []; | ||
| if (!Array.isArray(array)) { | ||
| throw new Error('Input must be an array') | ||
| } | ||
| for (const [index, value] of array.entries()) { | ||
| let expanded = []; | ||
| replaceWiths.forEach(replaceWith => { | ||
| if (typeof replaceWith === 'function') { | ||
| expanded = expanded.concat(replaceWith(value)); | ||
| } else { | ||
| expanded.push(replaceWith); | ||
| } | ||
| }); | ||
| if (findFn(value)) { | ||
| found.push({ | ||
| index: index, | ||
| replaceWithValue: expanded | ||
| }); | ||
| } | ||
| } | ||
| for (const item of found.reverse()) { | ||
| const spliceArgs = [item.index, 1].concat(item.replaceWithValue); | ||
| array.splice.apply(array, spliceArgs); | ||
| } | ||
| return array | ||
| } | ||
| /** | ||
| * Some useful tools for working with `process.argv`. | ||
| * | ||
| * @module argv-tools | ||
| * @typicalName argvTools | ||
| * @example | ||
| * const argvTools = require('argv-tools') | ||
| */ | ||
| /** | ||
| * Regular expressions for matching option formats. | ||
| * @static | ||
| */ | ||
| const re = { | ||
| short: /^-([^\d-])$/, | ||
| long: /^--(\S+)/, | ||
| combinedShort: /^-[^\d-]{2,}$/, | ||
| optEquals: /^(--\S+?)=(.*)/ | ||
| }; | ||
| /** | ||
| * Array subclass encapsulating common operations on `process.argv`. | ||
| * @static | ||
| */ | ||
| class ArgvArray extends Array { | ||
| /** | ||
| * Clears the array has loads the supplied input. | ||
| * @param {string[]} argv - The argv list to load. Defaults to `process.argv`. | ||
| */ | ||
| load (argv) { | ||
| this.clear(); | ||
| if (argv && argv !== process.argv) { | ||
| argv = arrayify(argv); | ||
| } else { | ||
| /* if no argv supplied, assume we are parsing process.argv */ | ||
| argv = process.argv.slice(0); | ||
| const deleteCount = process.execArgv.some(isExecArg) ? 1 : 2; | ||
| argv.splice(0, deleteCount); | ||
| } | ||
| argv.forEach(arg => this.push(String(arg))); | ||
| } | ||
| /** | ||
| * Clear the array. | ||
| */ | ||
| clear () { | ||
| this.length = 0; | ||
| } | ||
| /** | ||
| * expand ``--option=value` style args. | ||
| */ | ||
| expandOptionEqualsNotation () { | ||
| if (this.some(arg => re.optEquals.test(arg))) { | ||
| const expandedArgs = []; | ||
| this.forEach(arg => { | ||
| const matches = arg.match(re.optEquals); | ||
| if (matches) { | ||
| expandedArgs.push(matches[1], matches[2]); | ||
| } else { | ||
| expandedArgs.push(arg); | ||
| } | ||
| }); | ||
| this.clear(); | ||
| this.load(expandedArgs); | ||
| } | ||
| } | ||
| /** | ||
| * expand getopt-style combinedShort options. | ||
| */ | ||
| expandGetoptNotation () { | ||
| if (this.hasCombinedShortOptions()) { | ||
| findReplace(this, re.combinedShort, expandCombinedShortArg); | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if the array contains combined short options (e.g. `-ab`). | ||
| * @returns {boolean} | ||
| */ | ||
| hasCombinedShortOptions () { | ||
| return this.some(arg => re.combinedShort.test(arg)) | ||
| } | ||
| static from (argv) { | ||
| const result = new this(); | ||
| result.load(argv); | ||
| return result | ||
| } | ||
| } | ||
| /** | ||
| * Expand a combined short option. | ||
| * @param {string} - the string to expand, e.g. `-ab` | ||
| * @returns {string[]} | ||
| * @static | ||
| */ | ||
| function expandCombinedShortArg (arg) { | ||
| /* remove initial hypen */ | ||
| arg = arg.slice(1); | ||
| return arg.split('').map(letter => '-' + letter) | ||
| } | ||
| /** | ||
| * Returns true if the supplied arg matches `--option=value` notation. | ||
| * @param {string} - the arg to test, e.g. `--one=something` | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isOptionEqualsNotation (arg) { | ||
| return re.optEquals.test(arg) | ||
| } | ||
| /** | ||
| * Returns true if the supplied arg is in either long (`--one`) or short (`-o`) format. | ||
| * @param {string} - the arg to test, e.g. `--one` | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isOption (arg) { | ||
| return (re.short.test(arg) || re.long.test(arg)) && !re.optEquals.test(arg) | ||
| } | ||
| /** | ||
| * Returns true if the supplied arg is in long (`--one`) format. | ||
| * @param {string} - the arg to test, e.g. `--one` | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isLongOption (arg) { | ||
| return re.long.test(arg) && !isOptionEqualsNotation(arg) | ||
| } | ||
| /** | ||
| * Returns the name from a long, short or `--options=value` arg. | ||
| * @param {string} - the arg to inspect, e.g. `--one` | ||
| * @returns {string} | ||
| * @static | ||
| */ | ||
| function getOptionName (arg) { | ||
| if (re.short.test(arg)) { | ||
| return arg.match(re.short)[1] | ||
| } else if (isLongOption(arg)) { | ||
| return arg.match(re.long)[1] | ||
| } else if (isOptionEqualsNotation(arg)) { | ||
| return arg.match(re.optEquals)[1].replace(/^--/, '') | ||
| } else { | ||
| return null | ||
| } | ||
| } | ||
| function isValue (arg) { | ||
| return !(isOption(arg) || re.combinedShort.test(arg) || re.optEquals.test(arg)) | ||
| } | ||
| function isExecArg (arg) { | ||
| return ['--eval', '-e'].indexOf(arg) > -1 || arg.startsWith('--eval=') | ||
| } | ||
| /** | ||
| * Isomorphic, functional type-checking for Javascript. | ||
| * @module typical | ||
| * @typicalname t | ||
| * @example | ||
| * import * as t from 'typical' | ||
| * const allDefined = array.every(t.isDefined) | ||
| */ | ||
| /** | ||
| * Returns true if input is a number (including infinity). It is a more reasonable alternative to `typeof n` which returns `number` for `NaN`. | ||
| * | ||
| * @param {*} n - The input to test | ||
| * @returns {boolean} `true` if input is a number | ||
| * @static | ||
| * @example | ||
| * > t.isNumber(0) | ||
| * true | ||
| * > t.isNumber(1) | ||
| * true | ||
| * > t.isNumber(1.1) | ||
| * true | ||
| * > t.isNumber(0xff) | ||
| * true | ||
| * > t.isNumber(0644) | ||
| * true | ||
| * > t.isNumber(6.2e5) | ||
| * true | ||
| * > t.isNumber(NaN) | ||
| * false | ||
| * > t.isNumber(Infinity) | ||
| * true | ||
| */ | ||
| function isNumber (n) { | ||
| return !isNaN(parseFloat(n)) | ||
| } | ||
| /** | ||
| * Returns true if input is a finite number. Identical to `isNumber` beside excluding infinity. | ||
| * | ||
| * @param {*} n - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| * @example | ||
| * > t.isFiniteNumber(0) | ||
| * true | ||
| * > t.isFiniteNumber(1) | ||
| * true | ||
| * > t.isFiniteNumber(1.1) | ||
| * true | ||
| * > t.isFiniteNumber(0xff) | ||
| * true | ||
| * > t.isFiniteNumber(0644) | ||
| * true | ||
| * > t.isFiniteNumber(6.2e5) | ||
| * true | ||
| * > t.isFiniteNumber(NaN) | ||
| * false | ||
| * > t.isFiniteNumber(Infinity) | ||
| * false | ||
| */ | ||
| function isFiniteNumber (n) { | ||
| return !isNaN(parseFloat(n)) && isFinite(n) | ||
| } | ||
| /** | ||
| * A plain object is a simple object literal, it is not an instance of a class. Returns true if the input `typeof` is `object` and directly decends from `Object`. | ||
| * | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| * @example | ||
| * > t.isPlainObject({ something: 'one' }) | ||
| * true | ||
| * > t.isPlainObject(new Date()) | ||
| * false | ||
| * > t.isPlainObject([ 0, 1 ]) | ||
| * false | ||
| * > t.isPlainObject(/test/) | ||
| * false | ||
| * > t.isPlainObject(1) | ||
| * false | ||
| * > t.isPlainObject('one') | ||
| * false | ||
| * > t.isPlainObject(null) | ||
| * false | ||
| * > t.isPlainObject((function * () {})()) | ||
| * false | ||
| * > t.isPlainObject(function * () {}) | ||
| * false | ||
| */ | ||
| function isPlainObject (input) { | ||
| return input !== null && typeof input === 'object' && input.constructor === Object | ||
| } | ||
| /** | ||
| * An array-like value has all the properties of an array yet is not an array instance. An example is the `arguments` object. Returns `true`` if the input value is an object, not `null`` and has a `length` property set with a numeric value. | ||
| * | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| * @example | ||
| * function sum(x, y){ | ||
| * console.log(t.isArrayLike(arguments)) | ||
| * // prints `true` | ||
| * } | ||
| */ | ||
| function isArrayLike (input) { | ||
| return isObject(input) && typeof input.length === 'number' | ||
| } | ||
| /** | ||
| * Returns true if the typeof input is `'object'` but not null. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isObject (input) { | ||
| return typeof input === 'object' && input !== null | ||
| } | ||
| /** | ||
| * Returns true if the input value is defined. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isDefined (input) { | ||
| return typeof input !== 'undefined' | ||
| } | ||
| /** | ||
| * Returns true if the input value is undefined. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isUndefined (input) { | ||
| return !isDefined(input) | ||
| } | ||
| /** | ||
| * Returns true if the input value is null. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isNull (input) { | ||
| return input === null | ||
| } | ||
| /** | ||
| * Returns true if the input value is not one of `undefined`, `null`, or `NaN`. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isDefinedValue (input) { | ||
| return isDefined(input) && !isNull(input) && !Number.isNaN(input) | ||
| } | ||
| /** | ||
| * Returns true if the input value is an ES2015 `class`. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isClass (input) { | ||
| if (typeof input === 'function') { | ||
| return /^class /.test(Function.prototype.toString.call(input)) | ||
| } else { | ||
| return false | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if the input is a string, number, symbol, boolean, null or undefined value. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isPrimitive (input) { | ||
| if (input === null) return true | ||
| switch (typeof input) { | ||
| case 'string': | ||
| case 'number': | ||
| case 'symbol': | ||
| case 'undefined': | ||
| case 'boolean': | ||
| return true | ||
| default: | ||
| return false | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if the input is a Promise. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isPromise (input) { | ||
| if (input) { | ||
| const isPromise = isDefined(Promise) && input instanceof Promise; | ||
| const isThenable = input.then && typeof input.then === 'function'; | ||
| return !!(isPromise || isThenable) | ||
| } else { | ||
| return false | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if the input is an iterable (`Map`, `Set`, `Array`, Generator etc.). | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| * @example | ||
| * > t.isIterable('string') | ||
| * true | ||
| * > t.isIterable(new Map()) | ||
| * true | ||
| * > t.isIterable([]) | ||
| * true | ||
| * > t.isIterable((function * () {})()) | ||
| * true | ||
| * > t.isIterable(Promise.resolve()) | ||
| * false | ||
| * > t.isIterable(Promise) | ||
| * false | ||
| * > t.isIterable(true) | ||
| * false | ||
| * > t.isIterable({}) | ||
| * false | ||
| * > t.isIterable(0) | ||
| * false | ||
| * > t.isIterable(1.1) | ||
| * false | ||
| * > t.isIterable(NaN) | ||
| * false | ||
| * > t.isIterable(Infinity) | ||
| * false | ||
| * > t.isIterable(function () {}) | ||
| * false | ||
| * > t.isIterable(Date) | ||
| * false | ||
| * > t.isIterable() | ||
| * false | ||
| * > t.isIterable({ then: function () {} }) | ||
| * false | ||
| */ | ||
| function isIterable (input) { | ||
| if (input === null || !isDefined(input)) { | ||
| return false | ||
| } else { | ||
| return ( | ||
| typeof input[Symbol.iterator] === 'function' || | ||
| typeof input[Symbol.asyncIterator] === 'function' | ||
| ) | ||
| } | ||
| } | ||
| /** | ||
| * Returns true if the input value is a string. The equivalent of `typeof input === 'string'` for use in funcitonal contexts. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isString (input) { | ||
| return typeof input === 'string' | ||
| } | ||
| /** | ||
| * Returns true if the input value is a function. The equivalent of `typeof input === 'function'` for use in funcitonal contexts. | ||
| * @param {*} input - The input to test | ||
| * @returns {boolean} | ||
| * @static | ||
| */ | ||
| function isFunction (input) { | ||
| return typeof input === 'function' | ||
| } | ||
| var t = { | ||
| isNumber, | ||
| isFiniteNumber, | ||
| isPlainObject, | ||
| isArrayLike, | ||
| isObject, | ||
| isDefined, | ||
| isUndefined, | ||
| isNull, | ||
| isDefinedValue, | ||
| isClass, | ||
| isPrimitive, | ||
| isPromise, | ||
| isIterable, | ||
| isString, | ||
| isFunction | ||
| }; | ||
| /** | ||
| * @module option-definition | ||
| */ | ||
| /** | ||
| * Describes a command-line option. Additionally, if generating a usage guide with [command-line-usage](https://github.com/75lb/command-line-usage) you could optionally add `description` and `typeLabel` properties to each definition. | ||
| * | ||
| * @alias module:option-definition | ||
| * @typicalname option | ||
| */ | ||
| class OptionDefinition { | ||
| constructor (definition) { | ||
| /** | ||
| * The only required definition property is `name`, so the simplest working example is | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'file' }, | ||
| * { name: 'depth' } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * Where a `type` property is not specified it will default to `String`. | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | -------------------- | ------------ | | ||
| * | 1 | `--file` | `{ file: null }` | | ||
| * | 2 | `--file lib.js` | `{ file: 'lib.js' }` | | ||
| * | 3 | `--depth 2` | `{ depth: '2' }` | | ||
| * | ||
| * Unicode option names and aliases are valid, for example: | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'один' }, | ||
| * { name: '两' }, | ||
| * { name: 'три', alias: 'т' } | ||
| * ] | ||
| * ``` | ||
| * @type {string} | ||
| */ | ||
| this.name = definition.name; | ||
| /** | ||
| * The `type` value is a setter function (you receive the output from this), enabling you to be specific about the type and value received. | ||
| * | ||
| * The most common values used are `String` (the default), `Number` and `Boolean` but you can use a custom function, for example: | ||
| * | ||
| * ```js | ||
| * const fs = require('fs') | ||
| * | ||
| * class FileDetails { | ||
| * constructor (filename) { | ||
| * this.filename = filename | ||
| * this.exists = fs.existsSync(filename) | ||
| * } | ||
| * } | ||
| * | ||
| * const cli = commandLineArgs([ | ||
| * { name: 'file', type: filename => new FileDetails(filename) }, | ||
| * { name: 'depth', type: Number } | ||
| * ]) | ||
| * ``` | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ----------------- | ------------ | | ||
| * | 1 | `--file asdf.txt` | `{ file: { filename: 'asdf.txt', exists: false } }` | | ||
| * | ||
| * The `--depth` option expects a `Number`. If no value was set, you will receive `null`. | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ----------------- | ------------ | | ||
| * | 2 | `--depth` | `{ depth: null }` | | ||
| * | 3 | `--depth 2` | `{ depth: 2 }` | | ||
| * | ||
| * @type {function} | ||
| * @default String | ||
| */ | ||
| this.type = definition.type || String; | ||
| /** | ||
| * getopt-style short option names. Can be any single character (unicode included) except a digit or hyphen. | ||
| * | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'hot', alias: 'h', type: Boolean }, | ||
| * { name: 'discount', alias: 'd', type: Boolean }, | ||
| * { name: 'courses', alias: 'c' , type: Number } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ------------ | ------------ | | ||
| * | 1 | `-hcd` | `{ hot: true, courses: null, discount: true }` | | ||
| * | 2 | `-hdc 3` | `{ hot: true, discount: true, courses: 3 }` | | ||
| * | ||
| * @type {string} | ||
| */ | ||
| this.alias = definition.alias; | ||
| /** | ||
| * Set this flag if the option takes a list of values. You will receive an array of values, each passed through the `type` function (if specified). | ||
| * | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'files', type: String, multiple: true } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * Note, examples 1 and 3 below demonstrate "greedy" parsing which can be disabled by using `lazyMultiple`. | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ------------ | ------------ | | ||
| * | 1 | `--files one.js two.js` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | 2 | `--files one.js --files two.js` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | 3 | `--files *` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | ||
| * @type {boolean} | ||
| */ | ||
| this.multiple = definition.multiple; | ||
| /** | ||
| * Identical to `multiple` but with greedy parsing disabled. | ||
| * | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'files', lazyMultiple: true }, | ||
| * { name: 'verbose', alias: 'v', type: Boolean, lazyMultiple: true } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ------------ | ------------ | | ||
| * | 1 | `--files one.js --files two.js` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | 2 | `-vvv` | `{ verbose: [ true, true, true ] }` | | ||
| * | ||
| * @type {boolean} | ||
| */ | ||
| this.lazyMultiple = definition.lazyMultiple; | ||
| /** | ||
| * Any values unaccounted for by an option definition will be set on the `defaultOption`. This flag is typically set on the most commonly-used option to make for more concise usage (i.e. `$ example *.js` instead of `$ example --files *.js`). | ||
| * | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'files', multiple: true, defaultOption: true } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ------------ | ------------ | | ||
| * | 1 | `--files one.js two.js` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | 2 | `one.js two.js` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | 3 | `*` | `{ files: [ 'one.js', 'two.js' ] }` | | ||
| * | ||
| * @type {boolean} | ||
| */ | ||
| this.defaultOption = definition.defaultOption; | ||
| /** | ||
| * An initial value for the option. | ||
| * | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'files', multiple: true, defaultValue: [ 'one.js' ] }, | ||
| * { name: 'max', type: Number, defaultValue: 3 } | ||
| * ] | ||
| * ``` | ||
| * | ||
| * | # | argv input | commandLineArgs() output | | ||
| * | --- | ------------ | ------------ | | ||
| * | 1 | | `{ files: [ 'one.js' ], max: 3 }` | | ||
| * | 2 | `--files two.js` | `{ files: [ 'two.js' ], max: 3 }` | | ||
| * | 3 | `--max 4` | `{ files: [ 'one.js' ], max: 4 }` | | ||
| * | ||
| * @type {*} | ||
| */ | ||
| this.defaultValue = definition.defaultValue; | ||
| /** | ||
| * When your app has a large amount of options it makes sense to organise them in groups. | ||
| * | ||
| * There are two automatic groups: `_all` (contains all options) and `_none` (contains options without a `group` specified in their definition). | ||
| * | ||
| * ```js | ||
| * const optionDefinitions = [ | ||
| * { name: 'verbose', group: 'standard' }, | ||
| * { name: 'help', group: [ 'standard', 'main' ] }, | ||
| * { name: 'compress', group: [ 'server', 'main' ] }, | ||
| * { name: 'static', group: 'server' }, | ||
| * { name: 'debug' } | ||
| * ] | ||
| * ``` | ||
| * | ||
| *<table> | ||
| * <tr> | ||
| * <th>#</th><th>Command Line</th><th>commandLineArgs() output</th> | ||
| * </tr> | ||
| * <tr> | ||
| * <td>1</td><td><code>--verbose</code></td><td><pre><code> | ||
| *{ | ||
| * _all: { verbose: true }, | ||
| * standard: { verbose: true } | ||
| *} | ||
| *</code></pre></td> | ||
| * </tr> | ||
| * <tr> | ||
| * <td>2</td><td><code>--debug</code></td><td><pre><code> | ||
| *{ | ||
| * _all: { debug: true }, | ||
| * _none: { debug: true } | ||
| *} | ||
| *</code></pre></td> | ||
| * </tr> | ||
| * <tr> | ||
| * <td>3</td><td><code>--verbose --debug --compress</code></td><td><pre><code> | ||
| *{ | ||
| * _all: { | ||
| * verbose: true, | ||
| * debug: true, | ||
| * compress: true | ||
| * }, | ||
| * standard: { verbose: true }, | ||
| * server: { compress: true }, | ||
| * main: { compress: true }, | ||
| * _none: { debug: true } | ||
| *} | ||
| *</code></pre></td> | ||
| * </tr> | ||
| * <tr> | ||
| * <td>4</td><td><code>--compress</code></td><td><pre><code> | ||
| *{ | ||
| * _all: { compress: true }, | ||
| * server: { compress: true }, | ||
| * main: { compress: true } | ||
| *} | ||
| *</code></pre></td> | ||
| * </tr> | ||
| *</table> | ||
| * | ||
| * @type {string|string[]} | ||
| */ | ||
| this.group = definition.group; | ||
| /* pick up any remaining properties */ | ||
| for (const prop in definition) { | ||
| if (!this[prop]) this[prop] = definition[prop]; | ||
| } | ||
| } | ||
| isBoolean () { | ||
| return this.type === Boolean || (t.isFunction(this.type) && this.type.name === 'Boolean') | ||
| } | ||
| isMultiple () { | ||
| return this.multiple || this.lazyMultiple | ||
| } | ||
| static create (def) { | ||
| const result = new this(def); | ||
| return result | ||
| } | ||
| } | ||
| /** | ||
| * @module option-definitions | ||
| */ | ||
| /** | ||
| * @alias module:option-definitions | ||
| */ | ||
| class Definitions extends Array { | ||
| /** | ||
| * validate option definitions | ||
| * @param {boolean} [caseInsensitive=false] - whether arguments will be parsed in a case insensitive manner | ||
| * @returns {string} | ||
| */ | ||
| validate (caseInsensitive) { | ||
| const someHaveNoName = this.some(def => !def.name); | ||
| if (someHaveNoName) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Invalid option definitions: the `name` property is required on each definition' | ||
| ); | ||
| } | ||
| const someDontHaveFunctionType = this.some(def => def.type && typeof def.type !== 'function'); | ||
| if (someDontHaveFunctionType) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Invalid option definitions: the `type` property must be a setter fuction (default: `Boolean`)' | ||
| ); | ||
| } | ||
| let invalidOption; | ||
| const numericAlias = this.some(def => { | ||
| invalidOption = def; | ||
| return t.isDefined(def.alias) && t.isNumber(def.alias) | ||
| }); | ||
| if (numericAlias) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Invalid option definition: to avoid ambiguity an alias cannot be numeric [--' + invalidOption.name + ' alias is -' + invalidOption.alias + ']' | ||
| ); | ||
| } | ||
| const multiCharacterAlias = this.some(def => { | ||
| invalidOption = def; | ||
| return t.isDefined(def.alias) && def.alias.length !== 1 | ||
| }); | ||
| if (multiCharacterAlias) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Invalid option definition: an alias must be a single character' | ||
| ); | ||
| } | ||
| const hypenAlias = this.some(def => { | ||
| invalidOption = def; | ||
| return def.alias === '-' | ||
| }); | ||
| if (hypenAlias) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Invalid option definition: an alias cannot be "-"' | ||
| ); | ||
| } | ||
| const duplicateName = hasDuplicates(this.map(def => caseInsensitive ? def.name.toLowerCase() : def.name)); | ||
| if (duplicateName) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Two or more option definitions have the same name' | ||
| ); | ||
| } | ||
| const duplicateAlias = hasDuplicates(this.map(def => caseInsensitive && t.isDefined(def.alias) ? def.alias.toLowerCase() : def.alias)); | ||
| if (duplicateAlias) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Two or more option definitions have the same alias' | ||
| ); | ||
| } | ||
| const duplicateDefaultOption = this.filter(def => def.defaultOption === true).length > 1; | ||
| if (duplicateDefaultOption) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| 'Only one option definition can be the defaultOption' | ||
| ); | ||
| } | ||
| const defaultBoolean = this.some(def => { | ||
| invalidOption = def; | ||
| return def.isBoolean() && def.defaultOption | ||
| }); | ||
| if (defaultBoolean) { | ||
| halt( | ||
| 'INVALID_DEFINITIONS', | ||
| `A boolean option ["${invalidOption.name}"] can not also be the defaultOption.` | ||
| ); | ||
| } | ||
| } | ||
| /** | ||
| * Get definition by option arg (e.g. `--one` or `-o`) | ||
| * @param {string} [arg] the argument name to get the definition for | ||
| * @param {boolean} [caseInsensitive] whether to use case insensitive comparisons when finding the appropriate definition | ||
| * @returns {Definition} | ||
| */ | ||
| get (arg, caseInsensitive) { | ||
| if (isOption(arg)) { | ||
| if (re.short.test(arg)) { | ||
| const shortOptionName = getOptionName(arg); | ||
| if (caseInsensitive) { | ||
| const lowercaseShortOptionName = shortOptionName.toLowerCase(); | ||
| return this.find(def => t.isDefined(def.alias) && def.alias.toLowerCase() === lowercaseShortOptionName) | ||
| } else { | ||
| return this.find(def => def.alias === shortOptionName) | ||
| } | ||
| } else { | ||
| const optionName = getOptionName(arg); | ||
| if (caseInsensitive) { | ||
| const lowercaseOptionName = optionName.toLowerCase(); | ||
| return this.find(def => def.name.toLowerCase() === lowercaseOptionName) | ||
| } else { | ||
| return this.find(def => def.name === optionName) | ||
| } | ||
| } | ||
| } else { | ||
| return this.find(def => def.name === arg) | ||
| } | ||
| } | ||
| getDefault () { | ||
| return this.find(def => def.defaultOption === true) | ||
| } | ||
| isGrouped () { | ||
| return this.some(def => def.group) | ||
| } | ||
| whereGrouped () { | ||
| return this.filter(containsValidGroup) | ||
| } | ||
| whereNotGrouped () { | ||
| return this.filter(def => !containsValidGroup(def)) | ||
| } | ||
| whereDefaultValueSet () { | ||
| return this.filter(def => t.isDefined(def.defaultValue)) | ||
| } | ||
| static from (definitions, caseInsensitive) { | ||
| if (definitions instanceof this) return definitions | ||
| const result = super.from(arrayify(definitions), def => OptionDefinition.create(def)); | ||
| result.validate(caseInsensitive); | ||
| return result | ||
| } | ||
| } | ||
| function halt (name, message) { | ||
| const err = new Error(message); | ||
| err.name = name; | ||
| throw err | ||
| } | ||
| function containsValidGroup (def) { | ||
| return arrayify(def.group).some(group => group) | ||
| } | ||
| function hasDuplicates (array) { | ||
| const items = {}; | ||
| for (let i = 0; i < array.length; i++) { | ||
| const value = array[i]; | ||
| if (items[value]) { | ||
| return true | ||
| } else { | ||
| if (t.isDefined(value)) items[value] = true; | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * @module argv-parser | ||
| */ | ||
| /** | ||
| * @alias module:argv-parser | ||
| */ | ||
| class ArgvParser { | ||
| /** | ||
| * @param {OptionDefinitions} - Definitions array | ||
| * @param {object} [options] - Options | ||
| * @param {string[]} [options.argv] - Overrides `process.argv` | ||
| * @param {boolean} [options.stopAtFirstUnknown] - | ||
| * @param {boolean} [options.caseInsensitive] - Arguments will be parsed in a case insensitive manner. Defaults to false. | ||
| */ | ||
| constructor (definitions, options) { | ||
| this.options = Object.assign({}, options); | ||
| /** | ||
| * Option Definitions | ||
| */ | ||
| this.definitions = Definitions.from(definitions, this.options.caseInsensitive); | ||
| /** | ||
| * Argv | ||
| */ | ||
| this.argv = ArgvArray.from(this.options.argv); | ||
| if (this.argv.hasCombinedShortOptions()) { | ||
| findReplace(this.argv, re.combinedShort.test.bind(re.combinedShort), arg => { | ||
| arg = arg.slice(1); | ||
| return arg.split('').map(letter => ({ origArg: `-${arg}`, arg: '-' + letter })) | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Yields one `{ event, name, value, arg, def }` argInfo object for each arg in `process.argv` (or `options.argv`). | ||
| */ | ||
| * [Symbol.iterator] () { | ||
| const definitions = this.definitions; | ||
| let def; | ||
| let value; | ||
| let name; | ||
| let event; | ||
| let singularDefaultSet = false; | ||
| let unknownFound = false; | ||
| let origArg; | ||
| for (let arg of this.argv) { | ||
| if (t.isPlainObject(arg)) { | ||
| origArg = arg.origArg; | ||
| arg = arg.arg; | ||
| } | ||
| if (unknownFound && this.options.stopAtFirstUnknown) { | ||
| yield { event: 'unknown_value', arg, name: '_unknown', value: undefined }; | ||
| continue | ||
| } | ||
| /* handle long or short option */ | ||
| if (isOption(arg)) { | ||
| def = definitions.get(arg, this.options.caseInsensitive); | ||
| value = undefined; | ||
| if (def) { | ||
| value = def.isBoolean() ? true : null; | ||
| event = 'set'; | ||
| } else { | ||
| event = 'unknown_option'; | ||
| } | ||
| /* handle --option-value notation */ | ||
| } else if (isOptionEqualsNotation(arg)) { | ||
| const matches = arg.match(re.optEquals); | ||
| def = definitions.get(matches[1], this.options.caseInsensitive); | ||
| if (def) { | ||
| if (def.isBoolean()) { | ||
| yield { event: 'unknown_value', arg, name: '_unknown', value, def }; | ||
| event = 'set'; | ||
| value = true; | ||
| } else { | ||
| event = 'set'; | ||
| value = matches[2]; | ||
| } | ||
| } else { | ||
| event = 'unknown_option'; | ||
| } | ||
| /* handle value */ | ||
| } else if (isValue(arg)) { | ||
| if (def) { | ||
| value = arg; | ||
| event = 'set'; | ||
| } else { | ||
| /* get the defaultOption */ | ||
| def = this.definitions.getDefault(); | ||
| if (def && !singularDefaultSet) { | ||
| value = arg; | ||
| event = 'set'; | ||
| } else { | ||
| event = 'unknown_value'; | ||
| def = undefined; | ||
| } | ||
| } | ||
| } | ||
| name = def ? def.name : '_unknown'; | ||
| const argInfo = { event, arg, name, value, def }; | ||
| if (origArg) { | ||
| argInfo.subArg = arg; | ||
| argInfo.arg = origArg; | ||
| } | ||
| yield argInfo; | ||
| /* unknownFound logic */ | ||
| if (name === '_unknown') unknownFound = true; | ||
| /* singularDefaultSet logic */ | ||
| if (def && def.defaultOption && !def.isMultiple() && event === 'set') singularDefaultSet = true; | ||
| /* reset values once consumed and yielded */ | ||
| if (def && def.isBoolean()) def = undefined; | ||
| /* reset the def if it's a singular which has been set */ | ||
| if (def && !def.multiple && t.isDefined(value) && value !== null) { | ||
| def = undefined; | ||
| } | ||
| value = undefined; | ||
| event = undefined; | ||
| name = undefined; | ||
| origArg = undefined; | ||
| } | ||
| } | ||
| } | ||
| const _value = new WeakMap(); | ||
| /** | ||
| * Encapsulates behaviour (defined by an OptionDefinition) when setting values | ||
| */ | ||
| class Option { | ||
| constructor (definition) { | ||
| this.definition = new OptionDefinition(definition); | ||
| this.state = null; /* set or default */ | ||
| this.resetToDefault(); | ||
| } | ||
| get () { | ||
| return _value.get(this) | ||
| } | ||
| set (val) { | ||
| this._set(val, 'set'); | ||
| } | ||
| _set (val, state) { | ||
| const def = this.definition; | ||
| if (def.isMultiple()) { | ||
| /* don't add null or undefined to a multiple */ | ||
| if (val !== null && val !== undefined) { | ||
| const arr = this.get(); | ||
| if (this.state === 'default') arr.length = 0; | ||
| arr.push(def.type(val)); | ||
| this.state = state; | ||
| } | ||
| } else { | ||
| /* throw if already set on a singlar defaultOption */ | ||
| if (!def.isMultiple() && this.state === 'set') { | ||
| const err = new Error(`Singular option already set [${this.definition.name}=${this.get()}]`); | ||
| err.name = 'ALREADY_SET'; | ||
| err.value = val; | ||
| err.optionName = def.name; | ||
| throw err | ||
| } else if (val === null || val === undefined) { | ||
| _value.set(this, val); | ||
| // /* required to make 'partial: defaultOption with value equal to defaultValue 2' pass */ | ||
| // if (!(def.defaultOption && !def.isMultiple())) { | ||
| // this.state = state | ||
| // } | ||
| } else { | ||
| _value.set(this, def.type(val)); | ||
| this.state = state; | ||
| } | ||
| } | ||
| } | ||
| resetToDefault () { | ||
| if (t.isDefined(this.definition.defaultValue)) { | ||
| if (this.definition.isMultiple()) { | ||
| _value.set(this, arrayify(this.definition.defaultValue).slice()); | ||
| } else { | ||
| _value.set(this, this.definition.defaultValue); | ||
| } | ||
| } else { | ||
| if (this.definition.isMultiple()) { | ||
| _value.set(this, []); | ||
| } else { | ||
| _value.set(this, null); | ||
| } | ||
| } | ||
| this.state = 'default'; | ||
| } | ||
| static create (definition) { | ||
| definition = new OptionDefinition(definition); | ||
| if (definition.isBoolean()) { | ||
| return FlagOption.create(definition) | ||
| } else { | ||
| return new this(definition) | ||
| } | ||
| } | ||
| } | ||
| class FlagOption extends Option { | ||
| set (val) { | ||
| super.set(true); | ||
| } | ||
| static create (def) { | ||
| return new this(def) | ||
| } | ||
| } | ||
| var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
| function getDefaultExportFromCjs (x) { | ||
| return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; | ||
| } | ||
| /** | ||
| * lodash (Custom Build) <https://lodash.com/> | ||
| * Build: `lodash modularize exports="npm" -o ./` | ||
| * Copyright jQuery Foundation and other contributors <https://jquery.org/> | ||
| * Released under MIT license <https://lodash.com/license> | ||
| * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> | ||
| * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors | ||
| */ | ||
| /** Used as references for various `Number` constants. */ | ||
| var INFINITY = 1 / 0; | ||
| /** `Object#toString` result references. */ | ||
| var symbolTag = '[object Symbol]'; | ||
| /** Used to match words composed of alphanumeric characters. */ | ||
| var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; | ||
| /** Used to match Latin Unicode letters (excluding mathematical operators). */ | ||
| var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; | ||
| /** Used to compose unicode character classes. */ | ||
| var rsAstralRange = '\\ud800-\\udfff', | ||
| rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', | ||
| rsComboSymbolsRange = '\\u20d0-\\u20f0', | ||
| rsDingbatRange = '\\u2700-\\u27bf', | ||
| rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', | ||
| rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', | ||
| rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', | ||
| rsPunctuationRange = '\\u2000-\\u206f', | ||
| rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', | ||
| rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', | ||
| rsVarRange = '\\ufe0e\\ufe0f', | ||
| rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; | ||
| /** Used to compose unicode capture groups. */ | ||
| var rsApos = "['\u2019]", | ||
| rsAstral = '[' + rsAstralRange + ']', | ||
| rsBreak = '[' + rsBreakRange + ']', | ||
| rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', | ||
| rsDigits = '\\d+', | ||
| rsDingbat = '[' + rsDingbatRange + ']', | ||
| rsLower = '[' + rsLowerRange + ']', | ||
| rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', | ||
| rsFitz = '\\ud83c[\\udffb-\\udfff]', | ||
| rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', | ||
| rsNonAstral = '[^' + rsAstralRange + ']', | ||
| rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', | ||
| rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', | ||
| rsUpper = '[' + rsUpperRange + ']', | ||
| rsZWJ = '\\u200d'; | ||
| /** Used to compose unicode regexes. */ | ||
| var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', | ||
| rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', | ||
| rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', | ||
| rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', | ||
| reOptMod = rsModifier + '?', | ||
| rsOptVar = '[' + rsVarRange + ']?', | ||
| rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', | ||
| rsSeq = rsOptVar + reOptMod + rsOptJoin, | ||
| rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, | ||
| rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; | ||
| /** Used to match apostrophes. */ | ||
| var reApos = RegExp(rsApos, 'g'); | ||
| /** | ||
| * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and | ||
| * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). | ||
| */ | ||
| var reComboMark = RegExp(rsCombo, 'g'); | ||
| /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ | ||
| var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); | ||
| /** Used to match complex or compound words. */ | ||
| var reUnicodeWord = RegExp([ | ||
| rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', | ||
| rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', | ||
| rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr, | ||
| rsUpper + '+' + rsOptUpperContr, | ||
| rsDigits, | ||
| rsEmoji | ||
| ].join('|'), 'g'); | ||
| /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ | ||
| var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); | ||
| /** Used to detect strings that need a more robust regexp to match words. */ | ||
| var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; | ||
| /** Used to map Latin Unicode letters to basic Latin letters. */ | ||
| var deburredLetters = { | ||
| // Latin-1 Supplement block. | ||
| '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', | ||
| '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', | ||
| '\xc7': 'C', '\xe7': 'c', | ||
| '\xd0': 'D', '\xf0': 'd', | ||
| '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', | ||
| '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', | ||
| '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', | ||
| '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', | ||
| '\xd1': 'N', '\xf1': 'n', | ||
| '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', | ||
| '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', | ||
| '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', | ||
| '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', | ||
| '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', | ||
| '\xc6': 'Ae', '\xe6': 'ae', | ||
| '\xde': 'Th', '\xfe': 'th', | ||
| '\xdf': 'ss', | ||
| // Latin Extended-A block. | ||
| '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', | ||
| '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', | ||
| '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', | ||
| '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', | ||
| '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', | ||
| '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', | ||
| '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', | ||
| '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', | ||
| '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', | ||
| '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', | ||
| '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', | ||
| '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', | ||
| '\u0134': 'J', '\u0135': 'j', | ||
| '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', | ||
| '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', | ||
| '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', | ||
| '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', | ||
| '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', | ||
| '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', | ||
| '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', | ||
| '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', | ||
| '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', | ||
| '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', | ||
| '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', | ||
| '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', | ||
| '\u0163': 't', '\u0165': 't', '\u0167': 't', | ||
| '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', | ||
| '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', | ||
| '\u0174': 'W', '\u0175': 'w', | ||
| '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', | ||
| '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', | ||
| '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', | ||
| '\u0132': 'IJ', '\u0133': 'ij', | ||
| '\u0152': 'Oe', '\u0153': 'oe', | ||
| '\u0149': "'n", '\u017f': 'ss' | ||
| }; | ||
| /** Detect free variable `global` from Node.js. */ | ||
| var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; | ||
| /** Detect free variable `self`. */ | ||
| var freeSelf = typeof self == 'object' && self && self.Object === Object && self; | ||
| /** Used as a reference to the global object. */ | ||
| var root = freeGlobal || freeSelf || Function('return this')(); | ||
| /** | ||
| * A specialized version of `_.reduce` for arrays without support for | ||
| * iteratee shorthands. | ||
| * | ||
| * @private | ||
| * @param {Array} [array] The array to iterate over. | ||
| * @param {Function} iteratee The function invoked per iteration. | ||
| * @param {*} [accumulator] The initial value. | ||
| * @param {boolean} [initAccum] Specify using the first element of `array` as | ||
| * the initial value. | ||
| * @returns {*} Returns the accumulated value. | ||
| */ | ||
| function arrayReduce(array, iteratee, accumulator, initAccum) { | ||
| var index = -1, | ||
| length = array ? array.length : 0; | ||
| while (++index < length) { | ||
| accumulator = iteratee(accumulator, array[index], index, array); | ||
| } | ||
| return accumulator; | ||
| } | ||
| /** | ||
| * Converts an ASCII `string` to an array. | ||
| * | ||
| * @private | ||
| * @param {string} string The string to convert. | ||
| * @returns {Array} Returns the converted array. | ||
| */ | ||
| function asciiToArray(string) { | ||
| return string.split(''); | ||
| } | ||
| /** | ||
| * Splits an ASCII `string` into an array of its words. | ||
| * | ||
| * @private | ||
| * @param {string} The string to inspect. | ||
| * @returns {Array} Returns the words of `string`. | ||
| */ | ||
| function asciiWords(string) { | ||
| return string.match(reAsciiWord) || []; | ||
| } | ||
| /** | ||
| * The base implementation of `_.propertyOf` without support for deep paths. | ||
| * | ||
| * @private | ||
| * @param {Object} object The object to query. | ||
| * @returns {Function} Returns the new accessor function. | ||
| */ | ||
| function basePropertyOf(object) { | ||
| return function(key) { | ||
| return object == null ? undefined : object[key]; | ||
| }; | ||
| } | ||
| /** | ||
| * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A | ||
| * letters to basic Latin letters. | ||
| * | ||
| * @private | ||
| * @param {string} letter The matched letter to deburr. | ||
| * @returns {string} Returns the deburred letter. | ||
| */ | ||
| var deburrLetter = basePropertyOf(deburredLetters); | ||
| /** | ||
| * Checks if `string` contains Unicode symbols. | ||
| * | ||
| * @private | ||
| * @param {string} string The string to inspect. | ||
| * @returns {boolean} Returns `true` if a symbol is found, else `false`. | ||
| */ | ||
| function hasUnicode(string) { | ||
| return reHasUnicode.test(string); | ||
| } | ||
| /** | ||
| * Checks if `string` contains a word composed of Unicode symbols. | ||
| * | ||
| * @private | ||
| * @param {string} string The string to inspect. | ||
| * @returns {boolean} Returns `true` if a word is found, else `false`. | ||
| */ | ||
| function hasUnicodeWord(string) { | ||
| return reHasUnicodeWord.test(string); | ||
| } | ||
| /** | ||
| * Converts `string` to an array. | ||
| * | ||
| * @private | ||
| * @param {string} string The string to convert. | ||
| * @returns {Array} Returns the converted array. | ||
| */ | ||
| function stringToArray(string) { | ||
| return hasUnicode(string) | ||
| ? unicodeToArray(string) | ||
| : asciiToArray(string); | ||
| } | ||
| /** | ||
| * Converts a Unicode `string` to an array. | ||
| * | ||
| * @private | ||
| * @param {string} string The string to convert. | ||
| * @returns {Array} Returns the converted array. | ||
| */ | ||
| function unicodeToArray(string) { | ||
| return string.match(reUnicode) || []; | ||
| } | ||
| /** | ||
| * Splits a Unicode `string` into an array of its words. | ||
| * | ||
| * @private | ||
| * @param {string} The string to inspect. | ||
| * @returns {Array} Returns the words of `string`. | ||
| */ | ||
| function unicodeWords(string) { | ||
| return string.match(reUnicodeWord) || []; | ||
| } | ||
| /** Used for built-in method references. */ | ||
| var objectProto = Object.prototype; | ||
| /** | ||
| * Used to resolve the | ||
| * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) | ||
| * of values. | ||
| */ | ||
| var objectToString = objectProto.toString; | ||
| /** Built-in value references. */ | ||
| var Symbol$1 = root.Symbol; | ||
| /** Used to convert symbols to primitives and strings. */ | ||
| var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, | ||
| symbolToString = symbolProto ? symbolProto.toString : undefined; | ||
| /** | ||
| * The base implementation of `_.slice` without an iteratee call guard. | ||
| * | ||
| * @private | ||
| * @param {Array} array The array to slice. | ||
| * @param {number} [start=0] The start position. | ||
| * @param {number} [end=array.length] The end position. | ||
| * @returns {Array} Returns the slice of `array`. | ||
| */ | ||
| function baseSlice(array, start, end) { | ||
| var index = -1, | ||
| length = array.length; | ||
| if (start < 0) { | ||
| start = -start > length ? 0 : (length + start); | ||
| } | ||
| end = end > length ? length : end; | ||
| if (end < 0) { | ||
| end += length; | ||
| } | ||
| length = start > end ? 0 : ((end - start) >>> 0); | ||
| start >>>= 0; | ||
| var result = Array(length); | ||
| while (++index < length) { | ||
| result[index] = array[index + start]; | ||
| } | ||
| return result; | ||
| } | ||
| /** | ||
| * The base implementation of `_.toString` which doesn't convert nullish | ||
| * values to empty strings. | ||
| * | ||
| * @private | ||
| * @param {*} value The value to process. | ||
| * @returns {string} Returns the string. | ||
| */ | ||
| function baseToString(value) { | ||
| // Exit early for strings to avoid a performance hit in some environments. | ||
| if (typeof value == 'string') { | ||
| return value; | ||
| } | ||
| if (isSymbol(value)) { | ||
| return symbolToString ? symbolToString.call(value) : ''; | ||
| } | ||
| var result = (value + ''); | ||
| return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; | ||
| } | ||
| /** | ||
| * Casts `array` to a slice if it's needed. | ||
| * | ||
| * @private | ||
| * @param {Array} array The array to inspect. | ||
| * @param {number} start The start position. | ||
| * @param {number} [end=array.length] The end position. | ||
| * @returns {Array} Returns the cast slice. | ||
| */ | ||
| function castSlice(array, start, end) { | ||
| var length = array.length; | ||
| end = end === undefined ? length : end; | ||
| return (!start && end >= length) ? array : baseSlice(array, start, end); | ||
| } | ||
| /** | ||
| * Creates a function like `_.lowerFirst`. | ||
| * | ||
| * @private | ||
| * @param {string} methodName The name of the `String` case method to use. | ||
| * @returns {Function} Returns the new case function. | ||
| */ | ||
| function createCaseFirst(methodName) { | ||
| return function(string) { | ||
| string = toString(string); | ||
| var strSymbols = hasUnicode(string) | ||
| ? stringToArray(string) | ||
| : undefined; | ||
| var chr = strSymbols | ||
| ? strSymbols[0] | ||
| : string.charAt(0); | ||
| var trailing = strSymbols | ||
| ? castSlice(strSymbols, 1).join('') | ||
| : string.slice(1); | ||
| return chr[methodName]() + trailing; | ||
| }; | ||
| } | ||
| /** | ||
| * Creates a function like `_.camelCase`. | ||
| * | ||
| * @private | ||
| * @param {Function} callback The function to combine each word. | ||
| * @returns {Function} Returns the new compounder function. | ||
| */ | ||
| function createCompounder(callback) { | ||
| return function(string) { | ||
| return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); | ||
| }; | ||
| } | ||
| /** | ||
| * Checks if `value` is object-like. A value is object-like if it's not `null` | ||
| * and has a `typeof` result of "object". | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 4.0.0 | ||
| * @category Lang | ||
| * @param {*} value The value to check. | ||
| * @returns {boolean} Returns `true` if `value` is object-like, else `false`. | ||
| * @example | ||
| * | ||
| * _.isObjectLike({}); | ||
| * // => true | ||
| * | ||
| * _.isObjectLike([1, 2, 3]); | ||
| * // => true | ||
| * | ||
| * _.isObjectLike(_.noop); | ||
| * // => false | ||
| * | ||
| * _.isObjectLike(null); | ||
| * // => false | ||
| */ | ||
| function isObjectLike(value) { | ||
| return !!value && typeof value == 'object'; | ||
| } | ||
| /** | ||
| * Checks if `value` is classified as a `Symbol` primitive or object. | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 4.0.0 | ||
| * @category Lang | ||
| * @param {*} value The value to check. | ||
| * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. | ||
| * @example | ||
| * | ||
| * _.isSymbol(Symbol.iterator); | ||
| * // => true | ||
| * | ||
| * _.isSymbol('abc'); | ||
| * // => false | ||
| */ | ||
| function isSymbol(value) { | ||
| return typeof value == 'symbol' || | ||
| (isObjectLike(value) && objectToString.call(value) == symbolTag); | ||
| } | ||
| /** | ||
| * Converts `value` to a string. An empty string is returned for `null` | ||
| * and `undefined` values. The sign of `-0` is preserved. | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 4.0.0 | ||
| * @category Lang | ||
| * @param {*} value The value to process. | ||
| * @returns {string} Returns the string. | ||
| * @example | ||
| * | ||
| * _.toString(null); | ||
| * // => '' | ||
| * | ||
| * _.toString(-0); | ||
| * // => '-0' | ||
| * | ||
| * _.toString([1, 2, 3]); | ||
| * // => '1,2,3' | ||
| */ | ||
| function toString(value) { | ||
| return value == null ? '' : baseToString(value); | ||
| } | ||
| /** | ||
| * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 3.0.0 | ||
| * @category String | ||
| * @param {string} [string=''] The string to convert. | ||
| * @returns {string} Returns the camel cased string. | ||
| * @example | ||
| * | ||
| * _.camelCase('Foo Bar'); | ||
| * // => 'fooBar' | ||
| * | ||
| * _.camelCase('--foo-bar--'); | ||
| * // => 'fooBar' | ||
| * | ||
| * _.camelCase('__FOO_BAR__'); | ||
| * // => 'fooBar' | ||
| */ | ||
| var camelCase = createCompounder(function(result, word, index) { | ||
| word = word.toLowerCase(); | ||
| return result + (index ? capitalize(word) : word); | ||
| }); | ||
| /** | ||
| * Converts the first character of `string` to upper case and the remaining | ||
| * to lower case. | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 3.0.0 | ||
| * @category String | ||
| * @param {string} [string=''] The string to capitalize. | ||
| * @returns {string} Returns the capitalized string. | ||
| * @example | ||
| * | ||
| * _.capitalize('FRED'); | ||
| * // => 'Fred' | ||
| */ | ||
| function capitalize(string) { | ||
| return upperFirst(toString(string).toLowerCase()); | ||
| } | ||
| /** | ||
| * Deburrs `string` by converting | ||
| * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) | ||
| * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) | ||
| * letters to basic Latin letters and removing | ||
| * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 3.0.0 | ||
| * @category String | ||
| * @param {string} [string=''] The string to deburr. | ||
| * @returns {string} Returns the deburred string. | ||
| * @example | ||
| * | ||
| * _.deburr('déjà vu'); | ||
| * // => 'deja vu' | ||
| */ | ||
| function deburr(string) { | ||
| string = toString(string); | ||
| return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); | ||
| } | ||
| /** | ||
| * Converts the first character of `string` to upper case. | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 4.0.0 | ||
| * @category String | ||
| * @param {string} [string=''] The string to convert. | ||
| * @returns {string} Returns the converted string. | ||
| * @example | ||
| * | ||
| * _.upperFirst('fred'); | ||
| * // => 'Fred' | ||
| * | ||
| * _.upperFirst('FRED'); | ||
| * // => 'FRED' | ||
| */ | ||
| var upperFirst = createCaseFirst('toUpperCase'); | ||
| /** | ||
| * Splits `string` into an array of its words. | ||
| * | ||
| * @static | ||
| * @memberOf _ | ||
| * @since 3.0.0 | ||
| * @category String | ||
| * @param {string} [string=''] The string to inspect. | ||
| * @param {RegExp|string} [pattern] The pattern to match words. | ||
| * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. | ||
| * @returns {Array} Returns the words of `string`. | ||
| * @example | ||
| * | ||
| * _.words('fred, barney, & pebbles'); | ||
| * // => ['fred', 'barney', 'pebbles'] | ||
| * | ||
| * _.words('fred, barney, & pebbles', /[^, ]+/g); | ||
| * // => ['fred', 'barney', '&', 'pebbles'] | ||
| */ | ||
| function words(string, pattern, guard) { | ||
| string = toString(string); | ||
| pattern = pattern; | ||
| if (pattern === undefined) { | ||
| return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string); | ||
| } | ||
| return string.match(pattern) || []; | ||
| } | ||
| var lodash_camelcase = camelCase; | ||
| var camelCase$1 = /*@__PURE__*/getDefaultExportFromCjs(lodash_camelcase); | ||
| /** | ||
| * A map of { DefinitionNameString: Option }. By default, an Output has an `_unknown` property and any options with defaultValues. | ||
| */ | ||
| class Output extends Map { | ||
| constructor (definitions) { | ||
| super(); | ||
| /** | ||
| * @type {OptionDefinitions} | ||
| */ | ||
| this.definitions = Definitions.from(definitions); | ||
| /* by default, an Output has an `_unknown` property and any options with defaultValues */ | ||
| this.set('_unknown', Option.create({ name: '_unknown', multiple: true })); | ||
| for (const def of this.definitions.whereDefaultValueSet()) { | ||
| this.set(def.name, Option.create(def)); | ||
| } | ||
| } | ||
| toObject (options) { | ||
| options = options || {}; | ||
| const output = {}; | ||
| for (const item of this) { | ||
| const name = options.camelCase && item[0] !== '_unknown' ? camelCase$1(item[0]) : item[0]; | ||
| const option = item[1]; | ||
| if (name === '_unknown' && !option.get().length) continue | ||
| output[name] = option.get(); | ||
| } | ||
| if (options.skipUnknown) delete output._unknown; | ||
| return output | ||
| } | ||
| } | ||
| class GroupedOutput extends Output { | ||
| toObject (options) { | ||
| const superOutputNoCamel = super.toObject({ skipUnknown: options.skipUnknown }); | ||
| const superOutput = super.toObject(options); | ||
| const unknown = superOutput._unknown; | ||
| delete superOutput._unknown; | ||
| const grouped = { | ||
| _all: superOutput | ||
| }; | ||
| if (unknown && unknown.length) grouped._unknown = unknown; | ||
| this.definitions.whereGrouped().forEach(def => { | ||
| const name = options.camelCase ? camelCase$1(def.name) : def.name; | ||
| const outputValue = superOutputNoCamel[def.name]; | ||
| for (const groupName of arrayify(def.group)) { | ||
| grouped[groupName] = grouped[groupName] || {}; | ||
| if (t.isDefined(outputValue)) { | ||
| grouped[groupName][name] = outputValue; | ||
| } | ||
| } | ||
| }); | ||
| this.definitions.whereNotGrouped().forEach(def => { | ||
| const name = options.camelCase ? camelCase$1(def.name) : def.name; | ||
| const outputValue = superOutputNoCamel[def.name]; | ||
| if (t.isDefined(outputValue)) { | ||
| if (!grouped._none) grouped._none = {}; | ||
| grouped._none[name] = outputValue; | ||
| } | ||
| }); | ||
| return grouped | ||
| } | ||
| } | ||
| /** | ||
| * @module command-line-args | ||
| */ | ||
| /** | ||
| * Returns an object containing all option values set on the command line. By default it parses the global [`process.argv`](https://nodejs.org/api/process.html#process_process_argv) array. | ||
| * | ||
| * Parsing is strict by default - an exception is thrown if the user sets a singular option more than once or sets an unknown value or option (one without a valid [definition](https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md)). To be more permissive, enabling [partial](https://github.com/75lb/command-line-args/wiki/Partial-mode-example) or [stopAtFirstUnknown](https://github.com/75lb/command-line-args/wiki/stopAtFirstUnknown) modes will return known options in the usual manner while collecting unknown arguments in a separate `_unknown` property. | ||
| * | ||
| * @param {Array<OptionDefinition>} - 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; |
| import arrayify from 'array-back' | ||
| import findReplace from 'find-replace' | ||
| /** | ||
| * 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=') | ||
| } | ||
| export { | ||
| expandCombinedShortArg, | ||
| re, | ||
| ArgvArray, | ||
| getOptionName, | ||
| isOption, | ||
| isLongOption, | ||
| isOptionEqualsNotation, | ||
| isValue | ||
| } |
+13
-9
@@ -1,2 +0,6 @@ | ||
| 'use strict' | ||
| 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' | ||
@@ -6,3 +10,2 @@ /** | ||
| */ | ||
| module.exports = commandLineArgs | ||
@@ -14,3 +17,3 @@ /** | ||
| * | ||
| * @param {module:definition[]} - An array of [OptionDefinition](https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md) objects | ||
| * @param {Array<OptionDefinition>} - An array of [OptionDefinition](https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md) objects | ||
| * @param {object} [options] - Options. | ||
@@ -21,2 +24,3 @@ * @param {string[]} [options.argv] - An array of strings which, if present will be parsed instead of `process.argv`. | ||
| * @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} | ||
@@ -39,13 +43,11 @@ * @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`. | ||
| if (options.stopAtFirstUnknown) options.partial = true | ||
| const Definitions = require('./lib/option-definitions') | ||
| optionDefinitions = Definitions.from(optionDefinitions) | ||
| optionDefinitions = Definitions.from(optionDefinitions, options.caseInsensitive) | ||
| const ArgvParser = require('./lib/argv-parser') | ||
| const parser = new ArgvParser(optionDefinitions, { | ||
| argv: options.argv, | ||
| stopAtFirstUnknown: options.stopAtFirstUnknown | ||
| stopAtFirstUnknown: options.stopAtFirstUnknown, | ||
| caseInsensitive: options.caseInsensitive | ||
| }) | ||
| const Option = require('./lib/option') | ||
| const OutputClass = optionDefinitions.isGrouped() ? require('./lib/output-grouped') : require('./lib/output') | ||
| const OutputClass = optionDefinitions.isGrouped() ? OutputGrouped : Output | ||
| const output = new OutputClass(optionDefinitions) | ||
@@ -87,1 +89,3 @@ | ||
| } | ||
| export default commandLineArgs |
+17
-38
@@ -1,3 +0,5 @@ | ||
| 'use strict' | ||
| const argvTools = require('argv-tools') | ||
| import * as argvTools from './argv-tools.js' | ||
| import Definitions from './option-definitions.js' | ||
| import findReplace from 'find-replace' | ||
| import t from 'typical' | ||
@@ -16,52 +18,29 @@ /** | ||
| * @param {string[]} [options.argv] - Overrides `process.argv` | ||
| * @param {boolean} [options.stopAtFirstUnknown] | ||
| * @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) | ||
| const Definitions = require('./option-definitions') | ||
| /** | ||
| * Option Definitions | ||
| * @type {OptionDefinition[]} | ||
| */ | ||
| this.definitions = Definitions.from(definitions) | ||
| this.definitions = Definitions.from(definitions, this.options.caseInsensitive) | ||
| /** | ||
| * Argv | ||
| * @type {Array<string|object>} | ||
| */ | ||
| this.argv = argvTools.ArgvArray.from(this.options.argv) | ||
| if (this.argv.hasCombinedShortOptions()) { | ||
| this.expandCluster() | ||
| findReplace(this.argv, argvTools.re.combinedShort.test.bind(argvTools.re.combinedShort), arg => { | ||
| arg = arg.slice(1) | ||
| return arg.split('').map(letter => ({ origArg: `-${arg}`, arg: '-' + letter })) | ||
| }) | ||
| } | ||
| } | ||
| expandCluster () { | ||
| const findReplace = require('find-replace') | ||
| findReplace(this.argv, argvTools.re.combinedShort, arg => { | ||
| const result = [] | ||
| arg = arg.slice(1) | ||
| for (const letter of arg.split('')) { | ||
| const def = this.definitions.get(`-${letter}`) | ||
| if (def) { | ||
| if (def.isBoolean()) { | ||
| result.push({ origArg: `-${arg}`, arg: `-${letter}` }) | ||
| } else { | ||
| result.push({ origArg: `-${arg}`, arg: `-${letter}` }) | ||
| const attachedValue = arg.slice(arg.indexOf(letter) + 1) | ||
| if (attachedValue) { | ||
| result.push({ origArg: `-${arg}`, arg: attachedValue }) | ||
| } | ||
| break | ||
| } | ||
| } else { | ||
| result.push({ origArg: `-${arg}`, arg: `-${letter}` }) | ||
| } | ||
| } | ||
| return result | ||
| }) | ||
| } | ||
| /** | ||
| * Yields one `{ event, name, value, arg, def }` argInfo object for each arg in `process.argv` (or `options.argv`). | ||
| */ | ||
| * [Symbol.iterator] () { | ||
| const definitions = this.definitions | ||
| const t = require('typical') | ||
@@ -89,3 +68,3 @@ let def | ||
| if (argvTools.isOption(arg)) { | ||
| def = definitions.get(arg) | ||
| def = definitions.get(arg, this.options.caseInsensitive) | ||
| value = undefined | ||
@@ -102,3 +81,3 @@ if (def) { | ||
| const matches = arg.match(argvTools.re.optEquals) | ||
| def = definitions.get(matches[1]) | ||
| def = definitions.get(matches[1], this.options.caseInsensitive) | ||
| if (def) { | ||
@@ -163,2 +142,2 @@ if (def.isBoolean()) { | ||
| module.exports = ArgvParser | ||
| export default ArgvParser |
@@ -1,3 +0,2 @@ | ||
| 'use strict' | ||
| const t = require('typical') | ||
| import t from 'typical' | ||
@@ -247,3 +246,3 @@ /** | ||
| /* pick up any remaining properties */ | ||
| for (let prop in definition) { | ||
| for (const prop in definition) { | ||
| if (!this[prop]) this[prop] = definition[prop] | ||
@@ -256,2 +255,3 @@ } | ||
| } | ||
| isMultiple () { | ||
@@ -267,2 +267,2 @@ return this.multiple || this.lazyMultiple | ||
| module.exports = OptionDefinition | ||
| export default OptionDefinition |
@@ -1,5 +0,5 @@ | ||
| 'use strict' | ||
| const arrayify = require('array-back') | ||
| const argvTools = require('argv-tools') | ||
| const t = require('typical') | ||
| import arrayify from 'array-back' | ||
| import * as argvTools from './argv-tools.js' | ||
| import t from 'typical' | ||
| import Definition from './option-definition.js' | ||
@@ -16,5 +16,6 @@ /** | ||
| * validate option definitions | ||
| * @param {boolean} [caseInsensitive=false] - whether arguments will be parsed in a case insensitive manner | ||
| * @returns {string} | ||
| */ | ||
| validate () { | ||
| validate (caseInsensitive) { | ||
| const someHaveNoName = this.some(def => !def.name) | ||
@@ -71,3 +72,3 @@ if (someHaveNoName) { | ||
| const duplicateName = hasDuplicates(this.map(def => def.name)) | ||
| const duplicateName = hasDuplicates(this.map(def => caseInsensitive ? def.name.toLowerCase() : def.name)) | ||
| if (duplicateName) { | ||
@@ -80,3 +81,3 @@ halt( | ||
| const duplicateAlias = hasDuplicates(this.map(def => def.alias)) | ||
| const duplicateAlias = hasDuplicates(this.map(def => caseInsensitive && t.isDefined(def.alias) ? def.alias.toLowerCase() : def.alias)) | ||
| if (duplicateAlias) { | ||
@@ -89,3 +90,3 @@ halt( | ||
| const duplicateDefaultOption = hasDuplicates(this.map(def => def.defaultOption)) | ||
| const duplicateDefaultOption = this.filter(def => def.defaultOption === true).length > 1 | ||
| if (duplicateDefaultOption) { | ||
@@ -112,10 +113,25 @@ halt( | ||
| * Get definition by option arg (e.g. `--one` or `-o`) | ||
| * @param {string} | ||
| * @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) { | ||
| get (arg, caseInsensitive) { | ||
| if (argvTools.isOption(arg)) { | ||
| return argvTools.re.short.test(arg) | ||
| ? this.find(def => def.alias === argvTools.getOptionName(arg)) | ||
| : this.find(def => def.name === argvTools.getOptionName(arg)) | ||
| if (argvTools.re.short.test(arg)) { | ||
| const shortOptionName = argvTools.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 = argvTools.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 { | ||
@@ -137,5 +153,7 @@ return this.find(def => def.name === arg) | ||
| } | ||
| whereNotGrouped () { | ||
| return this.filter(def => !containsValidGroup(def)) | ||
| } | ||
| whereDefaultValueSet () { | ||
@@ -145,7 +163,6 @@ return this.filter(def => t.isDefined(def.defaultValue)) | ||
| static from (definitions) { | ||
| static from (definitions, caseInsensitive) { | ||
| if (definitions instanceof this) return definitions | ||
| const Definition = require('./option-definition') | ||
| const result = super.from(arrayify(definitions), def => Definition.create(def)) | ||
| result.validate() | ||
| result.validate(caseInsensitive) | ||
| return result | ||
@@ -177,2 +194,2 @@ } | ||
| module.exports = Definitions | ||
| export default Definitions |
@@ -1,3 +0,2 @@ | ||
| 'use strict' | ||
| const Option = require('./option') | ||
| import Option from './option.js' | ||
@@ -14,2 +13,2 @@ class FlagOption extends Option { | ||
| module.exports = FlagOption | ||
| export default FlagOption |
+15
-6
@@ -1,6 +0,5 @@ | ||
| 'use strict' | ||
| import arrayify from 'array-back' | ||
| import t from 'typical' | ||
| import Definition from './option-definition.js' | ||
| const _value = new WeakMap() | ||
| const arrayify = require('array-back') | ||
| const t = require('typical') | ||
| const Definition = require('./option-definition') | ||
@@ -76,3 +75,3 @@ /** | ||
| if (definition.isBoolean()) { | ||
| return require('./option-flag').create(definition) | ||
| return FlagOption.create(definition) | ||
| } else { | ||
@@ -84,2 +83,12 @@ return new this(definition) | ||
| module.exports = Option | ||
| class FlagOption extends Option { | ||
| set (val) { | ||
| super.set(true) | ||
| } | ||
| static create (def) { | ||
| return new this(def) | ||
| } | ||
| } | ||
| export default Option |
@@ -1,9 +0,8 @@ | ||
| 'use strict' | ||
| const Output = require('./output') | ||
| import Output from './output.js' | ||
| import arrayify from 'array-back' | ||
| import t from 'typical' | ||
| import camelCase from 'lodash.camelcase' | ||
| class GroupedOutput extends Output { | ||
| toObject (options) { | ||
| const arrayify = require('array-back') | ||
| const t = require('typical') | ||
| const camelCase = require('lodash.camelcase') | ||
| const superOutputNoCamel = super.toObject({ skipUnknown: options.skipUnknown }) | ||
@@ -41,2 +40,2 @@ const superOutput = super.toObject(options) | ||
| module.exports = GroupedOutput | ||
| export default GroupedOutput |
+4
-5
@@ -1,3 +0,4 @@ | ||
| 'use strict' | ||
| const Option = require('./option') | ||
| import Option from './option.js' | ||
| import Definitions from './option-definitions.js' | ||
| import camelCase from 'lodash.camelcase' | ||
@@ -10,3 +11,2 @@ /** | ||
| super() | ||
| const Definitions = require('./option-definitions') | ||
| /** | ||
@@ -25,3 +25,2 @@ * @type {OptionDefinitions} | ||
| toObject (options) { | ||
| const camelCase = require('lodash.camelcase') | ||
| options = options || {} | ||
@@ -41,2 +40,2 @@ const output = {} | ||
| module.exports = Output | ||
| export default Output |
+1
-1
| The MIT License (MIT) | ||
| Copyright (c) 2014-18 Lloyd Brookes <75pound@gmail.com> | ||
| Copyright (c) 2014-24 Lloyd Brookes <75pound@gmail.com> | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
+27
-13
| { | ||
| "name": "command-line-args", | ||
| "version": "6.0.0-preview.1", | ||
| "version": "6.0.0", | ||
| "description": "A mature, feature-complete library to parse command-line options.", | ||
| "repository": "https://github.com/75lb/command-line-args.git", | ||
| "repository": "https://github.com/75lb/command-line-args", | ||
| "scripts": { | ||
| "test": "test-runner test/*.js test/internals/*.js", | ||
| "test": "npm run dist && npm run test:ci", | ||
| "test:ci": "test-runner 'test/**/*.js' 'test/**/*.cjs'", | ||
| "docs": "jsdoc2md index.js > doc/API.md && jsdoc2md lib/option-definition.js > doc/option-definition.md", | ||
| "cover": "nyc --reporter=text-lcov test-runner test/*.js test/internals/*.js | coveralls" | ||
| "dist": "rollup -c" | ||
| }, | ||
| "type": "module", | ||
| "exports": { | ||
| "import": "./index.js", | ||
| "require": "./dist/index.cjs" | ||
| }, | ||
| "keywords": [ | ||
@@ -27,20 +33,28 @@ "argv", | ||
| "engines": { | ||
| "node": ">=4.0.0" | ||
| "node": ">=12.20" | ||
| }, | ||
| "files": [ | ||
| "index.js", | ||
| "lib" | ||
| "lib", | ||
| "dist" | ||
| ], | ||
| "devDependencies": { | ||
| "coveralls": "^3.0.0", | ||
| "jsdoc-to-markdown": "^4.0.1", | ||
| "test-runner": "^0.5.0" | ||
| "@rollup/plugin-commonjs": "^26.0.1", | ||
| "@rollup/plugin-node-resolve": "^15.2.3", | ||
| "jsdoc-to-markdown": "^8.0.1", | ||
| "rollup": "~4.18.0", | ||
| "test-runner": "^0.10.1" | ||
| }, | ||
| "dependencies": { | ||
| "argv-tools": "^0.1.1", | ||
| "array-back": "^2.0.0", | ||
| "find-replace": "^2.0.1", | ||
| "array-back": "^6.2.2", | ||
| "find-replace": "^5.0.1", | ||
| "lodash.camelcase": "^4.3.0", | ||
| "typical": "^2.6.1" | ||
| "typical": "^7.1.1" | ||
| }, | ||
| "standard": { | ||
| "ignore": [ | ||
| "dist" | ||
| ], | ||
| "envs": [] | ||
| } | ||
| } |
+8
-7
@@ -1,8 +0,7 @@ | ||
| [](https://www.npmjs.org/package/command-line-args) | ||
| [](https://www.npmjs.org/package/command-line-args) | ||
| [](https://travis-ci.org/75lb/command-line-args) | ||
| [](https://coveralls.io/github/75lb/command-line-args?branch=master) | ||
| [](https://david-dm.org/75lb/command-line-args) | ||
| [](https://www.npmjs.org/package/command-line-args) | ||
| [](https://www.npmjs.org/package/command-line-args) | ||
| [](https://github.com/75lb/command-line-args/network/dependents?dependent_type=REPOSITORY) | ||
| [](https://github.com/75lb/command-line-args/network/dependents?dependent_type=PACKAGE) | ||
| [](https://github.com/75lb/command-line-args/actions/workflows/node.js.yml) | ||
| [](https://github.com/feross/standard) | ||
| [](https://gitter.im/75lb/command-line-args?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | ||
@@ -12,5 +11,7 @@ ***Upgraders, please read the [release notes](https://github.com/75lb/command-line-args/releases)*** | ||
| # command-line-args | ||
| A mature, feature-complete library to parse command-line options. | ||
| ## Synopsis | ||
| You can set options using the main notation standards ([learn more](https://github.com/75lb/command-line-args/wiki/Notation-rules)). These commands are all equivalent, setting the same values: | ||
@@ -104,2 +105,2 @@ ``` | ||
| © 2014-18 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). |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
96096
192.49%4
-20%13
18.18%2746
252.05%1
-50%105
0.96%Yes
NaN5
66.67%14
600%2
100%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated