diff --git a/.documentup.json b/.documentup.json deleted file mode 100644 index 57fe30116..000000000 --- a/.documentup.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "ShellJS", - "twitter": [ - "r2r" - ] -} diff --git a/.editorconfig b/.editorconfig index a35cd0dca..afe97de28 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,5 +10,8 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true +[*.js] +quote_type = single + [*.{md,markdown}] trim_trailing_whitespace = false diff --git a/.eslintrc.json b/.eslintrc.json index d3759e0b2..4f40d77b8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,13 +2,16 @@ "env": { "node": true }, - "extends": "airbnb-base/legacy", + "extends": "airbnb-base", "rules": { "comma-dangle": ["error", "always-multiline"], "consistent-return": "off", "curly": ["error", "multi-line"], "func-names": "off", + "function-call-argument-newline": "off", + "function-paren-newline": "off", "global-require": "off", + "import/no-unresolved": "off", "indent": "off", "max-len": "off", "newline-per-chained-call": "off", @@ -26,9 +29,18 @@ "no-throw-literal": "off", "no-underscore-dangle": "off", "no-use-before-define": "off", + "no-var": "off", "operator-linebreak": "off", + "prefer-arrow-callback": "off", + "prefer-destructuring": "off", + "prefer-numeric-literals": "off", + "prefer-object-spread": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "prefer-template": "off", "quote-props": "off", "spaced-comment": ["error", "always", { "markers": ["@", "@include"], "exceptions": ["@", "@commands"] }], + "strict": "off", "vars-on-top": "off", "new-cap": ["error", { "capIsNewExceptions": [ diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 000000000..4c96dd513 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,31 @@ +# ShellJS Security Policy + +Thank you for reaching out regarding the security of the ShellJS module! Please +note that this project is maintained on a best-effort basis, however I still +intend to prioritize reviewing and addressing security issues. + +## Supported Versions + +I generally only support the latest ShellJS release (see +https://www.npmjs.com/package/shelljs). My goal is to release security fixes as +patch releases on top of whatever was most recently shipped. + +If breaking changes have already landed on the main development branch, I may +apply the patch on the relevant release branch (ex. +[`0.8-release`](https://github.com/shelljs/shelljs/commits/0.8-release)) and +create a new release from there. + +## Reporting a Vulnerability + +Please report security vulnerabilities to ntfschr@gmail.com. I should respond +within a few days. Although it's not strictly required, it helps me out if you +can include any proof of concept exploit code, suggested fix, etc. + +**Please do not publicly disclose the suspected vulnerability** until I have a +chance to review your report. I'd like a chance to patch the code before the +issue is known to the public. + +Please **only** use this email for security issues. It's also OK to use the +email if you're legitimately unsure if this is a security issue (better safe +than sorry). But for all other non-security issues, please use the GitHub issue +tracker. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..6c207c2bb --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,36 @@ +name: CI +on: + - push + - pull_request +jobs: + test: + name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + node-version: + - 18 + - 20 + - 22 + - 24 + - 26 + os: + - ubuntu-latest + - macos-latest + - windows-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - name: test with coverage + run: npm run test-with-coverage + - run: npm run lint + - run: npm run check-node-support + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v7 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 2be0a0afb..000000000 --- a/.npmrc +++ /dev/null @@ -1,3 +0,0 @@ -# We can't use lockfiles because npm@5 and npm@6 disagree about the syntax (and -# will modify the lockfile when we run `npm install`). -package-lock=false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ea1731437..000000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: node_js -sudo: false -node_js: - - 6 - - 7 - - 8 - - 9 - - 10 - - 11 - - 12 - - 13 - -os: - - linux - - osx -script: - - npm run test-with-coverage - - npm run lint - # make sure when the docs are generated nothing changes (a.k.a. the docs have already been generated) - - npm run gendocs - - npm run check-node-support - - npm run after-travis "Make sure to generate docs!" -after_success: - - npm run codecov -- -f coverage/lcov.info - -notifications: - email: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 3afb73026..c30d70896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,14 @@ # Change Log -## [Unreleased](https://github.com/shelljs/shelljs/tree/HEAD) +## [v0.8.5](https://github.com/shelljs/shelljs/tree/v0.8.5) (2022-01-13) +[Full Changelog](https://github.com/shelljs/shelljs/compare/v0.8.4...v0.8.5) -[Full Changelog](https://github.com/shelljs/shelljs/compare/v0.8.3...HEAD) +This was a small security fix for [\#1058](https://github.com/shelljs/shelljs/issues/1058). -**Closed issues:** - -- find returns empty array even though directory has files [\#922](https://github.com/shelljs/shelljs/issues/922) -- exec\(\) should support node v10 \(maxbuffer change\) [\#915](https://github.com/shelljs/shelljs/issues/915) -- grep exit status and extra newlines [\#900](https://github.com/shelljs/shelljs/issues/900) -- Travis CI currently broken [\#893](https://github.com/shelljs/shelljs/issues/893) -- Drop node v4 support [\#873](https://github.com/shelljs/shelljs/issues/873) -- cp -Ru respects the -R but not the -u [\#808](https://github.com/shelljs/shelljs/issues/808) - -**Merged pull requests:** +## [v0.8.4](https://github.com/shelljs/shelljs/tree/v0.8.4) (2020-04-24) +[Full Changelog](https://github.com/shelljs/shelljs/compare/v0.8.3...v0.8.4) -- feat\(options\): initial support for long options [\#926](https://github.com/shelljs/shelljs/pull/926) ([nfischer](https://github.com/nfischer)) -- test\(touch\): add coverage for -d option [\#925](https://github.com/shelljs/shelljs/pull/925) ([nfischer](https://github.com/nfischer)) -- chore\(node\): add v10 and v11 to CI [\#921](https://github.com/shelljs/shelljs/pull/921) ([nfischer](https://github.com/nfischer)) -- chore\(test\): no coverage by default [\#920](https://github.com/shelljs/shelljs/pull/920) ([nfischer](https://github.com/nfischer)) -- fix\(exec\): consistent error message for maxBuffer [\#919](https://github.com/shelljs/shelljs/pull/919) ([nfischer](https://github.com/nfischer)) -- chore\(node\): drop node v4 and v5 [\#917](https://github.com/shelljs/shelljs/pull/917) ([nfischer](https://github.com/nfischer)) -- chore: script to bump supported node versions [\#913](https://github.com/shelljs/shelljs/pull/913) ([nfischer](https://github.com/nfischer)) -- chore\(npm\): remove lockfile [\#911](https://github.com/shelljs/shelljs/pull/911) ([nfischer](https://github.com/nfischer)) -- ci: change language to node\_js and remove obsolete scripts [\#910](https://github.com/shelljs/shelljs/pull/910) ([DanielRuf](https://github.com/DanielRuf)) -- chore: remove gitter integration [\#907](https://github.com/shelljs/shelljs/pull/907) ([nfischer](https://github.com/nfischer)) -- fix: Exit 1 with empty string if no match [\#901](https://github.com/shelljs/shelljs/pull/901) ([wyardley](https://github.com/wyardley)) -- feat\(cp\): support update flag when recursing [\#889](https://github.com/shelljs/shelljs/pull/889) ([joshi-sh](https://github.com/joshi-sh)) +Small patch release to fix a circular dependency warning in node v14. See [\#973](https://github.com/shelljs/shelljs/issues/973). ## [v0.8.3](https://github.com/shelljs/shelljs/tree/v0.8.3) (2018-11-13) [Full Changelog](https://github.com/shelljs/shelljs/compare/v0.8.2...v0.8.3) @@ -966,4 +948,4 @@ ## [v0.0.2pre1](https://github.com/shelljs/shelljs/tree/v0.0.2pre1) (2012-03-03) -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a6b32ba32..1559b4d77 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,9 +15,8 @@ stable). If you've found a bug, please follow these steps: PRs are welcome! However, we ask that you follow a few guidelines: - Please add tests for all changes/new features. - - Make sure your code passes `npm test`. Please check the CI (both Appveyor and - Travis). If you can't figure out why something doesn't work, feel free to ask - for help. + - Make sure your code passes `npm test`. Please check the CI. If you can't + figure out why something doesn't work, feel free to ask for help. - Make sure you conform to our style guidelines. You can run `npm run lint` to check style, and `npm run lint -- --fix` to automatically fix some issues. - Make documentation changes *within the source files*, not in the README. diff --git a/LICENSE b/LICENSE index 0f0f119be..40a2bf650 100644 --- a/LICENSE +++ b/LICENSE @@ -1,26 +1,29 @@ +BSD 3-Clause License + Copyright (c) 2012, Artur Adib All rights reserved. -You may use this project under the terms of the New BSD license as follows: - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Artur Adib nor the - names of the contributors may be used to endorse or promote products - derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 6bb7c3fff..a0de67655 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # ShellJS - Unix shell commands for Node.js -[![Travis](https://img.shields.io/travis/shelljs/shelljs/master.svg?style=flat-square&label=unix)](https://travis-ci.org/shelljs/shelljs) -[![AppVeyor](https://img.shields.io/appveyor/ci/shelljs/shelljs/master.svg?style=flat-square&label=windows)](https://ci.appveyor.com/project/shelljs/shelljs/branch/master) -[![Codecov](https://img.shields.io/codecov/c/github/shelljs/shelljs/master.svg?style=flat-square&label=coverage)](https://codecov.io/gh/shelljs/shelljs) +[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/shelljs/shelljs/main.yml?style=flat-square&logo=github)](https://github.com/shelljs/shelljs/actions/workflows/main.yml) +[![Codecov](https://img.shields.io/codecov/c/github/shelljs/shelljs/main.svg?style=flat-square&label=coverage)](https://codecov.io/gh/shelljs/shelljs) [![npm version](https://img.shields.io/npm/v/shelljs.svg?style=flat-square)](https://www.npmjs.com/package/shelljs) [![npm downloads](https://img.shields.io/npm/dm/shelljs.svg?style=flat-square)](https://www.npmjs.com/package/shelljs) @@ -12,9 +11,9 @@ script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts! -ShellJS is proudly tested on every node release since `v6`! +ShellJS is proudly tested on every LTS node release since `v18`! -The project is [unit-tested](http://travis-ci.org/shelljs/shelljs) and battle-tested in projects like: +The project is unit-tested and battle-tested in projects like: + [Firebug](http://getfirebug.com/) - Firefox's infamous debugger + [JSHint](http://jshint.com) & [ESLint](http://eslint.org/) - popular JavaScript linters @@ -58,8 +57,7 @@ wiki](https://github.com/shelljs/shelljs/wiki/Using-ShellJS-Plugins). For documentation on all the latest features, check out our [README](https://github.com/shelljs/shelljs). To read docs that are consistent with the latest release, check out [the npm -page](https://www.npmjs.com/package/shelljs) or -[shelljs.org](http://documentup.com/shelljs/shelljs). +page](https://www.npmjs.com/package/shelljs). ## Installing @@ -122,6 +120,13 @@ var shell = require('shelljs'); shell.echo('hello world'); ``` +Alternatively, we also support importing as a module with: + +```javascript +import shell from 'shelljs'; +shell.echo('hello world'); +``` + @@ -130,7 +135,7 @@ shell.echo('hello world'); All commands run synchronously, unless otherwise stated. All commands accept standard bash globbing characters (`*`, `?`, etc.), -compatible with the [node `glob` module](https://github.com/isaacs/node-glob). +compatible with [`fast-glob`](https://www.npmjs.com/package/fast-glob). For less-commonly used commands and features, please check out our [wiki page](https://github.com/shelljs/shelljs/wiki). @@ -189,10 +194,49 @@ Notable exceptions: + In symbolic modes, `a-r` and `-r` are identical. No consideration is given to the `umask`. + There is no "quiet" option, since default behavior is to run silent. ++ Windows OS uses a very different permission model than POSIX. `chmod()` + does its best on Windows, but there are limits to how file permissions can + be set. Note that WSL (Windows subsystem for Linux) **does** follow POSIX, + so cross-platform compatibility should not be a concern there. Returns a [ShellString](#shellstringstr) indicating success or failure. +### cmd(arg1[, arg2, ...] [, options]) + +Available options: + ++ `cwd: directoryPath`: change the current working directory only for this + cmd() invocation. ++ `maxBuffer: num`: Raise or decrease the default buffer size for + stdout/stderr. ++ `timeout`: Change the default timeout. + +Examples: + +```javascript +var version = cmd('node', '--version').stdout; +cmd('git', 'commit', '-am', `Add suport for node ${version}`); +console.log(cmd('echo', '1st arg', '2nd arg', '3rd arg').stdout) +console.log(cmd('echo', 'this handles ;, |, &, etc. as literal characters').stdout) +``` + +Executes the given command synchronously. This is intended as an easier +alternative for [exec()](#execcommand--options--callback), with better +security around globbing, comamnd injection, and variable expansion. This is +guaranteed to only run one external command, and won't give special +treatment for any shell characters (ex. this treats `|` as a literal +character, not as a shell pipeline). +This returns a [ShellString](#shellstringstr). + +By default, this performs globbing on all platforms, but you can disable +this with `set('-f')`. + +This **does not** support asynchronous mode. If you need asynchronous +command execution, check out [execa](https://www.npmjs.com/package/execa) or +the node builtin `child_process.execFile()` instead. + + ### cp([options,] source [, source ...], dest) ### cp([options,] source_array, dest) @@ -204,6 +248,7 @@ Available options: + `-r`, `-R`: recursive + `-L`: follow symlinks + `-P`: don't follow symlinks ++ `-p`: preserve file mode, ownership, and timestamps Examples: @@ -247,7 +292,7 @@ Save the current directory on the top of the directory stack and then `cd` to `d Available options: + `-n`: Suppress the normal directory change when removing directories from the stack, so that only the stack is manipulated. -+ `-q`: Supresses output to the console. ++ `-q`: Suppresses output to the console. Arguments: @@ -272,7 +317,7 @@ When no arguments are given, `popd` removes the top directory from the stack and Available options: + `-c`: Clears the directory stack by deleting all of the elements. -+ `-q`: Supresses output to the console. ++ `-q`: Suppresses output to the console. Arguments: @@ -373,12 +418,19 @@ Available options: + `-v`: Invert `regex_filter` (only print non-matching lines). + `-l`: Print only filenames of matching files. + `-i`: Ignore case. ++ `-n`: Print line numbers. ++ `-B `: Show `` lines before each result. ++ `-A `: Show `` lines after each result. ++ `-C `: Show `` lines before and after each result. -B and -A override this option. Examples: ```javascript grep('-v', 'GLOBAL_VARIABLE', '*.js'); grep('GLOBAL_VARIABLE', '*.js'); +grep('-B', 3, 'GLOBAL_VARIABLE', '*.js'); +grep({ '-B': 3 }, 'GLOBAL_VARIABLE', '*.js'); +grep({ '-B': 3, '-C': 2 }, 'GLOBAL_VARIABLE', '*.js'); ``` Reads input string from given files and returns a @@ -432,15 +484,20 @@ Available options: + `-A`: all files (include files beginning with `.`, except for `.` and `..`) + `-L`: follow symlinks + `-d`: list directories themselves, not their contents -+ `-l`: list objects representing each file, each with fields containing `ls - -l` output fields. See - [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) - for more info ++ `-l`: provides more details for each file. Specifically, each file is + represented by a structured object with separate fields for file + metadata (see + [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)). The + return value also overrides `.toString()` to resemble `ls -l`'s + output format for human readability, but programmatic usage should + depend on the stable object format rather than the `.toString()` + representation. Examples: ```javascript ls('projs/*.js'); +ls('projs/**/*.js'); // Find all js files recursively in projs ls('-R', '/users/me', '/tmp'); ls('-R', ['/users/me', '/tmp']); // same as above ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...} @@ -541,7 +598,7 @@ sed(/(\w+)\s(\w+)/, '$2, $1', 'file.txt'); ``` Also, like unix `sed`, ShellJS `sed` runs replacements on each line from the input file -(split by '\n') separately, so `search_regex`es that span more than one line (or inlclude '\n') +(split by '\n') separately, so `search_regex`es that span more than one line (or include '\n') will not match anything and nothing will be replaced. @@ -630,7 +687,7 @@ Examples: ```javascript if (test('-d', path)) { /* do something with dir */ }; -if (!test('-f', path)) continue; // skip if it's a regular file +if (!test('-f', path)) continue; // skip if it's not a regular file ``` Evaluates `expression` using the available primaries and returns @@ -672,10 +729,10 @@ Available options: + `-a`: Change only the access time + `-c`: Do not create any files + `-m`: Change only the modification time -+ `{'-d': someDate}`, `{date: someDate}`: Use `someDate` (instance of - `Date`) instead of current time ++ `{'-d': someDate}`, `{date: someDate}`: Use a `Date` instance (ex. `someDate`) + instead of current time + `{'-r': file}`, `{reference: file}`: Use `file`'s times instead of current - time + time Examples: @@ -683,6 +740,7 @@ Examples: touch('source.js'); touch('-c', 'path/to/file.js'); touch({ '-r': 'referenceFile.txt' }, 'path/to/file.js'); +touch({ '-d': new Date('December 17, 1995 03:24:00'), '-m': true }, 'path/to/file.js'); touch({ date: new Date('December 17, 1995 03:24:00') }, 'path/to/file.js'); ``` @@ -741,6 +799,11 @@ return value to be an error message. If you need the last error message, use the `.stderr` attribute from the last command's return value instead. +### errorCode() + +Returns the error code from the last command. + + ### ShellString(str) Examples: @@ -772,7 +835,7 @@ Examples: ```javascript grep('foo', 'file1.txt', 'file2.txt').sed(/o/g, 'a').to('output.txt'); -echo('files with o\'s in the name:\n' + ls().grep('o')); +echo("files with o's in the name:\n" + ls().grep('o')); cat('test.js').exec('node'); // pipe to exec() call ``` @@ -832,7 +895,14 @@ rm -rf foo.txt bar.txt exec echo hello ``` -### config.globOptions +### config.globOptions (deprecated) + +**Deprecated**: we recommend that you do not edit `config.globOptions`. +Support for this configuration option may be changed or removed in a future +ShellJS release. + +**Breaking change**: ShellJS v0.8.x uses `node-glob`. Starting with ShellJS +v0.9.x, `config.globOptions` is compatible with `fast-glob`. Example: @@ -840,7 +910,11 @@ Example: config.globOptions = {nodir: true}; ``` -Use this value for calls to `glob.sync()` instead of the default options. +`config.globOptions` changes how ShellJS expands glob (wildcard) +expressions. See +[fast-glob](https://github.com/mrmlnc/fast-glob?tab=readme-ov-file#options-3) +for available options. Be aware that modifying `config.globOptions` **may +break ShellJS functionality.** ### config.reset() @@ -870,6 +944,6 @@ Reset `shell.config` to the defaults: ## Team -| [![Nate Fischer](https://avatars.githubusercontent.com/u/5801521?s=130)](https://github.com/nfischer) | [![Brandon Freitag](https://avatars1.githubusercontent.com/u/5988055?v=3&s=130)](http://github.com/freitagbr) | -|:---:|:---:| -| [Nate Fischer](https://github.com/nfischer) | [Brandon Freitag](http://github.com/freitagbr) | +| [![Nate Fischer](https://avatars.githubusercontent.com/u/5801521?s=130)](https://github.com/nfischer) | +|:---:| +| [Nate Fischer](https://github.com/nfischer) | diff --git a/RELEASE.md b/RELEASE.md index 80aae7f7b..751cad391 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,6 +1,6 @@ # Release steps -1. Ensure master passes CI tests +1. Ensure main branch passes CI tests 2. Bump version, create tags, push, and release: - `$ npm run ` - `major` - breaking API changes @@ -10,5 +10,5 @@ - `$ npm run changelog` - Manually verify that the changelog makes sense - `$ git push` -4. Generate the documentup website by visiting - http://documentup.com/shelljs/shelljs/__recompile in your browser +4. Update https://github.com/shelljs/shelljs/releases to create a new release + from the latest git tag diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index da92cbf2b..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,33 +0,0 @@ -environment: - matrix: - - nodejs_version: '13' - - nodejs_version: '12' - - nodejs_version: '11' - - nodejs_version: '10' - - nodejs_version: '9' - - nodejs_version: '8' - - nodejs_version: '7' - - nodejs_version: '6' - -version: '{build}' - -# Install scripts. (runs after repo cloning) -install: - - ps: Install-Product node $env:nodejs_version - - set PATH=%APPDATA%\npm;%PATH% - - node --version - - npm --version - - npm install - -matrix: - fast_finish: false - -# No need for MSBuild on this project -build: off - -test_script: - - npm run test-with-coverage - - npm run lint - -on_success: - - npm run codecov -- -f coverage/lcov.info diff --git a/bin/shjs b/bin/shjs deleted file mode 100755 index c4609f7af..000000000 --- a/bin/shjs +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env node - -if (require.main !== module) { - throw new Error('Executable-only module should not be required'); -} - -// we must import global ShellJS methods after the require.main check to prevent the global -// namespace from being polluted if the error is caught -require('../global'); - -function exitWithErrorMessage(msg) { - console.log(msg); - console.log(); - process.exit(1); -} - -if (process.argv.length < 3) { - exitWithErrorMessage('ShellJS: missing argument (script name)'); -} - -var args, - scriptName = process.argv[2]; -env['NODE_PATH'] = __dirname + '/../..'; - -if (!scriptName.match(/\.js/) && !scriptName.match(/\.coffee/)) { - if (test('-f', scriptName + '.js')) - scriptName += '.js'; - if (test('-f', scriptName + '.coffee')) - scriptName += '.coffee'; -} - -if (!test('-f', scriptName)) { - exitWithErrorMessage('ShellJS: script not found ('+scriptName+')'); -} - -args = process.argv.slice(3); - -for (var i = 0, l = args.length; i < l; i++) { - if (args[i][0] !== "-"){ - args[i] = '"' + args[i] + '"'; // fixes arguments with multiple words - } -} - -var path = require('path'); -var extensions = require('interpret').extensions; -var rechoir = require('rechoir'); -rechoir.prepare(extensions, scriptName); -require(require.resolve(path.resolve(process.cwd(), scriptName))); diff --git a/commands.js b/commands.js deleted file mode 100644 index 884ff8ea4..000000000 --- a/commands.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = [ - 'cat', - 'cd', - 'chmod', - // TODO(nfischer): uncomment this when shell.cmd() is finished. - // 'cmd', - 'cp', - 'dirs', - 'echo', - 'exec', - 'find', - 'grep', - 'head', - 'ln', - 'ls', - 'mkdir', - 'mv', - 'pwd', - 'rm', - 'sed', - 'set', - 'sort', - 'tail', - 'tempdir', - 'test', - 'to', - 'toEnd', - 'touch', - 'uniq', - 'which', -]; diff --git a/global.js b/global.js index b232e66d5..e061f5a1e 100644 --- a/global.js +++ b/global.js @@ -1,12 +1,15 @@ /* eslint no-extend-native: 0 */ -var shell = require('./shell.js'); +var shell = require('./shell'); var common = require('./src/common'); + Object.keys(shell).forEach(function (cmd) { global[cmd] = shell[cmd]; }); var _to = require('./src/to'); + String.prototype.to = common.wrap('to', _to); var _toEnd = require('./src/toEnd'); + String.prototype.toEnd = common.wrap('toEnd', _toEnd); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..cdaeeed0a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6431 @@ +{ + "name": "shelljs", + "version": "0.10.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "shelljs", + "version": "0.10.0", + "license": "BSD-3-Clause", + "dependencies": { + "execa": "^5.1.1", + "fast-glob": "^3.3.2" + }, + "devDependencies": { + "ava": "^6.2.0", + "chalk": "^4.1.2", + "coffee-script": "^1.12.7", + "eslint": "^8.2.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.31.0", + "js-yaml": "^4.1.0", + "nyc": "^17.1.0", + "shelljs-changelog": "^0.2.6", + "shelljs-release": "^0.5.3", + "shx": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.27.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", + "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", + "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", + "dev": true, + "dependencies": { + "consola": "^3.2.3", + "detect-libc": "^2.0.0", + "https-proxy-agent": "^7.0.5", + "node-fetch": "^2.6.7", + "nopt": "^8.0.0", + "semver": "^7.5.3", + "tar": "^7.4.0" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true + }, + "node_modules/@vercel/nft": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.10.tgz", + "integrity": "sha512-zbaF9Wp/NsZtKLE4uVmL3FyfFwlpDyuymQM1kPbeT0mVOHKDQQNjnnfslB3REg3oZprmNFJuh3pkHBk2qAaizg==", + "dev": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^2.0.0-rc.0", + "@rollup/pluginutils": "^5.1.3", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.5", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "node-gyp-build": "^4.2.2", + "picomatch": "^4.0.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/abbrev": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", + "dev": true, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", + "dev": true + }, + "node_modules/ava": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-6.2.0.tgz", + "integrity": "sha512-+GZk5PbyepjiO/68hzCZCUepQOQauKfNnI7sA4JukBTg97jD7E+tDKEA7OhGOGr6EorNNMM9+jqvgHVOTOzG4w==", + "dev": true, + "dependencies": { + "@vercel/nft": "^0.27.5", + "acorn": "^8.13.0", + "acorn-walk": "^8.3.4", + "ansi-styles": "^6.2.1", + "arrgv": "^1.0.2", + "arrify": "^3.0.0", + "callsites": "^4.2.0", + "cbor": "^9.0.2", + "chalk": "^5.3.0", + "chunkd": "^2.0.1", + "ci-info": "^4.0.0", + "ci-parallel-vars": "^1.0.1", + "cli-truncate": "^4.0.0", + "code-excerpt": "^4.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.4", + "currently-unhandled": "^0.4.1", + "debug": "^4.3.7", + "emittery": "^1.0.3", + "figures": "^6.1.0", + "globby": "^14.0.2", + "ignore-by-default": "^2.1.0", + "indent-string": "^5.0.0", + "is-plain-object": "^5.0.0", + "is-promise": "^4.0.0", + "matcher": "^5.0.0", + "memoize": "^10.0.0", + "ms": "^2.1.3", + "p-map": "^7.0.2", + "package-config": "^5.0.0", + "picomatch": "^4.0.2", + "plur": "^5.1.0", + "pretty-ms": "^9.1.0", + "resolve-cwd": "^3.0.0", + "stack-utils": "^2.0.6", + "strip-ansi": "^7.1.0", + "supertap": "^3.0.1", + "temp-dir": "^3.0.0", + "write-file-atomic": "^6.0.0", + "yargs": "^17.7.2" + }, + "bin": { + "ava": "entrypoints/cli.mjs" + }, + "engines": { + "node": "^18.18 || ^20.8 || ^22 || >=23" + }, + "peerDependencies": { + "@ava/typescript": "*" + }, + "peerDependenciesMeta": { + "@ava/typescript": { + "optional": true + } + } + }, + "node_modules/ava/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/blueimp-md5": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", + "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz", + "integrity": "sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001715", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz", + "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, + "node_modules/ci-info": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/ci-parallel-vars": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "dev": true, + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "dev": true, + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concordance": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", + "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", + "dev": true, + "dependencies": { + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", + "well-known-symbols": "^2.0.0" + }, + "engines": { + "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "dependencies": { + "time-zone": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.144", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.144.tgz", + "integrity": "sha512-eJIaMRKeAzxfBSxtjYnoIAw/tdD6VIH6tHBZepZnAbE3Gyqqs5mGN87DvcldPUbVkIljTK8pY0CMcUljP64lfQ==", + "dev": true + }, + "node_modules/emittery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.1.0.tgz", + "integrity": "sha512-rsX7ktqARv/6UQDgMaLfIqUWAEzzbCQiVh7V9rhDXp6c37yoJcks12NVD+XPkgl4AEavmNhVfrhGoqYwIsMYYA==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-abstract": { + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", + "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", + "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", + "dev": true, + "engines": { + "node": ">=10 <11 || >=12 <13 || >=14" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/irregular-plurals": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", + "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/matcher": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", + "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/matcher/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "dependencies": { + "blueimp-md5": "^2.10.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/memoize": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/memoize/-/memoize-10.1.0.tgz", + "integrity": "sha512-MMbFhJzh4Jlg/poq1si90XRlTZRDHVqdlz2mPyGJ6kqMpyHUyVpDd5gpFAvVehW64+RA1eKE9Yt8aSLY7w2Kgg==", + "dev": true, + "dependencies": { + "mimic-function": "^5.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/memoize?sponsor=1" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nan": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.24.0.tgz", + "integrity": "sha512-Vpf9qnVW1RaDkoNKFUvfxqAbtI8ncb8OJlqZ9wwpXzWPEsvsB1nvdUi6oYrHIkQ1Y/tMDnr1h4nczS0VB9Xykg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", + "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^3.3.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^6.0.2", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nyc/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-config": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/package-config/-/package-config-5.0.0.tgz", + "integrity": "sha512-GYTTew2slBcYdvRHqjhwaaydVMvn/qrGC323+nKclYioNSLTDUM/lGgtGTgyHVtYcozb+XkE8CNhwcraOmZ9Mg==", + "dev": true, + "dependencies": { + "find-up-simple": "^1.0.0", + "load-json-file": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module/node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/plur": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", + "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.3.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dev": true, + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-on-spawn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz", + "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs-changelog": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/shelljs-changelog/-/shelljs-changelog-0.2.6.tgz", + "integrity": "sha512-+jghG+Cdksxc4bHyzQzSjWC+ULcUWX9SVzKBE8J6ShIb1yKAS2m10GNrqNquLS9uqSlGrRZPAyIXLxfrmmd+BA==", + "dev": true, + "dependencies": { + "shelljs": "^0.8.5", + "shelljs-plugin-sleep": "^0.2.1" + }, + "bin": { + "shelljs-changelog": "index.js" + } + }, + "node_modules/shelljs-plugin-sleep": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/shelljs-plugin-sleep/-/shelljs-plugin-sleep-0.2.2.tgz", + "integrity": "sha512-w4yozqtrxfqeybp1lrAPmcb4+RfLfkNtHqLMOGvIXuWxNcqDdttREX+DhXy3F8Xfp5ll+/WQLLEgJbH7RCHqWQ==", + "dev": true, + "engines": { + "node": ">=4.0.0" + }, + "optionalDependencies": { + "sleep": "^3.0.1" + }, + "peerDependencies": { + "shelljs": "^0.8.5" + } + }, + "node_modules/shelljs-release": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/shelljs-release/-/shelljs-release-0.5.3.tgz", + "integrity": "sha512-9L15opORTyWZSn7eIm+rmdo4hwgwf99bXqIAPS572KdX9KjqBcdex7FvOrCI8YxaAxosYfS73rVeJ22SkWIxGA==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "minimist": "^1.2.0", + "shelljs": "^0.8.5" + }, + "bin": { + "shelljs-release": "index.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs-release/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs-release/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs-release/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/shelljs-release/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/shelljs-release/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/shelljs-release/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs-release/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.4.0.tgz", + "integrity": "sha512-Z0KixSIlGPpijKgcH6oCMCbltPImvaKy0sGH8AkLRXw1KyzpKtaCTizP2xen+hNDqVF4xxgvA0KXSb9o4Q6hnA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.8", + "shelljs": "^0.9.2" + }, + "bin": { + "shx": "lib/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/shx/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/shx/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/shx/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/shx/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shx/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shx/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shx/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shx/node_modules/shelljs": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.9.2.tgz", + "integrity": "sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "fast-glob": "^3.3.2", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/shx/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sleep": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sleep/-/sleep-3.0.1.tgz", + "integrity": "sha512-dtegFdlKDk05SQzlA29LVj8gzf01bTvtSOHCt+JwYRXEmx3qp85OZ+MpB65IYwxTNylwSmq8mOcsa4MitU8PpQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "nan": ">=2.0.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supertap": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", + "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", + "dev": true, + "dependencies": { + "indent-string": "^5.0.0", + "js-yaml": "^3.14.1", + "serialize-error": "^7.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/supertap/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/supertap/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", + "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "dev": true, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz", + "integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 8ad2be672..243271d9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shelljs", - "version": "0.8.3", + "version": "0.10.0", "description": "Portable Unix shell commands for Node.js", "keywords": [ "shelljs", @@ -23,59 +23,66 @@ "license": "BSD-3-Clause", "homepage": "http://github.com/shelljs/shelljs", "main": "./shell.js", + "exports": { + ".": "./shell.js", + "./global": "./global.js", + "./global.js": "./global.js", + "./make": "./make.js", + "./make.js": "./make.js", + "./package": "./package.json", + "./package.json": "./package.json", + "./plugin": "./plugin.js", + "./plugin.js": "./plugin.js" + }, "files": [ - "commands.js", "global.js", "make.js", "plugin.js", "shell.js", - "bin", "src" ], "scripts": { "check-node-support": "node scripts/check-node-support", "posttest": "npm run lint", - "test": "ava test/*.js", - "test-with-coverage": "nyc --reporter=text --reporter=lcov ava test/*.js", + "test": "ava", + "test-with-coverage": "nyc --reporter=text --reporter=lcov ava", "gendocs": "node scripts/generate-docs", "lint": "eslint .", - "after-travis": "travis-check-changes", "changelog": "shelljs-changelog", - "codecov": "codecov", "release:major": "shelljs-release major", "release:minor": "shelljs-release minor", "release:patch": "shelljs-release patch" }, - "bin": { - "shjs": "./bin/shjs" - }, "dependencies": { - "execa": "^1.0.0", - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "execa": "^5.1.1", + "fast-glob": "^3.3.2" }, "ava": { "serial": true, - "powerAssert": false + "workerThreads": false, + "powerAssert": false, + "files": [ + "test/*.js" + ], + "helpers": [ + "test/resources/**", + "test/utils/**" + ] }, "devDependencies": { - "ava": "^1.4.1", - "chalk": "^1.1.3", - "codecov": "^3.0.2", - "coffee-script": "^1.10.0", - "eslint": "^5.16.0", - "eslint-config-airbnb-base": "^13.1.0", - "eslint-plugin-import": "^2.17.3", - "js-yaml": "^3.12.0", - "nyc": "^14.1.1", - "shelljs-changelog": "^0.2.0", - "shelljs-release": "^0.3.0", - "shx": "^0.2.0", - "travis-check-changes": "^0.2.0" + "ava": "^6.2.0", + "chalk": "^4.1.2", + "coffee-script": "^1.12.7", + "eslint": "^8.2.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.31.0", + "js-yaml": "^4.1.0", + "nyc": "^17.1.0", + "shelljs-changelog": "^0.2.6", + "shelljs-release": "^0.5.3", + "shx": "^0.4.0" }, - "optionalDependencies": {}, "engines": { - "node": ">=6" + "node": ">=18" } } diff --git a/plugin.js b/plugin.js index f879ab320..2e1585092 100644 --- a/plugin.js +++ b/plugin.js @@ -1,4 +1,4 @@ -// Various utilties exposed to plugins +// Various utilities exposed to plugins require('./shell'); // Create the ShellJS instance (mandatory) diff --git a/scripts/check-node-support.js b/scripts/check-node-support.js index af8eec8f4..df2065e17 100755 --- a/scripts/check-node-support.js +++ b/scripts/check-node-support.js @@ -3,33 +3,44 @@ var assert = require('assert'); var path = require('path'); +// eslint-disable-next-line import/no-extraneous-dependencies var yaml = require('js-yaml'); var shell = require('..'); // This is the authoritative list of supported node versions. -var MIN_NODE_VERSION = 6; -var MAX_NODE_VERSION = 13; +var MIN_NODE_VERSION = 18; +var MAX_NODE_VERSION = 26; + +// Ideally this map should be empty, however we can pin node releases to +// specific versions if necessary to workaround bugs. See +// https://github.com/shelljs/shelljs/issues/1180. +var pinnedNodeVersions = { + // Format: + // majorVersionInt: 'full.node.version', + // Example: + // 22: '22.9.0', +}; function checkReadme(minNodeVersion) { var start = ''; var stop = ''; var formattedMinVersion = '`v' + minNodeVersion + '`'; var expectedReadmeRegex = new RegExp( - start + '\\s*' + formattedMinVersion + '\\s*' + stop, '' + start + '\\s*' + formattedMinVersion + '\\s*' + stop, '', ); var readme = path.join(__dirname, '..', 'README.md'); var match = shell.grep(expectedReadmeRegex, readme); - if (!match.toString()) { + if (!match.toString().trim()) { var msg = 'Update README to specify the min supported version. Look for "' + start + '"'; throw new Error(msg); } } -function checkEngines(minNodeVersion, package) { +function checkEngines(minNodeVersion, packageJson) { var expectedEnginesNode = '>=' + minNodeVersion; - if (package.engines.node !== expectedEnginesNode) { + if (packageJson.engines.node !== expectedEnginesNode) { var msg = 'Update package.json to fix the "engines" attribute'; throw new Error(msg); } @@ -45,42 +56,38 @@ function assertDeepEquals(arr1, arr2, msg) { function range(start, stop) { var ret = []; - for (var i = start; i <= stop; i++) { + for (var i = start; i <= stop; i += 2) { + if (i % 2 !== 0) { + console.warn('Warning: testing a non-LTS nodejs release: ' + i); + } ret.push(i); } return ret; } -function checkTravis(minNodeVersion, maxNodeVersion, travisYaml) { - var expectedTravisVersions = range(minNodeVersion, maxNodeVersion); - var msg = 'Check Travis node_js versions'; - assertDeepEquals(travisYaml.node_js, expectedTravisVersions, msg); -} - -function checkAppveyor(minNodeVersion, maxNodeVersion, appveyorYaml) { - var expectedAppveyorVersions = range(minNodeVersion, maxNodeVersion) - .map(function (num) { - return { nodejs_version: num.toString() }; - }) - .reverse(); // Arbitrarily, we store appveyor in reverse order. - var msg = 'Check Appveyor environment.matrix versions'; - assertDeepEquals(appveyorYaml.environment.matrix, expectedAppveyorVersions, - msg); +function checkGithubActions(minNodeVersion, maxNodeVersion, githubActionsYaml) { + var expectedVersions = range(minNodeVersion, maxNodeVersion); + expectedVersions = expectedVersions.map(function (majorVersion) { + return pinnedNodeVersions[majorVersion] || majorVersion; + }); + var msg = 'Check GitHub Actions node_js versions'; + assertDeepEquals(githubActionsYaml.jobs.test.strategy.matrix['node-version'], + expectedVersions, msg); } try { checkReadme(MIN_NODE_VERSION); - var package = require('../package.json'); - checkEngines(MIN_NODE_VERSION, package); + var packageJson = require('../package.json'); + checkEngines(MIN_NODE_VERSION, packageJson); - var travisFileName = path.join(__dirname, '..', '.travis.yml'); - var travisYaml = yaml.safeLoad(shell.cat(travisFileName)); - checkTravis(MIN_NODE_VERSION, MAX_NODE_VERSION, travisYaml); + var githubActionsFileName = path.join(__dirname, '..', '.github', 'workflows', + 'main.yml'); + var githubActionsYaml = yaml.load(shell.cat(githubActionsFileName)); + checkGithubActions(MIN_NODE_VERSION, MAX_NODE_VERSION, githubActionsYaml); - var appveyorFileName = path.join(__dirname, '..', 'appveyor.yml'); - var appveyorYaml = yaml.safeLoad(shell.cat(appveyorFileName)); - checkAppveyor(MIN_NODE_VERSION, MAX_NODE_VERSION, appveyorYaml); + console.log('All files look good (this project supports LTS releases v' + + MIN_NODE_VERSION + '-v' + MAX_NODE_VERSION + ')!'); } catch (e) { console.error('Please check the files which declare our Node version'); console.error('support, as something is out-of-sync. This script failed'); diff --git a/scripts/generate-docs.js b/scripts/generate-docs.js index 64f4aab3e..3942c28b4 100755 --- a/scripts/generate-docs.js +++ b/scripts/generate-docs.js @@ -1,36 +1,76 @@ #!/usr/bin/env node -/* globals cat, cd, echo, grep, sed, ShellString */ +/* globals cat, cd, echo, grep, ls, sed, ShellString */ require('../global'); var path = require('path'); -echo('Appending docs to README.md'); +var COMMAND_PREFIX = '## Command reference'; +var COMMAND_SUFFIX = '\n## Team'; +var COMMAND_PATTERN = /## Command reference\n\n((?:.|\n)*)\n## Team/; +function extractCurrentDocs() { + var m = cat('README.md').match(COMMAND_PATTERN); + if (m) { + var docs = m[1]; + return docs; + } + /* istanbul ignore next */ + throw new Error('Unable to extract current docs'); +} +module.exports.extractCurrentDocs = extractCurrentDocs; -cd(path.join(__dirname, '..')); +function generateNewDocs() { + // Extract docs from shell.js + var docs = grep('^//@', 'shell.js'); -// Extract docs from shell.js -var docs = grep('^//@', 'shell.js'); + // Insert the docs for all the registered commands + var blocklist = [ + './src/common.js', + './src/error.js', + './src/errorCode.js', + ]; + docs = docs.replace(/\/\/@commands\n/g, function () { + return ls('./src/*.js').map(function (file) { + if (blocklist.includes(file)) { + return ''; + } + var commandDoc = grep('^//@', file).toString(); + if (commandDoc !== '') { + commandDoc += '\n'; + } + return commandDoc; + }).join(''); + }); -// Insert the docs for all the registered commands -docs = docs.replace(/\/\/@commands\n/g, function () { - return require('../commands').map(function (commandName) { - var file = './src/' + commandName + '.js'; - return grep('^//@', file) + '\n'; - }).join(''); -}); + // Now extract docs from the remaining src/*.js files + docs = docs.replace(/\/\/@include (.+)/g, function (match, filename) { + return grep('^//@', filename); + }); -// Now extract docs from the remaining src/*.js files -docs = docs.replace(/\/\/@include (.+)/g, function (match, filename) { - return grep('^//@', filename); -}); + // Remove '//@' + docs = docs.replace(/\/\/@ ?/g, ''); + return docs; +} +module.exports.generateNewDocs = generateNewDocs; -// Remove '//@' -docs = docs.replace(/\/\/@ ?/g, ''); +/* istanbul ignore next */ +function main() { + echo('Appending docs to README.md'); -// Wipe out the old docs -ShellString(cat('README.md').replace(/## Command reference(.|\n)*\n## Team/, '## Command reference\n## Team')).to('README.md'); + cd(path.join(__dirname, '..')); -// Append new docs to README -sed('-i', /## Command reference/, '## Command reference\n\n' + docs, 'README.md'); + var docs = generateNewDocs(); -echo('All done.'); + // Wipe out the old docs + ShellString(cat('README.md').replace(COMMAND_PATTERN, + COMMAND_PREFIX + COMMAND_SUFFIX)).to('README.md'); + + // Append new docs to README + sed('-i', /## Command reference/, COMMAND_PREFIX + '\n\n' + docs, 'README.md'); + + echo('All done.'); +} + +/* istanbul ignore if */ +if (require.main === module) { + main(); +} diff --git a/shell.js b/shell.js index e4c1c5df1..8a3a67d30 100644 --- a/shell.js +++ b/shell.js @@ -8,10 +8,12 @@ var common = require('./src/common'); +module.exports = common.shell; + //@ //@ All commands run synchronously, unless otherwise stated. //@ All commands accept standard bash globbing characters (`*`, `?`, etc.), -//@ compatible with the [node `glob` module](https://github.com/isaacs/node-glob). +//@ compatible with [`fast-glob`](https://www.npmjs.com/package/fast-glob). //@ //@ For less-commonly used commands and features, please check out our [wiki //@ page](https://github.com/shelljs/shelljs/wiki). @@ -20,29 +22,76 @@ var common = require('./src/common'); // Include the docs for all the default commands //@commands -// Load all default commands -require('./commands').forEach(function (command) { - require('./src/' + command); -}); +// Load all default commands. We import these for their side effect of loading +// using the plugin architecture via `common.register()`. +require('./src/cat'); +require('./src/cd'); +require('./src/chmod'); +require('./src/cmd'); +require('./src/cp'); +require('./src/dirs'); +require('./src/echo'); +require('./src/exec'); +require('./src/exec-child'); // A hint to the bundler to keep exec-child.js +require('./src/find'); +require('./src/grep'); +require('./src/head'); +require('./src/ln'); +require('./src/ls'); +require('./src/mkdir'); +require('./src/mv'); +require('./src/popd'); +require('./src/pushd'); +require('./src/pwd'); +require('./src/rm'); +require('./src/sed'); +require('./src/set'); +require('./src/sort'); +require('./src/tail'); +require('./src/tempdir'); +require('./src/test'); +require('./src/to'); +require('./src/toEnd'); +require('./src/touch'); +require('./src/uniq'); +require('./src/which'); //@ //@ ### exit(code) //@ //@ Exits the current process with the given exit `code`. -exports.exit = process.exit; +module.exports.exit = function exit(code) { + common.state.error = null; + common.state.errorCode = 0; + if (code) { + common.error('exit', { + continue: true, + code, + prefix: '', + silent: true, + fatal: false, + }); + process.exit(code); + } else { + process.exit(); + } +}; //@include ./src/error.js -exports.error = require('./src/error'); +module.exports.error = require('./src/error'); + +//@include ./src/errorCode.js +module.exports.errorCode = require('./src/errorCode'); //@include ./src/common.js -exports.ShellString = common.ShellString; +module.exports.ShellString = common.ShellString; //@ //@ ### env['VAR_NAME'] //@ //@ Object containing environment variables (both getter and setter). Shortcut //@ to `process.env`. -exports.env = process.env; +module.exports.env = process.env; //@ //@ ### Pipes @@ -51,7 +100,7 @@ exports.env = process.env; //@ //@ ```javascript //@ grep('foo', 'file1.txt', 'file2.txt').sed(/o/g, 'a').to('output.txt'); -//@ echo('files with o\'s in the name:\n' + ls().grep('o')); +//@ echo("files with o's in the name:\n" + ls().grep('o')); //@ cat('test.js').exec('node'); // pipe to exec() call //@ ``` //@ @@ -63,7 +112,7 @@ exports.env = process.env; //@ ## Configuration //@ -exports.config = common.config; +module.exports.config = common.config; //@ //@ ### config.silent @@ -118,7 +167,14 @@ exports.config = common.config; //@ ``` //@ -//@ ### config.globOptions +//@ ### config.globOptions (deprecated) +//@ +//@ **Deprecated**: we recommend that you do not edit `config.globOptions`. +//@ Support for this configuration option may be changed or removed in a future +//@ ShellJS release. +//@ +//@ **Breaking change**: ShellJS v0.8.x uses `node-glob`. Starting with ShellJS +//@ v0.9.x, `config.globOptions` is compatible with `fast-glob`. //@ //@ Example: //@ @@ -126,7 +182,11 @@ exports.config = common.config; //@ config.globOptions = {nodir: true}; //@ ``` //@ -//@ Use this value for calls to `glob.sync()` instead of the default options. +//@ `config.globOptions` changes how ShellJS expands glob (wildcard) +//@ expressions. See +//@ [fast-glob](https://github.com/mrmlnc/fast-glob?tab=readme-ov-file#options-3) +//@ for available options. Be aware that modifying `config.globOptions` **may +//@ break ShellJS functionality.** //@ //@ ### config.reset() diff --git a/src/cat.js b/src/cat.js index 86214fac4..ca264a9d1 100644 --- a/src/cat.js +++ b/src/cat.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('cat', _cat, { canReceivePipe: true, diff --git a/src/chmod.js b/src/chmod.js index 5268cbce5..b930cc764 100644 --- a/src/chmod.js +++ b/src/chmod.js @@ -1,6 +1,6 @@ -var common = require('./common'); var fs = require('fs'); var path = require('path'); +var common = require('./common'); var PERMS = (function (base) { return { @@ -59,6 +59,10 @@ common.register('chmod', _chmod, { //@ + In symbolic modes, `a-r` and `-r` are identical. No consideration is //@ given to the `umask`. //@ + There is no "quiet" option, since default behavior is to run silent. +//@ + Windows OS uses a very different permission model than POSIX. `chmod()` +//@ does its best on Windows, but there are limits to how file permissions can +//@ be set. Note that WSL (Windows subsystem for Linux) **does** follow POSIX, +//@ so cross-platform compatibility should not be a concern there. //@ //@ Returns a [ShellString](#shellstringstr) indicating success or failure. function _chmod(options, mode, filePattern) { @@ -132,16 +136,16 @@ function _chmod(options, mode, filePattern) { var operator = matches[2]; var change = matches[3]; - var changeOwner = applyTo.indexOf('u') !== -1 || applyTo === 'a' || applyTo === ''; - var changeGroup = applyTo.indexOf('g') !== -1 || applyTo === 'a' || applyTo === ''; - var changeOther = applyTo.indexOf('o') !== -1 || applyTo === 'a' || applyTo === ''; + var changeOwner = applyTo.includes('u') || applyTo === 'a' || applyTo === ''; + var changeGroup = applyTo.includes('g') || applyTo === 'a' || applyTo === ''; + var changeOther = applyTo.includes('o') || applyTo === 'a' || applyTo === ''; - var changeRead = change.indexOf('r') !== -1; - var changeWrite = change.indexOf('w') !== -1; - var changeExec = change.indexOf('x') !== -1; - var changeExecDir = change.indexOf('X') !== -1; - var changeSticky = change.indexOf('t') !== -1; - var changeSetuid = change.indexOf('s') !== -1; + var changeRead = change.includes('r'); + var changeWrite = change.includes('w'); + var changeExec = change.includes('x'); + var changeExecDir = change.includes('X'); + var changeSticky = change.includes('t'); + var changeSetuid = change.includes('s'); if (changeExecDir && isDir) { changeExec = true; diff --git a/src/cmd.js b/src/cmd.js index 9d19a92ed..a00d6c497 100644 --- a/src/cmd.js +++ b/src/cmd.js @@ -1,5 +1,5 @@ -var common = require('./common'); var execa = require('execa'); +var common = require('./common'); var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024; var COMMAND_NOT_FOUND_ERROR_CODE = 127; @@ -11,16 +11,58 @@ common.register('cmd', _cmd, { wrapOutput: true, }); -function commandNotFound(execaResult) { +function isCommandNotFound(execaResult) { if (process.platform === 'win32') { var str = 'is not recognized as an internal or external command'; - return execaResult.code && execaResult.stderr.includes(str); - } else { - return execaResult.code && - execaResult.stdout === null && execaResult.stderr === null; + return execaResult.exitCode && execaResult.stderr.includes(str); } + return execaResult.failed && execaResult.code === 'ENOENT'; +} + +function isExecaInternalError(result) { + if (typeof result.stdout !== 'string') return true; + if (typeof result.stderr !== 'string') return true; + if (typeof result.exitCode !== 'number') return true; + if (result.exitCode === 0 && result.failed) return true; + // Otherwise assume this executed correctly. The command may still have exited + // with non-zero status, but that's not due to anything execa did. + return false; } +//@ +//@ ### cmd(arg1[, arg2, ...] [, options]) +//@ +//@ Available options: +//@ +//@ + `cwd: directoryPath`: change the current working directory only for this +//@ cmd() invocation. +//@ + `maxBuffer: num`: Raise or decrease the default buffer size for +//@ stdout/stderr. +//@ + `timeout`: Change the default timeout. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var version = cmd('node', '--version').stdout; +//@ cmd('git', 'commit', '-am', `Add suport for node ${version}`); +//@ console.log(cmd('echo', '1st arg', '2nd arg', '3rd arg').stdout) +//@ console.log(cmd('echo', 'this handles ;, |, &, etc. as literal characters').stdout) +//@ ``` +//@ +//@ Executes the given command synchronously. This is intended as an easier +//@ alternative for [exec()](#execcommand--options--callback), with better +//@ security around globbing, comamnd injection, and variable expansion. This is +//@ guaranteed to only run one external command, and won't give special +//@ treatment for any shell characters (ex. this treats `|` as a literal +//@ character, not as a shell pipeline). +//@ This returns a [ShellString](#shellstringstr). +//@ +//@ By default, this performs globbing on all platforms, but you can disable +//@ this with `set('-f')`. +//@ +//@ This **does not** support asynchronous mode. If you need asynchronous +//@ command execution, check out [execa](https://www.npmjs.com/package/execa) or +//@ the node builtin `child_process.execFile()` instead. function _cmd(options, command, commandArgs, userOptions) { if (!command) { common.error('Must specify a non-empty string as a command'); @@ -51,7 +93,7 @@ function _cmd(options, command, commandArgs, userOptions) { // by the user. var defaultOptions = { maxBuffer: DEFAULT_MAXBUFFER_SIZE, - stripEof: false, // Preserve trailing newlines for consistency with unix. + stripFinalNewline: false, // Preserve trailing newlines for consistency with unix. reject: false, // Use ShellJS's error handling system. }; @@ -69,16 +111,24 @@ function _cmd(options, command, commandArgs, userOptions) { var stdout; var stderr; var code; - if (commandNotFound(result)) { + if (isCommandNotFound(result)) { // This can happen if `command` is not an executable binary, or possibly // under other conditions. stdout = ''; stderr = "'" + command + "': command not found"; code = COMMAND_NOT_FOUND_ERROR_CODE; + } else if (isExecaInternalError(result)) { + // Catch-all: execa tried to run `command` but it encountered some error + // (ex. maxBuffer, timeout). + stdout = result.stdout || ''; + stderr = result.stderr || + `'${command}' encountered an error during execution`; + code = result.exitCode !== undefined && result.exitCode > 0 ? result.exitCode : 1; } else { + // Normal exit: execa was able to execute `command` and get a return value. stdout = result.stdout.toString(); stderr = result.stderr.toString(); - code = result.code; + code = result.exitCode; } // Pass `continue: true` so we can specify a value for stdout. diff --git a/src/common.js b/src/common.js index 0ec1f8131..d46e3c9b8 100644 --- a/src/common.js +++ b/src/common.js @@ -6,8 +6,10 @@ var os = require('os'); var fs = require('fs'); -var glob = require('glob'); -var shell = require('..'); +var glob = require('fast-glob'); + +var shell = {}; +exports.shell = shell; var shellMethods = Object.create(shell); @@ -29,13 +31,13 @@ var DEFAULT_CONFIG = { }; var config = { - reset: function () { + reset() { Object.assign(this, DEFAULT_CONFIG); if (!isElectron) { this.execPath = process.execPath; } }, - resetForTesting: function () { + resetForTesting() { this.reset(); this.silent = true; }, @@ -81,11 +83,12 @@ exports.convertErrorOutput = convertErrorOutput; // An exception class to help propagate command errors (e.g., non-zero exit // status) up to the top-level. {@param value} should be a ShellString. -function CommandError(value) { - this.returnValue = value; +class CommandError extends Error { + constructor(value) { + super(value.toString()); + this.returnValue = value; + } } -CommandError.prototype = Object.create(Error.prototype); -CommandError.prototype.constructor = CommandError; exports.CommandError = CommandError; // visible for testing // Shows error message. Throws if fatal is true (defaults to config.fatal, overridable with options.fatal) @@ -119,7 +122,11 @@ function error(msg, _code, options) { state.error += logEntry; // Throw an error, or log the entry - if (options.fatal) throw new Error(logEntry); + if (options.fatal) { + var err = new Error(logEntry); + err.code = options.code; + throw err; + } if (msg.length > 0 && !options.silent) log(logEntry); if (!options.continue) { @@ -184,7 +191,7 @@ function parseOptions(opt, map, errorOptions) { throw new TypeError('parseOptions() internal error: map must be an object'); } else if (!isObject(errorOptions)) { throw new TypeError( - 'parseOptions() internal error: errorOptions must be object' + 'parseOptions() internal error: errorOptions must be object', ); } @@ -247,6 +254,78 @@ function parseOptions(opt, map, errorOptions) { } exports.parseOptions = parseOptions; +function globOptions() { + // These options are just to make fast-glob be compatible with POSIX (bash) + // wildcard behavior. + var defaultGlobOptions = { + onlyFiles: false, + followSymbolicLinks: false, + }; + + var newGlobOptions = Object.assign({}, config.globOptions); + var optionRenames = { + // node-glob's 'nodir' is not quote the same as fast-glob's 'onlyFiles'. + // Compatibility for this is implemented at the call site. + mark: 'markDirectories', + matchBase: 'baseNameMatch', + }; + Object.keys(optionRenames).forEach(function (oldKey) { + var newKey = optionRenames[oldKey]; + if (oldKey in config.globOptions) { + newGlobOptions[newKey] = config.globOptions[oldKey]; + } + }); + var invertedOptionRenames = { + nobrace: 'braceExpansion', + noglobstar: 'globstar', + noext: 'extglob', + nocase: 'caseSensitiveMatch', + }; + Object.keys(invertedOptionRenames).forEach(function (oldKey) { + var newKey = invertedOptionRenames[oldKey]; + if (oldKey in config.globOptions) { + newGlobOptions[newKey] = !config.globOptions[oldKey]; + } + }); + return Object.assign({}, defaultGlobOptions, newGlobOptions); +} + + +// Workaround for https://github.com/shelljs/shelljs/issues/1197 +// fast-glob's dependency glob-parent does not recognize the '?' wildcard in +// non-final path segments, causing those patterns to be treated as literal +// directory names. Replace standalone '?' with the equivalent character class +// '[^/]' which glob-parent handles correctly. +function convertQuestionMarkForGlob(pattern) { + if (pattern.indexOf('?') === -1) { + return pattern; + } + var result = ''; + var inBracket = false; + for (var i = 0; i < pattern.length; i++) { + var ch = pattern[i]; + if (ch === '\\' && i + 1 < pattern.length) { + // Escaped character: keep as-is + result += ch + pattern[i + 1]; + i++; + } else if (ch === '[' && !inBracket) { + inBracket = true; + result += ch; + } else if (ch === ']' && inBracket) { + inBracket = false; + result += ch; + } else if (ch === '?' && !inBracket && pattern[i + 1] === '(') { + // Extglob pattern ?(...) keep as-is + result += ch; + } else if (ch === '?' && !inBracket) { + result += '[^/]'; + } else { + result += ch; + } + } + return result; +} + // Expands wildcards with matching (ie. existing) file names. // For example: // expand(['file*.js']) = ['file1.js', 'file2.js', ...] @@ -262,14 +341,20 @@ function expand(list) { expanded.push(listEl); } else { var ret; + var globOpts = globOptions(); try { - ret = glob.sync(listEl, config.globOptions); - // if nothing matched, interpret the string literally - ret = ret.length > 0 ? ret : [listEl]; + ret = glob.sync(convertQuestionMarkForGlob(listEl), globOpts); } catch (e) { // if glob fails, interpret the string literally ret = [listEl]; } + // if nothing matched, interpret the string literally + ret = ret.length > 0 ? ret.sort() : [listEl]; + if (globOpts.nodir) { + ret = ret.filter(function (file) { + return !statNoFollowLinks(file).isDirectory(); + }); + } expanded = expanded.concat(ret); } }); diff --git a/src/cp.js b/src/cp.js index 09bde25bc..abed9a987 100644 --- a/src/cp.js +++ b/src/cp.js @@ -11,6 +11,7 @@ common.register('cp', _cp, { 'r': 'recursive', 'L': 'followsymlink', 'P': 'noFollowsymlink', + 'p': 'preserve', }, wrapOutput: false, }); @@ -23,6 +24,12 @@ function copyFileSync(srcFile, destFile, options) { common.error('copyFileSync: no such file or directory: ' + srcFile); } + // Bail if src and dest are the same file to avoid data loss + if (path.relative(srcFile, destFile) === '') { + common.error("'" + destFile + "' and '" + srcFile + "' are the same file", { continue: true }); + return; + } + var isWindows = process.platform === 'win32'; // Check the mtimes of the files if the '-u' flag is provided @@ -51,6 +58,7 @@ function copyFileSync(srcFile, destFile, options) { var pos = 0; var fdr = null; var fdw = null; + var srcStat = common.statFollowLinks(srcFile); try { fdr = fs.openSync(srcFile, 'r'); @@ -60,7 +68,7 @@ function copyFileSync(srcFile, destFile, options) { } try { - fdw = fs.openSync(destFile, 'w'); + fdw = fs.openSync(destFile, 'w', srcStat.mode); } catch (e) { /* istanbul ignore next */ common.error('copyFileSync: could not write to dest file (code=' + e.code + '):' + destFile); @@ -72,10 +80,15 @@ function copyFileSync(srcFile, destFile, options) { pos += bytesRead; } + if (options.preserve) { + fs.fchownSync(fdw, srcStat.uid, srcStat.gid); + // Note: utimesSync does not work (rounds to seconds), but futimesSync has + // millisecond precision. + fs.futimesSync(fdw, srcStat.atime, srcStat.mtime); + } + fs.closeSync(fdr); fs.closeSync(fdw); - - fs.chmodSync(destFile, common.statFollowLinks(srcFile).mode); } } @@ -96,8 +109,9 @@ function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) { var isWindows = process.platform === 'win32'; - // Create the directory where all our junk is moving to; read the mode of the - // source directory and mirror it + // Create the directory where all our junk is moving to; read the mode/etc. of + // the source directory (we'll set this on the destDir at the end). + var checkDir = common.statFollowLinks(sourceDir); try { fs.mkdirSync(destDir); } catch (e) { @@ -150,7 +164,10 @@ function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) { // finally change the mode for the newly created directory (otherwise, we // couldn't add files to a read-only directory). - var checkDir = common.statFollowLinks(sourceDir); + // var checkDir = common.statFollowLinks(sourceDir); + if (opts.preserve) { + fs.utimesSync(destDir, checkDir.atime, checkDir.mtime); + } fs.chmodSync(destDir, checkDir.mode); } // cpdirSyncRecursive @@ -196,6 +213,7 @@ function cpcheckcycle(sourceDir, srcFile) { //@ + `-r`, `-R`: recursive //@ + `-L`: follow symlinks //@ + `-P`: don't follow symlinks +//@ + `-p`: preserve file mode, ownership, and timestamps //@ //@ Examples: //@ @@ -256,9 +274,15 @@ function _cp(options, sources, dest) { path.join(dest, path.basename(src)) : dest; + if (path.relative(src, newDest) === '') { + // a directory cannot be copied into itself, but we want to continue copying other sources + common.error("'" + newDest + "' and '" + src + "' are the same file", { continue: true }); + return; + } + try { common.statFollowLinks(path.dirname(dest)); - cpdirSyncRecursive(src, newDest, 0, { no_force: options.no_force, followsymlink: options.followsymlink, update: options.update }); + cpdirSyncRecursive(src, newDest, 0, options); } catch (e) { /* istanbul ignore next */ common.error("cannot create directory '" + dest + "': No such file or directory"); @@ -287,12 +311,6 @@ function _cp(options, sources, dest) { return; // skip file } - if (path.relative(src, thisDest) === '') { - // a file cannot be copied to itself, but we want to continue copying other files - common.error("'" + thisDest + "' and '" + src + "' are the same file", { continue: true }); - return; - } - copyFileSync(src, thisDest, options); } }); // forEach(src) diff --git a/src/dirs.js b/src/dirs.js index 0ff08783f..9b7251d0e 100644 --- a/src/dirs.js +++ b/src/dirs.js @@ -1,6 +1,6 @@ +var path = require('path'); var common = require('./common'); var _cd = require('./cd'); -var path = require('path'); common.register('dirs', _dirs, { wrapOutput: false, @@ -106,7 +106,7 @@ exports.pushd = _pushd; //@ Available options: //@ //@ + `-n`: Suppress the normal directory change when removing directories from the stack, so that only the stack is manipulated. -//@ + `-q`: Supresses output to the console. +//@ + `-q`: Suppresses output to the console. //@ //@ Arguments: //@ @@ -160,7 +160,7 @@ exports.popd = _popd; //@ Available options: //@ //@ + `-c`: Clears the directory stack by deleting all of the elements. -//@ + `-q`: Supresses output to the console. +//@ + `-q`: Suppresses output to the console. //@ //@ Arguments: //@ diff --git a/src/errorCode.js b/src/errorCode.js new file mode 100644 index 000000000..a1c7fd23f --- /dev/null +++ b/src/errorCode.js @@ -0,0 +1,10 @@ +var common = require('./common'); + +//@ +//@ ### errorCode() +//@ +//@ Returns the error code from the last command. +function errorCode() { + return common.state.errorCode; +} +module.exports = errorCode; diff --git a/src/exec-child.js b/src/exec-child.js index cc844e4b6..e8446f6f0 100644 --- a/src/exec-child.js +++ b/src/exec-child.js @@ -1,67 +1,71 @@ -if (require.main !== module) { - throw new Error('This file should not be required'); -} - var childProcess = require('child_process'); var fs = require('fs'); -var paramFilePath = process.argv[2]; +function main() { + var paramFilePath = process.argv[2]; -var serializedParams = fs.readFileSync(paramFilePath, 'utf8'); -var params = JSON.parse(serializedParams); + var serializedParams = fs.readFileSync(paramFilePath, 'utf8'); + var params = JSON.parse(serializedParams); -var cmd = params.command; -var execOptions = params.execOptions; -var pipe = params.pipe; -var stdoutFile = params.stdoutFile; -var stderrFile = params.stderrFile; + var cmd = params.command; + var execOptions = params.execOptions; + var pipe = params.pipe; + var stdoutFile = params.stdoutFile; + var stderrFile = params.stderrFile; -function isMaxBufferError(err) { - var maxBufferErrorPattern = /^.*\bmaxBuffer\b.*exceeded.*$/; - if (err instanceof Error && err.message && - err.message.match(maxBufferErrorPattern)) { - // < v10 - // Error: stdout maxBuffer exceeded - return true; - } else if (err instanceof RangeError && err.message && - err.message.match(maxBufferErrorPattern)) { - // >= v10 - // RangeError [ERR_CHILD_PROCESS_STDIO_MAXBUFFER]: stdout maxBuffer length - // exceeded - return true; + function isMaxBufferError(err) { + var maxBufferErrorPattern = /^.*\bmaxBuffer\b.*exceeded.*$/; + if (err instanceof Error && err.message && + err.message.match(maxBufferErrorPattern)) { + // < v10 + // Error: stdout maxBuffer exceeded + return true; + } else if (err instanceof RangeError && err.message && + err.message.match(maxBufferErrorPattern)) { + // >= v10 + // RangeError [ERR_CHILD_PROCESS_STDIO_MAXBUFFER]: stdout maxBuffer length + // exceeded + return true; + } + return false; } - return false; -} -var stdoutStream = fs.createWriteStream(stdoutFile); -var stderrStream = fs.createWriteStream(stderrFile); - -function appendError(message, code) { - stderrStream.write(message); - process.exitCode = code; -} + var stdoutStream = fs.createWriteStream(stdoutFile); + var stderrStream = fs.createWriteStream(stderrFile); -var c = childProcess.exec(cmd, execOptions, function (err) { - if (!err) { - process.exitCode = 0; - } else if (isMaxBufferError(err)) { - appendError('maxBuffer exceeded', 1); - } else if (err.code === undefined && err.message) { - /* istanbul ignore next */ - appendError(err.message, 1); - } else if (err.code === undefined) { - /* istanbul ignore next */ - appendError('Unknown issue', 1); - } else { - process.exitCode = err.code; + function appendError(message, code) { + stderrStream.write(message); + process.exitCode = code; } -}); -c.stdout.pipe(stdoutStream); -c.stderr.pipe(stderrStream); -c.stdout.pipe(process.stdout); -c.stderr.pipe(process.stderr); + var c = childProcess.exec(cmd, execOptions, function (err) { + if (!err) { + process.exitCode = 0; + } else if (isMaxBufferError(err)) { + appendError('maxBuffer exceeded', 1); + } else if (err.code === undefined && err.message) { + /* istanbul ignore next */ + appendError(err.message, 1); + } else if (err.code === undefined) { + /* istanbul ignore next */ + appendError('Unknown issue', 1); + } else { + process.exitCode = err.code; + } + }); + + c.stdout.pipe(stdoutStream); + c.stderr.pipe(stderrStream); + c.stdout.pipe(process.stdout); + c.stderr.pipe(process.stderr); + + if (pipe) { + c.stdin.end(pipe); + } +} -if (pipe) { - c.stdin.end(pipe); +// This file should only be executed. This module does not export anything. +/* istanbul ignore else */ +if (require.main === module) { + main(); } diff --git a/src/exec.js b/src/exec.js index ab67f56cc..0082f63ed 100644 --- a/src/exec.js +++ b/src/exec.js @@ -1,9 +1,15 @@ -var common = require('./common'); -var _tempDir = require('./tempdir').tempDir; -var _pwd = require('./pwd'); var path = require('path'); var fs = require('fs'); var child = require('child_process'); +var common = require('./common'); +var _tempDir = require('./tempdir').tempDir; +var _pwd = require('./pwd'); + +// Resolve exec-child.js path at module load time using require.resolve() so that +// bundlers (e.g. Next.js/webpack) do not break the path by replacing __dirname +// with the bundled output directory. require.resolve() always returns the real +// filesystem path of the module, regardless of bundler transformations. +var EXEC_CHILD_PATH = require.resolve('./exec-child.js'); var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024; var DEFAULT_ERROR_CODE = 1; @@ -53,15 +59,32 @@ function execSync(cmd, opts, pipe) { var paramsToSerialize = { command: cmd, execOptions: opts, - pipe: pipe, - stdoutFile: stdoutFile, - stderrFile: stderrFile, + pipe, + stdoutFile, + stderrFile, }; - fs.writeFileSync(paramsFile, JSON.stringify(paramsToSerialize), 'utf8'); + // Create the files and ensure these are locked down (for read and write) to + // the current user. The main concerns here are: + // + // * If we execute a command which prints sensitive output, then + // stdoutFile/stderrFile must not be readable by other users. + // * paramsFile must not be readable by other users, or else they can read it + // to figure out the path for stdoutFile/stderrFile and create these first + // (locked down to their own access), which will crash exec() when it tries + // to write to the files. + function writeFileLockedDown(filePath, data) { + fs.writeFileSync(filePath, data, { + encoding: 'utf8', + mode: parseInt('600', 8), + }); + } + writeFileLockedDown(stdoutFile, ''); + writeFileLockedDown(stderrFile, ''); + writeFileLockedDown(paramsFile, JSON.stringify(paramsToSerialize)); var execArgs = [ - path.join(__dirname, 'exec-child.js'), + EXEC_CHILD_PATH, paramsFile, ]; @@ -101,6 +124,7 @@ function execSync(cmd, opts, pipe) { } // No biggie if we can't erase the files now -- they're in a temp dir anyway + // and we locked down permissions (see the note above). try { common.unlinkSync(paramsFile); } catch (e) {} try { common.unlinkSync(stderrFile); } catch (e) {} try { common.unlinkSync(stdoutFile); } catch (e) {} diff --git a/src/find.js b/src/find.js index b6c882979..80db9935b 100644 --- a/src/find.js +++ b/src/find.js @@ -2,7 +2,11 @@ var path = require('path'); var common = require('./common'); var _ls = require('./ls'); -common.register('find', _find, {}); +common.register('find', _find, { + cmdOptions: { + 'L': 'link', + }, +}); //@ //@ ### find(path [, path ...]) @@ -51,7 +55,7 @@ function _find(options, paths) { pushFile(file); if (stat.isDirectory()) { - _ls({ recursive: true, all: true }, file).forEach(function (subfile) { + _ls({ recursive: true, all: true, link: options.link }, file).forEach(function (subfile) { pushFile(path.join(file, subfile)); }); } diff --git a/src/grep.js b/src/grep.js index 57450d10d..cfc83e40e 100644 --- a/src/grep.js +++ b/src/grep.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('grep', _grep, { globStart: 2, // don't glob-expand the regex @@ -8,6 +8,10 @@ common.register('grep', _grep, { 'v': 'inverse', 'l': 'nameOnly', 'i': 'ignoreCase', + 'n': 'lineNumber', + 'B': 'beforeContext', + 'A': 'afterContext', + 'C': 'context', }, }); @@ -20,12 +24,19 @@ common.register('grep', _grep, { //@ + `-v`: Invert `regex_filter` (only print non-matching lines). //@ + `-l`: Print only filenames of matching files. //@ + `-i`: Ignore case. +//@ + `-n`: Print line numbers. +//@ + `-B `: Show `` lines before each result. +//@ + `-A `: Show `` lines after each result. +//@ + `-C `: Show `` lines before and after each result. -B and -A override this option. //@ //@ Examples: //@ //@ ```javascript //@ grep('-v', 'GLOBAL_VARIABLE', '*.js'); //@ grep('GLOBAL_VARIABLE', '*.js'); +//@ grep('-B', 3, 'GLOBAL_VARIABLE', '*.js'); +//@ grep({ '-B': 3 }, 'GLOBAL_VARIABLE', '*.js'); +//@ grep({ '-B': 3, '-C': 2 }, 'GLOBAL_VARIABLE', '*.js'); //@ ``` //@ //@ Reads input string from given files and returns a @@ -37,7 +48,41 @@ function _grep(options, regex, files) { if (!files && !pipe) common.error('no paths given', 2); - files = [].slice.call(arguments, 2); + var idx = 2; + var contextError = ': invalid context length argument'; + // If the option has been found but not read, copy value from arguments + if (options.beforeContext === true) { + idx = 3; + options.beforeContext = Number(arguments[1]); + if (options.beforeContext < 0) { + common.error(options.beforeContext + contextError, 2); + } + } + if (options.afterContext === true) { + idx = 3; + options.afterContext = Number(arguments[1]); + if (options.afterContext < 0) { + common.error(options.afterContext + contextError, 2); + } + } + if (options.context === true) { + idx = 3; + options.context = Number(arguments[1]); + if (options.context < 0) { + common.error(options.context + contextError, 2); + } + } + // If before or after not given but context is, update values + if (typeof options.context === 'number') { + if (options.beforeContext === false) { + options.beforeContext = options.context; + } + if (options.afterContext === false) { + options.afterContext = options.context; + } + } + regex = arguments[idx - 1]; + files = [].slice.call(arguments, idx); if (pipe) { files.unshift('-'); @@ -60,12 +105,79 @@ function _grep(options, regex, files) { } } else { var lines = contents.split('\n'); - lines.forEach(function (line) { + var matches = []; + + lines.forEach(function (line, index) { var matched = line.match(regex); if ((options.inverse && !matched) || (!options.inverse && matched)) { - grep.push(line); + var lineNumber = index + 1; + var result = {}; + if (matches.length > 0) { + // If the last result intersects, combine them + var last = matches[matches.length - 1]; + var minimumLineNumber = Math.max( + 1, + lineNumber - options.beforeContext - 1, + ); + if ( + last.hasOwnProperty('' + lineNumber) || + last.hasOwnProperty('' + minimumLineNumber) + ) { + result = last; + } + } + result[lineNumber] = { + line, + match: true, + }; + if (options.beforeContext > 0) { + // Store the lines with their line numbers to check for overlap + lines + .slice(Math.max(index - options.beforeContext, 0), index) + .forEach(function (v, i, a) { + var lineNum = '' + (index - a.length + i + 1); + if (!result.hasOwnProperty(lineNum)) { + result[lineNum] = { line: v, match: false }; + } + }); + } + if (options.afterContext > 0) { + // Store the lines with their line numbers to check for overlap + lines + .slice( + index + 1, + Math.min(index + options.afterContext + 1, lines.length - 1), + ) + .forEach(function (v, i) { + var lineNum = '' + (index + 1 + i + 1); + if (!result.hasOwnProperty(lineNum)) { + result[lineNum] = { line: v, match: false }; + } + }); + } + // Only add the result if it's new + if (!matches.includes(result)) { + matches.push(result); + } } }); + + // Loop through the matches and add them to the output + Array.prototype.push.apply( + grep, + matches.map(function (result) { + return Object.entries(result) + .map(function (entry) { + var lineNumber = entry[0]; + var line = entry[1].line; + var match = entry[1].match; + return options.lineNumber + ? lineNumber + (match ? ':' : '-') + line + : line; + }) + .join('\n'); + }), + ); } }); @@ -73,6 +185,14 @@ function _grep(options, regex, files) { // We didn't hit the error above, but pattern didn't match common.error('', { silent: true }); } - return grep.join('\n') + '\n'; + + var separator = '\n'; + if ( + typeof options.beforeContext === 'number' || + typeof options.afterContext === 'number' + ) { + separator = '\n--\n'; + } + return grep.join(separator) + '\n'; } module.exports = _grep; diff --git a/src/head.js b/src/head.js index ffb08fd7c..f3f4f2269 100644 --- a/src/head.js +++ b/src/head.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('head', _head, { canReceivePipe: true, diff --git a/src/ls.js b/src/ls.js index 31495fbdc..7f32c6e09 100644 --- a/src/ls.js +++ b/src/ls.js @@ -1,9 +1,10 @@ var path = require('path'); var fs = require('fs'); +var glob = require('fast-glob'); var common = require('./common'); -var glob = require('glob'); -var globPatternRecursive = path.sep + '**'; +// glob patterns use the UNIX path seperator +var globPatternRecursive = '/**'; common.register('ls', _ls, { cmdOptions: { @@ -26,15 +27,20 @@ common.register('ls', _ls, { //@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`) //@ + `-L`: follow symlinks //@ + `-d`: list directories themselves, not their contents -//@ + `-l`: list objects representing each file, each with fields containing `ls -//@ -l` output fields. See -//@ [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) -//@ for more info +//@ + `-l`: provides more details for each file. Specifically, each file is +//@ represented by a structured object with separate fields for file +//@ metadata (see +//@ [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)). The +//@ return value also overrides `.toString()` to resemble `ls -l`'s +//@ output format for human readability, but programmatic usage should +//@ depend on the stable object format rather than the `.toString()` +//@ representation. //@ //@ Examples: //@ //@ ```javascript //@ ls('projs/*.js'); +//@ ls('projs/**/*.js'); // Find all js files recursively in projs //@ ls('-R', '/users/me', '/tmp'); //@ ls('-R', ['/users/me', '/tmp']); // same as above //@ ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...} @@ -100,13 +106,20 @@ function _ls(options, paths) { if (stat.isDirectory() && !options.directory) { if (options.recursive) { // use glob, because it's simple - glob.sync(p + globPatternRecursive, { dot: options.all, follow: options.link }) - .forEach(function (item) { - // Glob pattern returns the directory itself and needs to be filtered out. - if (path.relative(p, item)) { - pushFile(item, path.relative(p, item)); - } - }); + glob.sync(p + globPatternRecursive, { + // These options are just to make fast-glob be compatible with POSIX + // (bash) wildcard behavior. + onlyFiles: false, + + // These options depend on the cmdOptions provided to ls. + dot: options.all, + followSymbolicLinks: options.link, + }).forEach(function (item) { + // Glob pattern returns the directory itself and needs to be filtered out. + if (path.relative(p, item)) { + pushFile(item, path.relative(p, item)); + } + }); } else if (options.all) { // use fs.readdirSync, because it's fast fs.readdirSync(p).forEach(function (item) { diff --git a/src/mkdir.js b/src/mkdir.js index 992df7c0d..021cad9c0 100644 --- a/src/mkdir.js +++ b/src/mkdir.js @@ -1,6 +1,6 @@ -var common = require('./common'); var fs = require('fs'); var path = require('path'); +var common = require('./common'); common.register('mkdir', _mkdir, { cmdOptions: { @@ -19,17 +19,18 @@ function mkdirSyncRecursive(dir) { common.error('dirname() failed: [' + dir + ']'); } - // Base dir exists, no recursion necessary - if (fs.existsSync(baseDir)) { - fs.mkdirSync(dir, parseInt('0777', 8)); - return; - } - // Base dir does not exist, go recursive - mkdirSyncRecursive(baseDir); + if (!fs.existsSync(baseDir)) { + mkdirSyncRecursive(baseDir); + } - // Base dir created, can create dir - fs.mkdirSync(dir, parseInt('0777', 8)); + try { + // Base dir created, can create dir + fs.mkdirSync(dir, parseInt('0777', 8)); + } catch (e) { + // swallow error if dir already exists + if (e.code !== 'EEXIST' || common.statNoFollowLinks(dir).isFile()) { throw e; } + } } //@ diff --git a/src/rm.js b/src/rm.js index 7cf07af07..6bb57558b 100644 --- a/src/rm.js +++ b/src/rm.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('rm', _rm, { cmdOptions: { diff --git a/src/sed.js b/src/sed.js index f616ba9ff..693652362 100644 --- a/src/sed.js +++ b/src/sed.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('sed', _sed, { globStart: 3, // don't glob-expand regexes @@ -37,7 +37,7 @@ common.register('sed', _sed, { //@ ``` //@ //@ Also, like unix `sed`, ShellJS `sed` runs replacements on each line from the input file -//@ (split by '\n') separately, so `search_regex`es that span more than one line (or inlclude '\n') +//@ (split by '\n') separately, so `search_regex`es that span more than one line (or include '\n') //@ will not match anything and nothing will be replaced. function _sed(options, regex, replacement, files) { // Check if this is coming from a pipe @@ -86,6 +86,10 @@ function _sed(options, regex, replacement, files) { } }); - return sed.join('\n'); + if (options.inplace) { + return ''; + } else { + return sed.join('\n'); + } } module.exports = _sed; diff --git a/src/sort.js b/src/sort.js index 3468268ea..66b042ce4 100644 --- a/src/sort.js +++ b/src/sort.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('sort', _sort, { canReceivePipe: true, diff --git a/src/tail.js b/src/tail.js index 10f5a3c32..eee75c570 100644 --- a/src/tail.js +++ b/src/tail.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('tail', _tail, { canReceivePipe: true, @@ -32,12 +32,20 @@ function _tail(options, files) { if (!files && !pipe) common.error('no paths given'); var idx = 1; + var plusOption = false; if (options.numLines === true) { idx = 2; + if (arguments[1][0] === '+') { + plusOption = true; + } options.numLines = Number(arguments[1]); } else if (options.numLines === false) { options.numLines = 10; } + // arguments[0] is a json object + if (arguments[0].numLines[0] === '+') { + plusOption = true; + } options.numLines = -1 * Math.abs(options.numLines); files = [].slice.call(arguments, idx); @@ -69,12 +77,14 @@ function _tail(options, files) { shouldAppendNewline = false; } - tail = tail.concat(lines.slice(options.numLines)); + tail = tail.concat(plusOption ? lines.slice(-options.numLines - 1) : lines.slice(options.numLines)); }); if (shouldAppendNewline) { tail.push(''); // to add a trailing newline once we join } + return tail.join('\n'); } + module.exports = _tail; diff --git a/src/tempdir.js b/src/tempdir.js index b62032d7d..b6f7796ee 100644 --- a/src/tempdir.js +++ b/src/tempdir.js @@ -1,6 +1,6 @@ -var common = require('./common'); var os = require('os'); var fs = require('fs'); +var common = require('./common'); common.register('tempdir', _tempDir, { allowGlobbing: false, diff --git a/src/test.js b/src/test.js index 20fe886fc..7e769083d 100644 --- a/src/test.js +++ b/src/test.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('test', _test, { cmdOptions: { @@ -35,7 +35,7 @@ common.register('test', _test, { //@ //@ ```javascript //@ if (test('-d', path)) { /* do something with dir */ }; -//@ if (!test('-f', path)) continue; // skip if it's a regular file +//@ if (!test('-f', path)) continue; // skip if it's not a regular file //@ ``` //@ //@ Evaluates `expression` using the available primaries and returns diff --git a/src/to.js b/src/to.js index e7dcc50d7..e4b064f49 100644 --- a/src/to.js +++ b/src/to.js @@ -1,6 +1,6 @@ -var common = require('./common'); var fs = require('fs'); var path = require('path'); +var common = require('./common'); common.register('to', _to, { pipeOnly: true, diff --git a/src/toEnd.js b/src/toEnd.js index 1d6e9609f..dc30e6264 100644 --- a/src/toEnd.js +++ b/src/toEnd.js @@ -1,6 +1,6 @@ -var common = require('./common'); var fs = require('fs'); var path = require('path'); +var common = require('./common'); common.register('toEnd', _toEnd, { pipeOnly: true, diff --git a/src/touch.js b/src/touch.js index ed1839ae8..a26858648 100644 --- a/src/touch.js +++ b/src/touch.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); common.register('touch', _touch, { cmdOptions: { @@ -20,10 +20,10 @@ common.register('touch', _touch, { //@ + `-a`: Change only the access time //@ + `-c`: Do not create any files //@ + `-m`: Change only the modification time -//@ + `{'-d': someDate}`, `{date: someDate}`: Use `someDate` (instance of -//@ `Date`) instead of current time +//@ + `{'-d': someDate}`, `{date: someDate}`: Use a `Date` instance (ex. `someDate`) +//@ instead of current time //@ + `{'-r': file}`, `{reference: file}`: Use `file`'s times instead of current -//@ time +//@ time //@ //@ Examples: //@ @@ -31,6 +31,7 @@ common.register('touch', _touch, { //@ touch('source.js'); //@ touch('-c', 'path/to/file.js'); //@ touch({ '-r': 'referenceFile.txt' }, 'path/to/file.js'); +//@ touch({ '-d': new Date('December 17, 1995 03:24:00'), '-m': true }, 'path/to/file.js'); //@ touch({ date: new Date('December 17, 1995 03:24:00') }, 'path/to/file.js'); //@ ``` //@ diff --git a/src/uniq.js b/src/uniq.js index e46f92b34..580270651 100644 --- a/src/uniq.js +++ b/src/uniq.js @@ -1,5 +1,5 @@ -var common = require('./common'); var fs = require('fs'); +var common = require('./common'); // add c spaces to the left of str function lpad(c, str) { diff --git a/src/which.js b/src/which.js index 28ba267df..8ac7b77e5 100644 --- a/src/which.js +++ b/src/which.js @@ -1,6 +1,6 @@ -var common = require('./common'); var fs = require('fs'); var path = require('path'); +var common = require('./common'); common.register('which', _which, { allowGlobbing: false, @@ -64,7 +64,7 @@ function _which(options, cmd) { var queryMatches = []; // No relative/absolute paths provided? - if (cmd.indexOf('/') === -1) { + if (!cmd.includes('/')) { // Assume that there are no extensions to append to queries (this is the // case for unix) var pathExtArray = ['']; @@ -87,7 +87,7 @@ function _which(options, cmd) { } var match = attempt.match(/\.[^<>:"/|?*.]+$/); - if (match && pathExtArray.indexOf(match[0]) >= 0) { // this is Windows-only + if (match && pathExtArray.includes(match[0])) { // this is Windows-only // The user typed a query with the file extension, like // `which('node.exe')` if (checkPath(attempt)) { diff --git a/test/.eslintrc.json b/test/.eslintrc.json index cd6aa4739..1e28f5360 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -7,13 +7,17 @@ "arrow-parens": "off", "comma-dangle": "off", "curly": "off", + "function-call-argument-newline": "off", + "function-paren-newline": "off", "global-require": "off", "import/no-dynamic-require": "off", "import/no-mutable-exports": "off", + "import/no-unresolved": "off", "indent": "off", "max-len": "off", "no-bitwise": "off", "no-console": "off", + "no-multiple-empty-lines": "off", "no-param-reassign": "off", "no-plusplus": "off", "no-underscore-dangle": "off", @@ -29,7 +33,11 @@ "new-cap": ["error", { "capIsNewExceptions": [ "ShellString" - ]} - ] + ] + }], + "quotes": ["error", "single", { + "avoidEscape": true, + "allowTemplateLiterals": true + }] } } diff --git a/test/cat.js b/test/cat.js index cc21ce575..e077b9be9 100644 --- a/test/cat.js +++ b/test/cat.js @@ -1,8 +1,8 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; +const shell = require('..'); shell.config.silent = true; diff --git a/test/cd.js b/test/cd.js index c472973da..53404e249 100644 --- a/test/cd.js +++ b/test/cd.js @@ -1,11 +1,11 @@ -import fs from 'fs'; -import os from 'os'; -import path from 'path'; +const fs = require('fs'); +const os = require('os'); +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); const cur = shell.pwd().toString(); diff --git a/test/chmod.js b/test/chmod.js index 1e3bdacd4..660972c91 100644 --- a/test/chmod.js +++ b/test/chmod.js @@ -1,10 +1,10 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); let TMP; const BITMASK = parseInt('777', 8); diff --git a/test/cmd.js b/test/cmd.js index bc47f3fdf..f49c98873 100644 --- a/test/cmd.js +++ b/test/cmd.js @@ -1,12 +1,8 @@ -import path from 'path'; +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; - -// TODO(nfischer): remove this when shell.cmd() is finished. For now, load it -// like any other plugin. -require('../src/cmd'); +const shell = require('..'); const CWD = process.cwd(); @@ -34,7 +30,7 @@ test('config.fatal and unknown command', t => { shell.config.fatal = true; t.throws(() => { shell.cmd('asdfasdf'); // could not find command - }, /.*command not found.*/); + }, { message: /.*command not found.*/ }); }); // TODO(nfischer): enable only if we implement realtime output + captured @@ -95,14 +91,18 @@ test('interaction with cd', t => { test('no need to escape quotes', t => { const result = shell.cmd(shell.config.execPath, '-e', - `console.log("'+'_'+'");`); // eslint-disable-line quotes + `console.log("'+'_'+'");`); t.falsy(shell.error()); t.is(result.code, 0); t.is(result.stdout, "'+'_'+'\n"); }); test('commands can contain newlines', t => { - // Github issue #175 + // GitHub issue #175. This test uses a nodejs script rather than a shell + // command because Windows 'echo' doesn't handle \n the same way as Unix + // 'echo'. This test case proves the newline is passed correctly to the + // underlying program because otherwise node would not parse the two lines as + // separate statements and it would throw a JavaScript syntax error. const result = shell.cmd(shell.config.execPath, '-e', ` console.log('line1') console.log('line2') @@ -132,6 +132,14 @@ test('does not expand windows-style variables', t => { t.is(result.stdout, '!FOO!\n'); }); +test('caret character is passed through to the command', t => { + // '^' is a special character on Windows, see issue #1015 + const result = shell.cmd('shx', 'echo', 'shelljs@^0.8.4'); + t.falsy(shell.error()); + t.is(result.code, 0); + t.is(result.stdout, 'shelljs@^0.8.4\n'); +}); + test('cannot inject multiple commands', t => { const injection = '; echo semicolon && echo and || echo or'; const result = shell.cmd('shx', 'echo', `hi${injection}`); @@ -169,21 +177,35 @@ test('set cwd', t => { t.is(result.stdout, path.resolve('..') + '\n'); }); +test('command fails silently with non-zero status', t => { + const result = shell.cmd('shx', 'false'); + t.truthy(shell.error()); + t.is(result.code, 1); + t.is(result.stdout, ''); + t.is(result.stderr, ''); +}); + test('set maxBuffer (very small)', t => { - const result = shell.cmd('shx', 'echo', '1234567890'); // default maxBuffer is ok + let result = shell.cmd('shx', 'echo', '1234567890'); // default maxBuffer is ok t.falsy(shell.error()); t.is(result.code, 0); t.is(result.stdout, '1234567890\n'); - shell.cmd('shx', 'echo', '1234567890', { maxBuffer: 6 }); + result = shell.cmd('shx', 'echo', '1234567890', { maxBuffer: 6 }); t.truthy(shell.error()); + t.is(result.code, 1); + t.is(result.stdout, '1234567890\n'); }); test('set timeout option', t => { - const result = shell.cmd(shell.config.execPath, 'test/resources/exec/slow.js', '100'); // default timeout is ok + let result = shell.cmd(shell.config.execPath, 'test/resources/exec/slow.js', '100'); // default timeout is ok t.falsy(shell.error()); + t.is(result.stdout, 'fast\nslow\n'); t.is(result.code, 0); - shell.cmd(shell.config.execPath, 'test/resources/exec/slow.js', '2000', { timeout: 1000 }); // times out + result = shell.cmd(shell.config.execPath, 'test/resources/exec/slow.js', '2000', { timeout: 1000 }); // times out t.truthy(shell.error()); + t.is(result.stdout, 'fast\n'); + t.truthy(result.stderr); + t.is(result.code, 1); }); test('check process.env works', t => { @@ -209,50 +231,49 @@ test('cmd returns a ShellString', t => { // async // +function cmdAsync(...commandArgs) { + return new Promise((resolve) => { + shell.cmd(...commandArgs, (code, stdout, stderr) => { + resolve({ code, stdout, stderr }); + }); + }); +} + // TODO(nfischer): enable after we implement async. -test.cb.skip('no callback', t => { +test.skip('no callback', t => { const c = shell.cmd(shell.config.execPath, '-e', 'console.log(1234)', { async: true }); t.falsy(shell.error()); t.truthy('stdout' in c, 'async exec returns child process object'); - t.end(); }); // TODO(nfischer): enable after we implement async. -test.cb.skip('callback as 2nd argument', t => { - shell.cmd(shell.config.execPath, '-e', 'console.log(5678);', (code, stdout, stderr) => { - t.is(code, 0); - t.is(stdout, '5678\n'); - t.is(stderr, ''); - t.end(); - }); +test.skip('callback as 2nd argument', async t => { + const result = await cmdAsync(shell.config.execPath, '-e', 'console.log(5678);'); + t.is(result.code, 0); + t.is(result.stdout, '5678\n'); + t.is(result.stderr, ''); }); // TODO(nfischer): enable after we implement async. -test.cb.skip('callback as end argument', t => { - shell.cmd(shell.config.execPath, '-e', 'console.log(5566);', { async: true }, (code, stdout, stderr) => { - t.is(code, 0); - t.is(stdout, '5566\n'); - t.is(stderr, ''); - t.end(); - }); +test.skip('callback as end argument', async t => { + const result = await cmdAsync(shell.config.execPath, '-e', 'console.log(5566);', { async: true }); + t.is(result.code, 0); + t.is(result.stdout, '5566\n'); + t.is(result.stderr, ''); }); // TODO(nfischer): enable after we implement async. -test.cb.skip('callback as 3rd argument (silent:true)', t => { - shell.cmd(shell.config.execPath, '-e', 'console.log(5678);', { silent: true }, (code, stdout, stderr) => { - t.is(code, 0); - t.is(stdout, '5678\n'); - t.is(stderr, ''); - t.end(); - }); +test.skip('callback as 3rd argument (silent:true)', async t => { + const result = await cmdAsync(shell.config.execPath, '-e', 'console.log(5678);', { silent: true }); + t.is(result.code, 0); + t.is(result.stdout, '5678\n'); + t.is(result.stderr, ''); }); // TODO(nfischer): enable after we implement async. -test.cb.skip('command that fails', t => { - shell.cmd('shx', 'cp', 'onlyOneCpArgument.txt', { silent: true }, (code, stdout, stderr) => { - t.is(code, 1); - t.is(stdout, ''); - t.is(stderr, 'cp: missing and/or \n'); - t.end(); - }); +test.skip('command that fails', async t => { + const result = await cmdAsync('shx', 'cp', 'onlyOneCpArgument.txt', { silent: true }); + t.is(result.code, 1); + t.is(result.stdout, ''); + t.is(result.stderr, 'cp: missing and/or \n'); }); diff --git a/test/common.js b/test/common.js index 814ec0744..8fc836590 100644 --- a/test/common.js +++ b/test/common.js @@ -1,8 +1,8 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); test.beforeEach(() => { shell.config.silent = true; @@ -21,13 +21,13 @@ test.afterEach(() => { test('too few args', t => { t.throws(() => { common.expand(); - }, TypeError); + }, { instanceOf: TypeError }); }); test('should be a list', t => { t.throws(() => { common.expand('test/resources'); - }, TypeError); + }, { instanceOf: TypeError }); }); test('parseOptions (invalid option in options object)', t => { @@ -37,7 +37,7 @@ test('parseOptions (invalid option in options object)', t => { f: 'force', r: 'reverse', }); - }, common.CommandError); + }, { instanceOf: common.CommandError }); }); test('parseOptions (without a hyphen in the string)', t => { @@ -45,7 +45,7 @@ test('parseOptions (without a hyphen in the string)', t => { common.parseOptions('f', { f: 'force', }); - }, Error); + }, { instanceOf: Error }); }); test('parseOptions (opt is not a string/object)', t => { @@ -53,13 +53,13 @@ test('parseOptions (opt is not a string/object)', t => { common.parseOptions(1, { f: 'force', }); - }, TypeError); + }, { instanceOf: TypeError }); }); test('parseOptions (map is not an object)', t => { t.throws(() => { common.parseOptions('-f', 27); - }, TypeError); + }, { instanceOf: TypeError }); }); test('parseOptions (errorOptions is not an object)', t => { @@ -67,7 +67,7 @@ test('parseOptions (errorOptions is not an object)', t => { common.parseOptions('-f', { f: 'force', }, 'not a valid errorOptions'); - }, TypeError); + }, { instanceOf: TypeError }); }); test('parseOptions (unrecognized string option)', t => { @@ -75,7 +75,7 @@ test('parseOptions (unrecognized string option)', t => { common.parseOptions('-z', { f: 'force', }); - }, common.CommandError); + }, { instanceOf: common.CommandError }); }); test('parseOptions (unrecognized option in Object)', t => { @@ -99,17 +99,17 @@ test('parseOptions (invalid type)', t => { test('convertErrorOutput: no args', t => { t.throws(() => { common.convertErrorOutput(); - }, TypeError); + }, { instanceOf: TypeError }); }); test('convertErrorOutput: input must be a vanilla string', t => { t.throws(() => { common.convertErrorOutput(3); - }, TypeError); + }, { instanceOf: TypeError }); t.throws(() => { common.convertErrorOutput({}); - }, TypeError); + }, { instanceOf: TypeError }); }); // @@ -168,6 +168,26 @@ test('broken links still expand', t => { t.deepEqual(result, ['test/resources/badlink']); }); +test('glob syntax, ? for single char in directory name', t => { + const result = common.expand(['test/r?sources/file1.txt']); + t.deepEqual(result, ['test/resources/file1.txt']); +}); + +test('glob syntax, ? for single char in directory name with * in file name', t => { + const result = common.expand(['test/r?sources/file*.txt']); + t.deepEqual(result.sort(), ['test/resources/file1.txt', 'test/resources/file2.txt'].sort()); +}); + +test('glob syntax, ? in multiple path segments', t => { + const result = common.expand(['test/r?sources/file?.txt']); + t.deepEqual(result.sort(), ['test/resources/file1.txt', 'test/resources/file2.txt'].sort()); +}); + +test('glob syntax, ? in file name still works', t => { + const result = common.expand(['test/resources/file?.txt']); + t.deepEqual(result.sort(), ['test/resources/file1.txt', 'test/resources/file2.txt'].sort()); +}); + test('empty array', t => { const result = common.expand([]); t.deepEqual(result, []); @@ -263,7 +283,7 @@ test('common.parseOptions using an object to hold options', t => { test('common.parseOptions throws when passed a string not starting with "-"', t => { t.throws(() => { common.parseOptions('a', { '-a': 'throws' }); - }, Error, "Options string must start with a '-'"); + }, { instanceOf: Error }, "Options string must start with a '-'"); }); test('common.parseOptions allows long options', t => { @@ -286,7 +306,7 @@ test('common.parseOptions throws for unknown long option', t => { common.parseOptions({ throws: true }, { v: 'value', }); - }, common.CommandError); + }, { instanceOf: common.CommandError }); }); test('common.parseOptions with -- argument', t => { @@ -310,16 +330,14 @@ test('Some basic tests on the ShellString type', t => { t.truthy(result.toEnd); }); -test.cb('Commands that fail will still output error messages to stderr', t => { - const script = 'require(\'./global\'); ls(\'noexist\'); cd(\'noexist\');'; - utils.runScript(script, (err, stdout, stderr) => { - t.is(stdout, ''); - t.is( - stderr, - 'ls: no such file or directory: noexist\ncd: no such file or directory: noexist\n' - ); - t.end(); - }); +test('Commands that fail will still output error messages to stderr', async t => { + const script = "require('./global'); ls('noexist'); cd('noexist');"; + const result = await utils.runScript(script); + t.is(result.stdout, ''); + t.is( + result.stderr, + 'ls: no such file or directory: noexist\ncd: no such file or directory: noexist\n' + ); }); test('execPath value makes sense', t => { diff --git a/test/config.js b/test/config.js index 743df3561..1e3a337ce 100644 --- a/test/config.js +++ b/test/config.js @@ -1,8 +1,10 @@ -import test from 'ava'; +const path = require('path'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const test = require('ava'); + +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); // // Valids @@ -30,46 +32,295 @@ test('config.silent can be set to false', t => { // config.fatal // -test.cb('config.fatal = false', t => { +test('config.fatal = false', async t => { t.falsy(shell.config.fatal); - const script = 'require(\'./global.js\'); config.silent=true; config.fatal=false; cp("this_file_doesnt_exist", "."); echo("got here");'; - utils.runScript(script, (err, stdout) => { - t.truthy(stdout.match('got here')); - t.end(); - }); + const script = `require('./global.js'); config.silent=true; config.fatal=false; cp("this_file_doesnt_exist", "."); echo("got here");`; + const result = await utils.runScript(script); + t.truthy(result.stdout.match('got here')); +}); + +test('config.fatal = true', async t => { + const script = `require('./global.js'); config.silent=true; config.fatal=true; cp("this_file_doesnt_exist", "."); echo("got here");`; + await t.throwsAsync(utils.runScript(script), + { message: /this_file_doesnt_exist/ }); }); -test.cb('config.fatal = true', t => { - const script = 'require(\'./global.js\'); config.silent=true; config.fatal=true; cp("this_file_doesnt_exist", "."); echo("got here");'; - utils.runScript(script, (err, stdout) => { - t.falsy(stdout.match('got here')); - t.end(); +test('config.fatal = false with an exec() failure returns, does not throw', t => { + const expected = { code: 2 }; + t.notThrows(() => { + const result = shell.exec('exit 2'); + t.is(result.code, expected.code); }); }); +test('config.fatal = true with an exec() failure includes a .code on the Error', t => { + shell.config.fatal = true; + try { + t.throws(() => { + shell.exec('exit 2'); + }, { code: 2 }); + } finally { + shell.config.fatal = false; + } +}); + // // config.globOptions // -test('Expands to directories by default', t => { +test('config.globOptions expands directories by default', t => { + const result = common.expand(['test/resources/*a*']); + const expected = [ + 'test/resources/a.txt', + 'test/resources/badlink', + 'test/resources/cat', + 'test/resources/external', + 'test/resources/head', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions handles non-wildcards by default', t => { + const result = common.expand(['test/resources/a.txt']); + const expected = [ + 'test/resources/a.txt', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions expands "?" symbol by default', t => { + const result = common.expand(['test/resources/file?.t*']); + const expected = [ + 'test/resources/file1.txt', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions expands "*" in multiple path segments by default', t => { + const result = common.expand(['test/r*sources/file?.txt']); + const expected = [ + 'test/resources/file1.txt', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); +}); + +// https://github.com/shelljs/shelljs/issues/1197 +test('config.globOptions expands "?" in folder path by default', t => { + const result = common.expand(['test/r?sources/file*.txt']); + const expected = [ + 'test/resources/file1.txt', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects cwd', t => { + // Both node-glob and fast-glob call this option 'cwd'. + shell.config.globOptions = { cwd: 'test' }; + const result = common.expand(['resources/*a*']); + const expected = [ + 'resources/a.txt', + 'resources/badlink', + 'resources/cat', + 'resources/external', + 'resources/head', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects dot', t => { + // Both node-glob and fast-glob call this option 'dot'. + shell.config.globOptions = { dot: true }; + const result = common.expand(['test/resources/ls/*']); + t.is(result.length, 8); + t.truthy(result.includes('test/resources/ls/.hidden_dir')); + t.truthy(result.includes('test/resources/ls/.hidden_file')); +}); + +test('config.globOptions respects ignore', t => { + // Both node-glob and fast-glob call this option 'ignore'. + shell.config.globOptions = { ignore: ['test/resources/external'] }; + const result = common.expand(['test/resources/*a*']); + const expected = [ + 'test/resources/a.txt', + 'test/resources/badlink', + 'test/resources/cat', + 'test/resources/head', + ]; + t.deepEqual(result, expected); + // Does not include the result that we chose to ignore + t.falsy(result.includes('test/resources/external')); +}); + +test('config.globOptions respects absolute', t => { + // Both node-glob and fast-glob call this option 'absolute'. + shell.config.globOptions = { absolute: true }; const result = common.expand(['test/resources/*a*']); - t.is(result.length, 5); - t.truthy(result.indexOf('test/resources/a.txt') > -1); - t.truthy(result.indexOf('test/resources/badlink') > -1); - t.truthy(result.indexOf('test/resources/cat') > -1); - t.truthy(result.indexOf('test/resources/head') > -1); - t.truthy(result.indexOf('test/resources/external') > -1); -}); - -test( - 'Check to make sure options get passed through (nodir is an example)', - t => { - shell.config.globOptions = { nodir: true }; - const result = common.expand(['test/resources/*a*']); - t.is(result.length, 2); - t.truthy(result.indexOf('test/resources/a.txt') > -1); - t.truthy(result.indexOf('test/resources/badlink') > -1); - t.truthy(result.indexOf('test/resources/cat') < 0); - t.truthy(result.indexOf('test/resources/external') < 0); + function abs(file) { + // Normalize to posix-style path separators on all platforms. + const CWD = process.platform === 'win32' ? + process.cwd().replace(/\\/g, '/') : + process.cwd(); + return path.posix.join(CWD, file); } -); + const expected = [ + abs('test/resources/a.txt'), + abs('test/resources/badlink'), + abs('test/resources/cat'), + abs('test/resources/external'), + abs('test/resources/head'), + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects nodir', t => { + shell.config.globOptions = { nodir: true }; + const result = common.expand(['test/resources/*a*']); + // Includes files and symlinks. + const expected = [ + 'test/resources/a.txt', + 'test/resources/badlink', + ]; + t.deepEqual(result, expected); + // Does not include the directories. + t.falsy(result.includes('test/resources/cat')); + t.falsy(result.includes('test/resources/head')); + t.falsy(result.includes('test/resources/external')); +}); + +test('config.globOptions respects mark', t => { + shell.config.globOptions = { mark: true }; + const result = common.expand(['test/resources/*a*']); + // Directories get a '/' character at the end. + const expected = [ + 'test/resources/a.txt', + 'test/resources/badlink', + 'test/resources/cat/', + 'test/resources/external/', + 'test/resources/head/', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects nobrace', t => { + // Default behavior is to expand "file{1..2}.txt" to ["file1.txt", + // "file2.txt"]. + let result = common.expand(['test/resources/file{1..2}.txt']); + let expected = [ + 'test/resources/file1.txt', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); + + // When 'nobrace' is true, brace expressions will expand as literals. + shell.config.globOptions = { nobrace: true }; + result = common.expand(['test/resources/file{1..2}.txt']); + expected = [ + 'test/resources/file{1..2}.txt', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects noglobstar', t => { + // Default behavior is to expand "**" to match zero or more directories. + let result = common.expand(['test/**/file1']); + let expected = [ + 'test/resources/cat/file1', + 'test/resources/chmod/file1', + 'test/resources/cp/file1', + 'test/resources/file1', + 'test/resources/ls/file1', + 'test/resources/sort/file1', + 'test/resources/uniq/file1', + ]; + t.deepEqual(result, expected); + + // When 'noglobstar' is true, "**" will behave like a regular "*" and matches + // exactly 1 directory. + shell.config.globOptions = { noglobstar: true }; + result = common.expand(['test/**/file1']); + expected = [ + 'test/resources/file1', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects noext', t => { + // Default behavior is to support fancy glob patterns (like "file1.+(js|txt)"). + let result = common.expand([ + 'test/resources/file1.+(js|txt)', + 'test/resources/file2.*', + ]); + let expected = [ + 'test/resources/file1.js', + 'test/resources/file1.txt', + 'test/resources/file2.js', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); + + // When 'noext' is true, this only matches regular globs (like "file2.*"). + shell.config.globOptions = { noext: true }; + result = common.expand([ + 'test/resources/file1.+(js|txt)', + 'test/resources/file2.*', + ]); + expected = [ + 'test/resources/file1.+(js|txt)', + 'test/resources/file2.js', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects nocase', t => { + // Default behavior will change depending on macOS, Windows, or Linux. This is + // difficult to test in a cross-platform way. + + // When 'nocase' is true, we should be able to match files even if we use the + // wrong case in the pattern. + shell.config.globOptions = { nocase: true }; + let result = common.expand(['test/resources/FILE*.TXT']); + let expected = [ + 'test/resources/file1.txt', + 'test/resources/file2.txt', + ]; + t.deepEqual(result, expected); + + // When 'nocase' is false, using the wrong case will fail to match any files. + shell.config.globOptions = { nocase: false }; + result = common.expand(['test/resources/FILE*.TXT']); + expected = [ + 'test/resources/FILE*.TXT', + ]; + t.deepEqual(result, expected); +}); + +test('config.globOptions respects matchBase', t => { + // By default, "*" expressions only match inside of the same directory. + shell.config.globOptions = { cwd: 'test/resources' }; + let result = common.expand(['*ile1']); + let expected = [ + 'file1', + ]; + t.deepEqual(result, expected); + + // When 'matchBase' is true (and the pattern contains no slashes), the + // pattern is implicitly treated like "**/*" and will expand to + // subdirectories. + shell.config.globOptions = { cwd: 'test/resources', matchBase: true }; + result = common.expand(['*ile1']); + expected = [ + 'cat/file1', + 'chmod/file1', + 'cp/file1', + 'file1', + 'head/shortfile1', + 'ls/file1', + 'sort/file1', + 'uniq/file1', + ]; + t.deepEqual(result, expected); +}); diff --git a/test/cp.js b/test/cp.js index ba3a60468..749884ccb 100644 --- a/test/cp.js +++ b/test/cp.js @@ -1,10 +1,10 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); const oldMaxDepth = shell.config.maxdepth; const CWD = process.cwd(); @@ -443,23 +443,24 @@ test('-R implies -P', t => { }); }); -test('-Ru respects the -u flag recursively (don\'t update newer file)', t => { +test("-Ru respects the -u flag recursively (don't update newer file)", t => { // Setup code - const TWO_DAYS_IN_MS = 2 * 24 * 60 * 60 * 1000; const dir = `${t.context.tmp}/cp-Ru`; - const sourceDir = `${dir}/old`; + const sourceDir = `${dir}/original`; const sourceFile = `${sourceDir}/file`; const destDir = `${dir}/new`; - const destFile = `${destDir}/file`; - [sourceDir, destDir].forEach(d => shell.mkdir('-p', d)); + const nestedDestDir = `${dir}/new/original`; + const destFile = `${nestedDestDir}/file`; + [sourceDir, destDir, nestedDestDir].forEach(d => shell.mkdir('-p', d)); shell.ShellString('Source File Contents\n').to(sourceFile); shell.ShellString('Destination File Contents\n').to(destFile); + const oldModifyTimeMs = 12345000; + const newModifyTimeMs = 67890000; // End setup - // Get the old mtime for dest - const oldTime = fs.statSync(destFile).mtimeMs; - // Set the source file to be older than the destination file - shell.touch('-m', oldTime - TWO_DAYS_IN_MS, sourceFile); - // Now, copy the old dir to the new one + + // Set the source file to be OLDER than the destination file + shell.touch({ '-m': true, '-d': new Date(oldModifyTimeMs) }, sourceFile); + shell.touch({ '-m': true, '-d': new Date(newModifyTimeMs) }, destFile); shell.cp('-Ru', sourceDir, destDir); // Check that dest has not been updated t.is(shell.cat(destFile).stdout, 'Destination File Contents\n'); @@ -467,24 +468,25 @@ test('-Ru respects the -u flag recursively (don\'t update newer file)', t => { test('-Ru respects the -u flag recursively (update older file)', t => { // Setup code - const TWO_DAYS_IN_MS = 2 * 24 * 60 * 60 * 1000; const dir = `${t.context.tmp}/cp-Ru`; - const sourceDir = `${dir}/old`; + const sourceDir = `${dir}/original`; const sourceFile = `${sourceDir}/file`; const destDir = `${dir}/new`; - const destFile = `${destDir}/file`; - [sourceDir, destDir].forEach(d => shell.mkdir('-p', d)); + const nestedDestDir = `${dir}/new/original`; + const destFile = `${nestedDestDir}/file`; + [sourceDir, destDir, nestedDestDir].forEach(d => shell.mkdir('-p', d)); shell.ShellString('Source File Contents\n').to(sourceFile); shell.ShellString('Destination File Contents\n').to(destFile); + const oldModifyTimeMs = 12345000; + const newModifyTimeMs = 67890000; // End setup - // Get the old mtime for dest - const oldTime = fs.statSync(destFile).mtimeMs; - // Set the destination file to be older than the source file - shell.touch('-m', oldTime + TWO_DAYS_IN_MS, sourceFile); - // Now, copy the old dir to the new one + + // Set the source file to be NEWER than the destination file + shell.touch({ '-m': true, '-d': new Date(newModifyTimeMs) }, sourceFile); + shell.touch({ '-m': true, '-d': new Date(oldModifyTimeMs) }, destFile); shell.cp('-Ru', sourceDir, destDir); - // Check that dest has been updated - t.is(shell.cat(sourceFile).stdout, 'Source File Contents\n'); + // Check that dest has been overwritten + t.is(shell.cat(destFile).stdout, 'Source File Contents\n'); }); test('using -P explicitly works', t => { @@ -519,7 +521,7 @@ test('Recursive, copies entire directory with no symlinks and -L option does not }); }); -test('-u flag won\'t overwrite newer files', t => { +test("-u flag won't overwrite newer files", t => { shell.touch(`${t.context.tmp}/file1.js`); shell.cp('-u', 'test/resources/file1.js', t.context.tmp); t.falsy(shell.error()); @@ -533,7 +535,7 @@ test('-u flag does overwrite older files', t => { t.is(shell.cat('test/resources/file1.js').toString(), shell.cat(`${t.context.tmp}/file1.js`).toString()); }); -test('-u flag works even if it\'s not overwriting a file', t => { +test("-u flag works even if it's not overwriting a file", t => { t.falsy(fs.existsSync(`${t.context.tmp}/file1.js`)); shell.cp('-u', 'test/resources/file1.js', t.context.tmp); t.falsy(shell.error()); @@ -733,7 +735,7 @@ test('copy file to same directory', t => { t.is(result.stderr, "cp: 'test/resources/file1' and 'test/resources/file1' are the same file"); }); -test('copy mutliple files to same location', t => { +test('copy multiple files to same location', t => { const result = shell.cp('test/resources/file1', 'test/resources/file2', 'test/resources'); t.truthy(shell.error()); t.is(result.code, 1); @@ -803,3 +805,191 @@ test('cp -R should be able to copy a readonly src. issue #98; (Non window platfo shell.chmod('-R', '755', t.context.tmp); }); }); + +test('cp -p should preserve mode, ownership, and timestamp (regular file)', t => { + // Setup: copy to srcFile and modify mode and timestamp + const srcFile = `${t.context.tmp}/srcFile`; + shell.cp('test/resources/cp/file1', srcFile); + // Make this a round number of seconds, since the underlying system may not + // have millisecond precision. + const newModifyTimeMs = 12345000; + const newAccessTimeMs = 67890000; + shell.touch({ '-d': new Date(newModifyTimeMs), '-m': true }, srcFile); + shell.touch({ '-d': new Date(newAccessTimeMs), '-a': true }, srcFile); + const mode = '444'; + shell.chmod(mode, srcFile); + + // Now re-copy with '-p' and verify metadata. + const result = shell.cp('-p', srcFile, `${t.context.tmp}/preservedFile1`); + const stat = common.statFollowLinks(srcFile); + const statOfResult = common.statFollowLinks(`${t.context.tmp}/preservedFile1`); + + t.is(result.code, 0); + + // Original file should be unchanged: + t.is(stat.mtime.getTime(), newModifyTimeMs); + // cp appears to update the atime, but only of the srcFile + t.is(stat.mode.toString(8), '100' + mode); + + // New file should keep same attributes + t.is(statOfResult.mtime.getTime(), newModifyTimeMs); + t.is(statOfResult.atime.getTime(), newAccessTimeMs); + t.is(statOfResult.mode.toString(8), '100' + mode); + + t.is(stat.uid, statOfResult.uid); + t.is(stat.gid, statOfResult.gid); +}); + +test('cp -p should preserve mode, ownership, and timestamp (directory)', t => { + // Setup: copy to srcFile and modify mode and timestamp + const srcDir = `${t.context.tmp}/srcDir`; + const srcFile = `${srcDir}/srcFile`; + shell.mkdir(srcDir); + shell.cp('test/resources/cp/file1', srcFile); + // Make this a round number of seconds, since the underlying system may not + // have millisecond precision. + const newModifyTimeMs = 12345000; + const newAccessTimeMs = 67890000; + shell.touch({ '-d': new Date(newModifyTimeMs), '-m': true }, srcFile); + shell.touch({ '-d': new Date(newAccessTimeMs), '-a': true }, srcFile); + fs.utimesSync(srcDir, new Date(newAccessTimeMs), new Date(newModifyTimeMs)); + const mode = '444'; + shell.chmod(mode, srcFile); + + // Now re-copy (the whole dir) with '-p' and verify metadata of file contents. + const result = shell.cp('-pr', srcDir, `${t.context.tmp}/preservedDir`); + const stat = common.statFollowLinks(srcFile); + const statDir = common.statFollowLinks(srcDir); + const statOfResult = common.statFollowLinks(`${t.context.tmp}/preservedDir/srcFile`); + const statOfResultDir = common.statFollowLinks(`${t.context.tmp}/preservedDir`); + + t.is(result.code, 0); + + // Both original file and original dir should be unchanged: + t.is(statDir.mtime.getTime(), newModifyTimeMs); + t.is(stat.mtime.getTime(), newModifyTimeMs); + // cp appears to update the atime, but only of the srcFile & srcDir + t.is(stat.mode.toString(8), '100' + mode); + + // Both new file and new dir should keep same attributes + t.is(statOfResultDir.mtime.getTime(), newModifyTimeMs); + utils.skipOnWin(t, () => { + // The resultDir atime may be updated on Windows as a side-effect, e.g. chmod(). + t.is(statOfResultDir.atime.getTime(), newAccessTimeMs); + }); + t.is(statOfResult.mtime.getTime(), newModifyTimeMs); + t.is(statOfResult.atime.getTime(), newAccessTimeMs); + t.is(statOfResult.mode.toString(8), '100' + mode); + + t.is(stat.uid, statOfResult.uid); + t.is(stat.gid, statOfResult.gid); +}); + +test('cp -p should preserve mode, ownership, and timestamp (symlink)', t => { + // Skip in Windows because symlinks require elevated permissions. + utils.skipOnWin(t, () => { + // Setup: copy to srcFile, create srcLink, and modify mode and timestamp + shell.cp('test/resources/cp/file1', `${t.context.tmp}/srcFile`); + const srcLink = `${t.context.tmp}/srcLink`; + shell.ln('-s', 'srcFile', `${t.context.tmp}/srcLink`); + // Make this a round number of seconds, since the underlying system may not + // have millisecond precision. + const newModifyTimeMs = 12345000; + const newAccessTimeMs = 67890000; + shell.touch({ '-d': new Date(newModifyTimeMs), '-m': true }, srcLink); + shell.touch({ '-d': new Date(newAccessTimeMs), '-a': true }, srcLink); + const mode = '444'; + shell.chmod(mode, srcLink); + + // Now re-copy with '-p' and verify metadata. + const result = shell.cp('-p', srcLink, `${t.context.tmp}/preservedLink`); + const stat = common.statFollowLinks(srcLink); + const statOfResult = common.statFollowLinks(`${t.context.tmp}/preservedLink`); + + t.is(result.code, 0); + + // Original file should be unchanged: + t.is(stat.mtime.getTime(), newModifyTimeMs); + // cp appears to update the atime, but only of the srcFile + t.is(stat.mode.toString(8), '100' + mode); + + // New file should keep same attributes + t.is(statOfResult.mtime.getTime(), newModifyTimeMs); + t.is(statOfResult.atime.getTime(), newAccessTimeMs); + t.is(statOfResult.mode.toString(8), '100' + mode); + + t.is(stat.uid, statOfResult.uid); + t.is(stat.gid, statOfResult.gid); + }); +}); + +test('copy directory to its parent dir (same location) should not erase content', t => { + // Setup: create a directory with a file inside t.context.tmp + shell.mkdir(`${t.context.tmp}/srcdir`); + shell.ShellString('deadbeef').to(`${t.context.tmp}/srcdir/lol`); + + // Verify setup + t.is(shell.cat(`${t.context.tmp}/srcdir/lol`).toString(), 'deadbeef'); + + // This should error, not silently erase the file contents + const result = shell.cp('-R', `${t.context.tmp}/srcdir`, t.context.tmp); + t.truthy(shell.error()); + t.is(result.code, 1); + t.truthy(result.stderr.match(/are the same file/)); + + // Most importantly: file content must be preserved (no data loss) + t.is(shell.cat(`${t.context.tmp}/srcdir/lol`).toString(), 'deadbeef'); +}); + +test('copy directory to same location with trailing slash should not erase content', t => { + // Setup: create a directory with a file inside t.context.tmp + shell.mkdir(`${t.context.tmp}/srcdir`); + shell.ShellString('deadbeef').to(`${t.context.tmp}/srcdir/lol`); + + // Verify setup + t.is(shell.cat(`${t.context.tmp}/srcdir/lol`).toString(), 'deadbeef'); + + // cp -R /path/srcdir /path/ should detect same directory + const result = shell.cp('-R', `${t.context.tmp}/srcdir`, `${t.context.tmp}/`); + t.truthy(shell.error()); + t.is(result.code, 1); + t.truthy(result.stderr.match(/are the same file/)); + + // File content must be preserved + t.is(shell.cat(`${t.context.tmp}/srcdir/lol`).toString(), 'deadbeef'); +}); + +test('copy multiple dirs where one is to same location should error for that one and continue', t => { + // Setup: src1 in tmp root, src2 inside destination + shell.mkdir(`${t.context.tmp}/src1`); + shell.mkdir('-p', `${t.context.tmp}/destination/src2`); + shell.ShellString('content1').to(`${t.context.tmp}/src1/file`); + shell.ShellString('content2').to(`${t.context.tmp}/destination/src2/file`); + + // src1 copy should succeed, src2 copy should fail (but the original src2 is still intact) + const result = shell.cp('-R', `${t.context.tmp}/src1`, `${t.context.tmp}/destination/src2`, `${t.context.tmp}/destination`); + t.truthy(shell.error()); + t.is(result.code, 1); + + // src1 was copied successfully into destination + t.is(shell.cat(`${t.context.tmp}/destination/src1/file`).toString(), 'content1'); + // src2's original content is preserved (not lost due to same-file copy) + t.is(shell.cat(`${t.context.tmp}/destination/src2/file`).toString(), 'content2'); +}); + +test('copy single file to itself should not erase content', t => { + // Setup: create a file in t.context.tmp + shell.ShellString('important data').to(`${t.context.tmp}/myfile.txt`); + + // Verify setup + t.is(shell.cat(`${t.context.tmp}/myfile.txt`).toString(), 'important data'); + + // Copying a file to itself should error but preserve data + const result = shell.cp(`${t.context.tmp}/myfile.txt`, `${t.context.tmp}/myfile.txt`); + t.truthy(shell.error()); + t.is(result.code, 1); + t.truthy(result.stderr.match(/are the same file/)); + + // File content must be preserved (no data loss) + t.is(shell.cat(`${t.context.tmp}/myfile.txt`).toString(), 'important data'); +}); diff --git a/test/dirs.js b/test/dirs.js index 10d6e4d7f..44f82486a 100644 --- a/test/dirs.js +++ b/test/dirs.js @@ -1,8 +1,8 @@ -import path from 'path'; +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; +const shell = require('..'); test.beforeEach(() => { shell.config.resetForTesting(); diff --git a/test/docs.js b/test/docs.js new file mode 100644 index 000000000..67d503462 --- /dev/null +++ b/test/docs.js @@ -0,0 +1,11 @@ +const test = require('ava'); + +const gendocs = require('../scripts/generate-docs'); + +test('Documentation generation', t => { + if (gendocs.extractCurrentDocs() === gendocs.generateNewDocs()) { + t.pass(); + } else { + t.fail('README documentation is stale. Please run `npm run gendocs`.'); + } +}); diff --git a/test/echo.js b/test/echo.js index 1d571e49b..c6989ac1e 100644 --- a/test/echo.js +++ b/test/echo.js @@ -1,19 +1,21 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; -import mocks from './utils/mocks'; +const shell = require('..'); +const utils = require('./utils/utils'); +const mocks = require('./utils/mocks'); shell.config.silent = true; test.beforeEach(t => { t.context.tmp = utils.getTempDir(); - mocks.init(); + mocks.stdout.init(); + mocks.stderr.init(); }); test.afterEach.always(t => { shell.rm('-rf', t.context.tmp); - mocks.restore(); + mocks.stdout.restore(); + mocks.stderr.restore(); }); // @@ -22,8 +24,8 @@ test.afterEach.always(t => { test('simple test with defaults', t => { const result = shell.echo('hello', 'world'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, 'hello world\n'); @@ -33,8 +35,8 @@ test('simple test with defaults', t => { test('allow arguments to begin with a hyphen', t => { // Github issue #20 const result = shell.echo('-asdf', '111'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 1); t.is(stdout, '-asdf 111\n'); @@ -43,8 +45,8 @@ test('allow arguments to begin with a hyphen', t => { test("using null as an explicit argument doesn't crash the function", t => { const result = shell.echo(null); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, 'null\n'); @@ -53,8 +55,8 @@ test("using null as an explicit argument doesn't crash the function", t => { test('-e option', t => { const result = shell.echo('-e', '\tmessage'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, '\tmessage\n'); @@ -72,8 +74,8 @@ test('piping to a file', t => { t.falsy(shell.error()); t.is(resultB.code, 0); const result = shell.cat(tmp); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(stdout, 'A\nB\n'); t.is(stderr, ''); @@ -82,8 +84,8 @@ test('piping to a file', t => { test('-n option', t => { const result = shell.echo('-n', 'message'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, 'message'); @@ -92,8 +94,8 @@ test('-n option', t => { test('-ne option', t => { const result = shell.echo('-ne', 'message'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, 'message'); @@ -102,8 +104,8 @@ test('-ne option', t => { test('-en option', t => { const result = shell.echo('-en', 'message'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, 'message'); @@ -112,8 +114,8 @@ test('-en option', t => { test('-en option with escaped characters', t => { const result = shell.echo('-en', '\tmessage\n'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 0); t.is(stdout, '\tmessage\n'); @@ -131,8 +133,8 @@ test('piping to a file with -n', t => { t.falsy(shell.error()); t.is(resultB.code, 0); const result = shell.cat(tmp); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(stdout, 'AB'); t.is(stderr, ''); @@ -141,8 +143,8 @@ test('piping to a file with -n', t => { test('stderr with unrecognized options is empty', t => { const result = shell.echo('-asdf'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(result.code, 1); t.falsy(result.stderr); diff --git a/test/env.js b/test/env.js index 50a143545..a9f2c009e 100644 --- a/test/env.js +++ b/test/env.js @@ -1,6 +1,6 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; +const shell = require('..'); shell.config.silent = true; diff --git a/test/exec.js b/test/exec.js index a8e79dfa4..79caca5da 100644 --- a/test/exec.js +++ b/test/exec.js @@ -1,25 +1,27 @@ -import os from 'os'; -import path from 'path'; -import util from 'util'; +const os = require('os'); +const path = require('path'); +const util = require('util'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; -import mocks from './utils/mocks'; +const shell = require('..'); +const utils = require('./utils/utils'); +const mocks = require('./utils/mocks'); const CWD = process.cwd(); const ORIG_EXEC_PATH = shell.config.execPath; shell.config.silent = true; test.beforeEach(() => { - mocks.init(); + mocks.stdout.init(); + mocks.stderr.init(); }); test.afterEach.always(() => { process.chdir(CWD); shell.config.execPath = ORIG_EXEC_PATH; - mocks.restore(); + mocks.stdout.restore(); + mocks.stderr.restore(); }); // @@ -41,7 +43,7 @@ test('config.fatal and unknown command', t => { shell.config.fatal = true; t.throws(() => { shell.exec('asdfasdf'); // could not find command - }, /asdfasdf/); // name of command should be in error message + }, { message: /asdfasdf/ }); // name of command should be in error message shell.config.fatal = oldFatal; }); @@ -50,7 +52,7 @@ test('options.fatal = true and unknown command', t => { shell.config.fatal = false; t.throws(() => { shell.exec('asdfasdf', { fatal: true }); // could not find command - }, /asdfasdf/); // name of command should be in error message + }, { message: /asdfasdf/ }); // name of command should be in error message shell.config.fatal = oldFatal; // TODO(nfischer): this setting won't get reset if the assertion above fails }); @@ -63,10 +65,9 @@ test('exec exits gracefully if we cannot find the execPath', t => { ); }); -test('cannot require exec-child.js', t => { - t.throws(() => { - require('../src/exec-child.js'); - }, /This file should not be required/); +test('exec-child.js should not be imported', t => { + const execChild = require('../src/exec-child'); + t.deepEqual([], Object.keys(execChild)); }); // @@ -102,8 +103,8 @@ test('check if stdout + stderr go to output', t => { test('check if stdout + stderr should not be printed to console if silent', t => { shell.exec(`${JSON.stringify(shell.config.execPath)} -e "console.error(1234); console.log(666); process.exit(12);"`, { silent: true }); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.is(stdout, ''); t.is(stderr, ''); }); @@ -151,11 +152,14 @@ test('set maxBuffer (very small)', t => { }); test('set timeout option', t => { - const result = shell.exec(`${JSON.stringify(shell.config.execPath)} test/resources/exec/slow.js 100`); // default timeout is ok + let result = shell.exec(`${JSON.stringify(shell.config.execPath)} test/resources/exec/slow.js 100`); // default timeout is ok t.falsy(shell.error()); t.is(result.code, 0); - shell.exec(`${JSON.stringify(shell.config.execPath)} test/resources/exec/slow.js 2000`, { timeout: 1000 }); // times out + t.is(result.stdout, 'fast\nslow\n'); + result = shell.exec(`${JSON.stringify(shell.config.execPath)} test/resources/exec/slow.js 2000`, { timeout: 1000 }); // times out t.truthy(shell.error()); + t.is(result.code, 1); + t.is(result.stdout, 'fast\n'); }); test('check process.env works', t => { @@ -176,10 +180,10 @@ test('set shell option (TODO: add tests for Windows)', t => { t.is(result.stdout, '/bin/sh\n'); // sh by default const bashPath = shell.which('bash').trim(); if (bashPath) { - result = shell.exec('echo $0', { shell: '/bin/bash' }); + result = shell.exec('echo $0', { shell: bashPath }); t.falsy(shell.error()); t.is(result.code, 0); - t.is(result.stdout, '/bin/bash\n'); + t.is(result.stdout, `${bashPath}\n`); } }); }); @@ -215,56 +219,53 @@ test('options.fatal = false and unknown command', t => { // async // -test.cb('no callback', t => { +function execAsync(...execArgs) { + return new Promise((resolve) => { + shell.exec(...execArgs, (code, stdout, stderr) => { + resolve({ code, stdout, stderr }); + }); + }); +} + +test('no callback', t => { const c = shell.exec(`${JSON.stringify(shell.config.execPath)} -e "console.log(1234)"`, { async: true }); t.falsy(shell.error()); t.truthy('stdout' in c, 'async exec returns child process object'); - t.end(); }); -test.cb('callback as 2nd argument', t => { - shell.exec(`${JSON.stringify(shell.config.execPath)} -e "console.log(5678);"`, (code, stdout, stderr) => { - t.is(code, 0); - t.is(stdout, '5678\n'); - t.is(stderr, ''); - t.end(); - }); +test('callback as 2nd argument', async t => { + const result = await execAsync(`${JSON.stringify(shell.config.execPath)} -e "console.log(5678);"`); + t.is(result.code, 0); + t.is(result.stdout, '5678\n'); + t.is(result.stderr, ''); }); -test.cb('callback as end argument', t => { - shell.exec(`${JSON.stringify(shell.config.execPath)} -e "console.log(5566);"`, { async: true }, (code, stdout, stderr) => { - t.is(code, 0); - t.is(stdout, '5566\n'); - t.is(stderr, ''); - t.end(); - }); +test('callback as end argument', async t => { + const result = await execAsync(`${JSON.stringify(shell.config.execPath)} -e "console.log(5566);"`, { async: true }); + t.is(result.code, 0); + t.is(result.stdout, '5566\n'); + t.is(result.stderr, ''); }); -test.cb('callback as 3rd argument (silent:true)', t => { - shell.exec(`${JSON.stringify(shell.config.execPath)} -e "console.log(5678);"`, { silent: true }, (code, stdout, stderr) => { - t.is(code, 0); - t.is(stdout, '5678\n'); - t.is(stderr, ''); - t.end(); - }); +test('callback as 3rd argument (silent:true)', async t => { + const result = await execAsync(`${JSON.stringify(shell.config.execPath)} -e "console.log(5678);"`, { silent: true }); + t.is(result.code, 0); + t.is(result.stdout, '5678\n'); + t.is(result.stderr, ''); }); -test.cb('command that fails', t => { - shell.exec('shx cp onlyOneCpArgument.txt', { silent: true }, (code, stdout, stderr) => { - t.is(code, 1); - t.is(stdout, ''); - t.is(stderr, 'cp: missing and/or \n'); - t.end(); - }); +test('command that fails', async t => { + const result = await execAsync('shx cp onlyOneCpArgument.txt', { silent: true }); + t.is(result.code, 1); + t.is(result.stdout, ''); + t.is(result.stderr, 'cp: missing and/or \n'); }); -test.cb('encoding option works with async', t => { - shell.exec(`${JSON.stringify(shell.config.execPath)} -e "console.log(5566);"`, { async: true, encoding: 'buffer' }, (code, stdout, stderr) => { - t.is(code, 0); - t.truthy(Buffer.isBuffer(stdout)); - t.truthy(Buffer.isBuffer(stderr)); - t.is(stdout.toString(), '5566\n'); - t.is(stderr.toString(), ''); - t.end(); - }); +test('encoding option works with async', async t => { + const result = await execAsync(`${JSON.stringify(shell.config.execPath)} -e "console.log(5566);"`, { async: true, encoding: 'buffer' }); + t.is(result.code, 0); + t.truthy(Buffer.isBuffer(result.stdout)); + t.truthy(Buffer.isBuffer(result.stderr)); + t.is(result.stdout.toString(), '5566\n'); + t.is(result.stderr.toString(), ''); }); diff --git a/test/exit.js b/test/exit.js new file mode 100644 index 000000000..b0add2552 --- /dev/null +++ b/test/exit.js @@ -0,0 +1,57 @@ +const test = require('ava'); + +const shell = require('..'); + +const mocks = require('./utils/mocks'); + +// +// Valids +// + +function runExitInSubprocess(code) { + const script = code !== undefined + ? `var shell = require("."); shell.exit(${code});` + : 'var shell = require("."); shell.exit();'; + const result = shell.exec( + `${JSON.stringify(shell.config.execPath)} -e ${JSON.stringify(script)}` + ); + const actualReturnCode = result.code; + return actualReturnCode; +} + +test('exit with success status code', t => { + t.is(runExitInSubprocess(0), 0); +}); + +test('exit without explicit code should be success', t => { + t.is(runExitInSubprocess(), 0); +}); + +test('exit with failure status code', t => { + t.is(runExitInSubprocess(5), 5); + t.is(runExitInSubprocess(2), 2); + t.is(runExitInSubprocess(25), 25); +}); + +test('exit correctly sets the shell.errorCode()', t => { + try { + mocks.exit.init(); + shell.exit(5); // Safe to call shell.exit() because it's mocked. + t.is(shell.errorCode(), 5); + t.is(mocks.exit.getValue(), 5); + t.truthy(shell.error()); + + shell.exit(0); // Safe to call shell.exit() because it's mocked. + t.is(shell.errorCode(), 0); + t.falsy(mocks.exit.getValue()); + t.falsy(shell.error()); + + // Also try it without an explicit argument. + shell.exit(); // Safe to call shell.exit() because it's mocked. + t.is(shell.errorCode(), 0); + t.falsy(mocks.exit.getValue()); + t.falsy(shell.error()); + } finally { + mocks.exit.restore(); + } +}); diff --git a/test/find.js b/test/find.js index 2f9e0aa6c..f698028df 100644 --- a/test/find.js +++ b/test/find.js @@ -1,6 +1,6 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; +const shell = require('..'); const CWD = process.cwd(); @@ -28,9 +28,9 @@ test('current path', t => { const result = shell.find('.'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('.hidden') > -1); - t.truthy(result.indexOf('dir1/dir11/a_dir11') > -1); - t.is(result.length, 11); + t.truthy(result.includes('.hidden')); + t.truthy(result.includes('dir1/dir11/a_dir11')); + t.is(result.length, 12); shell.cd('../..'); }); @@ -38,17 +38,17 @@ test('simple path', t => { const result = shell.find('test/resources/find'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/find/.hidden') > -1); - t.truthy(result.indexOf('test/resources/find/dir1/dir11/a_dir11') > -1); - t.is(result.length, 11); + t.truthy(result.includes('test/resources/find/.hidden')); + t.truthy(result.includes('test/resources/find/dir1/dir11/a_dir11')); + t.is(result.length, 12); }); test('multiple paths - comma', t => { const result = shell.find('test/resources/find/dir1', 'test/resources/find/dir2'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/find/dir1/dir11/a_dir11') > -1); - t.truthy(result.indexOf('test/resources/find/dir2/a_dir1') > -1); + t.truthy(result.includes('test/resources/find/dir1/dir11/a_dir11')); + t.truthy(result.includes('test/resources/find/dir2/a_dir1')); t.is(result.length, 6); }); @@ -56,8 +56,8 @@ test('multiple paths - array', t => { const result = shell.find(['test/resources/find/dir1', 'test/resources/find/dir2']); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/find/dir1/dir11/a_dir11') > -1); - t.truthy(result.indexOf('test/resources/find/dir2/a_dir1') > -1); + t.truthy(result.includes('test/resources/find/dir1/dir11/a_dir11')); + t.truthy(result.includes('test/resources/find/dir2/a_dir1')); t.is(result.length, 6); }); @@ -66,3 +66,11 @@ test('nonexistent path', t => { t.is(shell.error(), 'find: no such file or directory: test/resources/find/nonexistent'); t.is(result.code, 1); }); + +test('-L flag, folder is symlinked', t => { + const result = shell.find('-L', 'test/resources/find'); + t.falsy(shell.error()); + t.is(result.code, 0); + t.truthy(result.includes('test/resources/find/dir2_link/a_dir1')); + t.is(result.length, 13); +}); diff --git a/test/global.js b/test/global.js index c1b46e229..81227f00a 100644 --- a/test/global.js +++ b/test/global.js @@ -1,10 +1,10 @@ /* globals cat, config, cp, env, error, mkdir, rm */ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import '../global'; -import utils from './utils/utils'; +require('../global'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); diff --git a/test/grep.js b/test/grep.js index 8f6a0c6a8..4b64d6e76 100644 --- a/test/grep.js +++ b/test/grep.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -24,6 +24,7 @@ test('no args', t => { const result = shell.grep(); t.truthy(shell.error()); t.is(result.code, 2); + t.is(shell.errorCode(), 2); }); test('too few args', t => { @@ -56,6 +57,27 @@ test("multiple files, one doesn't exist, one doesn't match", t => { t.is(result.code, 2); }); +test('-A option, negative value', t => { + const result = shell.grep('-A', -2, 'test*', 'test/resources/grep/file3'); + t.truthy(shell.error()); + t.is(result.code, 2); + t.is(result.stderr, 'grep: -2: invalid context length argument'); +}); + +test('-B option, negative value', t => { + const result = shell.grep('-B', -3, 'test*', 'test/resources/grep/file3'); + t.truthy(shell.error()); + t.is(result.code, 2); + t.is(result.stderr, 'grep: -3: invalid context length argument'); +}); + +test('-C option, negative value', t => { + const result = shell.grep('-C', -1, 'test*', 'test/resources/grep/file3'); + t.truthy(shell.error()); + t.is(result.code, 2); + t.is(result.stderr, 'grep: -1: invalid context length argument'); +}); + // // Valids // @@ -162,8 +184,233 @@ test('-i option', t => { t.is(result.split('\n').length - 1, 3); }); +test('-n option', t => { + const result = shell.grep('-n', /alpha*beta/, 'test/resources/grep/file'); + t.falsy(shell.error()); + t.is(result.toString(), '1:alphaaaaaaabeta\n3:alphbeta\n'); +}); + test('the pattern looks like an option', t => { const result = shell.grep('--', '-v', 'test/resources/grep/file2'); t.falsy(shell.error()); t.is(result.toString(), '-v\n-vv\n'); }); + +// +// Before & after contexts +// +test('-B option', t => { + const result = shell.grep('-B', 3, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line1\n' + + 'line2 test line\n' + + 'line3 test line\n' + + '--\n' + + 'line7\n' + + 'line8\n' + + 'line9\n' + + 'line10 test line\n' + + '--\n' + + 'line12\n' + + 'line13\n' + + 'line14\n' + + 'line15 test line\n', + ); +}); + +test('-B option, -n option', t => { + const result = shell.grep('-nB', 3, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + '1-line1\n' + + '2:line2 test line\n' + + '3:line3 test line\n' + + '--\n' + + '7-line7\n' + + '8-line8\n' + + '9-line9\n' + + '10:line10 test line\n' + + '--\n' + + '12-line12\n' + + '13-line13\n' + + '14-line14\n' + + '15:line15 test line\n', + ); +}); + +test('-A option', t => { + const result = shell.grep('-A', 2, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line2 test line\n' + + 'line3 test line\n' + + 'line4\n' + + 'line5\n' + + '--\n' + + 'line10 test line\n' + + 'line11\n' + + 'line12\n' + + '--\n' + + 'line15 test line\n', + ); +}); + +test('-A option, -B option', t => { + const result = shell.grep( + { '-A': 2, '-B': 3 }, + 'test*', + 'test/resources/grep/file3', + ); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line1\n' + + 'line2 test line\n' + + 'line3 test line\n' + + 'line4\n' + + 'line5\n' + + '--\n' + + 'line7\n' + + 'line8\n' + + 'line9\n' + + 'line10 test line\n' + + 'line11\n' + + 'line12\n' + + 'line13\n' + + 'line14\n' + + 'line15 test line\n', + ); +}); + +test('-A option, -B option, -n option', t => { + const result = shell.grep( + { '-n': true, '-A': 2, '-B': 3 }, + 'test*', + 'test/resources/grep/file3', + ); + t.falsy(shell.error()); + t.is( + result.toString(), + '1-line1\n' + + '2:line2 test line\n' + + '3:line3 test line\n' + + '4-line4\n' + + '5-line5\n' + + '--\n' + + '7-line7\n' + + '8-line8\n' + + '9-line9\n' + + '10:line10 test line\n' + + '11-line11\n' + + '12-line12\n' + + '13-line13\n' + + '14-line14\n' + + '15:line15 test line\n', + ); +}); + +test('-C option', t => { + const result = shell.grep('-C', 3, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line1\n' + + 'line2 test line\n' + + 'line3 test line\n' + + 'line4\n' + + 'line5\n' + + 'line6\n' + + 'line7\n' + + 'line8\n' + + 'line9\n' + + 'line10 test line\n' + + 'line11\n' + + 'line12\n' + + 'line13\n' + + 'line14\n' + + 'line15 test line\n', + ); +}); + +test('-C option, small value', t => { + const result = shell.grep('-C', 1, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line1\n' + + 'line2 test line\n' + + 'line3 test line\n' + + 'line4\n' + + '--\n' + + 'line9\n' + + 'line10 test line\n' + + 'line11\n' + + '--\n' + + 'line14\n' + + 'line15 test line\n', + ); +}); + +test('-C option, large value', t => { + const result = shell.grep('-C', 100, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line1\n' + + 'line2 test line\n' + + 'line3 test line\n' + + 'line4\n' + + 'line5\n' + + 'line6\n' + + 'line7\n' + + 'line8\n' + + 'line9\n' + + 'line10 test line\n' + + 'line11\n' + + 'line12\n' + + 'line13\n' + + 'line14\n' + + 'line15 test line\n', + ); +}); + +test('-C option, add line separators', t => { + const result = shell.grep('-C', 0, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + 'line2 test line\n' + + 'line3 test line\n' + + '--\n' + + 'line10 test line\n' + + '--\n' + + 'line15 test line\n', + ); +}); + +test('-C option, -n option', t => { + const result = shell.grep('-nC', 3, 'test*', 'test/resources/grep/file3'); + t.falsy(shell.error()); + t.is( + result.toString(), + '1-line1\n' + + '2:line2 test line\n' + + '3:line3 test line\n' + + '4-line4\n' + + '5-line5\n' + + '6-line6\n' + + '7-line7\n' + + '8-line8\n' + + '9-line9\n' + + '10:line10 test line\n' + + '11-line11\n' + + '12-line12\n' + + '13-line13\n' + + '14-line14\n' + + '15:line15 test line\n', + ); +}); diff --git a/test/head.js b/test/head.js index 51b812686..8f5f91574 100644 --- a/test/head.js +++ b/test/head.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; +const shell = require('..'); +const common = require('../src/common'); shell.config.silent = true; @@ -100,7 +100,7 @@ test('Globbed file', t => { .join('\n') + '\n'); }); -test('With `\'-n\' ` option', t => { +test("With '-n ' option", t => { const result = shell.head('-n', 4, 'test/resources/head/file2.txt', 'test/resources/head/file1.txt'); t.falsy(shell.error()); @@ -111,7 +111,7 @@ test('With `\'-n\' ` option', t => { .join('\n') + '\n'); }); -test('With `{\'-n\': }` option', t => { +test("With '{-n: }' option", t => { const result = shell.head({ '-n': 4 }, 'test/resources/head/file2.txt', 'test/resources/head/file1.txt'); t.falsy(shell.error()); diff --git a/test/ln.js b/test/ln.js index b16820584..1ef01eef4 100644 --- a/test/ln.js +++ b/test/ln.js @@ -1,10 +1,10 @@ -import fs from 'fs'; -import path from 'path'; +const fs = require('fs'); +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); const CWD = process.cwd(); diff --git a/test/ls.js b/test/ls.js index 0163f6f73..1c8ef6276 100644 --- a/test/ls.js +++ b/test/ls.js @@ -1,10 +1,10 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); const CWD = process.cwd(); @@ -36,10 +36,11 @@ test('no such file or dir', t => { // Valids // -test('it\'s ok to use no arguments', t => { +test("it's ok to use no arguments", t => { const result = shell.ls(); t.falsy(shell.error()); t.is(result.code, 0); + t.is(shell.errorCode(), 0); }); test('root directory', t => { @@ -53,12 +54,12 @@ test('no args provides the correct result', t => { const result = shell.ls(); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('file1') > -1); - t.truthy(result.indexOf('file2') > -1); - t.truthy(result.indexOf('file1.js') > -1); - t.truthy(result.indexOf('file2.js') > -1); - t.truthy(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1); - t.truthy(result.indexOf('a_dir') > -1); + t.truthy(result.includes('file1')); + t.truthy(result.includes('file2')); + t.truthy(result.includes('file1.js')); + t.truthy(result.includes('file2.js')); + t.truthy(result.includes('filename(with)[chars$]^that.must+be-escaped')); + t.truthy(result.includes('a_dir')); t.is(result.length, 6); }); @@ -66,12 +67,12 @@ test('simple arg', t => { const result = shell.ls('test/resources/ls'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('file1') > -1); - t.truthy(result.indexOf('file2') > -1); - t.truthy(result.indexOf('file1.js') > -1); - t.truthy(result.indexOf('file2.js') > -1); - t.truthy(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1); - t.truthy(result.indexOf('a_dir') > -1); + t.truthy(result.includes('file1')); + t.truthy(result.includes('file2')); + t.truthy(result.includes('file1.js')); + t.truthy(result.includes('file2.js')); + t.truthy(result.includes('filename(with)[chars$]^that.must+be-escaped')); + t.truthy(result.includes('a_dir')); t.is(result.length, 6); }); @@ -79,12 +80,12 @@ test('simple arg, with a trailing slash', t => { const result = shell.ls('test/resources/ls/'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('file1') > -1); - t.truthy(result.indexOf('file2') > -1); - t.truthy(result.indexOf('file1.js') > -1); - t.truthy(result.indexOf('file2.js') > -1); - t.truthy(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1); - t.truthy(result.indexOf('a_dir') > -1); + t.truthy(result.includes('file1')); + t.truthy(result.includes('file2')); + t.truthy(result.includes('file1.js')); + t.truthy(result.includes('file2.js')); + t.truthy(result.includes('filename(with)[chars$]^that.must+be-escaped')); + t.truthy(result.includes('a_dir')); t.is(result.length, 6); }); @@ -92,7 +93,7 @@ test('simple arg, a file', t => { const result = shell.ls('test/resources/ls/file1'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/ls/file1') > -1); + t.truthy(result.includes('test/resources/ls/file1')); t.is(result.length, 1); }); @@ -101,14 +102,14 @@ test('no args, -A option', t => { const result = shell.ls('-A'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('file1') > -1); - t.truthy(result.indexOf('file2') > -1); - t.truthy(result.indexOf('file1.js') > -1); - t.truthy(result.indexOf('file2.js') > -1); - t.truthy(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('.hidden_file') > -1); - t.truthy(result.indexOf('.hidden_dir') > -1); + t.truthy(result.includes('file1')); + t.truthy(result.includes('file2')); + t.truthy(result.includes('file1.js')); + t.truthy(result.includes('file2.js')); + t.truthy(result.includes('filename(with)[chars$]^that.must+be-escaped')); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('.hidden_file')); + t.truthy(result.includes('.hidden_dir')); t.is(result.length, 8); }); @@ -117,14 +118,14 @@ test('no args, deprecated -a option', t => { const result = shell.ls('-a'); // (deprecated) backwards compatibility test t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('file1') > -1); - t.truthy(result.indexOf('file2') > -1); - t.truthy(result.indexOf('file1.js') > -1); - t.truthy(result.indexOf('file2.js') > -1); - t.truthy(result.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('.hidden_file') > -1); - t.truthy(result.indexOf('.hidden_dir') > -1); + t.truthy(result.includes('file1')); + t.truthy(result.includes('file2')); + t.truthy(result.includes('file1.js')); + t.truthy(result.includes('file2.js')); + t.truthy(result.includes('filename(with)[chars$]^that.must+be-escaped')); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('.hidden_file')); + t.truthy(result.includes('.hidden_dir')); t.is(result.length, 8); }); @@ -132,11 +133,11 @@ test('wildcard, very simple', t => { const result = shell.ls('test/resources/cat/*'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/cat/file1') > -1); - t.truthy(result.indexOf('test/resources/cat/file2') > -1); - t.truthy(result.indexOf('test/resources/cat/file3') > -1); - t.truthy(result.indexOf('test/resources/cat/file4') > -1); - t.truthy(result.indexOf('test/resources/cat/file5') > -1); + t.truthy(result.includes('test/resources/cat/file1')); + t.truthy(result.includes('test/resources/cat/file2')); + t.truthy(result.includes('test/resources/cat/file3')); + t.truthy(result.includes('test/resources/cat/file4')); + t.truthy(result.includes('test/resources/cat/file5')); t.is(result.length, 5); }); @@ -144,16 +145,16 @@ test('wildcard, simple', t => { const result = shell.ls('test/resources/ls/*'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/ls/file1') > -1); - t.truthy(result.indexOf('test/resources/ls/file2') > -1); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); + t.truthy(result.includes('test/resources/ls/file1')); + t.truthy(result.includes('test/resources/ls/file2')); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); t.truthy( - result.indexOf('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1 + result.includes('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') ); - t.is(result.indexOf('test/resources/ls/a_dir'), -1); // this shouldn't be there - t.truthy(result.indexOf('nada') > -1); - t.truthy(result.indexOf('b_dir') > -1); + t.falsy(result.includes('test/resources/ls/a_dir')); // this shouldn't be there + t.truthy(result.includes('nada')); + t.truthy(result.includes('b_dir')); t.is(result.length, 7); }); @@ -161,14 +162,14 @@ test('wildcard, simple, with -d', t => { const result = shell.ls('-d', 'test/resources/ls/*'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/ls/file1') > -1); - t.truthy(result.indexOf('test/resources/ls/file2') > -1); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); + t.truthy(result.includes('test/resources/ls/file1')); + t.truthy(result.includes('test/resources/ls/file2')); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); t.truthy( - result.indexOf('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1 + result.includes('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') ); - t.truthy(result.indexOf('test/resources/ls/a_dir') > -1); + t.truthy(result.includes('test/resources/ls/a_dir')); t.is(result.length, 6); }); @@ -176,8 +177,8 @@ test('wildcard, hidden only', t => { const result = shell.ls('-d', 'test/resources/ls/.*'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/ls/.hidden_file') > -1); - t.truthy(result.indexOf('test/resources/ls/.hidden_dir') > -1); + t.truthy(result.includes('test/resources/ls/.hidden_file')); + t.truthy(result.includes('test/resources/ls/.hidden_dir')); t.is(result.length, 2); }); @@ -186,12 +187,12 @@ test('wildcard, mid-file', t => { t.falsy(shell.error()); t.is(result.code, 0); t.is(result.length, 5); - t.truthy(result.indexOf('test/resources/ls/file1') > -1); - t.truthy(result.indexOf('test/resources/ls/file2') > -1); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); + t.truthy(result.includes('test/resources/ls/file1')); + t.truthy(result.includes('test/resources/ls/file2')); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); t.truthy( - result.indexOf('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1 + result.includes('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') ); }); @@ -200,24 +201,24 @@ test('wildcard, mid-file with dot (should escape dot for regex)', t => { t.falsy(shell.error()); t.is(result.code, 0); t.is(result.length, 2); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); }); -test('one file that exists, one that doesn\'t', t => { +test("one file that exists, one that doesn't", t => { const result = shell.ls('test/resources/ls/file1.js', 'test/resources/ls/thisdoesntexist'); t.truthy(shell.error()); t.is(result.code, 2); t.is(result.length, 1); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); + t.truthy(result.includes('test/resources/ls/file1.js')); }); -test('one file that exists, one that doesn\'t (other order)', t => { +test("one file that exists, one that doesn't (other order)", t => { const result = shell.ls('test/resources/ls/thisdoesntexist', 'test/resources/ls/file1.js'); t.truthy(shell.error()); t.is(result.code, 2); t.is(result.length, 1); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); + t.truthy(result.includes('test/resources/ls/file1.js')); }); test('wildcard, should not do partial matches', t => { @@ -232,10 +233,10 @@ test('wildcard, all files with extension', t => { t.falsy(shell.error()); t.is(result.code, 0); t.is(result.length, 3); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); t.truthy( - result.indexOf('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1 + result.includes('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') ); }); @@ -244,10 +245,10 @@ test('wildcard, with additional path', t => { t.falsy(shell.error()); t.is(result.code, 0); t.is(result.length, 4); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); - t.truthy(result.indexOf('b_dir') > -1); // no wildcard == no path prefix - t.truthy(result.indexOf('nada') > -1); // no wildcard == no path prefix + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); + t.truthy(result.includes('b_dir')); // no wildcard == no path prefix + t.truthy(result.includes('nada')); // no wildcard == no path prefix }); test('wildcard for both paths', t => { @@ -255,10 +256,10 @@ test('wildcard for both paths', t => { t.falsy(shell.error()); t.is(result.code, 0); t.is(result.length, 4); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); - t.truthy(result.indexOf('z') > -1); - t.truthy(result.indexOf('test/resources/ls/a_dir/nada') > -1); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); + t.truthy(result.includes('z')); + t.truthy(result.includes('test/resources/ls/a_dir/nada')); }); test('wildcard for both paths, array', t => { @@ -266,10 +267,10 @@ test('wildcard for both paths, array', t => { t.falsy(shell.error()); t.is(result.code, 0); t.is(result.length, 4); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); - t.truthy(result.indexOf('z') > -1); - t.truthy(result.indexOf('test/resources/ls/a_dir/nada') > -1); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2.js')); + t.truthy(result.includes('z')); + t.truthy(result.includes('test/resources/ls/a_dir/nada')); }); test('recursive, no path', t => { @@ -277,9 +278,9 @@ test('recursive, no path', t => { const result = shell.ls('-R'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir/z') > -1); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('a_dir/b_dir')); + t.truthy(result.includes('a_dir/b_dir/z')); t.is(result.length, 9); }); @@ -287,9 +288,9 @@ test('recursive, path given', t => { const result = shell.ls('-R', 'test/resources/ls'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir/z') > -1); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('a_dir/b_dir')); + t.truthy(result.includes('a_dir/b_dir/z')); t.is(result.length, 9); }); @@ -297,10 +298,10 @@ test('-RA flag, path given', t => { const result = shell.ls('-RA', 'test/resources/ls'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir/z') > -1); - t.truthy(result.indexOf('a_dir/.hidden_dir/nada') > -1); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('a_dir/b_dir')); + t.truthy(result.includes('a_dir/b_dir/z')); + t.truthy(result.includes('a_dir/.hidden_dir/nada')); t.is(result.length, 14); }); @@ -308,11 +309,11 @@ test('-RA flag, symlinks are not followed', t => { const result = shell.ls('-RA', 'test/resources/rm'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('a_dir/a_file') > -1); - t.truthy(result.indexOf('link_to_a_dir') > -1); - t.is(result.indexOf('link_to_a_dir/a_file'), -1); - t.truthy(result.indexOf('fake.lnk') > -1); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('a_dir/a_file')); + t.truthy(result.includes('link_to_a_dir')); + t.falsy(result.includes('link_to_a_dir/a_file')); + t.truthy(result.includes('fake.lnk')); t.is(result.length, 4); }); @@ -321,11 +322,11 @@ test('-RAL flag, follows symlinks', t => { const result = shell.ls('-RAL', 'test/resources/rm'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('a_dir/a_file') > -1); - t.truthy(result.indexOf('link_to_a_dir') > -1); - t.truthy(result.indexOf('link_to_a_dir/a_file') > -1); - t.truthy(result.indexOf('fake.lnk') > -1); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('a_dir/a_file')); + t.truthy(result.includes('link_to_a_dir')); + t.truthy(result.includes('link_to_a_dir/a_file')); + t.truthy(result.includes('fake.lnk')); t.is(result.length, 5); }); }); @@ -335,7 +336,7 @@ test('-L flag, path is symlink', t => { const result = shell.ls('-L', 'test/resources/rm/link_to_a_dir'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_file') > -1); + t.truthy(result.includes('a_file')); t.is(result.length, 1); }); }); @@ -345,7 +346,7 @@ test('follow links to directories by default', t => { const result = shell.ls('test/resources/rm/link_to_a_dir'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_file') > -1); + t.truthy(result.includes('a_file')); t.is(result.length, 1); }); }); @@ -363,7 +364,7 @@ test('directory option, single arg', t => { t.is(result.length, 1); }); -test('directory option, single arg with trailing \'/\'', t => { +test("directory option, single arg with trailing '/'", t => { const result = shell.ls('-d', 'test/resources/ls/'); t.falsy(shell.error()); t.is(result.code, 0); @@ -374,8 +375,8 @@ test('directory option, multiple args', t => { const result = shell.ls('-d', 'test/resources/ls/a_dir', 'test/resources/ls/file1'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/ls/a_dir') > -1); - t.truthy(result.indexOf('test/resources/ls/file1') > -1); + t.truthy(result.includes('test/resources/ls/a_dir')); + t.truthy(result.includes('test/resources/ls/file1')); t.is(result.length, 2); }); @@ -383,14 +384,14 @@ test('directory option, globbed arg', t => { const result = shell.ls('-d', 'test/resources/ls/*'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/ls/a_dir') > -1); - t.truthy(result.indexOf('test/resources/ls/file1') > -1); - t.truthy(result.indexOf('test/resources/ls/file1.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2') > -1); - t.truthy(result.indexOf('test/resources/ls/file2.js') > -1); - t.truthy(result.indexOf('test/resources/ls/file2') > -1); + t.truthy(result.includes('test/resources/ls/a_dir')); + t.truthy(result.includes('test/resources/ls/file1')); + t.truthy(result.includes('test/resources/ls/file1.js')); + t.truthy(result.includes('test/resources/ls/file2')); + t.truthy(result.includes('test/resources/ls/file2.js')); + t.truthy(result.includes('test/resources/ls/file2')); t.truthy( - result.indexOf('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') > -1 + result.includes('test/resources/ls/filename(with)[chars$]^that.must+be-escaped') ); t.is(result.length, 6); }); @@ -482,7 +483,7 @@ test('still lists broken links', t => { const result = shell.ls('test/resources/badlink'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('test/resources/badlink') > -1); + t.truthy(result.includes('test/resources/badlink')); t.is(result.length, 1); }); @@ -490,14 +491,14 @@ test('Test new ShellString-like attributes', t => { const result = shell.ls('test/resources/ls'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.stdout.indexOf('file1') > -1); - t.truthy(result.stdout.indexOf('file2') > -1); - t.truthy(result.stdout.indexOf('file1.js') > -1); - t.truthy(result.stdout.indexOf('file2.js') > -1); + t.truthy(result.stdout.includes('file1')); + t.truthy(result.stdout.includes('file2')); + t.truthy(result.stdout.includes('file1.js')); + t.truthy(result.stdout.includes('file2.js')); t.truthy( - result.stdout.indexOf('filename(with)[chars$]^that.must+be-escaped') > -1 + result.stdout.includes('filename(with)[chars$]^that.must+be-escaped') ); - t.truthy(result.stdout.indexOf('a_dir') > -1); + t.truthy(result.stdout.includes('a_dir')); t.is(typeof result.stdout, 'string'); t.truthy(result.to); t.truthy(result.toEnd); @@ -527,8 +528,8 @@ test('non-normalized paths are still ok with -R', t => { const result = shell.ls('-R', 'test/resources/./ls/../ls'); t.falsy(shell.error()); t.is(result.code, 0); - t.truthy(result.indexOf('a_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir') > -1); - t.truthy(result.indexOf('a_dir/b_dir/z') > -1); + t.truthy(result.includes('a_dir')); + t.truthy(result.includes('a_dir/b_dir')); + t.truthy(result.includes('a_dir/b_dir/z')); t.is(result.length, 9); }); diff --git a/test/mkdir.js b/test/mkdir.js index c3e4451ca..f37b9f047 100644 --- a/test/mkdir.js +++ b/test/mkdir.js @@ -1,10 +1,10 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -37,7 +37,7 @@ test('dir already exists', t => { t.is(common.statFollowLinks(t.context.tmp).mtime.toString(), mtime); // didn't mess with dir }); -test('Can\'t overwrite a broken link', t => { +test("Can't overwrite a broken link", t => { const mtime = common.statNoFollowLinks('test/resources/badlink').mtime.toString(); const result = shell.mkdir('test/resources/badlink'); t.truthy(shell.error()); @@ -87,7 +87,7 @@ test('try to make a subdirectory of a file', t => { test('Check for invalid permissions', t => { utils.skipOnWin(t, () => { // This test case only works on unix, but should work on Windows as well - const dirName = 'nowritedir'; + const dirName = `${t.context.tmp}/nowritedir`; shell.mkdir(dirName); t.falsy(shell.error()); shell.chmod('-w', dirName); @@ -95,11 +95,10 @@ test('Check for invalid permissions', t => { t.is(result.code, 1); t.is( result.stderr, - 'mkdir: cannot create directory nowritedir/foo: Permission denied' + `mkdir: cannot create directory ${t.context.tmp}/nowritedir/foo: Permission denied` ); t.truthy(shell.error()); t.falsy(fs.existsSync(dirName + '/foo')); - shell.rm('-rf', dirName); // clean up }); }); @@ -142,7 +141,6 @@ test('-p flag', t => { t.falsy(shell.error()); t.is(result.code, 0); t.truthy(fs.existsSync(`${t.context.tmp}/a/b/c`)); - shell.rm('-Rf', `${t.context.tmp}/a`); // revert }); test('-p flag: multiple dirs', t => { @@ -165,6 +163,26 @@ test('-p flag: multiple dirs, array syntax', t => { t.truthy(fs.existsSync(`${t.context.tmp}/yyyc`)); }); +test('-p flag: subdirectory already exists', t => { + t.falsy(fs.existsSync(`${t.context.tmp}/d1`)); + shell.mkdir('-p', `${t.context.tmp}/d1/d2/d3`); + t.truthy(fs.existsSync(`${t.context.tmp}/d1/d2/d3`)); + const result = shell.mkdir('-p', `${t.context.tmp}/d1/d2`); + t.falsy(shell.error()); + t.is(result.code, 0); + t.truthy(fs.existsSync(`${t.context.tmp}/d1/d2/d3`)); +}); + +test('-p flag: create directory in subdirectory', t => { + t.falsy(fs.existsSync(`${t.context.tmp}/d1`)); + shell.mkdir('-p', `${t.context.tmp}/d1/d2`); + t.truthy(fs.existsSync(`${t.context.tmp}/d1/d2`)); + const result = shell.mkdir('-p', `${t.context.tmp}/d1/d2/d3`); + t.falsy(shell.error()); + t.is(result.code, 0); + t.truthy(fs.existsSync(`${t.context.tmp}/d1/d2/d3`)); +}); + test('globbed dir', t => { let result = shell.mkdir('-p', `${t.context.tmp}/mydir`); t.falsy(shell.error()); diff --git a/test/mv.js b/test/mv.js index eb68bd708..f6c34e6aa 100644 --- a/test/mv.js +++ b/test/mv.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); const CWD = process.cwd(); const numLines = utils.numLines; @@ -121,7 +121,7 @@ test('too many sources (exist, but dest is file)', t => { t.is(result.stderr, 'mv: dest is not a directory (too many sources)'); }); -test('can\'t use wildcard when dest is file', t => { +test("can't use wildcard when dest is file", t => { const result = shell.mv('file*', 'file1'); t.truthy(shell.error()); t.truthy(fs.existsSync('file1')); diff --git a/test/pipe.js b/test/pipe.js index ab75d944a..a8aabb928 100644 --- a/test/pipe.js +++ b/test/pipe.js @@ -1,6 +1,6 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; +const shell = require('..'); shell.config.silent = true; @@ -65,10 +65,16 @@ test('Synchronous exec', t => { t.is(result.toString(), 'alphaaaaaaabeta\nalphbeta\n'); }); -test.cb('Asynchronous exec', t => { - shell.cat('test/resources/grep/file').exec('shx grep "alpha*beta"', (code, stdout) => { - t.is(code, 0); - t.is(stdout, 'alphaaaaaaabeta\nalphbeta\n'); - t.end(); +test('Asynchronous exec', async t => { + const promise = new Promise(resolve => { + shell.cat('test/resources/grep/file') + .exec('shx grep "alpha*beta"', (code, stdout, stderr) => { + resolve({ code, stdout, stderr }); + }); }); + + const result = await promise; + t.is(result.code, 0); + t.is(result.stdout, 'alphaaaaaaabeta\nalphbeta\n'); + t.is(result.stderr, ''); }); diff --git a/test/plugin.js b/test/plugin.js index bafe2a050..59626c1c0 100644 --- a/test/plugin.js +++ b/test/plugin.js @@ -1,8 +1,8 @@ -import test from 'ava'; +const test = require('ava'); // This is the supported order for importing these files -import plugin from '../plugin'; -import shell from '..'; +const plugin = require('../plugin'); +const shell = require('..'); let data = 0; let fname; @@ -48,7 +48,7 @@ test('Unable to register a plugin with unknown options', t => { plugin.register('foo', fooImplementation, { foobar: true, }); - }, Error); + }, { instanceOf: Error }); }); test('Unable to register a plugin with wrong option types', t => { @@ -56,7 +56,7 @@ test('Unable to register a plugin with wrong option types', t => { plugin.register('foo', fooImplementation, { wrapOutput: 'true', // should be a boolean }); - }, TypeError); + }, { instanceOf: TypeError }); }); // @@ -70,7 +70,7 @@ test('All plugin utils exist', t => { t.is(typeof plugin.register, 'function'); }); -test('The plugin does not exist before it\'s registered', t => { +test("The plugin does not exist before it's registered", t => { t.falsy(shell.foo); }); @@ -162,6 +162,6 @@ test('Cannot overwrite an existing command', t => { const oldCat = shell.cat; t.throws(() => { plugin.register('cat', fooImplementation); - }, 'Command `cat` already exists'); + }, { message: 'Command `cat` already exists' }); t.is(shell.cat, oldCat); }); diff --git a/test/popd.js b/test/popd.js index 0626a0bec..e02880b75 100644 --- a/test/popd.js +++ b/test/popd.js @@ -1,9 +1,9 @@ -import path from 'path'; +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import mocks from './utils/mocks'; +const shell = require('..'); +const mocks = require('./utils/mocks'); const rootDir = path.resolve(); @@ -120,10 +120,11 @@ test('quiet mode off', t => { try { shell.pushd('test/resources/pushd'); shell.config.silent = false; - mocks.init(); + mocks.stdout.init(); + mocks.stderr.init(); const trail = shell.popd(); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(stdout, ''); t.is(stderr, `${rootDir}\n`); @@ -131,7 +132,8 @@ test('quiet mode off', t => { t.deepEqual(trail, [rootDir]); } finally { shell.config.silent = true; - mocks.restore(); + mocks.stdout.restore(); + mocks.stderr.restore(); } }); @@ -139,10 +141,11 @@ test('quiet mode on', t => { try { shell.pushd('test/resources/pushd'); shell.config.silent = false; - mocks.init(); + mocks.stdout.init(); + mocks.stderr.init(); const trail = shell.popd('-q'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(stdout, ''); t.is(stderr, ''); @@ -150,6 +153,7 @@ test('quiet mode on', t => { t.deepEqual(trail, [rootDir]); } finally { shell.config.silent = true; - mocks.restore(); + mocks.stdout.restore(); + mocks.stderr.restore(); } }); diff --git a/test/pushd.js b/test/pushd.js index d24b321fc..987dc093d 100644 --- a/test/pushd.js +++ b/test/pushd.js @@ -1,9 +1,9 @@ -import path from 'path'; +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import mocks from './utils/mocks'; +const shell = require('..'); +const mocks = require('./utils/mocks'); const rootDir = path.resolve(); @@ -333,10 +333,11 @@ test('Push without arguments invalid when stack is empty', t => { test('quiet mode off', t => { try { shell.config.silent = false; - mocks.init(); + mocks.stdout.init(); + mocks.stderr.init(); const trail = shell.pushd('test/resources/pushd'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(stdout, ''); t.is(stderr, `${path.resolve(rootDir, 'test/resources/pushd')} ${rootDir}\n`); @@ -347,17 +348,19 @@ test('quiet mode off', t => { ]); } finally { shell.config.silent = true; - mocks.restore(); + mocks.stdout.restore(); + mocks.stderr.restore(); } }); test('quiet mode on', t => { try { shell.config.silent = false; - mocks.init(); + mocks.stdout.init(); + mocks.stderr.init(); const trail = shell.pushd('-q', 'test/resources/pushd'); - const stdout = mocks.stdout(); - const stderr = mocks.stderr(); + const stdout = mocks.stdout.getValue(); + const stderr = mocks.stderr.getValue(); t.falsy(shell.error()); t.is(stdout, ''); t.is(stderr, ''); @@ -368,6 +371,7 @@ test('quiet mode on', t => { ]); } finally { shell.config.silent = true; - mocks.restore(); + mocks.stdout.restore(); + mocks.stderr.restore(); } }); diff --git a/test/pwd.js b/test/pwd.js index ce55b76ce..6e6534cc5 100644 --- a/test/pwd.js +++ b/test/pwd.js @@ -1,9 +1,9 @@ -import path from 'path'; +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); const cur = process.cwd(); diff --git a/test/resources/exec/slow.js b/test/resources/exec/slow.js index cffff43f5..d8f26becd 100644 --- a/test/resources/exec/slow.js +++ b/test/resources/exec/slow.js @@ -1,4 +1,5 @@ #!/usr/bin/env node +console.log('fast'); setTimeout(function() { console.log('slow'); }, parseInt(process.argv[2], 10)); diff --git a/test/resources/find/dir2_link b/test/resources/find/dir2_link new file mode 120000 index 000000000..1e039be90 --- /dev/null +++ b/test/resources/find/dir2_link @@ -0,0 +1 @@ +dir2 \ No newline at end of file diff --git a/test/resources/grep/file3 b/test/resources/grep/file3 new file mode 100644 index 000000000..e4bee9f8c --- /dev/null +++ b/test/resources/grep/file3 @@ -0,0 +1,15 @@ +line1 +line2 test line +line3 test line +line4 +line5 +line6 +line7 +line8 +line9 +line10 test line +line11 +line12 +line13 +line14 +line15 test line diff --git a/test/resources/shjs/a-file.js b/test/resources/shjs/a-file.js deleted file mode 100644 index 3050cd9a6..000000000 --- a/test/resources/shjs/a-file.js +++ /dev/null @@ -1,2 +0,0 @@ -console.log('OK!'); -process.exit(0); diff --git a/test/resources/shjs/coffeescript.coffee b/test/resources/shjs/coffeescript.coffee deleted file mode 100644 index 5b2766405..000000000 --- a/test/resources/shjs/coffeescript.coffee +++ /dev/null @@ -1,2 +0,0 @@ -msg = 'CoffeeScript: OK!' -console.log msg diff --git a/test/resources/shjs/exit-0.js b/test/resources/shjs/exit-0.js deleted file mode 100644 index dcbbff6c9..000000000 --- a/test/resources/shjs/exit-0.js +++ /dev/null @@ -1 +0,0 @@ -process.exit(0); diff --git a/test/resources/shjs/exit-codes.js b/test/resources/shjs/exit-codes.js deleted file mode 100644 index 6427ca060..000000000 --- a/test/resources/shjs/exit-codes.js +++ /dev/null @@ -1 +0,0 @@ -process.exit(42); diff --git a/test/resources/shjs/stdout-stderr.js b/test/resources/shjs/stdout-stderr.js deleted file mode 100644 index 220cb58f8..000000000 --- a/test/resources/shjs/stdout-stderr.js +++ /dev/null @@ -1,2 +0,0 @@ -console.log('stdout: OK!'); -console.error('stderr: OK!'); diff --git a/test/rm.js b/test/rm.js index ccd2c6ba6..01efd7c0b 100644 --- a/test/rm.js +++ b/test/rm.js @@ -1,10 +1,10 @@ -import fs from 'fs'; -import path from 'path'; +const fs = require('fs'); +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -35,7 +35,7 @@ test('file does not exist', t => { t.is(result.stderr, 'rm: no such file or directory: asdfasdf'); }); -test('cannot delete a directoy without recursive flag', t => { +test('cannot delete a directory without recursive flag', t => { const result = shell.rm(`${t.context.tmp}/rm`); t.truthy(shell.error()); t.is(result.code, 1); diff --git a/test/sed.js b/test/sed.js index b2dc655aa..fa0d41810 100644 --- a/test/sed.js +++ b/test/sed.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -94,7 +94,7 @@ test('-i option', t => { const result = shell.sed('-i', /test1/, 'hello', `${t.context.tmp}/file1`); t.falsy(shell.error()); t.is(result.code, 0); - t.is(result.toString(), 'hello'); + t.is(result.toString(), ''); t.is(shell.cat(`${t.context.tmp}/file1`).toString(), 'hello'); }); @@ -159,7 +159,7 @@ test('multiple file names, with in-place-replacement', t => { `${t.context.tmp}/file2`]); t.falsy(shell.error()); t.is(result.code, 0); - t.is(result.toString(), 'hello1\nhello2'); + t.is(result.toString(), ''); t.is(shell.cat(`${t.context.tmp}/file1`).toString(), 'hello1'); t.is(shell.cat(`${t.context.tmp}/file2`).toString(), 'hello2'); }); @@ -170,7 +170,7 @@ test('glob file names, with in-place-replacement', t => { const result = shell.sed('-i', 'test', 'hello', `${t.context.tmp}/file*.txt`); t.falsy(shell.error()); t.is(result.code, 0); - t.is(result.toString(), 'hello1\n\nhello2\n'); // TODO: fix sed's behavior + t.is(result.toString(), ''); t.is(shell.cat(`${t.context.tmp}/file1.txt`).toString(), 'hello1\n'); t.is(shell.cat(`${t.context.tmp}/file2.txt`).toString(), 'hello2\n'); }); diff --git a/test/set.js b/test/set.js index 39bcb6a2a..94c0a0bfa 100644 --- a/test/set.js +++ b/test/set.js @@ -1,7 +1,7 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); const oldConfigSilent = shell.config.silent; const uncaughtErrorExitCode = 1; @@ -28,21 +28,21 @@ test('initial values', t => { }); test('default behavior', t => { - const result = shell.exec(JSON.stringify(shell.config.execPath) + ' -e "require(\'./global\'); ls(\'file_doesnt_exist\'); echo(1234);"'); + const result = shell.exec(JSON.stringify(shell.config.execPath) + ` -e "require('./global'); ls('file_doesnt_exist'); echo(1234);"`); t.is(result.code, 0); t.is(result.stdout, '1234\n'); t.is(result.stderr, 'ls: no such file or directory: file_doesnt_exist\n'); }); test('set -e', t => { - const result = shell.exec(JSON.stringify(shell.config.execPath) + ' -e "require(\'./global\'); set(\'-e\'); ls(\'file_doesnt_exist\'); echo(1234);"'); + const result = shell.exec(JSON.stringify(shell.config.execPath) + ` -e "require('./global'); set('-e'); ls('file_doesnt_exist'); echo(1234);"`); t.is(result.code, uncaughtErrorExitCode); t.is(result.stdout, ''); - t.truthy(result.stderr.indexOf('Error: ls: no such file or directory: file_doesnt_exist') >= 0); + t.truthy(result.stderr.includes('Error: ls: no such file or directory: file_doesnt_exist')); }); test('set -v', t => { - const result = shell.exec(JSON.stringify(shell.config.execPath) + ' -e "require(\'./global\'); set(\'-v\'); ls(\'file_doesnt_exist\'); echo(1234);"'); + const result = shell.exec(JSON.stringify(shell.config.execPath) + ` -e "require('./global'); set('-v'); ls('file_doesnt_exist'); echo(1234);"`); t.is(result.code, 0); t.is(result.stdout, '1234\n'); t.is( @@ -52,16 +52,16 @@ test('set -v', t => { }); test('set -ev', t => { - const result = shell.exec(JSON.stringify(shell.config.execPath) + ' -e "require(\'./global\'); set(\'-ev\'); ls(\'file_doesnt_exist\'); echo(1234);"'); + const result = shell.exec(JSON.stringify(shell.config.execPath) + ` -e "require('./global'); set('-ev'); ls('file_doesnt_exist'); echo(1234);"`); t.is(result.code, uncaughtErrorExitCode); t.is(result.stdout, ''); - t.truthy(result.stderr.indexOf('Error: ls: no such file or directory: file_doesnt_exist') >= 0); - t.truthy(result.stderr.indexOf('ls file_doesnt_exist\n') >= 0); - t.is(result.stderr.indexOf('echo 1234\n'), -1); + t.truthy(result.stderr.includes('Error: ls: no such file or directory: file_doesnt_exist')); + t.truthy(result.stderr.includes('ls file_doesnt_exist\n')); + t.falsy(result.stderr.includes('echo 1234\n')); }); test('set -e, set +e', t => { - const result = shell.exec(JSON.stringify(shell.config.execPath) + ' -e "require(\'./global\'); set(\'-e\'); set(\'+e\'); ls(\'file_doesnt_exist\'); echo(1234);"'); + const result = shell.exec(JSON.stringify(shell.config.execPath) + ` -e "require('./global'); set('-e'); set('+e'); ls('file_doesnt_exist'); echo(1234);"`); t.is(result.code, 0); t.is(result.stdout, '1234\n'); t.is(result.stderr, 'ls: no such file or directory: file_doesnt_exist\n'); diff --git a/test/shjs.js b/test/shjs.js deleted file mode 100644 index 850a60f93..000000000 --- a/test/shjs.js +++ /dev/null @@ -1,63 +0,0 @@ -import path from 'path'; - -import test from 'ava'; - -import shell from '..'; - -const binPath = path.resolve(__dirname, '../bin/shjs'); - -function runWithShjs(name) { - // prefix with 'node ' for Windows, don't prefix for unix - const execPath = process.platform === 'win32' - ? `${JSON.stringify(shell.config.execPath)} ` - : ''; - const script = path.resolve(__dirname, 'resources', 'shjs', name); - return shell.exec(`${execPath}${binPath} ${script}`, { silent: true }); -} - -// -// Valids -// - -test('Non-zero exit code', t => { - const result = runWithShjs('exit-codes.js'); - t.is(result.code, 42); - t.is(result.stdout, ''); - t.falsy(result.stderr); -}); - -test('Zero exit code', t => { - const result = runWithShjs('exit-0.js'); - t.is(result.code, 0); - t.is(result.stdout, ''); - t.falsy(result.stderr); -}); - -test('Stdout/Stderr', t => { - const result = runWithShjs('stdout-stderr.js'); - t.is(result.code, 0); - t.is(result.stdout, 'stdout: OK!\n'); - t.is(result.stderr, 'stderr: OK!\n'); -}); - -test('CoffeeScript', t => { - const result = runWithShjs('coffeescript.coffee'); - t.is(result.code, 0); - t.is(result.stdout, 'CoffeeScript: OK!\n'); - t.falsy(result.stderr); -}); - -test('Extension detection', t => { - const result = runWithShjs('a-file'); - t.is(result.code, 0); - t.is(result.stdout, 'OK!\n'); - t.falsy(result.stderr); -}); - -// -// Invalids -// - -test('disallow require-ing', t => { - t.throws(() => require(binPath), 'Executable-only module should not be required'); -}); diff --git a/test/sort.js b/test/sort.js index 82015e41c..ac716e87c 100644 --- a/test/sort.js +++ b/test/sort.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; +const shell = require('..'); +const common = require('../src/common'); shell.config.silent = true; @@ -78,14 +78,14 @@ test('Globbed file', t => { t.is(result.toString(), doubleSorted); }); -test('With \'-n\' option', t => { +test("With '-n' option", t => { const result = shell.sort('-n', 'test/resources/sort/file2'); t.falsy(shell.error()); t.is(result.code, 0); t.is(result.toString(), shell.cat('test/resources/sort/sortedDashN').toString()); }); -test('With \'-r\' option', t => { +test("With '-r' option", t => { const result = shell.sort('-r', 'test/resources/sort/file2'); t.falsy(shell.error()); t.is(result.code, 0); @@ -96,7 +96,7 @@ test('With \'-r\' option', t => { .join('\n') + '\n'); }); -test('With \'-rn\' option', t => { +test("With '-rn' option", t => { const result = shell.sort('-rn', 'test/resources/sort/file2'); t.falsy(shell.error()); t.is(result.code, 0); diff --git a/test/tail.js b/test/tail.js index 0942aabf8..158b45d8f 100644 --- a/test/tail.js +++ b/test/tail.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; +const shell = require('..'); +const common = require('../src/common'); shell.config.silent = true; @@ -90,7 +90,7 @@ test('reading more lines than are in the file (with trailing newline)', t => { t.is(result.toString(), 'short2\nshort1\n'); // these files only have one line (with \n) }); -test('Globbed file', t => { +test('globbed file', t => { const result = shell.tail('test/resources/head/file?.txt'); t.falsy(shell.error()); t.is(result.code, 0); @@ -102,7 +102,7 @@ test('Globbed file', t => { .join('\n') + '\n'); }); -test('With `\'-n\' ` option', t => { +test("with '-n ' option", t => { const result = shell.tail('-n', 4, 'test/resources/head/file2.txt', 'test/resources/head/file1.txt'); t.falsy(shell.error()); @@ -115,7 +115,20 @@ test('With `\'-n\' ` option', t => { .join('\n') + '\n'); }); -test('With `{\'-n\': }` option', t => { +test("with '-n +' option", t => { + const result = shell.tail('-n', '+48', 'test/resources/head/file2.txt', + 'test/resources/head/file1.txt'); + t.falsy(shell.error()); + t.is(result.code, 0); + t.is(result.toString(), + bottomOfFile2 + .slice(0, 3) + .reverse() + .concat(bottomOfFile1.slice(0, 3).reverse()) + .join('\n') + '\n'); +}); + +test("with '{-n: }' option", t => { const result = shell.tail({ '-n': 4 }, 'test/resources/head/file2.txt', 'test/resources/head/file1.txt'); t.falsy(shell.error()); @@ -128,6 +141,19 @@ test('With `{\'-n\': }` option', t => { .join('\n') + '\n'); }); +test("with '{-n: +}' option", t => { + const result = shell.tail({ '-n': '+48' }, 'test/resources/head/file2.txt', + 'test/resources/head/file1.txt'); + t.falsy(shell.error()); + t.is(result.code, 0); + t.is(result.toString(), + bottomOfFile2 + .slice(0, 3) + .reverse() + .concat(bottomOfFile1.slice(0, 3).reverse()) + .join('\n') + '\n'); +}); + test('negative values are the same as positive values', t => { const result = shell.tail('-n', -4, 'test/resources/head/file2.txt', 'test/resources/head/file1.txt'); diff --git a/test/tempdir.js b/test/tempdir.js index c9c24754f..5590667e7 100644 --- a/test/tempdir.js +++ b/test/tempdir.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import { isCached, clearCache } from '../src/tempdir'; +const shell = require('..'); +const { isCached, clearCache } = require('../src/tempdir'); shell.config.silent = true; diff --git a/test/test.js b/test/test.js index 40a1778cb..1b42057ae 100644 --- a/test/test.js +++ b/test/test.js @@ -1,7 +1,7 @@ -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); shell.config.silent = true; diff --git a/test/to.js b/test/to.js index 9774b8331..4669052eb 100644 --- a/test/to.js +++ b/test/to.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -20,7 +20,7 @@ test.afterEach.always(t => { // Invalids // -test('Normal strings don\'t have \'.to()\' anymore', t => { +test("Normal strings don't have '.to()' anymore", t => { const str = 'hello world'; t.is(str.to, undefined); }); diff --git a/test/toEnd.js b/test/toEnd.js index cf3aec4f9..4e8417396 100644 --- a/test/toEnd.js +++ b/test/toEnd.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -20,7 +20,7 @@ test.afterEach.always(t => { // Invalids // -test('Normal strings don\'t have \'.toEnd()\' anymore', t => { +test("Normal strings don't have '.toEnd()' anymore", t => { const str = 'hello world'; t.is(str.toEnd, undefined); }); diff --git a/test/touch.js b/test/touch.js index a331bf70d..c767eafcd 100644 --- a/test/touch.js +++ b/test/touch.js @@ -1,11 +1,11 @@ -import crypto from 'crypto'; -import fs from 'fs'; +const crypto = require('crypto'); +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; -import utils from './utils/utils'; +const shell = require('..'); +const common = require('../src/common'); +const utils = require('./utils/utils'); test.beforeEach(t => { t.context.tmp = utils.getTempDir(); @@ -77,8 +77,8 @@ test('handles globs correctly', t => { const result = shell.touch(`${t.context.tmp}/file*`); t.is(result.code, 0); const files = shell.ls(`${t.context.tmp}/file*`); - t.truthy(files.indexOf(`${t.context.tmp}/file.txt`) > -1); - t.truthy(files.indexOf(`${t.context.tmp}/file.js`) > -1); + t.truthy(files.includes(`${t.context.tmp}/file.txt`)); + t.truthy(files.includes(`${t.context.tmp}/file.js`)); t.is(files.length, 2); }); @@ -129,14 +129,14 @@ test('accepts -d flag', t => { t.is(common.statFollowLinks(testFile).atime.getTime(), date.getTime()); }); -test('accepts long option (date)', t => { +test('accepts long option (--date)', t => { const testFile = tmpFile(t); - const date = new Date('December 17, 1995 03:24:00'); - const result = shell.touch({ date }, testFile); + const someDate = new Date('December 17, 1995 03:24:00'); + const result = shell.touch({ date: someDate }, testFile); t.is(result.code, 0); // Compare getTime(), because Date can't be compared with triple-equals. - t.is(common.statFollowLinks(testFile).mtime.getTime(), date.getTime()); - t.is(common.statFollowLinks(testFile).atime.getTime(), date.getTime()); + t.is(common.statFollowLinks(testFile).mtime.getTime(), someDate.getTime()); + t.is(common.statFollowLinks(testFile).atime.getTime(), someDate.getTime()); }); test('sets mtime and atime by default', t => { @@ -186,10 +186,10 @@ test('file array', t => { test('touching broken link creates a new file', t => { utils.skipOnWin(t, () => { - const result = shell.touch('test/resources/badlink'); + shell.ln('-s', 'not_existed_file', `${t.context.tmp}/badlink2`); + const result = shell.touch(`${t.context.tmp}/badlink2`); t.is(result.code, 0); t.falsy(shell.error()); - t.truthy(fs.existsSync('test/resources/not_existed_file')); - shell.rm('test/resources/not_existed_file'); + t.truthy(fs.existsSync(`${t.context.tmp}/not_existed_file`)); }); }); diff --git a/test/uniq.js b/test/uniq.js index 51881ff90..72611df83 100644 --- a/test/uniq.js +++ b/test/uniq.js @@ -1,9 +1,9 @@ -import fs from 'fs'; +const fs = require('fs'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import common from '../src/common'; +const shell = require('..'); +const common = require('../src/common'); shell.config.silent = true; diff --git a/test/utils/mocks.js b/test/utils/mocks.js index 79dc55087..a55e6d298 100644 --- a/test/utils/mocks.js +++ b/test/utils/mocks.js @@ -16,29 +16,53 @@ function wrapWrite(target) { }; } -const _processStdoutWrite = process.stdout.write; -const _processStderrWrite = process.stderr.write; -const _stdout = []; -const _stderr = []; -const _stdoutWrite = wrapWrite(_stdout); -const _stderrWrite = wrapWrite(_stderr); - -exports.stdout = function stdout() { - return joinData(_stdout); +const stdout = { + original: process.stdout.write, + value: [], + init: function init() { + this.value = []; + process.stdout.write = wrapWrite(this.value); + }, + restore: function restore() { + process.stdout.write = this.original; + }, + getValue: function getValue() { + return joinData(this.value); + } }; -exports.stderr = function stderr() { - return joinData(_stderr); +const stderr = { + original: process.stderr.write, + value: [], + init: function init() { + this.value = []; + process.stderr.write = wrapWrite(this.value); + }, + restore: function restore() { + process.stderr.write = this.original; + }, + getValue: function getValue() { + return joinData(this.value); + } }; -exports.init = function init() { - process.stdout.write = _stdoutWrite; - process.stderr.write = _stderrWrite; +const exit = { + original: process.exit, + value: undefined, + init: function init() { + this.value = undefined; + process.exit = (newCode) => { + this.value = newCode; + }; + }, + restore: function restore() { + process.exit = this.original; + }, + getValue: function getValue() { + return this.value; + } }; -exports.restore = function restore() { - process.stdout.write = _processStdoutWrite; - process.stderr.write = _processStderrWrite; - _stdout.splice(0); - _stderr.splice(0); -}; +exports.stdout = stdout; +exports.stderr = stderr; +exports.exit = exit; diff --git a/test/utils/utils.js b/test/utils/utils.js index df13fa9e5..9c20e5db3 100644 --- a/test/utils/utils.js +++ b/test/utils/utils.js @@ -1,5 +1,6 @@ const child = require('child_process'); const path = require('path'); +const { promisify } = require('node:util'); const chalk = require('chalk'); @@ -33,8 +34,9 @@ function skipOnWinForEPERM(action, testCase) { } exports.skipOnWinForEPERM = skipOnWinForEPERM; -function runScript(script, cb) { - child.execFile(common.config.execPath, ['-e', script], cb); +function runScript(script) { + const promiseExec = promisify(child.execFile); + return promiseExec(common.config.execPath, ['-e', script]); } exports.runScript = runScript; diff --git a/test/which.js b/test/which.js index f81d9e0e2..c49eb06d4 100644 --- a/test/which.js +++ b/test/which.js @@ -1,10 +1,10 @@ -import fs from 'fs'; -import path from 'path'; +const fs = require('fs'); +const path = require('path'); -import test from 'ava'; +const test = require('ava'); -import shell from '..'; -import utils from './utils/utils'; +const shell = require('..'); +const utils = require('./utils/utils'); shell.config.silent = true; @@ -90,7 +90,7 @@ test('None executable files does not appear in the result list', t => { t.truthy(resultForWhichA); t.truthy(resultForWhichA.length); t.not(resultForWhich.toString(), matchingFile); - t.is(resultForWhichA.indexOf(matchingFile), -1); + t.falsy(resultForWhichA.includes(matchingFile)); process.env.PATH = pathEnv; });