ヤミRoot VoidGate
User / IP
:
216.73.216.143
Host / Server
:
146.88.233.70 / dev.loger.cm
System
:
Linux hybrid1120.fr.ns.planethoster.net 3.10.0-957.21.2.el7.x86_64 #1 SMP Wed Jun 5 14:26:44 UTC 2019 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
logercm
/
dev.loger.cm
/
fixtures
/
assert
/
Viewing: yargs-parser.tar
CHANGELOG.md 0000644 00000033141 15120070332 0006350 0 ustar 00 # Changelog All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. ### [20.2.9](https://www.github.com/yargs/yargs-parser/compare/yargs-parser-v20.2.8...yargs-parser-v20.2.9) (2021-06-20) ### Bug Fixes * **build:** fixed automated release pipeline ([1fe9135](https://www.github.com/yargs/yargs-parser/commit/1fe9135884790a083615419b2861683e2597dac3)) ### [20.2.8](https://www.github.com/yargs/yargs-parser/compare/yargs-parser-v20.2.7...yargs-parser-v20.2.8) (2021-06-20) ### Bug Fixes * **locale:** Turkish camelize and decamelize issues with toLocaleLowerCase/toLocaleUpperCase ([2617303](https://www.github.com/yargs/yargs-parser/commit/261730383e02448562f737b94bbd1f164aed5143)) * **perf:** address slow parse when using unknown-options-as-args ([#394](https://www.github.com/yargs/yargs-parser/issues/394)) ([441f059](https://www.github.com/yargs/yargs-parser/commit/441f059d585d446551068ad213db79ac91daf83a)) * **string-utils:** detect [0,1] ranged values as numbers ([#388](https://www.github.com/yargs/yargs-parser/issues/388)) ([efcc32c](https://www.github.com/yargs/yargs-parser/commit/efcc32c2d6b09aba31abfa2db9bd947befe5586b)) ### [20.2.7](https://www.github.com/yargs/yargs-parser/compare/v20.2.6...v20.2.7) (2021-03-10) ### Bug Fixes * **deno:** force release for Deno ([6687c97](https://www.github.com/yargs/yargs-parser/commit/6687c972d0f3ca7865a97908dde3080b05f8b026)) ### [20.2.6](https://www.github.com/yargs/yargs-parser/compare/v20.2.5...v20.2.6) (2021-02-22) ### Bug Fixes * **populate--:** -- should always be array ([#354](https://www.github.com/yargs/yargs-parser/issues/354)) ([585ae8f](https://www.github.com/yargs/yargs-parser/commit/585ae8ffad74cc02974f92d788e750137fd65146)) ### [20.2.5](https://www.github.com/yargs/yargs-parser/compare/v20.2.4...v20.2.5) (2021-02-13) ### Bug Fixes * do not lowercase camel cased string ([#348](https://www.github.com/yargs/yargs-parser/issues/348)) ([5f4da1f](https://www.github.com/yargs/yargs-parser/commit/5f4da1f17d9d50542d2aaa206c9806ce3e320335)) ### [20.2.4](https://www.github.com/yargs/yargs-parser/compare/v20.2.3...v20.2.4) (2020-11-09) ### Bug Fixes * **deno:** address import issues in Deno ([#339](https://www.github.com/yargs/yargs-parser/issues/339)) ([3b54e5e](https://www.github.com/yargs/yargs-parser/commit/3b54e5eef6e9a7b7c6eec7c12bab3ba3b8ba8306)) ### [20.2.3](https://www.github.com/yargs/yargs-parser/compare/v20.2.2...v20.2.3) (2020-10-16) ### Bug Fixes * **exports:** node 13.0 and 13.1 require the dotted object form _with_ a string fallback ([#336](https://www.github.com/yargs/yargs-parser/issues/336)) ([3ae7242](https://www.github.com/yargs/yargs-parser/commit/3ae7242040ff876d28dabded60ac226e00150c88)) ### [20.2.2](https://www.github.com/yargs/yargs-parser/compare/v20.2.1...v20.2.2) (2020-10-14) ### Bug Fixes * **exports:** node 13.0-13.6 require a string fallback ([#333](https://www.github.com/yargs/yargs-parser/issues/333)) ([291aeda](https://www.github.com/yargs/yargs-parser/commit/291aeda06b685b7a015d83bdf2558e180b37388d)) ### [20.2.1](https://www.github.com/yargs/yargs-parser/compare/v20.2.0...v20.2.1) (2020-10-01) ### Bug Fixes * **deno:** update types for deno ^1.4.0 ([#330](https://www.github.com/yargs/yargs-parser/issues/330)) ([0ab92e5](https://www.github.com/yargs/yargs-parser/commit/0ab92e50b090f11196334c048c9c92cecaddaf56)) ## [20.2.0](https://www.github.com/yargs/yargs-parser/compare/v20.1.0...v20.2.0) (2020-09-21) ### Features * **string-utils:** export looksLikeNumber helper ([#324](https://www.github.com/yargs/yargs-parser/issues/324)) ([c8580a2](https://www.github.com/yargs/yargs-parser/commit/c8580a2327b55f6342acecb6e72b62963d506750)) ### Bug Fixes * **unknown-options-as-args:** convert positionals that look like numbers ([#326](https://www.github.com/yargs/yargs-parser/issues/326)) ([f85ebb4](https://www.github.com/yargs/yargs-parser/commit/f85ebb4face9d4b0f56147659404cbe0002f3dad)) ## [20.1.0](https://www.github.com/yargs/yargs-parser/compare/v20.0.0...v20.1.0) (2020-09-20) ### Features * adds parse-positional-numbers configuration ([#321](https://www.github.com/yargs/yargs-parser/issues/321)) ([9cec00a](https://www.github.com/yargs/yargs-parser/commit/9cec00a622251292ffb7dce6f78f5353afaa0d4c)) ### Bug Fixes * **build:** update release-please; make labels kick off builds ([#323](https://www.github.com/yargs/yargs-parser/issues/323)) ([09f448b](https://www.github.com/yargs/yargs-parser/commit/09f448b4cd66e25d2872544718df46dab8af062a)) ## [20.0.0](https://www.github.com/yargs/yargs-parser/compare/v19.0.4...v20.0.0) (2020-09-09) ### ⚠ BREAKING CHANGES * do not ship type definitions (#318) ### Bug Fixes * only strip camel case if hyphenated ([#316](https://www.github.com/yargs/yargs-parser/issues/316)) ([95a9e78](https://www.github.com/yargs/yargs-parser/commit/95a9e785127b9bbf2d1db1f1f808ca1fb100e82a)), closes [#315](https://www.github.com/yargs/yargs-parser/issues/315) ### Code Refactoring * do not ship type definitions ([#318](https://www.github.com/yargs/yargs-parser/issues/318)) ([8fbd56f](https://www.github.com/yargs/yargs-parser/commit/8fbd56f1d0b6c44c30fca62708812151ca0ce330)) ### [19.0.4](https://www.github.com/yargs/yargs-parser/compare/v19.0.3...v19.0.4) (2020-08-27) ### Bug Fixes * **build:** fixing publication ([#310](https://www.github.com/yargs/yargs-parser/issues/310)) ([5d3c6c2](https://www.github.com/yargs/yargs-parser/commit/5d3c6c29a9126248ba601920d9cf87c78e161ff5)) ### [19.0.3](https://www.github.com/yargs/yargs-parser/compare/v19.0.2...v19.0.3) (2020-08-27) ### Bug Fixes * **build:** switch to action for publish ([#308](https://www.github.com/yargs/yargs-parser/issues/308)) ([5c2f305](https://www.github.com/yargs/yargs-parser/commit/5c2f30585342bcd8aaf926407c863099d256d174)) ### [19.0.2](https://www.github.com/yargs/yargs-parser/compare/v19.0.1...v19.0.2) (2020-08-27) ### Bug Fixes * **types:** envPrefix should be optional ([#305](https://www.github.com/yargs/yargs-parser/issues/305)) ([ae3f180](https://www.github.com/yargs/yargs-parser/commit/ae3f180e14df2de2fd962145f4518f9aa0e76523)) ### [19.0.1](https://www.github.com/yargs/yargs-parser/compare/v19.0.0...v19.0.1) (2020-08-09) ### Bug Fixes * **build:** push tag created for deno ([2186a14](https://www.github.com/yargs/yargs-parser/commit/2186a14989749887d56189867602e39e6679f8b0)) ## [19.0.0](https://www.github.com/yargs/yargs-parser/compare/v18.1.3...v19.0.0) (2020-08-09) ### ⚠ BREAKING CHANGES * adds support for ESM and Deno (#295) * **ts:** projects using `@types/yargs-parser` may see variations in type definitions. * drops Node 6. begin following Node.js LTS schedule (#278) ### Features * adds support for ESM and Deno ([#295](https://www.github.com/yargs/yargs-parser/issues/295)) ([195bc4a](https://www.github.com/yargs/yargs-parser/commit/195bc4a7f20c2a8f8e33fbb6ba96ef6e9a0120a1)) * expose camelCase and decamelize helpers ([#296](https://www.github.com/yargs/yargs-parser/issues/296)) ([39154ce](https://www.github.com/yargs/yargs-parser/commit/39154ceb5bdcf76b5f59a9219b34cedb79b67f26)) * **deps:** update to latest camelcase/decamelize ([#281](https://www.github.com/yargs/yargs-parser/issues/281)) ([8931ab0](https://www.github.com/yargs/yargs-parser/commit/8931ab08f686cc55286f33a95a83537da2be5516)) ### Bug Fixes * boolean numeric short option ([#294](https://www.github.com/yargs/yargs-parser/issues/294)) ([f600082](https://www.github.com/yargs/yargs-parser/commit/f600082c959e092076caf420bbbc9d7a231e2418)) * raise permission error for Deno if config load fails ([#298](https://www.github.com/yargs/yargs-parser/issues/298)) ([1174e2b](https://www.github.com/yargs/yargs-parser/commit/1174e2b3f0c845a1cd64e14ffc3703e730567a84)) * **deps:** update dependency decamelize to v3 ([#274](https://www.github.com/yargs/yargs-parser/issues/274)) ([4d98698](https://www.github.com/yargs/yargs-parser/commit/4d98698bc6767e84ec54a0842908191739be73b7)) * **types:** switch back to using Partial types ([#293](https://www.github.com/yargs/yargs-parser/issues/293)) ([bdc80ba](https://www.github.com/yargs/yargs-parser/commit/bdc80ba59fa13bc3025ce0a85e8bad9f9da24ea7)) ### Build System * drops Node 6. begin following Node.js LTS schedule ([#278](https://www.github.com/yargs/yargs-parser/issues/278)) ([9014ed7](https://www.github.com/yargs/yargs-parser/commit/9014ed722a32768b96b829e65a31705db5c1458a)) ### Code Refactoring * **ts:** move index.js to TypeScript ([#292](https://www.github.com/yargs/yargs-parser/issues/292)) ([f78d2b9](https://www.github.com/yargs/yargs-parser/commit/f78d2b97567ac4828624406e420b4047c710b789)) ### [18.1.3](https://www.github.com/yargs/yargs-parser/compare/v18.1.2...v18.1.3) (2020-04-16) ### Bug Fixes * **setArg:** options using camel-case and dot-notation populated twice ([#268](https://www.github.com/yargs/yargs-parser/issues/268)) ([f7e15b9](https://www.github.com/yargs/yargs-parser/commit/f7e15b9800900b9856acac1a830a5f35847be73e)) ### [18.1.2](https://www.github.com/yargs/yargs-parser/compare/v18.1.1...v18.1.2) (2020-03-26) ### Bug Fixes * **array, nargs:** support -o=--value and --option=--value format ([#262](https://www.github.com/yargs/yargs-parser/issues/262)) ([41d3f81](https://www.github.com/yargs/yargs-parser/commit/41d3f8139e116706b28de9b0de3433feb08d2f13)) ### [18.1.1](https://www.github.com/yargs/yargs-parser/compare/v18.1.0...v18.1.1) (2020-03-16) ### Bug Fixes * \_\_proto\_\_ will now be replaced with \_\_\_proto\_\_\_ in parse ([#258](https://www.github.com/yargs/yargs-parser/issues/258)), patching a potential prototype pollution vulnerability. This was reported by the Snyk Security Research Team.([63810ca](https://www.github.com/yargs/yargs-parser/commit/63810ca1ae1a24b08293a4d971e70e058c7a41e2)) ## [18.1.0](https://www.github.com/yargs/yargs-parser/compare/v18.0.0...v18.1.0) (2020-03-07) ### Features * introduce single-digit boolean aliases ([#255](https://www.github.com/yargs/yargs-parser/issues/255)) ([9c60265](https://www.github.com/yargs/yargs-parser/commit/9c60265fd7a03cb98e6df3e32c8c5e7508d9f56f)) ## [18.0.0](https://www.github.com/yargs/yargs-parser/compare/v17.1.0...v18.0.0) (2020-03-02) ### ⚠ BREAKING CHANGES * the narg count is now enforced when parsing arrays. ### Features * NaN can now be provided as a value for nargs, indicating "at least" one value is expected for array ([#251](https://www.github.com/yargs/yargs-parser/issues/251)) ([9db4be8](https://www.github.com/yargs/yargs-parser/commit/9db4be81417a2c7097128db34d86fe70ef4af70c)) ## [17.1.0](https://www.github.com/yargs/yargs-parser/compare/v17.0.1...v17.1.0) (2020-03-01) ### Features * introduce greedy-arrays config, for specifying whether arrays consume multiple positionals ([#249](https://www.github.com/yargs/yargs-parser/issues/249)) ([60e880a](https://www.github.com/yargs/yargs-parser/commit/60e880a837046314d89fa4725f923837fd33a9eb)) ### [17.0.1](https://www.github.com/yargs/yargs-parser/compare/v17.0.0...v17.0.1) (2020-02-29) ### Bug Fixes * normalized keys were not enumerable ([#247](https://www.github.com/yargs/yargs-parser/issues/247)) ([57119f9](https://www.github.com/yargs/yargs-parser/commit/57119f9f17cf27499bd95e61c2f72d18314f11ba)) ## [17.0.0](https://www.github.com/yargs/yargs-parser/compare/v16.1.0...v17.0.0) (2020-02-10) ### ⚠ BREAKING CHANGES * this reverts parsing behavior of booleans to that of yargs@14 * objects used during parsing are now created with a null prototype. There may be some scenarios where this change in behavior leaks externally. ### Features * boolean arguments will not be collected into an implicit array ([#236](https://www.github.com/yargs/yargs-parser/issues/236)) ([34c4e19](https://www.github.com/yargs/yargs-parser/commit/34c4e19bae4e7af63e3cb6fa654a97ed476e5eb5)) * introduce nargs-eats-options config option ([#246](https://www.github.com/yargs/yargs-parser/issues/246)) ([d50822a](https://www.github.com/yargs/yargs-parser/commit/d50822ac10e1b05f2e9643671ca131ac251b6732)) ### Bug Fixes * address bugs with "uknown-options-as-args" ([bc023e3](https://www.github.com/yargs/yargs-parser/commit/bc023e3b13e20a118353f9507d1c999bf388a346)) * array should take precedence over nargs, but enforce nargs ([#243](https://www.github.com/yargs/yargs-parser/issues/243)) ([4cbc188](https://www.github.com/yargs/yargs-parser/commit/4cbc188b7abb2249529a19c090338debdad2fe6c)) * support keys that collide with object prototypes ([#234](https://www.github.com/yargs/yargs-parser/issues/234)) ([1587b6d](https://www.github.com/yargs/yargs-parser/commit/1587b6d91db853a9109f1be6b209077993fee4de)) * unknown options terminated with digits now handled by unknown-options-as-args ([#238](https://www.github.com/yargs/yargs-parser/issues/238)) ([d36cdfa](https://www.github.com/yargs/yargs-parser/commit/d36cdfa854254d7c7e0fe1d583818332ac46c2a5)) ## [16.1.0](https://www.github.com/yargs/yargs-parser/compare/v16.0.0...v16.1.0) (2019-11-01) ### ⚠ BREAKING CHANGES * populate error if incompatible narg/count or array/count options are used (#191) ### Features * options that have had their default value used are now tracked ([#211](https://www.github.com/yargs/yargs-parser/issues/211)) ([a525234](https://www.github.com/yargs/yargs-parser/commit/a525234558c847deedd73f8792e0a3b77b26e2c0)) * populate error if incompatible narg/count or array/count options are used ([#191](https://www.github.com/yargs/yargs-parser/issues/191)) ([84a401f](https://www.github.com/yargs/yargs-parser/commit/84a401f0fa3095e0a19661670d1570d0c3b9d3c9)) ### Reverts * revert 16.0.0 CHANGELOG entry ([920320a](https://www.github.com/yargs/yargs-parser/commit/920320ad9861bbfd58eda39221ae211540fc1daf)) LICENSE.txt 0000644 00000001333 15120070333 0006361 0 ustar 00 Copyright (c) 2016, Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. README.md 0000644 00000027214 15120070333 0006023 0 ustar 00 # yargs-parser  [](https://www.npmjs.com/package/yargs-parser) [](https://conventionalcommits.org)  The mighty option parser used by [yargs](https://github.com/yargs/yargs). visit the [yargs website](http://yargs.js.org/) for more examples, and thorough usage instructions. <img width="250" src="https://raw.githubusercontent.com/yargs/yargs-parser/main/yargs-logo.png"> ## Example ```sh npm i yargs-parser --save ``` ```js const argv = require('yargs-parser')(process.argv.slice(2)) console.log(argv) ``` ```console $ node example.js --foo=33 --bar hello { _: [], foo: 33, bar: 'hello' } ``` _or parse a string!_ ```js const argv = require('yargs-parser')('--foo=99 --bar=33') console.log(argv) ``` ```console { _: [], foo: 99, bar: 33 } ``` Convert an array of mixed types before passing to `yargs-parser`: ```js const parse = require('yargs-parser') parse(['-f', 11, '--zoom', 55].join(' ')) // <-- array to string parse(['-f', 11, '--zoom', 55].map(String)) // <-- array of strings ``` ## Deno Example As of `v19` `yargs-parser` supports [Deno](https://github.com/denoland/deno): ```typescript import parser from "https://deno.land/x/yargs_parser/deno.ts"; const argv = parser('--foo=99 --bar=9987930', { string: ['bar'] }) console.log(argv) ``` ## ESM Example As of `v19` `yargs-parser` supports ESM (_both in Node.js and in the browser_): **Node.js:** ```js import parser from 'yargs-parser' const argv = parser('--foo=99 --bar=9987930', { string: ['bar'] }) console.log(argv) ``` **Browsers:** ```html <!doctype html> <body> <script type="module"> import parser from "https://unpkg.com/yargs-parser@19.0.0/browser.js"; const argv = parser('--foo=99 --bar=9987930', { string: ['bar'] }) console.log(argv) </script> </body> ``` ## API ### parser(args, opts={}) Parses command line arguments returning a simple mapping of keys and values. **expects:** * `args`: a string or array of strings representing the options to parse. * `opts`: provide a set of hints indicating how `args` should be parsed: * `opts.alias`: an object representing the set of aliases for a key: `{alias: {foo: ['f']}}`. * `opts.array`: indicate that keys should be parsed as an array: `{array: ['foo', 'bar']}`.<br> Indicate that keys should be parsed as an array and coerced to booleans / numbers:<br> `{array: [{ key: 'foo', boolean: true }, {key: 'bar', number: true}]}`. * `opts.boolean`: arguments should be parsed as booleans: `{boolean: ['x', 'y']}`. * `opts.coerce`: provide a custom synchronous function that returns a coerced value from the argument provided (or throws an error). For arrays the function is called only once for the entire array:<br> `{coerce: {foo: function (arg) {return modifiedArg}}}`. * `opts.config`: indicate a key that represents a path to a configuration file (this file will be loaded and parsed). * `opts.configObjects`: configuration objects to parse, their properties will be set as arguments:<br> `{configObjects: [{'x': 5, 'y': 33}, {'z': 44}]}`. * `opts.configuration`: provide configuration options to the yargs-parser (see: [configuration](#configuration)). * `opts.count`: indicate a key that should be used as a counter, e.g., `-vvv` = `{v: 3}`. * `opts.default`: provide default values for keys: `{default: {x: 33, y: 'hello world!'}}`. * `opts.envPrefix`: environment variables (`process.env`) with the prefix provided should be parsed. * `opts.narg`: specify that a key requires `n` arguments: `{narg: {x: 2}}`. * `opts.normalize`: `path.normalize()` will be applied to values set to this key. * `opts.number`: keys should be treated as numbers. * `opts.string`: keys should be treated as strings (even if they resemble a number `-x 33`). **returns:** * `obj`: an object representing the parsed value of `args` * `key/value`: key value pairs for each argument and their aliases. * `_`: an array representing the positional arguments. * [optional] `--`: an array with arguments after the end-of-options flag `--`. ### require('yargs-parser').detailed(args, opts={}) Parses a command line string, returning detailed information required by the yargs engine. **expects:** * `args`: a string or array of strings representing options to parse. * `opts`: provide a set of hints indicating how `args`, inputs are identical to `require('yargs-parser')(args, opts={})`. **returns:** * `argv`: an object representing the parsed value of `args` * `key/value`: key value pairs for each argument and their aliases. * `_`: an array representing the positional arguments. * [optional] `--`: an array with arguments after the end-of-options flag `--`. * `error`: populated with an error object if an exception occurred during parsing. * `aliases`: the inferred list of aliases built by combining lists in `opts.alias`. * `newAliases`: any new aliases added via camel-case expansion: * `boolean`: `{ fooBar: true }` * `defaulted`: any new argument created by `opts.default`, no aliases included. * `boolean`: `{ foo: true }` * `configuration`: given by default settings and `opts.configuration`. <a name="configuration"></a> ### Configuration The yargs-parser applies several automated transformations on the keys provided in `args`. These features can be turned on and off using the `configuration` field of `opts`. ```js var parsed = parser(['--no-dice'], { configuration: { 'boolean-negation': false } }) ``` ### short option groups * default: `true`. * key: `short-option-groups`. Should a group of short-options be treated as boolean flags? ```console $ node example.js -abc { _: [], a: true, b: true, c: true } ``` _if disabled:_ ```console $ node example.js -abc { _: [], abc: true } ``` ### camel-case expansion * default: `true`. * key: `camel-case-expansion`. Should hyphenated arguments be expanded into camel-case aliases? ```console $ node example.js --foo-bar { _: [], 'foo-bar': true, fooBar: true } ``` _if disabled:_ ```console $ node example.js --foo-bar { _: [], 'foo-bar': true } ``` ### dot-notation * default: `true` * key: `dot-notation` Should keys that contain `.` be treated as objects? ```console $ node example.js --foo.bar { _: [], foo: { bar: true } } ``` _if disabled:_ ```console $ node example.js --foo.bar { _: [], "foo.bar": true } ``` ### parse numbers * default: `true` * key: `parse-numbers` Should keys that look like numbers be treated as such? ```console $ node example.js --foo=99.3 { _: [], foo: 99.3 } ``` _if disabled:_ ```console $ node example.js --foo=99.3 { _: [], foo: "99.3" } ``` ### parse positional numbers * default: `true` * key: `parse-positional-numbers` Should positional keys that look like numbers be treated as such. ```console $ node example.js 99.3 { _: [99.3] } ``` _if disabled:_ ```console $ node example.js 99.3 { _: ['99.3'] } ``` ### boolean negation * default: `true` * key: `boolean-negation` Should variables prefixed with `--no` be treated as negations? ```console $ node example.js --no-foo { _: [], foo: false } ``` _if disabled:_ ```console $ node example.js --no-foo { _: [], "no-foo": true } ``` ### combine arrays * default: `false` * key: `combine-arrays` Should arrays be combined when provided by both command line arguments and a configuration file. ### duplicate arguments array * default: `true` * key: `duplicate-arguments-array` Should arguments be coerced into an array when duplicated: ```console $ node example.js -x 1 -x 2 { _: [], x: [1, 2] } ``` _if disabled:_ ```console $ node example.js -x 1 -x 2 { _: [], x: 2 } ``` ### flatten duplicate arrays * default: `true` * key: `flatten-duplicate-arrays` Should array arguments be coerced into a single array when duplicated: ```console $ node example.js -x 1 2 -x 3 4 { _: [], x: [1, 2, 3, 4] } ``` _if disabled:_ ```console $ node example.js -x 1 2 -x 3 4 { _: [], x: [[1, 2], [3, 4]] } ``` ### greedy arrays * default: `true` * key: `greedy-arrays` Should arrays consume more than one positional argument following their flag. ```console $ node example --arr 1 2 { _: [], arr: [1, 2] } ``` _if disabled:_ ```console $ node example --arr 1 2 { _: [2], arr: [1] } ``` **Note: in `v18.0.0` we are considering defaulting greedy arrays to `false`.** ### nargs eats options * default: `false` * key: `nargs-eats-options` Should nargs consume dash options as well as positional arguments. ### negation prefix * default: `no-` * key: `negation-prefix` The prefix to use for negated boolean variables. ```console $ node example.js --no-foo { _: [], foo: false } ``` _if set to `quux`:_ ```console $ node example.js --quuxfoo { _: [], foo: false } ``` ### populate -- * default: `false`. * key: `populate--` Should unparsed flags be stored in `--` or `_`. _If disabled:_ ```console $ node example.js a -b -- x y { _: [ 'a', 'x', 'y' ], b: true } ``` _If enabled:_ ```console $ node example.js a -b -- x y { _: [ 'a' ], '--': [ 'x', 'y' ], b: true } ``` ### set placeholder key * default: `false`. * key: `set-placeholder-key`. Should a placeholder be added for keys not set via the corresponding CLI argument? _If disabled:_ ```console $ node example.js -a 1 -c 2 { _: [], a: 1, c: 2 } ``` _If enabled:_ ```console $ node example.js -a 1 -c 2 { _: [], a: 1, b: undefined, c: 2 } ``` ### halt at non-option * default: `false`. * key: `halt-at-non-option`. Should parsing stop at the first positional argument? This is similar to how e.g. `ssh` parses its command line. _If disabled:_ ```console $ node example.js -a run b -x y { _: [ 'b' ], a: 'run', x: 'y' } ``` _If enabled:_ ```console $ node example.js -a run b -x y { _: [ 'b', '-x', 'y' ], a: 'run' } ``` ### strip aliased * default: `false` * key: `strip-aliased` Should aliases be removed before returning results? _If disabled:_ ```console $ node example.js --test-field 1 { _: [], 'test-field': 1, testField: 1, 'test-alias': 1, testAlias: 1 } ``` _If enabled:_ ```console $ node example.js --test-field 1 { _: [], 'test-field': 1, testField: 1 } ``` ### strip dashed * default: `false` * key: `strip-dashed` Should dashed keys be removed before returning results? This option has no effect if `camel-case-expansion` is disabled. _If disabled:_ ```console $ node example.js --test-field 1 { _: [], 'test-field': 1, testField: 1 } ``` _If enabled:_ ```console $ node example.js --test-field 1 { _: [], testField: 1 } ``` ### unknown options as args * default: `false` * key: `unknown-options-as-args` Should unknown options be treated like regular arguments? An unknown option is one that is not configured in `opts`. _If disabled_ ```console $ node example.js --unknown-option --known-option 2 --string-option --unknown-option2 { _: [], unknownOption: true, knownOption: 2, stringOption: '', unknownOption2: true } ``` _If enabled_ ```console $ node example.js --unknown-option --known-option 2 --string-option --unknown-option2 { _: ['--unknown-option'], knownOption: 2, stringOption: '--unknown-option2' } ``` ## Supported Node.js Versions Libraries in this ecosystem make a best effort to track [Node.js' release schedule](https://nodejs.org/en/about/releases/). Here's [a post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a). ## Special Thanks The yargs project evolves from optimist and minimist. It owes its existence to a lot of James Halliday's hard work. Thanks [substack](https://github.com/substack) **beep** **boop** \o/ ## License ISC browser.js 0000644 00000001770 15120070333 0006564 0 ustar 00 // Main entrypoint for ESM web browser environments. Avoids using Node.js // specific libraries, such as "path". // // TODO: figure out reasonable web equivalents for "resolve", "normalize", etc. import { camelCase, decamelize, looksLikeNumber } from './build/lib/string-utils.js' import { YargsParser } from './build/lib/yargs-parser.js' const parser = new YargsParser({ cwd: () => { return '' }, format: (str, arg) => { return str.replace('%s', arg) }, normalize: (str) => { return str }, resolve: (str) => { return str }, require: () => { throw Error('loading config from files not currently supported in browser') }, env: () => {} }) const yargsParser = function Parser (args, opts) { const result = parser.parse(args.slice(), opts) return result.argv } yargsParser.detailed = function (args, opts) { return parser.parse(args.slice(), opts) } yargsParser.camelCase = camelCase yargsParser.decamelize = decamelize yargsParser.looksLikeNumber = looksLikeNumber export default yargsParser build/index.cjs 0000644 00000122511 15120070333 0007447 0 ustar 00 'use strict'; var util = require('util'); var fs = require('fs'); var path = require('path'); function camelCase(str) { const isCamelCase = str !== str.toLowerCase() && str !== str.toUpperCase(); if (!isCamelCase) { str = str.toLowerCase(); } if (str.indexOf('-') === -1 && str.indexOf('_') === -1) { return str; } else { let camelcase = ''; let nextChrUpper = false; const leadingHyphens = str.match(/^-+/); for (let i = leadingHyphens ? leadingHyphens[0].length : 0; i < str.length; i++) { let chr = str.charAt(i); if (nextChrUpper) { nextChrUpper = false; chr = chr.toUpperCase(); } if (i !== 0 && (chr === '-' || chr === '_')) { nextChrUpper = true; } else if (chr !== '-' && chr !== '_') { camelcase += chr; } } return camelcase; } } function decamelize(str, joinString) { const lowercase = str.toLowerCase(); joinString = joinString || '-'; let notCamelcase = ''; for (let i = 0; i < str.length; i++) { const chrLower = lowercase.charAt(i); const chrString = str.charAt(i); if (chrLower !== chrString && i > 0) { notCamelcase += `${joinString}${lowercase.charAt(i)}`; } else { notCamelcase += chrString; } } return notCamelcase; } function looksLikeNumber(x) { if (x === null || x === undefined) return false; if (typeof x === 'number') return true; if (/^0x[0-9a-f]+$/i.test(x)) return true; if (/^0[^.]/.test(x)) return false; return /^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); } function tokenizeArgString(argString) { if (Array.isArray(argString)) { return argString.map(e => typeof e !== 'string' ? e + '' : e); } argString = argString.trim(); let i = 0; let prevC = null; let c = null; let opening = null; const args = []; for (let ii = 0; ii < argString.length; ii++) { prevC = c; c = argString.charAt(ii); if (c === ' ' && !opening) { if (!(prevC === ' ')) { i++; } continue; } if (c === opening) { opening = null; } else if ((c === "'" || c === '"') && !opening) { opening = c; } if (!args[i]) args[i] = ''; args[i] += c; } return args; } var DefaultValuesForTypeKey; (function (DefaultValuesForTypeKey) { DefaultValuesForTypeKey["BOOLEAN"] = "boolean"; DefaultValuesForTypeKey["STRING"] = "string"; DefaultValuesForTypeKey["NUMBER"] = "number"; DefaultValuesForTypeKey["ARRAY"] = "array"; })(DefaultValuesForTypeKey || (DefaultValuesForTypeKey = {})); let mixin; class YargsParser { constructor(_mixin) { mixin = _mixin; } parse(argsInput, options) { const opts = Object.assign({ alias: undefined, array: undefined, boolean: undefined, config: undefined, configObjects: undefined, configuration: undefined, coerce: undefined, count: undefined, default: undefined, envPrefix: undefined, narg: undefined, normalize: undefined, string: undefined, number: undefined, __: undefined, key: undefined }, options); const args = tokenizeArgString(argsInput); const aliases = combineAliases(Object.assign(Object.create(null), opts.alias)); const configuration = Object.assign({ 'boolean-negation': true, 'camel-case-expansion': true, 'combine-arrays': false, 'dot-notation': true, 'duplicate-arguments-array': true, 'flatten-duplicate-arrays': true, 'greedy-arrays': true, 'halt-at-non-option': false, 'nargs-eats-options': false, 'negation-prefix': 'no-', 'parse-numbers': true, 'parse-positional-numbers': true, 'populate--': false, 'set-placeholder-key': false, 'short-option-groups': true, 'strip-aliased': false, 'strip-dashed': false, 'unknown-options-as-args': false }, opts.configuration); const defaults = Object.assign(Object.create(null), opts.default); const configObjects = opts.configObjects || []; const envPrefix = opts.envPrefix; const notFlagsOption = configuration['populate--']; const notFlagsArgv = notFlagsOption ? '--' : '_'; const newAliases = Object.create(null); const defaulted = Object.create(null); const __ = opts.__ || mixin.format; const flags = { aliases: Object.create(null), arrays: Object.create(null), bools: Object.create(null), strings: Object.create(null), numbers: Object.create(null), counts: Object.create(null), normalize: Object.create(null), configs: Object.create(null), nargs: Object.create(null), coercions: Object.create(null), keys: [] }; const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/; const negatedBoolean = new RegExp('^--' + configuration['negation-prefix'] + '(.+)'); [].concat(opts.array || []).filter(Boolean).forEach(function (opt) { const key = typeof opt === 'object' ? opt.key : opt; const assignment = Object.keys(opt).map(function (key) { const arrayFlagKeys = { boolean: 'bools', string: 'strings', number: 'numbers' }; return arrayFlagKeys[key]; }).filter(Boolean).pop(); if (assignment) { flags[assignment][key] = true; } flags.arrays[key] = true; flags.keys.push(key); }); [].concat(opts.boolean || []).filter(Boolean).forEach(function (key) { flags.bools[key] = true; flags.keys.push(key); }); [].concat(opts.string || []).filter(Boolean).forEach(function (key) { flags.strings[key] = true; flags.keys.push(key); }); [].concat(opts.number || []).filter(Boolean).forEach(function (key) { flags.numbers[key] = true; flags.keys.push(key); }); [].concat(opts.count || []).filter(Boolean).forEach(function (key) { flags.counts[key] = true; flags.keys.push(key); }); [].concat(opts.normalize || []).filter(Boolean).forEach(function (key) { flags.normalize[key] = true; flags.keys.push(key); }); if (typeof opts.narg === 'object') { Object.entries(opts.narg).forEach(([key, value]) => { if (typeof value === 'number') { flags.nargs[key] = value; flags.keys.push(key); } }); } if (typeof opts.coerce === 'object') { Object.entries(opts.coerce).forEach(([key, value]) => { if (typeof value === 'function') { flags.coercions[key] = value; flags.keys.push(key); } }); } if (typeof opts.config !== 'undefined') { if (Array.isArray(opts.config) || typeof opts.config === 'string') { [].concat(opts.config).filter(Boolean).forEach(function (key) { flags.configs[key] = true; }); } else if (typeof opts.config === 'object') { Object.entries(opts.config).forEach(([key, value]) => { if (typeof value === 'boolean' || typeof value === 'function') { flags.configs[key] = value; } }); } } extendAliases(opts.key, aliases, opts.default, flags.arrays); Object.keys(defaults).forEach(function (key) { (flags.aliases[key] || []).forEach(function (alias) { defaults[alias] = defaults[key]; }); }); let error = null; checkConfiguration(); let notFlags = []; const argv = Object.assign(Object.create(null), { _: [] }); const argvReturn = {}; for (let i = 0; i < args.length; i++) { const arg = args[i]; const truncatedArg = arg.replace(/^-{3,}/, '---'); let broken; let key; let letters; let m; let next; let value; if (arg !== '--' && isUnknownOptionAsArg(arg)) { pushPositional(arg); } else if (truncatedArg.match(/---+(=|$)/)) { pushPositional(arg); continue; } else if (arg.match(/^--.+=/) || (!configuration['short-option-groups'] && arg.match(/^-.+=/))) { m = arg.match(/^--?([^=]+)=([\s\S]*)$/); if (m !== null && Array.isArray(m) && m.length >= 3) { if (checkAllAliases(m[1], flags.arrays)) { i = eatArray(i, m[1], args, m[2]); } else if (checkAllAliases(m[1], flags.nargs) !== false) { i = eatNargs(i, m[1], args, m[2]); } else { setArg(m[1], m[2]); } } } else if (arg.match(negatedBoolean) && configuration['boolean-negation']) { m = arg.match(negatedBoolean); if (m !== null && Array.isArray(m) && m.length >= 2) { key = m[1]; setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false); } } else if (arg.match(/^--.+/) || (!configuration['short-option-groups'] && arg.match(/^-[^-]+/))) { m = arg.match(/^--?(.+)/); if (m !== null && Array.isArray(m) && m.length >= 2) { key = m[1]; if (checkAllAliases(key, flags.arrays)) { i = eatArray(i, key, args); } else if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args); } else { next = args[i + 1]; if (next !== undefined && (!next.match(/^-/) || next.match(negative)) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { setArg(key, next); i++; } else if (/^(true|false)$/.test(next)) { setArg(key, next); i++; } else { setArg(key, defaultValue(key)); } } } } else if (arg.match(/^-.\..+=/)) { m = arg.match(/^-([^=]+)=([\s\S]*)$/); if (m !== null && Array.isArray(m) && m.length >= 3) { setArg(m[1], m[2]); } } else if (arg.match(/^-.\..+/) && !arg.match(negative)) { next = args[i + 1]; m = arg.match(/^-(.\..+)/); if (m !== null && Array.isArray(m) && m.length >= 2) { key = m[1]; if (next !== undefined && !next.match(/^-/) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { setArg(key, next); i++; } else { setArg(key, defaultValue(key)); } } } else if (arg.match(/^-[^-]+/) && !arg.match(negative)) { letters = arg.slice(1, -1).split(''); broken = false; for (let j = 0; j < letters.length; j++) { next = arg.slice(j + 2); if (letters[j + 1] && letters[j + 1] === '=') { value = arg.slice(j + 3); key = letters[j]; if (checkAllAliases(key, flags.arrays)) { i = eatArray(i, key, args, value); } else if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args, value); } else { setArg(key, value); } broken = true; break; } if (next === '-') { setArg(letters[j], next); continue; } if (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && checkAllAliases(next, flags.bools) === false) { setArg(letters[j], next); broken = true; break; } if (letters[j + 1] && letters[j + 1].match(/\W/)) { setArg(letters[j], next); broken = true; break; } else { setArg(letters[j], defaultValue(letters[j])); } } key = arg.slice(-1)[0]; if (!broken && key !== '-') { if (checkAllAliases(key, flags.arrays)) { i = eatArray(i, key, args); } else if (checkAllAliases(key, flags.nargs) !== false) { i = eatNargs(i, key, args); } else { next = args[i + 1]; if (next !== undefined && (!/^(-|--)[^-]/.test(next) || next.match(negative)) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { setArg(key, next); i++; } else if (/^(true|false)$/.test(next)) { setArg(key, next); i++; } else { setArg(key, defaultValue(key)); } } } } else if (arg.match(/^-[0-9]$/) && arg.match(negative) && checkAllAliases(arg.slice(1), flags.bools)) { key = arg.slice(1); setArg(key, defaultValue(key)); } else if (arg === '--') { notFlags = args.slice(i + 1); break; } else if (configuration['halt-at-non-option']) { notFlags = args.slice(i); break; } else { pushPositional(arg); } } applyEnvVars(argv, true); applyEnvVars(argv, false); setConfig(argv); setConfigObjects(); applyDefaultsAndAliases(argv, flags.aliases, defaults, true); applyCoercions(argv); if (configuration['set-placeholder-key']) setPlaceholderKeys(argv); Object.keys(flags.counts).forEach(function (key) { if (!hasKey(argv, key.split('.'))) setArg(key, 0); }); if (notFlagsOption && notFlags.length) argv[notFlagsArgv] = []; notFlags.forEach(function (key) { argv[notFlagsArgv].push(key); }); if (configuration['camel-case-expansion'] && configuration['strip-dashed']) { Object.keys(argv).filter(key => key !== '--' && key.includes('-')).forEach(key => { delete argv[key]; }); } if (configuration['strip-aliased']) { [].concat(...Object.keys(aliases).map(k => aliases[k])).forEach(alias => { if (configuration['camel-case-expansion'] && alias.includes('-')) { delete argv[alias.split('.').map(prop => camelCase(prop)).join('.')]; } delete argv[alias]; }); } function pushPositional(arg) { const maybeCoercedNumber = maybeCoerceNumber('_', arg); if (typeof maybeCoercedNumber === 'string' || typeof maybeCoercedNumber === 'number') { argv._.push(maybeCoercedNumber); } } function eatNargs(i, key, args, argAfterEqualSign) { let ii; let toEat = checkAllAliases(key, flags.nargs); toEat = typeof toEat !== 'number' || isNaN(toEat) ? 1 : toEat; if (toEat === 0) { if (!isUndefined(argAfterEqualSign)) { error = Error(__('Argument unexpected for: %s', key)); } setArg(key, defaultValue(key)); return i; } let available = isUndefined(argAfterEqualSign) ? 0 : 1; if (configuration['nargs-eats-options']) { if (args.length - (i + 1) + available < toEat) { error = Error(__('Not enough arguments following: %s', key)); } available = toEat; } else { for (ii = i + 1; ii < args.length; ii++) { if (!args[ii].match(/^-[^0-9]/) || args[ii].match(negative) || isUnknownOptionAsArg(args[ii])) available++; else break; } if (available < toEat) error = Error(__('Not enough arguments following: %s', key)); } let consumed = Math.min(available, toEat); if (!isUndefined(argAfterEqualSign) && consumed > 0) { setArg(key, argAfterEqualSign); consumed--; } for (ii = i + 1; ii < (consumed + i + 1); ii++) { setArg(key, args[ii]); } return (i + consumed); } function eatArray(i, key, args, argAfterEqualSign) { let argsToSet = []; let next = argAfterEqualSign || args[i + 1]; const nargsCount = checkAllAliases(key, flags.nargs); if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) { argsToSet.push(true); } else if (isUndefined(next) || (isUndefined(argAfterEqualSign) && /^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) { if (defaults[key] !== undefined) { const defVal = defaults[key]; argsToSet = Array.isArray(defVal) ? defVal : [defVal]; } } else { if (!isUndefined(argAfterEqualSign)) { argsToSet.push(processValue(key, argAfterEqualSign)); } for (let ii = i + 1; ii < args.length; ii++) { if ((!configuration['greedy-arrays'] && argsToSet.length > 0) || (nargsCount && typeof nargsCount === 'number' && argsToSet.length >= nargsCount)) break; next = args[ii]; if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) break; i = ii; argsToSet.push(processValue(key, next)); } } if (typeof nargsCount === 'number' && ((nargsCount && argsToSet.length < nargsCount) || (isNaN(nargsCount) && argsToSet.length === 0))) { error = Error(__('Not enough arguments following: %s', key)); } setArg(key, argsToSet); return i; } function setArg(key, val) { if (/-/.test(key) && configuration['camel-case-expansion']) { const alias = key.split('.').map(function (prop) { return camelCase(prop); }).join('.'); addNewAlias(key, alias); } const value = processValue(key, val); const splitKey = key.split('.'); setKey(argv, splitKey, value); if (flags.aliases[key]) { flags.aliases[key].forEach(function (x) { const keyProperties = x.split('.'); setKey(argv, keyProperties, value); }); } if (splitKey.length > 1 && configuration['dot-notation']) { (flags.aliases[splitKey[0]] || []).forEach(function (x) { let keyProperties = x.split('.'); const a = [].concat(splitKey); a.shift(); keyProperties = keyProperties.concat(a); if (!(flags.aliases[key] || []).includes(keyProperties.join('.'))) { setKey(argv, keyProperties, value); } }); } if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) { const keys = [key].concat(flags.aliases[key] || []); keys.forEach(function (key) { Object.defineProperty(argvReturn, key, { enumerable: true, get() { return val; }, set(value) { val = typeof value === 'string' ? mixin.normalize(value) : value; } }); }); } } function addNewAlias(key, alias) { if (!(flags.aliases[key] && flags.aliases[key].length)) { flags.aliases[key] = [alias]; newAliases[alias] = true; } if (!(flags.aliases[alias] && flags.aliases[alias].length)) { addNewAlias(alias, key); } } function processValue(key, val) { if (typeof val === 'string' && (val[0] === "'" || val[0] === '"') && val[val.length - 1] === val[0]) { val = val.substring(1, val.length - 1); } if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) { if (typeof val === 'string') val = val === 'true'; } let value = Array.isArray(val) ? val.map(function (v) { return maybeCoerceNumber(key, v); }) : maybeCoerceNumber(key, val); if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) { value = increment(); } if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) { if (Array.isArray(val)) value = val.map((val) => { return mixin.normalize(val); }); else value = mixin.normalize(val); } return value; } function maybeCoerceNumber(key, value) { if (!configuration['parse-positional-numbers'] && key === '_') return value; if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) { const shouldCoerceNumber = looksLikeNumber(value) && configuration['parse-numbers'] && (Number.isSafeInteger(Math.floor(parseFloat(`${value}`)))); if (shouldCoerceNumber || (!isUndefined(value) && checkAllAliases(key, flags.numbers))) { value = Number(value); } } return value; } function setConfig(argv) { const configLookup = Object.create(null); applyDefaultsAndAliases(configLookup, flags.aliases, defaults); Object.keys(flags.configs).forEach(function (configKey) { const configPath = argv[configKey] || configLookup[configKey]; if (configPath) { try { let config = null; const resolvedConfigPath = mixin.resolve(mixin.cwd(), configPath); const resolveConfig = flags.configs[configKey]; if (typeof resolveConfig === 'function') { try { config = resolveConfig(resolvedConfigPath); } catch (e) { config = e; } if (config instanceof Error) { error = config; return; } } else { config = mixin.require(resolvedConfigPath); } setConfigObject(config); } catch (ex) { if (ex.name === 'PermissionDenied') error = ex; else if (argv[configKey]) error = Error(__('Invalid JSON config file: %s', configPath)); } } }); } function setConfigObject(config, prev) { Object.keys(config).forEach(function (key) { const value = config[key]; const fullKey = prev ? prev + '.' + key : key; if (typeof value === 'object' && value !== null && !Array.isArray(value) && configuration['dot-notation']) { setConfigObject(value, fullKey); } else { if (!hasKey(argv, fullKey.split('.')) || (checkAllAliases(fullKey, flags.arrays) && configuration['combine-arrays'])) { setArg(fullKey, value); } } }); } function setConfigObjects() { if (typeof configObjects !== 'undefined') { configObjects.forEach(function (configObject) { setConfigObject(configObject); }); } } function applyEnvVars(argv, configOnly) { if (typeof envPrefix === 'undefined') return; const prefix = typeof envPrefix === 'string' ? envPrefix : ''; const env = mixin.env(); Object.keys(env).forEach(function (envVar) { if (prefix === '' || envVar.lastIndexOf(prefix, 0) === 0) { const keys = envVar.split('__').map(function (key, i) { if (i === 0) { key = key.substring(prefix.length); } return camelCase(key); }); if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && !hasKey(argv, keys)) { setArg(keys.join('.'), env[envVar]); } } }); } function applyCoercions(argv) { let coerce; const applied = new Set(); Object.keys(argv).forEach(function (key) { if (!applied.has(key)) { coerce = checkAllAliases(key, flags.coercions); if (typeof coerce === 'function') { try { const value = maybeCoerceNumber(key, coerce(argv[key])); ([].concat(flags.aliases[key] || [], key)).forEach(ali => { applied.add(ali); argv[ali] = value; }); } catch (err) { error = err; } } } }); } function setPlaceholderKeys(argv) { flags.keys.forEach((key) => { if (~key.indexOf('.')) return; if (typeof argv[key] === 'undefined') argv[key] = undefined; }); return argv; } function applyDefaultsAndAliases(obj, aliases, defaults, canLog = false) { Object.keys(defaults).forEach(function (key) { if (!hasKey(obj, key.split('.'))) { setKey(obj, key.split('.'), defaults[key]); if (canLog) defaulted[key] = true; (aliases[key] || []).forEach(function (x) { if (hasKey(obj, x.split('.'))) return; setKey(obj, x.split('.'), defaults[key]); }); } }); } function hasKey(obj, keys) { let o = obj; if (!configuration['dot-notation']) keys = [keys.join('.')]; keys.slice(0, -1).forEach(function (key) { o = (o[key] || {}); }); const key = keys[keys.length - 1]; if (typeof o !== 'object') return false; else return key in o; } function setKey(obj, keys, value) { let o = obj; if (!configuration['dot-notation']) keys = [keys.join('.')]; keys.slice(0, -1).forEach(function (key) { key = sanitizeKey(key); if (typeof o === 'object' && o[key] === undefined) { o[key] = {}; } if (typeof o[key] !== 'object' || Array.isArray(o[key])) { if (Array.isArray(o[key])) { o[key].push({}); } else { o[key] = [o[key], {}]; } o = o[key][o[key].length - 1]; } else { o = o[key]; } }); const key = sanitizeKey(keys[keys.length - 1]); const isTypeArray = checkAllAliases(keys.join('.'), flags.arrays); const isValueArray = Array.isArray(value); let duplicate = configuration['duplicate-arguments-array']; if (!duplicate && checkAllAliases(key, flags.nargs)) { duplicate = true; if ((!isUndefined(o[key]) && flags.nargs[key] === 1) || (Array.isArray(o[key]) && o[key].length === flags.nargs[key])) { o[key] = undefined; } } if (value === increment()) { o[key] = increment(o[key]); } else if (Array.isArray(o[key])) { if (duplicate && isTypeArray && isValueArray) { o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : (Array.isArray(o[key][0]) ? o[key] : [o[key]]).concat([value]); } else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) { o[key] = value; } else { o[key] = o[key].concat([value]); } } else if (o[key] === undefined && isTypeArray) { o[key] = isValueArray ? value : [value]; } else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.counts) || checkAllAliases(key, flags.bools))) { o[key] = [o[key], value]; } else { o[key] = value; } } function extendAliases(...args) { args.forEach(function (obj) { Object.keys(obj || {}).forEach(function (key) { if (flags.aliases[key]) return; flags.aliases[key] = [].concat(aliases[key] || []); flags.aliases[key].concat(key).forEach(function (x) { if (/-/.test(x) && configuration['camel-case-expansion']) { const c = camelCase(x); if (c !== key && flags.aliases[key].indexOf(c) === -1) { flags.aliases[key].push(c); newAliases[c] = true; } } }); flags.aliases[key].concat(key).forEach(function (x) { if (x.length > 1 && /[A-Z]/.test(x) && configuration['camel-case-expansion']) { const c = decamelize(x, '-'); if (c !== key && flags.aliases[key].indexOf(c) === -1) { flags.aliases[key].push(c); newAliases[c] = true; } } }); flags.aliases[key].forEach(function (x) { flags.aliases[x] = [key].concat(flags.aliases[key].filter(function (y) { return x !== y; })); }); }); }); } function checkAllAliases(key, flag) { const toCheck = [].concat(flags.aliases[key] || [], key); const keys = Object.keys(flag); const setAlias = toCheck.find(key => keys.includes(key)); return setAlias ? flag[setAlias] : false; } function hasAnyFlag(key) { const flagsKeys = Object.keys(flags); const toCheck = [].concat(flagsKeys.map(k => flags[k])); return toCheck.some(function (flag) { return Array.isArray(flag) ? flag.includes(key) : flag[key]; }); } function hasFlagsMatching(arg, ...patterns) { const toCheck = [].concat(...patterns); return toCheck.some(function (pattern) { const match = arg.match(pattern); return match && hasAnyFlag(match[1]); }); } function hasAllShortFlags(arg) { if (arg.match(negative) || !arg.match(/^-[^-]+/)) { return false; } let hasAllFlags = true; let next; const letters = arg.slice(1).split(''); for (let j = 0; j < letters.length; j++) { next = arg.slice(j + 2); if (!hasAnyFlag(letters[j])) { hasAllFlags = false; break; } if ((letters[j + 1] && letters[j + 1] === '=') || next === '-' || (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) || (letters[j + 1] && letters[j + 1].match(/\W/))) { break; } } return hasAllFlags; } function isUnknownOptionAsArg(arg) { return configuration['unknown-options-as-args'] && isUnknownOption(arg); } function isUnknownOption(arg) { arg = arg.replace(/^-{3,}/, '--'); if (arg.match(negative)) { return false; } if (hasAllShortFlags(arg)) { return false; } const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/; const normalFlag = /^-+([^=]+?)$/; const flagEndingInHyphen = /^-+([^=]+?)-$/; const flagEndingInDigits = /^-+([^=]+?\d+)$/; const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/; return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters); } function defaultValue(key) { if (!checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts) && `${key}` in defaults) { return defaults[key]; } else { return defaultForType(guessType(key)); } } function defaultForType(type) { const def = { [DefaultValuesForTypeKey.BOOLEAN]: true, [DefaultValuesForTypeKey.STRING]: '', [DefaultValuesForTypeKey.NUMBER]: undefined, [DefaultValuesForTypeKey.ARRAY]: [] }; return def[type]; } function guessType(key) { let type = DefaultValuesForTypeKey.BOOLEAN; if (checkAllAliases(key, flags.strings)) type = DefaultValuesForTypeKey.STRING; else if (checkAllAliases(key, flags.numbers)) type = DefaultValuesForTypeKey.NUMBER; else if (checkAllAliases(key, flags.bools)) type = DefaultValuesForTypeKey.BOOLEAN; else if (checkAllAliases(key, flags.arrays)) type = DefaultValuesForTypeKey.ARRAY; return type; } function isUndefined(num) { return num === undefined; } function checkConfiguration() { Object.keys(flags.counts).find(key => { if (checkAllAliases(key, flags.arrays)) { error = Error(__('Invalid configuration: %s, opts.count excludes opts.array.', key)); return true; } else if (checkAllAliases(key, flags.nargs)) { error = Error(__('Invalid configuration: %s, opts.count excludes opts.narg.', key)); return true; } return false; }); } return { aliases: Object.assign({}, flags.aliases), argv: Object.assign(argvReturn, argv), configuration: configuration, defaulted: Object.assign({}, defaulted), error: error, newAliases: Object.assign({}, newAliases) }; } } function combineAliases(aliases) { const aliasArrays = []; const combined = Object.create(null); let change = true; Object.keys(aliases).forEach(function (key) { aliasArrays.push([].concat(aliases[key], key)); }); while (change) { change = false; for (let i = 0; i < aliasArrays.length; i++) { for (let ii = i + 1; ii < aliasArrays.length; ii++) { const intersect = aliasArrays[i].filter(function (v) { return aliasArrays[ii].indexOf(v) !== -1; }); if (intersect.length) { aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]); aliasArrays.splice(ii, 1); change = true; break; } } } } aliasArrays.forEach(function (aliasArray) { aliasArray = aliasArray.filter(function (v, i, self) { return self.indexOf(v) === i; }); const lastAlias = aliasArray.pop(); if (lastAlias !== undefined && typeof lastAlias === 'string') { combined[lastAlias] = aliasArray; } }); return combined; } function increment(orig) { return orig !== undefined ? orig + 1 : 1; } function sanitizeKey(key) { if (key === '__proto__') return '___proto___'; return key; } const minNodeVersion = (process && process.env && process.env.YARGS_MIN_NODE_VERSION) ? Number(process.env.YARGS_MIN_NODE_VERSION) : 10; if (process && process.version) { const major = Number(process.version.match(/v([^.]+)/)[1]); if (major < minNodeVersion) { throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`); } } const env = process ? process.env : {}; const parser = new YargsParser({ cwd: process.cwd, env: () => { return env; }, format: util.format, normalize: path.normalize, resolve: path.resolve, require: (path) => { if (typeof require !== 'undefined') { return require(path); } else if (path.match(/\.json$/)) { return fs.readFileSync(path, 'utf8'); } else { throw Error('only .json config files are supported in ESM'); } } }); const yargsParser = function Parser(args, opts) { const result = parser.parse(args.slice(), opts); return result.argv; }; yargsParser.detailed = function (args, opts) { return parser.parse(args.slice(), opts); }; yargsParser.camelCase = camelCase; yargsParser.decamelize = decamelize; yargsParser.looksLikeNumber = looksLikeNumber; module.exports = yargsParser; build/lib/index.js 0000644 00000004120 15120070333 0010045 0 ustar 00 /** * @fileoverview Main entrypoint for libraries using yargs-parser in Node.js * CJS and ESM environments. * * @license * Copyright (c) 2016, Contributors * SPDX-License-Identifier: ISC */ import { format } from 'util'; import { readFileSync } from 'fs'; import { normalize, resolve } from 'path'; import { camelCase, decamelize, looksLikeNumber } from './string-utils.js'; import { YargsParser } from './yargs-parser.js'; // See https://github.com/yargs/yargs-parser#supported-nodejs-versions for our // version support policy. The YARGS_MIN_NODE_VERSION is used for testing only. const minNodeVersion = (process && process.env && process.env.YARGS_MIN_NODE_VERSION) ? Number(process.env.YARGS_MIN_NODE_VERSION) : 10; if (process && process.version) { const major = Number(process.version.match(/v([^.]+)/)[1]); if (major < minNodeVersion) { throw Error(`yargs parser supports a minimum Node.js version of ${minNodeVersion}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`); } } // Creates a yargs-parser instance using Node.js standard libraries: const env = process ? process.env : {}; const parser = new YargsParser({ cwd: process.cwd, env: () => { return env; }, format, normalize, resolve, // TODO: figure out a way to combine ESM and CJS coverage, such that // we can exercise all the lines below: require: (path) => { if (typeof require !== 'undefined') { return require(path); } else if (path.match(/\.json$/)) { return readFileSync(path, 'utf8'); } else { throw Error('only .json config files are supported in ESM'); } } }); const yargsParser = function Parser(args, opts) { const result = parser.parse(args.slice(), opts); return result.argv; }; yargsParser.detailed = function (args, opts) { return parser.parse(args.slice(), opts); }; yargsParser.camelCase = camelCase; yargsParser.decamelize = decamelize; yargsParser.looksLikeNumber = looksLikeNumber; export default yargsParser; build/lib/string-utils.js 0000644 00000004044 15120070333 0011407 0 ustar 00 /** * @license * Copyright (c) 2016, Contributors * SPDX-License-Identifier: ISC */ export function camelCase(str) { // Handle the case where an argument is provided as camel case, e.g., fooBar. // by ensuring that the string isn't already mixed case: const isCamelCase = str !== str.toLowerCase() && str !== str.toUpperCase(); if (!isCamelCase) { str = str.toLowerCase(); } if (str.indexOf('-') === -1 && str.indexOf('_') === -1) { return str; } else { let camelcase = ''; let nextChrUpper = false; const leadingHyphens = str.match(/^-+/); for (let i = leadingHyphens ? leadingHyphens[0].length : 0; i < str.length; i++) { let chr = str.charAt(i); if (nextChrUpper) { nextChrUpper = false; chr = chr.toUpperCase(); } if (i !== 0 && (chr === '-' || chr === '_')) { nextChrUpper = true; } else if (chr !== '-' && chr !== '_') { camelcase += chr; } } return camelcase; } } export function decamelize(str, joinString) { const lowercase = str.toLowerCase(); joinString = joinString || '-'; let notCamelcase = ''; for (let i = 0; i < str.length; i++) { const chrLower = lowercase.charAt(i); const chrString = str.charAt(i); if (chrLower !== chrString && i > 0) { notCamelcase += `${joinString}${lowercase.charAt(i)}`; } else { notCamelcase += chrString; } } return notCamelcase; } export function looksLikeNumber(x) { if (x === null || x === undefined) return false; // if loaded from config, may already be a number. if (typeof x === 'number') return true; // hexadecimal. if (/^0x[0-9a-f]+$/i.test(x)) return true; // don't treat 0123 as a number; as it drops the leading '0'. if (/^0[^.]/.test(x)) return false; return /^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); } build/lib/tokenize-arg-string.js 0000644 00000002104 15120070333 0012641 0 ustar 00 /** * @license * Copyright (c) 2016, Contributors * SPDX-License-Identifier: ISC */ // take an un-split argv string and tokenize it. export function tokenizeArgString(argString) { if (Array.isArray(argString)) { return argString.map(e => typeof e !== 'string' ? e + '' : e); } argString = argString.trim(); let i = 0; let prevC = null; let c = null; let opening = null; const args = []; for (let ii = 0; ii < argString.length; ii++) { prevC = c; c = argString.charAt(ii); // split on spaces unless we're in quotes. if (c === ' ' && !opening) { if (!(prevC === ' ')) { i++; } continue; } // don't split the string if we're in matching // opening or closing single and double quotes. if (c === opening) { opening = null; } else if ((c === "'" || c === '"') && !opening) { opening = c; } if (!args[i]) args[i] = ''; args[i] += c; } return args; } build/lib/yargs-parser-types.js 0000644 00000000651 15120070333 0012524 0 ustar 00 /** * @license * Copyright (c) 2016, Contributors * SPDX-License-Identifier: ISC */ export var DefaultValuesForTypeKey; (function (DefaultValuesForTypeKey) { DefaultValuesForTypeKey["BOOLEAN"] = "boolean"; DefaultValuesForTypeKey["STRING"] = "string"; DefaultValuesForTypeKey["NUMBER"] = "number"; DefaultValuesForTypeKey["ARRAY"] = "array"; })(DefaultValuesForTypeKey || (DefaultValuesForTypeKey = {})); build/lib/yargs-parser.js 0000644 00000132476 15120070333 0011375 0 ustar 00 /** * @license * Copyright (c) 2016, Contributors * SPDX-License-Identifier: ISC */ import { tokenizeArgString } from './tokenize-arg-string.js'; import { DefaultValuesForTypeKey } from './yargs-parser-types.js'; import { camelCase, decamelize, looksLikeNumber } from './string-utils.js'; let mixin; export class YargsParser { constructor(_mixin) { mixin = _mixin; } parse(argsInput, options) { const opts = Object.assign({ alias: undefined, array: undefined, boolean: undefined, config: undefined, configObjects: undefined, configuration: undefined, coerce: undefined, count: undefined, default: undefined, envPrefix: undefined, narg: undefined, normalize: undefined, string: undefined, number: undefined, __: undefined, key: undefined }, options); // allow a string argument to be passed in rather // than an argv array. const args = tokenizeArgString(argsInput); // aliases might have transitive relationships, normalize this. const aliases = combineAliases(Object.assign(Object.create(null), opts.alias)); const configuration = Object.assign({ 'boolean-negation': true, 'camel-case-expansion': true, 'combine-arrays': false, 'dot-notation': true, 'duplicate-arguments-array': true, 'flatten-duplicate-arrays': true, 'greedy-arrays': true, 'halt-at-non-option': false, 'nargs-eats-options': false, 'negation-prefix': 'no-', 'parse-numbers': true, 'parse-positional-numbers': true, 'populate--': false, 'set-placeholder-key': false, 'short-option-groups': true, 'strip-aliased': false, 'strip-dashed': false, 'unknown-options-as-args': false }, opts.configuration); const defaults = Object.assign(Object.create(null), opts.default); const configObjects = opts.configObjects || []; const envPrefix = opts.envPrefix; const notFlagsOption = configuration['populate--']; const notFlagsArgv = notFlagsOption ? '--' : '_'; const newAliases = Object.create(null); const defaulted = Object.create(null); // allow a i18n handler to be passed in, default to a fake one (util.format). const __ = opts.__ || mixin.format; const flags = { aliases: Object.create(null), arrays: Object.create(null), bools: Object.create(null), strings: Object.create(null), numbers: Object.create(null), counts: Object.create(null), normalize: Object.create(null), configs: Object.create(null), nargs: Object.create(null), coercions: Object.create(null), keys: [] }; const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/; const negatedBoolean = new RegExp('^--' + configuration['negation-prefix'] + '(.+)'); [].concat(opts.array || []).filter(Boolean).forEach(function (opt) { const key = typeof opt === 'object' ? opt.key : opt; // assign to flags[bools|strings|numbers] const assignment = Object.keys(opt).map(function (key) { const arrayFlagKeys = { boolean: 'bools', string: 'strings', number: 'numbers' }; return arrayFlagKeys[key]; }).filter(Boolean).pop(); // assign key to be coerced if (assignment) { flags[assignment][key] = true; } flags.arrays[key] = true; flags.keys.push(key); }); [].concat(opts.boolean || []).filter(Boolean).forEach(function (key) { flags.bools[key] = true; flags.keys.push(key); }); [].concat(opts.string || []).filter(Boolean).forEach(function (key) { flags.strings[key] = true; flags.keys.push(key); }); [].concat(opts.number || []).filter(Boolean).forEach(function (key) { flags.numbers[key] = true; flags.keys.push(key); }); [].concat(opts.count || []).filter(Boolean).forEach(function (key) { flags.counts[key] = true; flags.keys.push(key); }); [].concat(opts.normalize || []).filter(Boolean).forEach(function (key) { flags.normalize[key] = true; flags.keys.push(key); }); if (typeof opts.narg === 'object') { Object.entries(opts.narg).forEach(([key, value]) => { if (typeof value === 'number') { flags.nargs[key] = value; flags.keys.push(key); } }); } if (typeof opts.coerce === 'object') { Object.entries(opts.coerce).forEach(([key, value]) => { if (typeof value === 'function') { flags.coercions[key] = value; flags.keys.push(key); } }); } if (typeof opts.config !== 'undefined') { if (Array.isArray(opts.config) || typeof opts.config === 'string') { ; [].concat(opts.config).filter(Boolean).forEach(function (key) { flags.configs[key] = true; }); } else if (typeof opts.config === 'object') { Object.entries(opts.config).forEach(([key, value]) => { if (typeof value === 'boolean' || typeof value === 'function') { flags.configs[key] = value; } }); } } // create a lookup table that takes into account all // combinations of aliases: {f: ['foo'], foo: ['f']} extendAliases(opts.key, aliases, opts.default, flags.arrays); // apply default values to all aliases. Object.keys(defaults).forEach(function (key) { (flags.aliases[key] || []).forEach(function (alias) { defaults[alias] = defaults[key]; }); }); let error = null; checkConfiguration(); let notFlags = []; const argv = Object.assign(Object.create(null), { _: [] }); // TODO(bcoe): for the first pass at removing object prototype we didn't // remove all prototypes from objects returned by this API, we might want // to gradually move towards doing so. const argvReturn = {}; for (let i = 0; i < args.length; i++) { const arg = args[i]; const truncatedArg = arg.replace(/^-{3,}/, '---'); let broken; let key; let letters; let m; let next; let value; // any unknown option (except for end-of-options, "--") if (arg !== '--' && isUnknownOptionAsArg(arg)) { pushPositional(arg); // ---, ---=, ----, etc, } else if (truncatedArg.match(/---+(=|$)/)) { // options without key name are invalid. pushPositional(arg); continue; // -- separated by = } else if (arg.match(/^--.+=/) || (!configuration['short-option-groups'] && arg.match(/^-.+=/))) { // Using [\s\S] instead of . because js doesn't support the // 'dotall' regex modifier. See: // http://stackoverflow.com/a/1068308/13216 m = arg.match(/^--?([^=]+)=([\s\S]*)$/); // arrays format = '--f=a b c' if (m !== null && Array.isArray(m) && m.length >= 3) { if (checkAllAliases(m[1], flags.arrays)) { i = eatArray(i, m[1], args, m[2]); } else if (checkAllAliases(m[1], flags.nargs) !== false) { // nargs format = '--f=monkey washing cat' i = eatNargs(i, m[1], args, m[2]); } else { setArg(m[1], m[2]); } } } else if (arg.match(negatedBoolean) && configuration['boolean-negation']) { m = arg.match(negatedBoolean); if (m !== null && Array.isArray(m) && m.length >= 2) { key = m[1]; setArg(key, checkAllAliases(key, flags.arrays) ? [false] : false); } // -- separated by space. } else if (arg.match(/^--.+/) || (!configuration['short-option-groups'] && arg.match(/^-[^-]+/))) { m = arg.match(/^--?(.+)/); if (m !== null && Array.isArray(m) && m.length >= 2) { key = m[1]; if (checkAllAliases(key, flags.arrays)) { // array format = '--foo a b c' i = eatArray(i, key, args); } else if (checkAllAliases(key, flags.nargs) !== false) { // nargs format = '--foo a b c' // should be truthy even if: flags.nargs[key] === 0 i = eatNargs(i, key, args); } else { next = args[i + 1]; if (next !== undefined && (!next.match(/^-/) || next.match(negative)) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { setArg(key, next); i++; } else if (/^(true|false)$/.test(next)) { setArg(key, next); i++; } else { setArg(key, defaultValue(key)); } } } // dot-notation flag separated by '='. } else if (arg.match(/^-.\..+=/)) { m = arg.match(/^-([^=]+)=([\s\S]*)$/); if (m !== null && Array.isArray(m) && m.length >= 3) { setArg(m[1], m[2]); } // dot-notation flag separated by space. } else if (arg.match(/^-.\..+/) && !arg.match(negative)) { next = args[i + 1]; m = arg.match(/^-(.\..+)/); if (m !== null && Array.isArray(m) && m.length >= 2) { key = m[1]; if (next !== undefined && !next.match(/^-/) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { setArg(key, next); i++; } else { setArg(key, defaultValue(key)); } } } else if (arg.match(/^-[^-]+/) && !arg.match(negative)) { letters = arg.slice(1, -1).split(''); broken = false; for (let j = 0; j < letters.length; j++) { next = arg.slice(j + 2); if (letters[j + 1] && letters[j + 1] === '=') { value = arg.slice(j + 3); key = letters[j]; if (checkAllAliases(key, flags.arrays)) { // array format = '-f=a b c' i = eatArray(i, key, args, value); } else if (checkAllAliases(key, flags.nargs) !== false) { // nargs format = '-f=monkey washing cat' i = eatNargs(i, key, args, value); } else { setArg(key, value); } broken = true; break; } if (next === '-') { setArg(letters[j], next); continue; } // current letter is an alphabetic character and next value is a number if (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next) && checkAllAliases(next, flags.bools) === false) { setArg(letters[j], next); broken = true; break; } if (letters[j + 1] && letters[j + 1].match(/\W/)) { setArg(letters[j], next); broken = true; break; } else { setArg(letters[j], defaultValue(letters[j])); } } key = arg.slice(-1)[0]; if (!broken && key !== '-') { if (checkAllAliases(key, flags.arrays)) { // array format = '-f a b c' i = eatArray(i, key, args); } else if (checkAllAliases(key, flags.nargs) !== false) { // nargs format = '-f a b c' // should be truthy even if: flags.nargs[key] === 0 i = eatNargs(i, key, args); } else { next = args[i + 1]; if (next !== undefined && (!/^(-|--)[^-]/.test(next) || next.match(negative)) && !checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts)) { setArg(key, next); i++; } else if (/^(true|false)$/.test(next)) { setArg(key, next); i++; } else { setArg(key, defaultValue(key)); } } } } else if (arg.match(/^-[0-9]$/) && arg.match(negative) && checkAllAliases(arg.slice(1), flags.bools)) { // single-digit boolean alias, e.g: xargs -0 key = arg.slice(1); setArg(key, defaultValue(key)); } else if (arg === '--') { notFlags = args.slice(i + 1); break; } else if (configuration['halt-at-non-option']) { notFlags = args.slice(i); break; } else { pushPositional(arg); } } // order of precedence: // 1. command line arg // 2. value from env var // 3. value from config file // 4. value from config objects // 5. configured default value applyEnvVars(argv, true); // special case: check env vars that point to config file applyEnvVars(argv, false); setConfig(argv); setConfigObjects(); applyDefaultsAndAliases(argv, flags.aliases, defaults, true); applyCoercions(argv); if (configuration['set-placeholder-key']) setPlaceholderKeys(argv); // for any counts either not in args or without an explicit default, set to 0 Object.keys(flags.counts).forEach(function (key) { if (!hasKey(argv, key.split('.'))) setArg(key, 0); }); // '--' defaults to undefined. if (notFlagsOption && notFlags.length) argv[notFlagsArgv] = []; notFlags.forEach(function (key) { argv[notFlagsArgv].push(key); }); if (configuration['camel-case-expansion'] && configuration['strip-dashed']) { Object.keys(argv).filter(key => key !== '--' && key.includes('-')).forEach(key => { delete argv[key]; }); } if (configuration['strip-aliased']) { ; [].concat(...Object.keys(aliases).map(k => aliases[k])).forEach(alias => { if (configuration['camel-case-expansion'] && alias.includes('-')) { delete argv[alias.split('.').map(prop => camelCase(prop)).join('.')]; } delete argv[alias]; }); } // Push argument into positional array, applying numeric coercion: function pushPositional(arg) { const maybeCoercedNumber = maybeCoerceNumber('_', arg); if (typeof maybeCoercedNumber === 'string' || typeof maybeCoercedNumber === 'number') { argv._.push(maybeCoercedNumber); } } // how many arguments should we consume, based // on the nargs option? function eatNargs(i, key, args, argAfterEqualSign) { let ii; let toEat = checkAllAliases(key, flags.nargs); // NaN has a special meaning for the array type, indicating that one or // more values are expected. toEat = typeof toEat !== 'number' || isNaN(toEat) ? 1 : toEat; if (toEat === 0) { if (!isUndefined(argAfterEqualSign)) { error = Error(__('Argument unexpected for: %s', key)); } setArg(key, defaultValue(key)); return i; } let available = isUndefined(argAfterEqualSign) ? 0 : 1; if (configuration['nargs-eats-options']) { // classic behavior, yargs eats positional and dash arguments. if (args.length - (i + 1) + available < toEat) { error = Error(__('Not enough arguments following: %s', key)); } available = toEat; } else { // nargs will not consume flag arguments, e.g., -abc, --foo, // and terminates when one is observed. for (ii = i + 1; ii < args.length; ii++) { if (!args[ii].match(/^-[^0-9]/) || args[ii].match(negative) || isUnknownOptionAsArg(args[ii])) available++; else break; } if (available < toEat) error = Error(__('Not enough arguments following: %s', key)); } let consumed = Math.min(available, toEat); if (!isUndefined(argAfterEqualSign) && consumed > 0) { setArg(key, argAfterEqualSign); consumed--; } for (ii = i + 1; ii < (consumed + i + 1); ii++) { setArg(key, args[ii]); } return (i + consumed); } // if an option is an array, eat all non-hyphenated arguments // following it... YUM! // e.g., --foo apple banana cat becomes ["apple", "banana", "cat"] function eatArray(i, key, args, argAfterEqualSign) { let argsToSet = []; let next = argAfterEqualSign || args[i + 1]; // If both array and nargs are configured, enforce the nargs count: const nargsCount = checkAllAliases(key, flags.nargs); if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) { argsToSet.push(true); } else if (isUndefined(next) || (isUndefined(argAfterEqualSign) && /^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) { // for keys without value ==> argsToSet remains an empty [] // set user default value, if available if (defaults[key] !== undefined) { const defVal = defaults[key]; argsToSet = Array.isArray(defVal) ? defVal : [defVal]; } } else { // value in --option=value is eaten as is if (!isUndefined(argAfterEqualSign)) { argsToSet.push(processValue(key, argAfterEqualSign)); } for (let ii = i + 1; ii < args.length; ii++) { if ((!configuration['greedy-arrays'] && argsToSet.length > 0) || (nargsCount && typeof nargsCount === 'number' && argsToSet.length >= nargsCount)) break; next = args[ii]; if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) break; i = ii; argsToSet.push(processValue(key, next)); } } // If both array and nargs are configured, create an error if less than // nargs positionals were found. NaN has special meaning, indicating // that at least one value is required (more are okay). if (typeof nargsCount === 'number' && ((nargsCount && argsToSet.length < nargsCount) || (isNaN(nargsCount) && argsToSet.length === 0))) { error = Error(__('Not enough arguments following: %s', key)); } setArg(key, argsToSet); return i; } function setArg(key, val) { if (/-/.test(key) && configuration['camel-case-expansion']) { const alias = key.split('.').map(function (prop) { return camelCase(prop); }).join('.'); addNewAlias(key, alias); } const value = processValue(key, val); const splitKey = key.split('.'); setKey(argv, splitKey, value); // handle populating aliases of the full key if (flags.aliases[key]) { flags.aliases[key].forEach(function (x) { const keyProperties = x.split('.'); setKey(argv, keyProperties, value); }); } // handle populating aliases of the first element of the dot-notation key if (splitKey.length > 1 && configuration['dot-notation']) { ; (flags.aliases[splitKey[0]] || []).forEach(function (x) { let keyProperties = x.split('.'); // expand alias with nested objects in key const a = [].concat(splitKey); a.shift(); // nuke the old key. keyProperties = keyProperties.concat(a); // populate alias only if is not already an alias of the full key // (already populated above) if (!(flags.aliases[key] || []).includes(keyProperties.join('.'))) { setKey(argv, keyProperties, value); } }); } // Set normalize getter and setter when key is in 'normalize' but isn't an array if (checkAllAliases(key, flags.normalize) && !checkAllAliases(key, flags.arrays)) { const keys = [key].concat(flags.aliases[key] || []); keys.forEach(function (key) { Object.defineProperty(argvReturn, key, { enumerable: true, get() { return val; }, set(value) { val = typeof value === 'string' ? mixin.normalize(value) : value; } }); }); } } function addNewAlias(key, alias) { if (!(flags.aliases[key] && flags.aliases[key].length)) { flags.aliases[key] = [alias]; newAliases[alias] = true; } if (!(flags.aliases[alias] && flags.aliases[alias].length)) { addNewAlias(alias, key); } } function processValue(key, val) { // strings may be quoted, clean this up as we assign values. if (typeof val === 'string' && (val[0] === "'" || val[0] === '"') && val[val.length - 1] === val[0]) { val = val.substring(1, val.length - 1); } // handle parsing boolean arguments --foo=true --bar false. if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) { if (typeof val === 'string') val = val === 'true'; } let value = Array.isArray(val) ? val.map(function (v) { return maybeCoerceNumber(key, v); }) : maybeCoerceNumber(key, val); // increment a count given as arg (either no value or value parsed as boolean) if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) { value = increment(); } // Set normalized value when key is in 'normalize' and in 'arrays' if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) { if (Array.isArray(val)) value = val.map((val) => { return mixin.normalize(val); }); else value = mixin.normalize(val); } return value; } function maybeCoerceNumber(key, value) { if (!configuration['parse-positional-numbers'] && key === '_') return value; if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.bools) && !Array.isArray(value)) { const shouldCoerceNumber = looksLikeNumber(value) && configuration['parse-numbers'] && (Number.isSafeInteger(Math.floor(parseFloat(`${value}`)))); if (shouldCoerceNumber || (!isUndefined(value) && checkAllAliases(key, flags.numbers))) { value = Number(value); } } return value; } // set args from config.json file, this should be // applied last so that defaults can be applied. function setConfig(argv) { const configLookup = Object.create(null); // expand defaults/aliases, in-case any happen to reference // the config.json file. applyDefaultsAndAliases(configLookup, flags.aliases, defaults); Object.keys(flags.configs).forEach(function (configKey) { const configPath = argv[configKey] || configLookup[configKey]; if (configPath) { try { let config = null; const resolvedConfigPath = mixin.resolve(mixin.cwd(), configPath); const resolveConfig = flags.configs[configKey]; if (typeof resolveConfig === 'function') { try { config = resolveConfig(resolvedConfigPath); } catch (e) { config = e; } if (config instanceof Error) { error = config; return; } } else { config = mixin.require(resolvedConfigPath); } setConfigObject(config); } catch (ex) { // Deno will receive a PermissionDenied error if an attempt is // made to load config without the --allow-read flag: if (ex.name === 'PermissionDenied') error = ex; else if (argv[configKey]) error = Error(__('Invalid JSON config file: %s', configPath)); } } }); } // set args from config object. // it recursively checks nested objects. function setConfigObject(config, prev) { Object.keys(config).forEach(function (key) { const value = config[key]; const fullKey = prev ? prev + '.' + key : key; // if the value is an inner object and we have dot-notation // enabled, treat inner objects in config the same as // heavily nested dot notations (foo.bar.apple). if (typeof value === 'object' && value !== null && !Array.isArray(value) && configuration['dot-notation']) { // if the value is an object but not an array, check nested object setConfigObject(value, fullKey); } else { // setting arguments via CLI takes precedence over // values within the config file. if (!hasKey(argv, fullKey.split('.')) || (checkAllAliases(fullKey, flags.arrays) && configuration['combine-arrays'])) { setArg(fullKey, value); } } }); } // set all config objects passed in opts function setConfigObjects() { if (typeof configObjects !== 'undefined') { configObjects.forEach(function (configObject) { setConfigObject(configObject); }); } } function applyEnvVars(argv, configOnly) { if (typeof envPrefix === 'undefined') return; const prefix = typeof envPrefix === 'string' ? envPrefix : ''; const env = mixin.env(); Object.keys(env).forEach(function (envVar) { if (prefix === '' || envVar.lastIndexOf(prefix, 0) === 0) { // get array of nested keys and convert them to camel case const keys = envVar.split('__').map(function (key, i) { if (i === 0) { key = key.substring(prefix.length); } return camelCase(key); }); if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && !hasKey(argv, keys)) { setArg(keys.join('.'), env[envVar]); } } }); } function applyCoercions(argv) { let coerce; const applied = new Set(); Object.keys(argv).forEach(function (key) { if (!applied.has(key)) { // If we haven't already coerced this option via one of its aliases coerce = checkAllAliases(key, flags.coercions); if (typeof coerce === 'function') { try { const value = maybeCoerceNumber(key, coerce(argv[key])); ([].concat(flags.aliases[key] || [], key)).forEach(ali => { applied.add(ali); argv[ali] = value; }); } catch (err) { error = err; } } } }); } function setPlaceholderKeys(argv) { flags.keys.forEach((key) => { // don't set placeholder keys for dot notation options 'foo.bar'. if (~key.indexOf('.')) return; if (typeof argv[key] === 'undefined') argv[key] = undefined; }); return argv; } function applyDefaultsAndAliases(obj, aliases, defaults, canLog = false) { Object.keys(defaults).forEach(function (key) { if (!hasKey(obj, key.split('.'))) { setKey(obj, key.split('.'), defaults[key]); if (canLog) defaulted[key] = true; (aliases[key] || []).forEach(function (x) { if (hasKey(obj, x.split('.'))) return; setKey(obj, x.split('.'), defaults[key]); }); } }); } function hasKey(obj, keys) { let o = obj; if (!configuration['dot-notation']) keys = [keys.join('.')]; keys.slice(0, -1).forEach(function (key) { o = (o[key] || {}); }); const key = keys[keys.length - 1]; if (typeof o !== 'object') return false; else return key in o; } function setKey(obj, keys, value) { let o = obj; if (!configuration['dot-notation']) keys = [keys.join('.')]; keys.slice(0, -1).forEach(function (key) { // TODO(bcoe): in the next major version of yargs, switch to // Object.create(null) for dot notation: key = sanitizeKey(key); if (typeof o === 'object' && o[key] === undefined) { o[key] = {}; } if (typeof o[key] !== 'object' || Array.isArray(o[key])) { // ensure that o[key] is an array, and that the last item is an empty object. if (Array.isArray(o[key])) { o[key].push({}); } else { o[key] = [o[key], {}]; } // we want to update the empty object at the end of the o[key] array, so set o to that object o = o[key][o[key].length - 1]; } else { o = o[key]; } }); // TODO(bcoe): in the next major version of yargs, switch to // Object.create(null) for dot notation: const key = sanitizeKey(keys[keys.length - 1]); const isTypeArray = checkAllAliases(keys.join('.'), flags.arrays); const isValueArray = Array.isArray(value); let duplicate = configuration['duplicate-arguments-array']; // nargs has higher priority than duplicate if (!duplicate && checkAllAliases(key, flags.nargs)) { duplicate = true; if ((!isUndefined(o[key]) && flags.nargs[key] === 1) || (Array.isArray(o[key]) && o[key].length === flags.nargs[key])) { o[key] = undefined; } } if (value === increment()) { o[key] = increment(o[key]); } else if (Array.isArray(o[key])) { if (duplicate && isTypeArray && isValueArray) { o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : (Array.isArray(o[key][0]) ? o[key] : [o[key]]).concat([value]); } else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) { o[key] = value; } else { o[key] = o[key].concat([value]); } } else if (o[key] === undefined && isTypeArray) { o[key] = isValueArray ? value : [value]; } else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.counts) || checkAllAliases(key, flags.bools))) { o[key] = [o[key], value]; } else { o[key] = value; } } // extend the aliases list with inferred aliases. function extendAliases(...args) { args.forEach(function (obj) { Object.keys(obj || {}).forEach(function (key) { // short-circuit if we've already added a key // to the aliases array, for example it might // exist in both 'opts.default' and 'opts.key'. if (flags.aliases[key]) return; flags.aliases[key] = [].concat(aliases[key] || []); // For "--option-name", also set argv.optionName flags.aliases[key].concat(key).forEach(function (x) { if (/-/.test(x) && configuration['camel-case-expansion']) { const c = camelCase(x); if (c !== key && flags.aliases[key].indexOf(c) === -1) { flags.aliases[key].push(c); newAliases[c] = true; } } }); // For "--optionName", also set argv['option-name'] flags.aliases[key].concat(key).forEach(function (x) { if (x.length > 1 && /[A-Z]/.test(x) && configuration['camel-case-expansion']) { const c = decamelize(x, '-'); if (c !== key && flags.aliases[key].indexOf(c) === -1) { flags.aliases[key].push(c); newAliases[c] = true; } } }); flags.aliases[key].forEach(function (x) { flags.aliases[x] = [key].concat(flags.aliases[key].filter(function (y) { return x !== y; })); }); }); }); } function checkAllAliases(key, flag) { const toCheck = [].concat(flags.aliases[key] || [], key); const keys = Object.keys(flag); const setAlias = toCheck.find(key => keys.includes(key)); return setAlias ? flag[setAlias] : false; } function hasAnyFlag(key) { const flagsKeys = Object.keys(flags); const toCheck = [].concat(flagsKeys.map(k => flags[k])); return toCheck.some(function (flag) { return Array.isArray(flag) ? flag.includes(key) : flag[key]; }); } function hasFlagsMatching(arg, ...patterns) { const toCheck = [].concat(...patterns); return toCheck.some(function (pattern) { const match = arg.match(pattern); return match && hasAnyFlag(match[1]); }); } // based on a simplified version of the short flag group parsing logic function hasAllShortFlags(arg) { // if this is a negative number, or doesn't start with a single hyphen, it's not a short flag group if (arg.match(negative) || !arg.match(/^-[^-]+/)) { return false; } let hasAllFlags = true; let next; const letters = arg.slice(1).split(''); for (let j = 0; j < letters.length; j++) { next = arg.slice(j + 2); if (!hasAnyFlag(letters[j])) { hasAllFlags = false; break; } if ((letters[j + 1] && letters[j + 1] === '=') || next === '-' || (/[A-Za-z]/.test(letters[j]) && /^-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) || (letters[j + 1] && letters[j + 1].match(/\W/))) { break; } } return hasAllFlags; } function isUnknownOptionAsArg(arg) { return configuration['unknown-options-as-args'] && isUnknownOption(arg); } function isUnknownOption(arg) { arg = arg.replace(/^-{3,}/, '--'); // ignore negative numbers if (arg.match(negative)) { return false; } // if this is a short option group and all of them are configured, it isn't unknown if (hasAllShortFlags(arg)) { return false; } // e.g. '--count=2' const flagWithEquals = /^-+([^=]+?)=[\s\S]*$/; // e.g. '-a' or '--arg' const normalFlag = /^-+([^=]+?)$/; // e.g. '-a-' const flagEndingInHyphen = /^-+([^=]+?)-$/; // e.g. '-abc123' const flagEndingInDigits = /^-+([^=]+?\d+)$/; // e.g. '-a/usr/local' const flagEndingInNonWordCharacters = /^-+([^=]+?)\W+.*$/; // check the different types of flag styles, including negatedBoolean, a pattern defined near the start of the parse method return !hasFlagsMatching(arg, flagWithEquals, negatedBoolean, normalFlag, flagEndingInHyphen, flagEndingInDigits, flagEndingInNonWordCharacters); } // make a best effort to pick a default value // for an option based on name and type. function defaultValue(key) { if (!checkAllAliases(key, flags.bools) && !checkAllAliases(key, flags.counts) && `${key}` in defaults) { return defaults[key]; } else { return defaultForType(guessType(key)); } } // return a default value, given the type of a flag., function defaultForType(type) { const def = { [DefaultValuesForTypeKey.BOOLEAN]: true, [DefaultValuesForTypeKey.STRING]: '', [DefaultValuesForTypeKey.NUMBER]: undefined, [DefaultValuesForTypeKey.ARRAY]: [] }; return def[type]; } // given a flag, enforce a default type. function guessType(key) { let type = DefaultValuesForTypeKey.BOOLEAN; if (checkAllAliases(key, flags.strings)) type = DefaultValuesForTypeKey.STRING; else if (checkAllAliases(key, flags.numbers)) type = DefaultValuesForTypeKey.NUMBER; else if (checkAllAliases(key, flags.bools)) type = DefaultValuesForTypeKey.BOOLEAN; else if (checkAllAliases(key, flags.arrays)) type = DefaultValuesForTypeKey.ARRAY; return type; } function isUndefined(num) { return num === undefined; } // check user configuration settings for inconsistencies function checkConfiguration() { // count keys should not be set as array/narg Object.keys(flags.counts).find(key => { if (checkAllAliases(key, flags.arrays)) { error = Error(__('Invalid configuration: %s, opts.count excludes opts.array.', key)); return true; } else if (checkAllAliases(key, flags.nargs)) { error = Error(__('Invalid configuration: %s, opts.count excludes opts.narg.', key)); return true; } return false; }); } return { aliases: Object.assign({}, flags.aliases), argv: Object.assign(argvReturn, argv), configuration: configuration, defaulted: Object.assign({}, defaulted), error: error, newAliases: Object.assign({}, newAliases) }; } } // if any aliases reference each other, we should // merge them together. function combineAliases(aliases) { const aliasArrays = []; const combined = Object.create(null); let change = true; // turn alias lookup hash {key: ['alias1', 'alias2']} into // a simple array ['key', 'alias1', 'alias2'] Object.keys(aliases).forEach(function (key) { aliasArrays.push([].concat(aliases[key], key)); }); // combine arrays until zero changes are // made in an iteration. while (change) { change = false; for (let i = 0; i < aliasArrays.length; i++) { for (let ii = i + 1; ii < aliasArrays.length; ii++) { const intersect = aliasArrays[i].filter(function (v) { return aliasArrays[ii].indexOf(v) !== -1; }); if (intersect.length) { aliasArrays[i] = aliasArrays[i].concat(aliasArrays[ii]); aliasArrays.splice(ii, 1); change = true; break; } } } } // map arrays back to the hash-lookup (de-dupe while // we're at it). aliasArrays.forEach(function (aliasArray) { aliasArray = aliasArray.filter(function (v, i, self) { return self.indexOf(v) === i; }); const lastAlias = aliasArray.pop(); if (lastAlias !== undefined && typeof lastAlias === 'string') { combined[lastAlias] = aliasArray; } }); return combined; } // this function should only be called when a count is given as an arg // it is NOT called to set a default value // thus we can start the count at 1 instead of 0 function increment(orig) { return orig !== undefined ? orig + 1 : 1; } // TODO(bcoe): in the next major version of yargs, switch to // Object.create(null) for dot notation: function sanitizeKey(key) { if (key === '__proto__') return '___proto___'; return key; } package.json 0000644 00000004531 15120070333 0007027 0 ustar 00 { "name": "yargs-parser", "version": "20.2.9", "description": "the mighty option parser used by yargs", "main": "build/index.cjs", "exports": { ".": [ { "import": "./build/lib/index.js", "require": "./build/index.cjs" }, "./build/index.cjs" ] }, "type": "module", "module": "./build/lib/index.js", "scripts": { "check": "standardx '**/*.ts' && standardx '**/*.js' && standardx '**/*.cjs'", "fix": "standardx --fix '**/*.ts' && standardx --fix '**/*.js' && standardx --fix '**/*.cjs'", "pretest": "rimraf build && tsc -p tsconfig.test.json && cross-env NODE_ENV=test npm run build:cjs", "test": "c8 --reporter=text --reporter=html mocha test/*.cjs", "test:browser": "start-server-and-test 'serve ./ -p 8080' http://127.0.0.1:8080/package.json 'node ./test/browser/yargs-test.cjs'", "pretest:typescript": "npm run pretest", "test:typescript": "c8 mocha ./build/test/typescript/*.js", "coverage": "c8 report --check-coverage", "precompile": "rimraf build", "compile": "tsc", "postcompile": "npm run build:cjs", "build:cjs": "rollup -c", "prepare": "npm run compile" }, "repository": { "type": "git", "url": "https://github.com/yargs/yargs-parser.git" }, "keywords": [ "argument", "parser", "yargs", "command", "cli", "parsing", "option", "args", "argument" ], "author": "Ben Coe <ben@npmjs.com>", "license": "ISC", "devDependencies": { "@types/chai": "^4.2.11", "@types/mocha": "^8.0.0", "@types/node": "^14.0.0", "@typescript-eslint/eslint-plugin": "^3.10.1", "@typescript-eslint/parser": "^3.10.1", "@wessberg/rollup-plugin-ts": "^1.2.28", "c8": "^7.3.0", "chai": "^4.2.0", "cross-env": "^7.0.2", "eslint": "^7.0.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-node": "^11.0.0", "gts": "^3.0.0", "mocha": "^9.0.0", "puppeteer": "^10.0.0", "rimraf": "^3.0.2", "rollup": "^2.22.1", "rollup-plugin-cleanup": "^3.1.1", "serve": "^12.0.0", "standardx": "^7.0.0", "start-server-and-test": "^1.11.2", "ts-transform-default-export": "^1.0.2", "typescript": "^4.0.0" }, "files": [ "browser.js", "build", "!*.d.ts" ], "engines": { "node": ">=10" }, "standardx": { "ignore": [ "build" ] } }
Coded With 💗 by
0x6ick