update socials section
This commit is contained in:
21
node_modules/lint-staged/LICENSE
generated
vendored
Normal file
21
node_modules/lint-staged/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Andrey Okonetchnikov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
909
node_modules/lint-staged/README.md
generated
vendored
Normal file
909
node_modules/lint-staged/README.md
generated
vendored
Normal file
@ -0,0 +1,909 @@
|
||||
# 🚫💩 lint-staged  [](https://badge.fury.io/js/lint-staged) [](https://codecov.io/gh/okonet/lint-staged)
|
||||
|
||||
Run linters against staged git files and don't let :poop: slip into your code base!
|
||||
|
||||
```bash
|
||||
npm install --save-dev lint-staged # requires further setup
|
||||
```
|
||||
|
||||
```
|
||||
$ git commit
|
||||
|
||||
✔ Preparing lint-staged...
|
||||
❯ Running tasks for staged files...
|
||||
❯ packages/frontend/.lintstagedrc.json — 1 file
|
||||
↓ *.js — no files [SKIPPED]
|
||||
❯ *.{json,md} — 1 file
|
||||
⠹ prettier --write
|
||||
↓ packages/backend/.lintstagedrc.json — 2 files
|
||||
❯ *.js — 2 files
|
||||
⠼ eslint --fix
|
||||
↓ *.{json,md} — no files [SKIPPED]
|
||||
◼ Applying modifications from tasks...
|
||||
◼ Cleaning up temporary files...
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>See asciinema video</summary>
|
||||
|
||||
[](https://asciinema.org/a/199934)
|
||||
|
||||
</details>
|
||||
|
||||
## Why
|
||||
|
||||
Linting makes more sense when run before committing your code. By doing so you can ensure no errors go into the repository and enforce code style. But running a lint process on a whole project is slow, and linting results can be irrelevant. Ultimately you only want to lint files that will be committed.
|
||||
|
||||
This project contains a script that will run arbitrary shell tasks with a list of staged files as an argument, filtered by a specified glob pattern.
|
||||
|
||||
## Related blog posts and talks
|
||||
|
||||
- [Introductory Medium post - Andrey Okonetchnikov, 2016](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8#.8qepn2b5l)
|
||||
- [Running Jest Tests Before Each Git Commit - Ben McCormick, 2017](https://benmccormick.org/2017/02/26/running-jest-tests-before-each-git-commit/)
|
||||
- [AgentConf presentation - Andrey Okonetchnikov, 2018](https://www.youtube.com/watch?v=-mhY7e-EsC4)
|
||||
- [SurviveJS interview - Juho Vepsäläinen and Andrey Okonetchnikov, 2018](https://survivejs.com/blog/lint-staged-interview/)
|
||||
- [Prettier your CSharp with `dotnet-format` and `lint-staged`](https://johnnyreilly.com/2020/12/22/prettier-your-csharp-with-dotnet-format-and-lint-staged)
|
||||
|
||||
> If you've written one, please submit a PR with the link to it!
|
||||
|
||||
## Installation and setup
|
||||
|
||||
To install _lint-staged_ in the recommended way, you need to:
|
||||
|
||||
1. Install _lint-staged_ itself:
|
||||
- `npm install --save-dev lint-staged`
|
||||
1. Set up the `pre-commit` git hook to run _lint-staged_
|
||||
- [Husky](https://github.com/typicode/husky) is a popular choice for configuring git hooks
|
||||
- Read more about git hooks [here](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
|
||||
1. Install some linters, like [ESLint](https://eslint.org) or [Prettier](https://prettier.io)
|
||||
1. Configure _lint-staged_ to run linters and other tasks:
|
||||
- for example: `{ "*.js": "eslint" }` to run ESLint for all staged JS files
|
||||
- See [Configuration](#configuration) for more info
|
||||
|
||||
Don't forget to commit changes to `package.json` and `.husky` to share this setup with your team!
|
||||
|
||||
Now change a few files, `git add` or `git add --patch` some of them to your commit, and try to `git commit` them.
|
||||
|
||||
See [examples](#examples) and [configuration](#configuration) for more information.
|
||||
|
||||
## Changelog
|
||||
|
||||
See [Releases](https://github.com/okonet/lint-staged/releases).
|
||||
|
||||
### Migration
|
||||
|
||||
#### v14
|
||||
|
||||
- Since `v14.0.0` _lint-staged_ no longer supports Node.js 14. Please upgrade your Node.js version to at least `16.14.0`.
|
||||
|
||||
#### v13
|
||||
|
||||
- Since `v13.0.0` _lint-staged_ no longer supports Node.js 12. Please upgrade your Node.js version to at least `14.13.1`, or `16.0.0` onward.
|
||||
|
||||
#### v12
|
||||
|
||||
- Since `v12.0.0` _lint-staged_ is a pure ESM module, so make sure your Node.js version is at least `12.20.0`, `14.13.1`, or `16.0.0`. Read more about ESM modules from the official [Node.js Documentation site here](https://nodejs.org/api/esm.html#introduction).
|
||||
|
||||
#### v10
|
||||
|
||||
- From `v10.0.0` onwards any new modifications to originally staged files will be automatically added to the commit.
|
||||
If your task previously contained a `git add` step, please remove this.
|
||||
The automatic behaviour ensures there are less race-conditions,
|
||||
since trying to run multiple git operations at the same time usually results in an error.
|
||||
- From `v10.0.0` onwards, lint-staged uses git stashes to improve speed and provide backups while running.
|
||||
Since git stashes require at least an initial commit, you shouldn't run lint-staged in an empty repo.
|
||||
- From `v10.0.0` onwards, lint-staged requires Node.js version 10.13.0 or later.
|
||||
- From `v10.0.0` onwards, lint-staged will abort the commit if linter tasks undo all staged changes. To allow creating an empty commit, please use the `--allow-empty` option.
|
||||
|
||||
## Command line flags
|
||||
|
||||
```
|
||||
❯ npx lint-staged --help
|
||||
Usage: lint-staged [options]
|
||||
|
||||
Options:
|
||||
-V, --version output the version number
|
||||
--allow-empty allow empty commits when tasks revert all staged changes (default: false)
|
||||
-p, --concurrent <number|boolean> the number of tasks to run concurrently, or false for serial (default: true)
|
||||
-c, --config [path] path to configuration file, or - to read from stdin
|
||||
--cwd [path] run all tasks in specific directory, instead of the current
|
||||
-d, --debug print additional debug information (default: false)
|
||||
--diff [string] override the default "--staged" flag of "git diff" to get list of files. Implies
|
||||
"--no-stash".
|
||||
--diff-filter [string] override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
|
||||
--max-arg-length [number] maximum length of the command-line argument string (default: 0)
|
||||
--no-stash disable the backup stash, and do not revert in case of errors
|
||||
-q, --quiet disable lint-staged’s own console output (default: false)
|
||||
-r, --relative pass relative filepaths to tasks (default: false)
|
||||
-x, --shell [path] skip parsing of tasks for better shell support (default: false)
|
||||
-v, --verbose show task output even when tasks succeed; by default only failed output is shown
|
||||
(default: false)
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
- **`--allow-empty`**: By default, when linter tasks undo all staged changes, lint-staged will exit with an error and abort the commit. Use this flag to allow creating empty git commits.
|
||||
- **`--concurrent [number|boolean]`**: Controls the [concurrency of tasks](#task-concurrency) being run by lint-staged. **NOTE**: This does NOT affect the concurrency of subtasks (they will always be run sequentially). Possible values are:
|
||||
- `false`: Run all tasks serially
|
||||
- `true` (default) : _Infinite_ concurrency. Runs as many tasks in parallel as possible.
|
||||
- `{number}`: Run the specified number of tasks in parallel, where `1` is equivalent to `false`.
|
||||
- **`--config [path]`**: Manually specify a path to a config file or npm package name. Note: when used, lint-staged won't perform the config file search and will print an error if the specified file cannot be found. If '-' is provided as the filename then the config will be read from stdin, allowing piping in the config like `cat my-config.json | npx lint-staged --config -`.
|
||||
- **`--cwd [path]`**: By default tasks run in the current working directory. Use the `--cwd some/directory` to override this. The path can be absolute or relative to the current working directory.
|
||||
- **`--debug`**: Run in debug mode. When set, it does the following:
|
||||
- uses [debug](https://github.com/visionmedia/debug) internally to log additional information about staged files, commands being executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable `$DEBUG` to `lint-staged*`.
|
||||
- uses [`verbose` renderer](https://listr2.kilic.dev/renderers/verbose-renderer/) for `listr2`; this causes serial, uncoloured output to the terminal, instead of the default (beautified, dynamic) output.
|
||||
(the [`verbose` renderer](https://listr2.kilic.dev/renderers/verbose-renderer/) can also be activated by setting the `TERM=dumb` or `NODE_ENV=test` environment variables)
|
||||
- **`--diff`**: By default linters are filtered against all files staged in git, generated from `git diff --staged`. This option allows you to override the `--staged` flag with arbitrary revisions. For example to get a list of changed files between two branches, use `--diff="branch1...branch2"`. You can also read more from about [git diff](https://git-scm.com/docs/git-diff) and [gitrevisions](https://git-scm.com/docs/gitrevisions). This option also implies `--no-stash`.
|
||||
- **`--diff-filter`**: By default only files that are _added_, _copied_, _modified_, or _renamed_ are included. Use this flag to override the default `ACMR` value with something else: _added_ (`A`), _copied_ (`C`), _deleted_ (`D`), _modified_ (`M`), _renamed_ (`R`), _type changed_ (`T`), _unmerged_ (`U`), _unknown_ (`X`), or _pairing broken_ (`B`). See also the `git diff` docs for [--diff-filter](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203).
|
||||
- **`--max-arg-length`**: long commands (a lot of files) are automatically split into multiple chunks when it detects the current shell cannot handle them. Use this flag to override the maximum length of the generated command string.
|
||||
- **`--no-stash`**: By default a backup stash will be created before running the tasks, and all task modifications will be reverted in case of an error. This option will disable creating the stash, and instead leave all modifications in the index when aborting the commit. Can be re-enabled with `--stash`.
|
||||
- **`--quiet`**: Supress all CLI output, except from tasks.
|
||||
- **`--relative`**: Pass filepaths relative to `process.cwd()` (where `lint-staged` runs) to tasks. Default is `false`.
|
||||
- **`--shell`**: By default linter commands will be parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. You can skip parsing of commands with this option. To use a specific shell, use a path like `--shell "/bin/bash"`.
|
||||
- **`--verbose`**: Show task output even when tasks succeed. By default only failed output is shown.
|
||||
|
||||
## Configuration
|
||||
|
||||
_Lint-staged_ can be configured in many ways:
|
||||
|
||||
- `lint-staged` object in your `package.json`
|
||||
- `.lintstagedrc` file in JSON or YML format, or you can be explicit with the file extension:
|
||||
- `.lintstagedrc.json`
|
||||
- `.lintstagedrc.yaml`
|
||||
- `.lintstagedrc.yml`
|
||||
- `.lintstagedrc.mjs` or `lint-staged.config.mjs` file in ESM format
|
||||
- the default export value should be a configuration: `export default { ... }`
|
||||
- `.lintstagedrc.cjs` or `lint-staged.config.cjs` file in CommonJS format
|
||||
- the exports value should be a configuration: `module.exports = { ... }`
|
||||
- `lint-staged.config.js` or `.lintstagedrc.js` in either ESM or CommonJS format, depending on
|
||||
whether your project's _package.json_ contains the `"type": "module"` option or not.
|
||||
- Pass a configuration file using the `--config` or `-c` flag
|
||||
|
||||
Configuration should be an object where each value is a command to run and its key is a glob pattern to use for this command. This package uses [micromatch](https://github.com/micromatch/micromatch) for glob patterns. JavaScript files can also export advanced configuration as a function. See [Using JS configuration files](#using-js-configuration-files) for more info.
|
||||
|
||||
You can also place multiple configuration files in different directories inside a project. For a given staged file, the closest configuration file will always be used. See ["How to use `lint-staged` in a multi-package monorepo?"](#how-to-use-lint-staged-in-a-multi-package-monorepo) for more info and an example.
|
||||
|
||||
#### `package.json` example:
|
||||
|
||||
```json
|
||||
{
|
||||
"lint-staged": {
|
||||
"*": "your-cmd"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `.lintstagedrc` example
|
||||
|
||||
```json
|
||||
{
|
||||
"*": "your-cmd"
|
||||
}
|
||||
```
|
||||
|
||||
This config will execute `your-cmd` with the list of currently staged files passed as arguments.
|
||||
|
||||
So, considering you did `git add file1.ext file2.ext`, lint-staged will run the following command:
|
||||
|
||||
`your-cmd file1.ext file2.ext`
|
||||
|
||||
### Task concurrency
|
||||
|
||||
By default _lint-staged_ will run configured tasks concurrently. This means that for every glob, all the commands will be started at the same time. With the following config, both `eslint` and `prettier` will run at the same time:
|
||||
|
||||
```json
|
||||
{
|
||||
"*.ts": "eslint",
|
||||
"*.md": "prettier --list-different"
|
||||
}
|
||||
```
|
||||
|
||||
This is typically not a problem since the globs do not overlap, and the commands do not make changes to the files, but only report possible errors (aborting the git commit). If you want to run multiple commands for the same set of files, you can use the array syntax to make sure commands are run in order. In the following example, `prettier` will run for both globs, and in addition `eslint` will run for `*.ts` files _after_ it. Both sets of commands (for each glob) are still started at the same time (but do not overlap).
|
||||
|
||||
```json
|
||||
{
|
||||
"*.ts": ["prettier --list-different", "eslint"],
|
||||
"*.md": "prettier --list-different"
|
||||
}
|
||||
```
|
||||
|
||||
Pay extra attention when the configured globs overlap, and tasks make edits to files. For example, in this configuration `prettier` and `eslint` might try to make changes to the same `*.ts` file at the same time, causing a _race condition_:
|
||||
|
||||
```json
|
||||
{
|
||||
"*": "prettier --write",
|
||||
"*.ts": "eslint --fix"
|
||||
}
|
||||
```
|
||||
|
||||
If necessary, you can limit the concurrency using `--concurrent <number>` or disable it entirely with `--concurrent false`.
|
||||
|
||||
## Filtering files
|
||||
|
||||
Linter commands work on a subset of all staged files, defined by a _glob pattern_. lint-staged uses [micromatch](https://github.com/micromatch/micromatch) for matching files with the following rules:
|
||||
|
||||
- If the glob pattern contains no slashes (`/`), micromatch's `matchBase` option will enabled, so globs match a file's basename regardless of directory:
|
||||
- `"*.js"` will match all JS files, like `/test.js` and `/foo/bar/test.js`
|
||||
- `"!(*test).js"` will match all JS files, except those ending in `test.js`, so `foo.js` but not `foo.test.js`
|
||||
- If the glob pattern does contain a slash (`/`), it will match for paths as well:
|
||||
- `"./*.js"` will match all JS files in the git repo root, so `/test.js` but not `/foo/bar/test.js`
|
||||
- `"foo/**/*.js"` will match all JS files inside the `/foo` directory, so `/foo/bar/test.js` but not `/test.js`
|
||||
|
||||
When matching, lint-staged will do the following
|
||||
|
||||
- Resolve the git root automatically, no configuration needed.
|
||||
- Pick the staged files which are present inside the project directory.
|
||||
- Filter them using the specified glob patterns.
|
||||
- Pass absolute paths to the linters as arguments.
|
||||
|
||||
**NOTE:** `lint-staged` will pass _absolute_ paths to the linters to avoid any confusion in case they're executed in a different working directory (i.e. when your `.git` directory isn't the same as your `package.json` directory).
|
||||
|
||||
Also see [How to use `lint-staged` in a multi-package monorepo?](#how-to-use-lint-staged-in-a-multi-package-monorepo)
|
||||
|
||||
### Ignoring files
|
||||
|
||||
The concept of `lint-staged` is to run configured linter tasks (or other tasks) on files that are staged in git. `lint-staged` will always pass a list of all staged files to the task, and ignoring any files should be configured in the task itself.
|
||||
|
||||
Consider a project that uses [`prettier`](https://prettier.io/) to keep code format consistent across all files. The project also stores minified 3rd-party vendor libraries in the `vendor/` directory. To keep `prettier` from throwing errors on these files, the vendor directory should be added to prettier's ignore configuration, the `.prettierignore` file. Running `npx prettier .` will ignore the entire vendor directory, throwing no errors. When `lint-staged` is added to the project and configured to run prettier, all modified and staged files in the vendor directory will be ignored by prettier, even though it receives them as input.
|
||||
|
||||
In advanced scenarios, where it is impossible to configure the linter task itself to ignore files, but some staged files should still be ignored by `lint-staged`, it is possible to filter filepaths before passing them to tasks by using the function syntax. See [Example: Ignore files from match](#example-ignore-files-from-match).
|
||||
|
||||
## What commands are supported?
|
||||
|
||||
Supported are any executables installed locally or globally via `npm` as well as any executable from your \$PATH.
|
||||
|
||||
> Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn't have it installed.
|
||||
|
||||
`lint-staged` uses [execa](https://github.com/sindresorhus/execa#preferlocal) to locate locally installed scripts. So in your `.lintstagedrc` you can write:
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": "eslint --fix"
|
||||
}
|
||||
```
|
||||
|
||||
Pass arguments to your commands separated by space as you would do in the shell. See [examples](#examples) below.
|
||||
|
||||
## Running multiple commands in a sequence
|
||||
|
||||
You can run multiple commands in a sequence on every glob. To do so, pass an array of commands instead of a single one. This is useful for running autoformatting tools like `eslint --fix` or `stylefmt` but can be used for any arbitrary sequences.
|
||||
|
||||
For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": ["eslint", "prettier --write"]
|
||||
}
|
||||
```
|
||||
|
||||
going to execute `eslint` and if it exits with `0` code, it will execute `prettier --write` on all staged `*.js` files.
|
||||
|
||||
## Using JS configuration files
|
||||
|
||||
Writing the configuration file in JavaScript is the most powerful way to configure lint-staged (`lint-staged.config.js`, [similar](https://github.com/okonet/lint-staged#configuration), or passed via `--config`). From the configuration file, you can export either a single function or an object.
|
||||
|
||||
If the `exports` value is a function, it will receive an array of all staged filenames. You can then build your own matchers for the files and return a command string or an array of command strings. These strings are considered complete and should include the filename arguments, if wanted.
|
||||
|
||||
If the `exports` value is an object, its keys should be glob matches (like in the normal non-js config format). The values can either be like in the normal config or individual functions like described above. Instead of receiving all matched files, the functions in the exported object will only receive the staged files matching the corresponding glob key.
|
||||
|
||||
### Function signature
|
||||
|
||||
The function can also be async:
|
||||
|
||||
```ts
|
||||
(filenames: string[]) => string | string[] | Promise<string | string[]>
|
||||
```
|
||||
|
||||
### Example: Export a function to build your own matchers
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```js
|
||||
// lint-staged.config.js
|
||||
import micromatch from 'micromatch'
|
||||
|
||||
export default (allStagedFiles) => {
|
||||
const shFiles = micromatch(allStagedFiles, ['**/src/**/*.sh'])
|
||||
if (shFiles.length) {
|
||||
return `printf '%s\n' "Script files aren't allowed in src directory" >&2`
|
||||
}
|
||||
const codeFiles = micromatch(allStagedFiles, ['**/*.js', '**/*.ts'])
|
||||
const docFiles = micromatch(allStagedFiles, ['**/*.md'])
|
||||
return [`eslint ${codeFiles.join(' ')}`, `mdl ${docFiles.join(' ')}`]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Example: Wrap filenames in single quotes and run once per file
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```js
|
||||
// .lintstagedrc.js
|
||||
export default {
|
||||
'**/*.js?(x)': (filenames) => filenames.map((filename) => `prettier --write '${filename}'`),
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Example: Run `tsc` on changes to TypeScript files, but do not pass any filename arguments
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```js
|
||||
// lint-staged.config.js
|
||||
export default {
|
||||
'**/*.ts?(x)': () => 'tsc -p tsconfig.json --noEmit',
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Example: Run ESLint on entire repo if more than 10 staged files
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```js
|
||||
// .lintstagedrc.js
|
||||
export default {
|
||||
'**/*.js?(x)': (filenames) =>
|
||||
filenames.length > 10 ? 'eslint .' : `eslint ${filenames.join(' ')}`,
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Example: Use your own globs
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
It's better to use the [function-based configuration (seen above)](https://github.com/okonet/lint-staged#example-export-a-function-to-build-your-own-matchers), if your use case is this.
|
||||
|
||||
```js
|
||||
// lint-staged.config.js
|
||||
import micromatch from 'micromatch'
|
||||
|
||||
export default {
|
||||
'*': (allFiles) => {
|
||||
const codeFiles = micromatch(allFiles, ['**/*.js', '**/*.ts'])
|
||||
const docFiles = micromatch(allFiles, ['**/*.md'])
|
||||
return [`eslint ${codeFiles.join(' ')}`, `mdl ${docFiles.join(' ')}`]
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Example: Ignore files from match
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
If for some reason you want to ignore files from the glob match, you can use `micromatch.not()`:
|
||||
|
||||
```js
|
||||
// lint-staged.config.js
|
||||
import micromatch from 'micromatch'
|
||||
|
||||
export default {
|
||||
'*.js': (files) => {
|
||||
// from `files` filter those _NOT_ matching `*test.js`
|
||||
const match = micromatch.not(files, '*test.js')
|
||||
return `eslint ${match.join(' ')}`
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Please note that for most cases, globs can achieve the same effect. For the above example, a matching glob would be `!(*test).js`.
|
||||
|
||||
</details>
|
||||
|
||||
### Example: Use relative paths for commands
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```js
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
'*.ts': (absolutePaths) => {
|
||||
const cwd = process.cwd()
|
||||
const relativePaths = absolutePaths.map((file) => path.relative(cwd, file))
|
||||
return `ng lint myProjectName --files ${relativePaths.join(' ')}`
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Reformatting the code
|
||||
|
||||
Tools like [Prettier](https://prettier.io), ESLint/TSLint, or stylelint can reformat your code according to an appropriate config by running `prettier --write`/`eslint --fix`/`tslint --fix`/`stylelint --fix`. Lint-staged will automatically add any modifications to the commit as long as there are no errors.
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": "prettier --write"
|
||||
}
|
||||
```
|
||||
|
||||
Prior to version 10, tasks had to manually include `git add` as the final step. This behavior has been integrated into lint-staged itself in order to prevent race conditions with multiple tasks editing the same files. If lint-staged detects `git add` in task configurations, it will show a warning in the console. Please remove `git add` from your configuration after upgrading.
|
||||
|
||||
## Examples
|
||||
|
||||
All examples assume you've already set up lint-staged in the `package.json` file and [husky](https://github.com/typicode/husky) in its own config file.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "My project",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"my-custom-script": "linter --arg1 --arg2"
|
||||
},
|
||||
"lint-staged": {}
|
||||
}
|
||||
```
|
||||
|
||||
In `.husky/pre-commit`
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
```
|
||||
|
||||
_Note: we don't pass a path as an argument for the runners. This is important since lint-staged will do this for you._
|
||||
|
||||
### ESLint with default parameters for `*.js` and `*.jsx` running as a pre-commit hook
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.{js,jsx}": "eslint"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Automatically fix code style with `--fix` and add to commit
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": "eslint --fix"
|
||||
}
|
||||
```
|
||||
|
||||
This will run `eslint --fix` and automatically add changes to the commit.
|
||||
|
||||
</details>
|
||||
|
||||
### Reuse npm script
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
If you wish to reuse a npm script defined in your package.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": "npm run my-custom-script --"
|
||||
}
|
||||
```
|
||||
|
||||
The following is equivalent:
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": "linter --arg1 --arg2"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Use environment variables with linting commands
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
Linting commands _do not_ support the shell convention of expanding environment variables. To enable the convention yourself, use a tool like [`cross-env`](https://github.com/kentcdodds/cross-env).
|
||||
|
||||
For example, here is `jest` running on all `.js` files with the `NODE_ENV` variable being set to `"test"`:
|
||||
|
||||
```json
|
||||
{
|
||||
"*.js": ["cross-env NODE_ENV=test jest --bail --findRelatedTests"]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Automatically fix code style with `prettier` for any format Prettier supports
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*": "prettier --ignore-unknown --write"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Automatically fix code style with `prettier` for JavaScript, TypeScript, Markdown, HTML, or CSS
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.{js,jsx,ts,tsx,md,html,css}": "prettier --write"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Stylelint for CSS with defaults and for SCSS with SCSS syntax
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.css": "stylelint",
|
||||
"*.scss": "stylelint --syntax=scss"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Run PostCSS sorting and Stylelint to check
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.scss": ["postcss --config path/to/your/config --replace", "stylelint"]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Minify the images
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.{png,jpeg,jpg,gif,svg}": "imagemin-lint-staged"
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>More about <code>imagemin-lint-staged</code></summary>
|
||||
|
||||
[imagemin-lint-staged](https://github.com/tomchentw/imagemin-lint-staged) is a CLI tool designed for lint-staged usage with sensible defaults.
|
||||
|
||||
See more on [this blog post](https://medium.com/@tomchentw/imagemin-lint-staged-in-place-minify-the-images-before-adding-to-the-git-repo-5acda0b4c57e) for benefits of this approach.
|
||||
|
||||
</details>
|
||||
</details>
|
||||
|
||||
### Typecheck your staged files with flow
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"*.{js,jsx}": "flow focus-check"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Integrate with Next.js
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
```js
|
||||
// .lintstagedrc.js
|
||||
// See https://nextjs.org/docs/basic-features/eslint#lint-staged for details
|
||||
|
||||
const path = require('path')
|
||||
|
||||
const buildEslintCommand = (filenames) =>
|
||||
`next lint --fix --file ${filenames.map((f) => path.relative(process.cwd(), f)).join(' --file ')}`
|
||||
|
||||
module.exports = {
|
||||
'*.{js,jsx,ts,tsx}': [buildEslintCommand],
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### The output of commit hook looks weird (no colors, duplicate lines, …)
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
Git 2.36.0 introduced a change to hooks where they were no longer run in the original TTY.
|
||||
This was fixed in 2.37.0:
|
||||
|
||||
https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.37.0.txt
|
||||
|
||||
> - In Git 2.36 we revamped the way how hooks are invoked. One change
|
||||
> that is end-user visible is that the output of a hook is no longer
|
||||
> directly connected to the standard output of "git" that spawns the
|
||||
> hook, which was noticed post release. This is getting corrected.
|
||||
> (merge [a082345372](https://github.com/git/git/commit/a082345372) ab/hooks-regression-fix later to maint).
|
||||
|
||||
</details>
|
||||
|
||||
### Can I use `lint-staged` via node?
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
Yes!
|
||||
|
||||
```js
|
||||
import lintStaged from 'lint-staged'
|
||||
|
||||
try {
|
||||
const success = await lintStaged()
|
||||
console.log(success ? 'Linting was successful!' : 'Linting failed!')
|
||||
} catch (e) {
|
||||
// Failed to load configuration
|
||||
console.error(e)
|
||||
}
|
||||
```
|
||||
|
||||
Parameters to `lintStaged` are equivalent to their CLI counterparts:
|
||||
|
||||
```js
|
||||
const success = await lintStaged({
|
||||
allowEmpty: false,
|
||||
concurrent: true,
|
||||
configPath: './path/to/configuration/file',
|
||||
cwd: process.cwd(),
|
||||
debug: false,
|
||||
maxArgLength: null,
|
||||
quiet: false,
|
||||
relative: false,
|
||||
shell: false,
|
||||
stash: true,
|
||||
verbose: false,
|
||||
})
|
||||
```
|
||||
|
||||
You can also pass config directly with `config` option:
|
||||
|
||||
```js
|
||||
const success = await lintStaged({
|
||||
allowEmpty: false,
|
||||
concurrent: true,
|
||||
config: { '*.js': 'eslint --fix' },
|
||||
cwd: process.cwd(),
|
||||
debug: false,
|
||||
maxArgLength: null,
|
||||
quiet: false,
|
||||
relative: false,
|
||||
shell: false,
|
||||
stash: true,
|
||||
verbose: false,
|
||||
})
|
||||
```
|
||||
|
||||
The `maxArgLength` option configures chunking of tasks into multiple parts that are run one after the other. This is to avoid issues on Windows platforms where the maximum length of the command line argument string is limited to 8192 characters. Lint-staged might generate a very long argument string when there are many staged files. This option is set automatically from the cli, but not via the Node.js API by default.
|
||||
|
||||
</details>
|
||||
|
||||
### Using with JetBrains IDEs _(WebStorm, PyCharm, IntelliJ IDEA, RubyMine, etc.)_
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
_**Update**_: The latest version of JetBrains IDEs now support running hooks as you would expect.
|
||||
|
||||
When using the IDE's GUI to commit changes with the `precommit` hook, you might see inconsistencies in the IDE and command line. This is [known issue](https://youtrack.jetbrains.com/issue/IDEA-135454) at JetBrains so if you want this fixed, please vote for it on YouTrack.
|
||||
|
||||
Until the issue is resolved in the IDE, you can use the following config to work around it:
|
||||
|
||||
husky v1.x
|
||||
|
||||
```json
|
||||
{
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged",
|
||||
"post-commit": "git update-index --again"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
husky v0.x
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"postcommit": "git update-index --again"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
_Thanks to [this comment](https://youtrack.jetbrains.com/issue/IDEA-135454#comment=27-2710654) for the fix!_
|
||||
|
||||
</details>
|
||||
|
||||
### How to use `lint-staged` in a multi-package monorepo?
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
Install _lint-staged_ on the monorepo root level, and add separate configuration files in each package. When running, _lint-staged_ will always use the configuration closest to a staged file, so having separate configuration files makes sure linters do not "leak" into other packages.
|
||||
|
||||
For example, in a monorepo with `packages/frontend/.lintstagedrc.json` and `packages/backend/.lintstagedrc.json`, a staged file inside `packages/frontend/` will only match that configuration, and not the one in `packages/backend/`.
|
||||
|
||||
**Note**: _lint-staged_ discovers the closest configuration to each staged file, even if that configuration doesn't include any matching globs. Given these example configurations:
|
||||
|
||||
```js
|
||||
// ./.lintstagedrc.json
|
||||
{ "*.md": "prettier --write" }
|
||||
```
|
||||
|
||||
```js
|
||||
// ./packages/frontend/.lintstagedrc.json
|
||||
{ "*.js": "eslint --fix" }
|
||||
```
|
||||
|
||||
When committing `./packages/frontend/README.md`, it **will not run** _prettier_, because the configuration in the `frontend/` directory is closer to the file and doesn't include it. You should treat all _lint-staged_ configuration files as isolated and separated from each other. You can always use JS files to "extend" configurations, for example:
|
||||
|
||||
```js
|
||||
import baseConfig from '../.lintstagedrc.js'
|
||||
|
||||
export default {
|
||||
...baseConfig,
|
||||
'*.js': 'eslint --fix',
|
||||
}
|
||||
```
|
||||
|
||||
To support backwards-compatibility, monorepo features require multiple _lint-staged_ configuration files present in the git repo. If you still want to run _lint-staged_ in only one of the packages in a monorepo, you can either add an "empty" _lint-staged_ configuration to the root of the repo (so that there's two configs in total), or alternatively run _lint-staged_ with the `--cwd` option pointing to your package directory (for example, `lint-staged --cwd packages/frontend`).
|
||||
|
||||
</details>
|
||||
|
||||
### Can I lint files outside of the current project folder?
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
tl;dr: Yes, but the pattern should start with `../`.
|
||||
|
||||
By default, `lint-staged` executes linters only on the files present inside the project folder(where `lint-staged` is installed and run from).
|
||||
So this question is relevant _only_ when the project folder is a child folder inside the git repo.
|
||||
In certain project setups, it might be desirable to bypass this restriction. See [#425](https://github.com/okonet/lint-staged/issues/425), [#487](https://github.com/okonet/lint-staged/issues/487) for more context.
|
||||
|
||||
`lint-staged` provides an escape hatch for the same(`>= v7.3.0`). For patterns that start with `../`, all the staged files are allowed to match against the pattern.
|
||||
Note that patterns like `*.js`, `**/*.js` will still only match the project files and not any of the files in parent or sibling directories.
|
||||
|
||||
Example repo: [sudo-suhas/lint-staged-django-react-demo](https://github.com/sudo-suhas/lint-staged-django-react-demo).
|
||||
|
||||
</details>
|
||||
|
||||
### Can I run `lint-staged` in CI, or when there are no staged files?
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
Lint-staged will by default run against files staged in git, and should be run during the git pre-commit hook, for example. It's also possible to override this default behaviour and run against files in a specific diff, for example
|
||||
all changed files between two different branches. If you want to run _lint-staged_ in the CI, maybe you can set it up to compare the branch in a _Pull Request_/_Merge Request_ to the target branch.
|
||||
|
||||
Try out the `git diff` command until you are satisfied with the result, for example:
|
||||
|
||||
```
|
||||
git diff --diff-filter=ACMR --name-only master...my-branch
|
||||
```
|
||||
|
||||
This will print a list of _added_, _changed_, _modified_, and _renamed_ files between `master` and `my-branch`.
|
||||
|
||||
You can then run lint-staged against the same files with:
|
||||
|
||||
```
|
||||
npx lint-staged --diff="master...my-branch"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Can I use `lint-staged` with `ng lint`
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
You should not use `ng lint` through _lint-staged_, because it's designed to lint an entire project. Instead, you can add `ng lint` to your git pre-commit hook the same way as you would run lint-staged.
|
||||
|
||||
See issue [!951](https://github.com/okonet/lint-staged/issues/951) for more details and possible workarounds.
|
||||
|
||||
</details>
|
||||
|
||||
### How can I ignore files from `.eslintignore`?
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
ESLint throws out `warning File ignored because of a matching ignore pattern. Use "--no-ignore" to override` warnings that breaks the linting process ( if you used `--max-warnings=0` which is recommended ).
|
||||
|
||||
#### ESLint < 7
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
Based on the discussion from [this issue](https://github.com/eslint/eslint/issues/9977), it was decided that using [the outlined script ](https://github.com/eslint/eslint/issues/9977#issuecomment-406420893)is the best route to fix this.
|
||||
|
||||
So you can setup a `.lintstagedrc.js` config file to do this:
|
||||
|
||||
```js
|
||||
import { CLIEngine } from 'eslint'
|
||||
|
||||
export default {
|
||||
'*.js': (files) => {
|
||||
const cli = new CLIEngine({})
|
||||
return 'eslint --max-warnings=0 ' + files.filter((file) => !cli.isPathIgnored(file)).join(' ')
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
#### ESLint >= 7
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
In versions of ESLint > 7, [isPathIgnored](https://eslint.org/docs/developer-guide/nodejs-api#-eslintispathignoredfilepath) is an async function and now returns a promise. The code below can be used to reinstate the above functionality.
|
||||
|
||||
Since [10.5.3](https://github.com/okonet/lint-staged/releases), any errors due to a bad ESLint config will come through to the console.
|
||||
|
||||
```js
|
||||
import { ESLint } from 'eslint'
|
||||
|
||||
const removeIgnoredFiles = async (files) => {
|
||||
const eslint = new ESLint()
|
||||
const isIgnored = await Promise.all(
|
||||
files.map((file) => {
|
||||
return eslint.isPathIgnored(file)
|
||||
})
|
||||
)
|
||||
const filteredFiles = files.filter((_, i) => !isIgnored[i])
|
||||
return filteredFiles.join(' ')
|
||||
}
|
||||
|
||||
export default {
|
||||
'**/*.{ts,tsx,js,jsx}': async (files) => {
|
||||
const filesToLint = await removeIgnoredFiles(files)
|
||||
return [`eslint --max-warnings=0 ${filesToLint}`]
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
</details>
|
131
node_modules/lint-staged/bin/lint-staged.js
generated
vendored
Executable file
131
node_modules/lint-staged/bin/lint-staged.js
generated
vendored
Executable file
@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import fs from 'node:fs/promises'
|
||||
|
||||
import { supportsColor } from 'chalk'
|
||||
import { Option, program } from 'commander'
|
||||
import debug from 'debug'
|
||||
|
||||
import lintStaged from '../lib/index.js'
|
||||
import { CONFIG_STDIN_ERROR } from '../lib/messages.js'
|
||||
|
||||
// Force colors for packages that depend on https://www.npmjs.com/package/supports-color
|
||||
if (supportsColor) {
|
||||
process.env.FORCE_COLOR = supportsColor.level.toString()
|
||||
}
|
||||
|
||||
// Do not terminate main Listr process on SIGINT
|
||||
process.on('SIGINT', () => {})
|
||||
|
||||
const packageJson = JSON.parse(await fs.readFile(new URL('../package.json', import.meta.url)))
|
||||
const version = packageJson.version
|
||||
|
||||
const debugLog = debug('lint-staged:bin')
|
||||
debugLog('Running `lint-staged@%s`', version)
|
||||
|
||||
const cli = program.version(version)
|
||||
|
||||
cli.option('--allow-empty', 'allow empty commits when tasks revert all staged changes', false)
|
||||
|
||||
cli.option(
|
||||
'-p, --concurrent <number|boolean>',
|
||||
'the number of tasks to run concurrently, or false for serial',
|
||||
true
|
||||
)
|
||||
|
||||
cli.option('-c, --config [path]', 'path to configuration file, or - to read from stdin')
|
||||
|
||||
cli.option('--cwd [path]', 'run all tasks in specific directory, instead of the current')
|
||||
|
||||
cli.option('-d, --debug', 'print additional debug information', false)
|
||||
|
||||
cli.addOption(
|
||||
new Option(
|
||||
'--diff [string]',
|
||||
'override the default "--staged" flag of "git diff" to get list of files. Implies "--no-stash".'
|
||||
).implies({ stash: false })
|
||||
)
|
||||
|
||||
cli.option(
|
||||
'--diff-filter [string]',
|
||||
'override the default "--diff-filter=ACMR" flag of "git diff" to get list of files'
|
||||
)
|
||||
|
||||
cli.option('--max-arg-length [number]', 'maximum length of the command-line argument string', 0)
|
||||
|
||||
/**
|
||||
* We don't want to show the `--stash` flag because it's on by default, and only show the
|
||||
* negatable flag `--no-stash` in stead. There seems to be a bug in Commander.js where
|
||||
* configuring only the latter won't actually set the default value.
|
||||
*/
|
||||
cli
|
||||
.addOption(
|
||||
new Option('--stash', 'enable the backup stash, and revert in case of errors')
|
||||
.default(true)
|
||||
.hideHelp()
|
||||
)
|
||||
.addOption(
|
||||
new Option(
|
||||
'--no-stash',
|
||||
'disable the backup stash, and do not revert in case of errors'
|
||||
).default(false)
|
||||
)
|
||||
|
||||
cli.option('-q, --quiet', 'disable lint-staged’s own console output', false)
|
||||
|
||||
cli.option('-r, --relative', 'pass relative filepaths to tasks', false)
|
||||
|
||||
cli.option('-x, --shell [path]', 'skip parsing of tasks for better shell support', false)
|
||||
|
||||
cli.option(
|
||||
'-v, --verbose',
|
||||
'show task output even when tasks succeed; by default only failed output is shown',
|
||||
false
|
||||
)
|
||||
|
||||
const cliOptions = cli.parse(process.argv).opts()
|
||||
|
||||
if (cliOptions.debug) {
|
||||
debug.enable('lint-staged*')
|
||||
}
|
||||
|
||||
const options = {
|
||||
allowEmpty: !!cliOptions.allowEmpty,
|
||||
concurrent: JSON.parse(cliOptions.concurrent),
|
||||
configPath: cliOptions.config,
|
||||
cwd: cliOptions.cwd,
|
||||
debug: !!cliOptions.debug,
|
||||
diff: cliOptions.diff,
|
||||
diffFilter: cliOptions.diffFilter,
|
||||
maxArgLength: cliOptions.maxArgLength || undefined,
|
||||
quiet: !!cliOptions.quiet,
|
||||
relative: !!cliOptions.relative,
|
||||
shell: cliOptions.shell /* Either a boolean or a string pointing to the shell */,
|
||||
stash: !!cliOptions.stash, // commander inverts `no-<x>` flags to `!x`
|
||||
verbose: !!cliOptions.verbose,
|
||||
}
|
||||
|
||||
debugLog('Options parsed from command-line:', options)
|
||||
|
||||
if (options.configPath === '-') {
|
||||
delete options.configPath
|
||||
try {
|
||||
options.config = await fs.readFile(process.stdin.fd, 'utf8').toString().trim()
|
||||
} catch {
|
||||
console.error(CONFIG_STDIN_ERROR)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
try {
|
||||
options.config = JSON.parse(options.config)
|
||||
} catch {
|
||||
// Let config parsing complain if it's not JSON
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const passed = await lintStaged(options)
|
||||
process.exitCode = passed ? 0 : 1
|
||||
} catch {
|
||||
process.exitCode = 1
|
||||
}
|
54
node_modules/lint-staged/lib/chunkFiles.js
generated
vendored
Normal file
54
node_modules/lint-staged/lib/chunkFiles.js
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
import { normalizePath } from './normalizePath.js'
|
||||
|
||||
const debugLog = debug('lint-staged:chunkFiles')
|
||||
|
||||
/**
|
||||
* Chunk array into sub-arrays
|
||||
* @param {Array} arr
|
||||
* @param {Number} chunkCount
|
||||
* @retuns {Array<Array>}
|
||||
*/
|
||||
const chunkArray = (arr, chunkCount) => {
|
||||
if (chunkCount === 1) return [arr]
|
||||
const chunked = []
|
||||
let position = 0
|
||||
for (let i = 0; i < chunkCount; i++) {
|
||||
const chunkLength = Math.ceil((arr.length - position) / (chunkCount - i))
|
||||
chunked.push([])
|
||||
chunked[i] = arr.slice(position, chunkLength + position)
|
||||
position += chunkLength
|
||||
}
|
||||
return chunked
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk files into sub-arrays based on the length of the resulting argument string
|
||||
* @param {Object} opts
|
||||
* @param {Array<String>} opts.files
|
||||
* @param {String} [opts.baseDir] The optional base directory to resolve relative paths.
|
||||
* @param {number} [opts.maxArgLength] the maximum argument string length
|
||||
* @param {Boolean} [opts.relative] whether files are relative to `gitDir` or should be resolved as absolute
|
||||
* @returns {Array<Array<String>>}
|
||||
*/
|
||||
export const chunkFiles = ({ files, baseDir, maxArgLength = null, relative = false }) => {
|
||||
const normalizedFiles = files.map((file) =>
|
||||
normalizePath(relative || !baseDir ? file : path.resolve(baseDir, file))
|
||||
)
|
||||
|
||||
if (!maxArgLength) {
|
||||
debugLog('Skip chunking files because of undefined maxArgLength')
|
||||
return [normalizedFiles] // wrap in an array to return a single chunk
|
||||
}
|
||||
|
||||
const fileListLength = normalizedFiles.join(' ').length
|
||||
debugLog(
|
||||
`Resolved an argument string length of ${fileListLength} characters from ${normalizedFiles.length} files`
|
||||
)
|
||||
const chunkCount = Math.min(Math.ceil(fileListLength / maxArgLength), normalizedFiles.length)
|
||||
debugLog(`Creating ${chunkCount} chunks for maxArgLength of ${maxArgLength}`)
|
||||
return chunkArray(normalizedFiles, chunkCount)
|
||||
}
|
3
node_modules/lint-staged/lib/dynamicImport.js
generated
vendored
Normal file
3
node_modules/lint-staged/lib/dynamicImport.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
export const dynamicImport = (path) => import(pathToFileURL(path)).then((module) => module.default)
|
27
node_modules/lint-staged/lib/execGit.js
generated
vendored
Normal file
27
node_modules/lint-staged/lib/execGit.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import debug from 'debug'
|
||||
import { execa } from 'execa'
|
||||
|
||||
const debugLog = debug('lint-staged:execGit')
|
||||
|
||||
/**
|
||||
* Explicitly never recurse commands into submodules, overriding local/global configuration.
|
||||
* @see https://git-scm.com/docs/git-config#Documentation/git-config.txt-submodulerecurse
|
||||
*/
|
||||
const NO_SUBMODULE_RECURSE = ['-c', 'submodule.recurse=false']
|
||||
|
||||
// exported for tests
|
||||
export const GIT_GLOBAL_OPTIONS = [...NO_SUBMODULE_RECURSE]
|
||||
|
||||
export const execGit = async (cmd, options = {}) => {
|
||||
debugLog('Running git command', cmd)
|
||||
try {
|
||||
const { stdout } = await execa('git', GIT_GLOBAL_OPTIONS.concat(cmd), {
|
||||
...options,
|
||||
all: true,
|
||||
cwd: options.cwd || process.cwd(),
|
||||
})
|
||||
return stdout
|
||||
} catch ({ all }) {
|
||||
throw new Error(all)
|
||||
}
|
||||
}
|
8
node_modules/lint-staged/lib/figures.js
generated
vendored
Normal file
8
node_modules/lint-staged/lib/figures.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import chalk from 'chalk'
|
||||
import { figures } from 'listr2'
|
||||
|
||||
export const info = chalk.blue(figures.arrowRight)
|
||||
|
||||
export const error = chalk.redBright(figures.cross)
|
||||
|
||||
export const warning = chalk.yellow(figures.warning)
|
53
node_modules/lint-staged/lib/file.js
generated
vendored
Normal file
53
node_modules/lint-staged/lib/file.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
import fs from 'node:fs/promises'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
const debugLog = debug('lint-staged:file')
|
||||
|
||||
/**
|
||||
* Read contents of a file to buffer
|
||||
* @param {String} filename
|
||||
* @param {Boolean} [ignoreENOENT=true] — Whether to throw if the file doesn't exist
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
export const readFile = async (filename, ignoreENOENT = true) => {
|
||||
debugLog('Reading file `%s`', filename)
|
||||
try {
|
||||
return await fs.readFile(filename)
|
||||
} catch (error) {
|
||||
if (ignoreENOENT && error.code === 'ENOENT') {
|
||||
debugLog("File `%s` doesn't exist, ignoring...", filename)
|
||||
return null // no-op file doesn't exist
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a file
|
||||
* @param {String} filename
|
||||
* @param {Boolean} [ignoreENOENT=true] — Whether to throw if the file doesn't exist
|
||||
*/
|
||||
export const unlink = async (filename, ignoreENOENT = true) => {
|
||||
debugLog('Removing file `%s`', filename)
|
||||
try {
|
||||
await fs.unlink(filename)
|
||||
} catch (error) {
|
||||
if (ignoreENOENT && error.code === 'ENOENT') {
|
||||
debugLog("File `%s` doesn't exist, ignoring...", filename)
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write buffer to file
|
||||
* @param {String} filename
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
export const writeFile = async (filename, buffer) => {
|
||||
debugLog('Writing file `%s`', filename)
|
||||
await fs.writeFile(filename, buffer)
|
||||
}
|
53
node_modules/lint-staged/lib/generateTasks.js
generated
vendored
Normal file
53
node_modules/lint-staged/lib/generateTasks.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
import micromatch from 'micromatch'
|
||||
|
||||
import { normalizePath } from './normalizePath.js'
|
||||
|
||||
const debugLog = debug('lint-staged:generateTasks')
|
||||
|
||||
/**
|
||||
* Generates all task commands, and filelist
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {Object} [options.config] - Task configuration
|
||||
* @param {Object} [options.cwd] - Current working directory
|
||||
* @param {boolean} [options.gitDir] - Git root directory
|
||||
* @param {boolean} [options.files] - Staged filepaths
|
||||
* @param {boolean} [options.relative] - Whether filepaths to should be relative to gitDir
|
||||
*/
|
||||
export const generateTasks = ({ config, cwd = process.cwd(), files, relative = false }) => {
|
||||
debugLog('Generating linter tasks')
|
||||
|
||||
const relativeFiles = files.map((file) => normalizePath(path.relative(cwd, file)))
|
||||
|
||||
return Object.entries(config).map(([pattern, commands]) => {
|
||||
const isParentDirPattern = pattern.startsWith('../')
|
||||
|
||||
// Only worry about children of the CWD unless the pattern explicitly
|
||||
// specifies that it concerns a parent directory.
|
||||
const filteredFiles = relativeFiles.filter((file) => {
|
||||
if (isParentDirPattern) return true
|
||||
return !file.startsWith('..') && !path.isAbsolute(file)
|
||||
})
|
||||
|
||||
const matches = micromatch(filteredFiles, pattern, {
|
||||
cwd,
|
||||
dot: true,
|
||||
// If the pattern doesn't look like a path, enable `matchBase` to
|
||||
// match against filenames in every directory. This makes `*.js`
|
||||
// match both `test.js` and `subdirectory/test.js`.
|
||||
matchBase: !pattern.includes('/'),
|
||||
posixSlashes: true,
|
||||
strictBrackets: true,
|
||||
})
|
||||
|
||||
const fileList = matches.map((file) => normalizePath(relative ? file : path.resolve(cwd, file)))
|
||||
|
||||
const task = { pattern, commands, fileList }
|
||||
debugLog('Generated task: \n%O', task)
|
||||
|
||||
return task
|
||||
})
|
||||
}
|
18
node_modules/lint-staged/lib/getDiffCommand.js
generated
vendored
Normal file
18
node_modules/lint-staged/lib/getDiffCommand.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
export function getDiffCommand(diff, diffFilter) {
|
||||
/**
|
||||
* Docs for --diff-filter option:
|
||||
* @see https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203
|
||||
*/
|
||||
const diffFilterArg = diffFilter !== undefined ? diffFilter.trim() : 'ACMR'
|
||||
|
||||
/** Use `--diff branch1...branch2` or `--diff="branch1 branch2", or fall back to default staged files */
|
||||
const diffArgs = diff !== undefined ? diff.trim().split(' ') : ['--staged']
|
||||
|
||||
/**
|
||||
* Docs for -z option:
|
||||
* @see https://git-scm.com/docs/git-diff#Documentation/git-diff.txt--z
|
||||
*/
|
||||
const diffCommand = ['diff', '--name-only', '-z', `--diff-filter=${diffFilterArg}`, ...diffArgs]
|
||||
|
||||
return diffCommand
|
||||
}
|
64
node_modules/lint-staged/lib/getRenderer.js
generated
vendored
Normal file
64
node_modules/lint-staged/lib/getRenderer.js
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
import { EOL } from 'node:os'
|
||||
import { Writable } from 'node:stream'
|
||||
|
||||
import { ListrLogger, ProcessOutput } from 'listr2'
|
||||
|
||||
const EOLRegex = new RegExp(EOL + '$')
|
||||
|
||||
const bindLogger = (consoleLogMethod) =>
|
||||
new Writable({
|
||||
write: function (chunk, encoding, next) {
|
||||
consoleLogMethod(chunk.toString().replace(EOLRegex, ''))
|
||||
next()
|
||||
},
|
||||
})
|
||||
|
||||
const getMainRendererOptions = ({ debug, quiet }, logger, env) => {
|
||||
if (quiet) {
|
||||
return {
|
||||
renderer: 'silent',
|
||||
}
|
||||
}
|
||||
|
||||
if (env.NODE_ENV === 'test') {
|
||||
return {
|
||||
renderer: 'test',
|
||||
rendererOptions: {
|
||||
logger: new ListrLogger({
|
||||
processOutput: new ProcessOutput(bindLogger(logger.log), bindLogger(logger.error)),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Better support for dumb terminals: https://en.wikipedia.org/wiki/Computer_terminal#Dumb_terminals
|
||||
if (debug || env.TERM === 'dumb') {
|
||||
return {
|
||||
renderer: 'verbose',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
renderer: 'update',
|
||||
rendererOptions: {
|
||||
formatOutput: 'truncate',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const getFallbackRenderer = ({ renderer }, { FORCE_COLOR }) => {
|
||||
if (renderer === 'silent' || renderer === 'test' || Number(FORCE_COLOR) > 0) {
|
||||
return renderer
|
||||
}
|
||||
|
||||
return 'verbose'
|
||||
}
|
||||
|
||||
export const getRenderer = (options, logger, env = process.env) => {
|
||||
const mainRendererOptions = getMainRendererOptions(options, logger, env)
|
||||
|
||||
return {
|
||||
...mainRendererOptions,
|
||||
fallbackRenderer: getFallbackRenderer(mainRendererOptions, env),
|
||||
}
|
||||
}
|
17
node_modules/lint-staged/lib/getStagedFiles.js
generated
vendored
Normal file
17
node_modules/lint-staged/lib/getStagedFiles.js
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import { execGit } from './execGit.js'
|
||||
import { getDiffCommand } from './getDiffCommand.js'
|
||||
import { normalizePath } from './normalizePath.js'
|
||||
import { parseGitZOutput } from './parseGitZOutput.js'
|
||||
|
||||
export const getStagedFiles = async ({ cwd = process.cwd(), diff, diffFilter } = {}) => {
|
||||
try {
|
||||
const lines = await execGit(getDiffCommand(diff, diffFilter), { cwd })
|
||||
if (!lines) return []
|
||||
|
||||
return parseGitZOutput(lines).map((file) => normalizePath(path.resolve(cwd, file)))
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
341
node_modules/lint-staged/lib/gitWorkflow.js
generated
vendored
Normal file
341
node_modules/lint-staged/lib/gitWorkflow.js
generated
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
import { execGit } from './execGit.js'
|
||||
import { readFile, unlink, writeFile } from './file.js'
|
||||
import { getDiffCommand } from './getDiffCommand.js'
|
||||
import {
|
||||
GitError,
|
||||
RestoreOriginalStateError,
|
||||
ApplyEmptyCommitError,
|
||||
GetBackupStashError,
|
||||
HideUnstagedChangesError,
|
||||
RestoreMergeStatusError,
|
||||
RestoreUnstagedChangesError,
|
||||
} from './symbols.js'
|
||||
|
||||
const debugLog = debug('lint-staged:GitWorkflow')
|
||||
|
||||
const MERGE_HEAD = 'MERGE_HEAD'
|
||||
const MERGE_MODE = 'MERGE_MODE'
|
||||
const MERGE_MSG = 'MERGE_MSG'
|
||||
|
||||
// In git status machine output, renames are presented as `to`NUL`from`
|
||||
// When diffing, both need to be taken into account, but in some cases on the `to`.
|
||||
// eslint-disable-next-line no-control-regex
|
||||
const RENAME = /\x00/
|
||||
|
||||
/**
|
||||
* From list of files, split renames and flatten into two files `to`NUL`from`.
|
||||
* @param {string[]} files
|
||||
* @param {Boolean} [includeRenameFrom=true] Whether or not to include the `from` renamed file, which is no longer on disk
|
||||
*/
|
||||
const processRenames = (files, includeRenameFrom = true) =>
|
||||
files.reduce((flattened, file) => {
|
||||
if (RENAME.test(file)) {
|
||||
const [to, from] = file.split(RENAME)
|
||||
if (includeRenameFrom) flattened.push(from)
|
||||
flattened.push(to)
|
||||
} else {
|
||||
flattened.push(file)
|
||||
}
|
||||
return flattened
|
||||
}, [])
|
||||
|
||||
export const STASH = 'lint-staged automatic backup'
|
||||
|
||||
const PATCH_UNSTAGED = 'lint-staged_unstaged.patch'
|
||||
|
||||
const GIT_DIFF_ARGS = [
|
||||
'--binary', // support binary files
|
||||
'--unified=0', // do not add lines around diff for consistent behaviour
|
||||
'--no-color', // disable colors for consistent behaviour
|
||||
'--no-ext-diff', // disable external diff tools for consistent behaviour
|
||||
'--src-prefix=a/', // force prefix for consistent behaviour
|
||||
'--dst-prefix=b/', // force prefix for consistent behaviour
|
||||
'--patch', // output a patch that can be applied
|
||||
'--submodule=short', // always use the default short format for submodules
|
||||
]
|
||||
const GIT_APPLY_ARGS = ['-v', '--whitespace=nowarn', '--recount', '--unidiff-zero']
|
||||
|
||||
const handleError = (error, ctx, symbol) => {
|
||||
ctx.errors.add(GitError)
|
||||
if (symbol) ctx.errors.add(symbol)
|
||||
throw error
|
||||
}
|
||||
|
||||
export class GitWorkflow {
|
||||
constructor({ allowEmpty, gitConfigDir, gitDir, matchedFileChunks, diff, diffFilter }) {
|
||||
this.execGit = (args, options = {}) => execGit(args, { ...options, cwd: gitDir })
|
||||
this.deletedFiles = []
|
||||
this.gitConfigDir = gitConfigDir
|
||||
this.gitDir = gitDir
|
||||
this.diff = diff
|
||||
this.diffFilter = diffFilter
|
||||
this.allowEmpty = allowEmpty
|
||||
this.matchedFileChunks = matchedFileChunks
|
||||
|
||||
/**
|
||||
* These three files hold state about an ongoing git merge
|
||||
* Resolve paths during constructor
|
||||
*/
|
||||
this.mergeHeadFilename = path.resolve(gitConfigDir, MERGE_HEAD)
|
||||
this.mergeModeFilename = path.resolve(gitConfigDir, MERGE_MODE)
|
||||
this.mergeMsgFilename = path.resolve(gitConfigDir, MERGE_MSG)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute path to file hidden inside .git
|
||||
* @param {string} filename
|
||||
*/
|
||||
getHiddenFilepath(filename) {
|
||||
return path.resolve(this.gitConfigDir, `./${filename}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of backup stash
|
||||
*/
|
||||
async getBackupStash(ctx) {
|
||||
const stashes = await this.execGit(['stash', 'list'])
|
||||
const index = stashes.split('\n').findIndex((line) => line.includes(STASH))
|
||||
if (index === -1) {
|
||||
ctx.errors.add(GetBackupStashError)
|
||||
throw new Error('lint-staged automatic backup is missing!')
|
||||
}
|
||||
|
||||
return String(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of unstaged deleted files
|
||||
*/
|
||||
async getDeletedFiles() {
|
||||
debugLog('Getting deleted files...')
|
||||
const lsFiles = await this.execGit(['ls-files', '--deleted'])
|
||||
const deletedFiles = lsFiles
|
||||
.split('\n')
|
||||
.filter(Boolean)
|
||||
.map((file) => path.resolve(this.gitDir, file))
|
||||
debugLog('Found deleted files:', deletedFiles)
|
||||
return deletedFiles
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta information about ongoing git merge
|
||||
*/
|
||||
async backupMergeStatus() {
|
||||
debugLog('Backing up merge state...')
|
||||
await Promise.all([
|
||||
readFile(this.mergeHeadFilename).then((buffer) => (this.mergeHeadBuffer = buffer)),
|
||||
readFile(this.mergeModeFilename).then((buffer) => (this.mergeModeBuffer = buffer)),
|
||||
readFile(this.mergeMsgFilename).then((buffer) => (this.mergeMsgBuffer = buffer)),
|
||||
])
|
||||
debugLog('Done backing up merge state!')
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore meta information about ongoing git merge
|
||||
*/
|
||||
async restoreMergeStatus(ctx) {
|
||||
debugLog('Restoring merge state...')
|
||||
try {
|
||||
await Promise.all([
|
||||
this.mergeHeadBuffer && writeFile(this.mergeHeadFilename, this.mergeHeadBuffer),
|
||||
this.mergeModeBuffer && writeFile(this.mergeModeFilename, this.mergeModeBuffer),
|
||||
this.mergeMsgBuffer && writeFile(this.mergeMsgFilename, this.mergeMsgBuffer),
|
||||
])
|
||||
debugLog('Done restoring merge state!')
|
||||
} catch (error) {
|
||||
debugLog('Failed restoring merge state with error:')
|
||||
debugLog(error)
|
||||
handleError(
|
||||
new Error('Merge state could not be restored due to an error!'),
|
||||
ctx,
|
||||
RestoreMergeStatusError
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all files with both staged and unstaged modifications.
|
||||
* Renames have special treatment, since the single status line includes
|
||||
* both the "from" and "to" filenames, where "from" is no longer on disk.
|
||||
*/
|
||||
async getPartiallyStagedFiles() {
|
||||
debugLog('Getting partially staged files...')
|
||||
const status = await this.execGit(['status', '-z'])
|
||||
/**
|
||||
* See https://git-scm.com/docs/git-status#_short_format
|
||||
* Entries returned in machine format are separated by a NUL character.
|
||||
* The first letter of each entry represents current index status,
|
||||
* and second the working tree. Index and working tree status codes are
|
||||
* separated from the file name by a space. If an entry includes a
|
||||
* renamed file, the file names are separated by a NUL character
|
||||
* (e.g. `to`\0`from`)
|
||||
*/
|
||||
const partiallyStaged = status
|
||||
// eslint-disable-next-line no-control-regex
|
||||
.split(/\x00(?=[ AMDRCU?!]{2} |$)/)
|
||||
.filter((line) => {
|
||||
const [index, workingTree] = line
|
||||
return index !== ' ' && workingTree !== ' ' && index !== '?' && workingTree !== '?'
|
||||
})
|
||||
.map((line) => line.substr(3)) // Remove first three letters (index, workingTree, and a whitespace)
|
||||
.filter(Boolean) // Filter empty string
|
||||
debugLog('Found partially staged files:', partiallyStaged)
|
||||
return partiallyStaged.length ? partiallyStaged : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a diff of partially staged files and backup stash if enabled.
|
||||
*/
|
||||
async prepare(ctx) {
|
||||
try {
|
||||
debugLog('Backing up original state...')
|
||||
|
||||
// Get a list of files with bot staged and unstaged changes.
|
||||
// Unstaged changes to these files should be hidden before the tasks run.
|
||||
this.partiallyStagedFiles = await this.getPartiallyStagedFiles()
|
||||
|
||||
if (this.partiallyStagedFiles) {
|
||||
ctx.hasPartiallyStagedFiles = true
|
||||
const unstagedPatch = this.getHiddenFilepath(PATCH_UNSTAGED)
|
||||
const files = processRenames(this.partiallyStagedFiles)
|
||||
await this.execGit(['diff', ...GIT_DIFF_ARGS, '--output', unstagedPatch, '--', ...files])
|
||||
} else {
|
||||
ctx.hasPartiallyStagedFiles = false
|
||||
}
|
||||
|
||||
/**
|
||||
* If backup stash should be skipped, no need to continue
|
||||
*/
|
||||
if (!ctx.shouldBackup) return
|
||||
|
||||
// When backup is enabled, the revert will clear ongoing merge status.
|
||||
await this.backupMergeStatus()
|
||||
|
||||
// Get a list of unstaged deleted files, because certain bugs might cause them to reappear:
|
||||
// - in git versions =< 2.13.0 the `git stash --keep-index` option resurrects deleted files
|
||||
// - git stash can't infer RD or MD states correctly, and will lose the deletion
|
||||
this.deletedFiles = await this.getDeletedFiles()
|
||||
|
||||
// Save stash of all staged files.
|
||||
// The `stash create` command creates a dangling commit without removing any files,
|
||||
// and `stash store` saves it as an actual stash.
|
||||
const hash = await this.execGit(['stash', 'create'])
|
||||
await this.execGit(['stash', 'store', '--quiet', '--message', STASH, hash])
|
||||
|
||||
debugLog('Done backing up original state!')
|
||||
} catch (error) {
|
||||
handleError(error, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unstaged changes to all partially staged files, to avoid tasks from seeing them
|
||||
*/
|
||||
async hideUnstagedChanges(ctx) {
|
||||
try {
|
||||
const files = processRenames(this.partiallyStagedFiles, false)
|
||||
await this.execGit(['checkout', '--force', '--', ...files])
|
||||
} catch (error) {
|
||||
/**
|
||||
* `git checkout --force` doesn't throw errors, so it shouldn't be possible to get here.
|
||||
* If this does fail, the handleError method will set ctx.gitError and lint-staged will fail.
|
||||
*/
|
||||
handleError(error, ctx, HideUnstagedChangesError)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies back task modifications, and unstaged changes hidden in the stash.
|
||||
* In case of a merge-conflict retry with 3-way merge.
|
||||
*/
|
||||
async applyModifications(ctx) {
|
||||
debugLog('Adding task modifications to index...')
|
||||
|
||||
// `matchedFileChunks` includes staged files that lint-staged originally detected and matched against a task.
|
||||
// Add only these files so any 3rd-party edits to other files won't be included in the commit.
|
||||
// These additions per chunk are run "serially" to prevent race conditions.
|
||||
// Git add creates a lockfile in the repo causing concurrent operations to fail.
|
||||
for (const files of this.matchedFileChunks) {
|
||||
await this.execGit(['add', '--', ...files])
|
||||
}
|
||||
|
||||
debugLog('Done adding task modifications to index!')
|
||||
|
||||
const stagedFilesAfterAdd = await this.execGit(getDiffCommand(this.diff, this.diffFilter))
|
||||
if (!stagedFilesAfterAdd && !this.allowEmpty) {
|
||||
// Tasks reverted all staged changes and the commit would be empty
|
||||
// Throw error to stop commit unless `--allow-empty` was used
|
||||
handleError(new Error('Prevented an empty git commit!'), ctx, ApplyEmptyCommitError)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore unstaged changes to partially changed files. If it at first fails,
|
||||
* this is probably because of conflicts between new task modifications.
|
||||
* 3-way merge usually fixes this, and in case it doesn't we should just give up and throw.
|
||||
*/
|
||||
async restoreUnstagedChanges(ctx) {
|
||||
debugLog('Restoring unstaged changes...')
|
||||
const unstagedPatch = this.getHiddenFilepath(PATCH_UNSTAGED)
|
||||
try {
|
||||
await this.execGit(['apply', ...GIT_APPLY_ARGS, unstagedPatch])
|
||||
} catch (applyError) {
|
||||
debugLog('Error while restoring changes:')
|
||||
debugLog(applyError)
|
||||
debugLog('Retrying with 3-way merge')
|
||||
try {
|
||||
// Retry with a 3-way merge if normal apply fails
|
||||
await this.execGit(['apply', ...GIT_APPLY_ARGS, '--3way', unstagedPatch])
|
||||
} catch (threeWayApplyError) {
|
||||
debugLog('Error while restoring unstaged changes using 3-way merge:')
|
||||
debugLog(threeWayApplyError)
|
||||
handleError(
|
||||
new Error('Unstaged changes could not be restored due to a merge conflict!'),
|
||||
ctx,
|
||||
RestoreUnstagedChangesError
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore original HEAD state in case of errors
|
||||
*/
|
||||
async restoreOriginalState(ctx) {
|
||||
try {
|
||||
debugLog('Restoring original state...')
|
||||
await this.execGit(['reset', '--hard', 'HEAD'])
|
||||
await this.execGit(['stash', 'apply', '--quiet', '--index', await this.getBackupStash(ctx)])
|
||||
|
||||
// Restore meta information about ongoing git merge
|
||||
await this.restoreMergeStatus(ctx)
|
||||
|
||||
// If stashing resurrected deleted files, clean them out
|
||||
await Promise.all(this.deletedFiles.map((file) => unlink(file)))
|
||||
|
||||
// Clean out patch
|
||||
await unlink(this.getHiddenFilepath(PATCH_UNSTAGED))
|
||||
|
||||
debugLog('Done restoring original state!')
|
||||
} catch (error) {
|
||||
handleError(error, ctx, RestoreOriginalStateError)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the created stashes after everything has run
|
||||
*/
|
||||
async cleanup(ctx) {
|
||||
try {
|
||||
debugLog('Dropping backup stash...')
|
||||
await this.execGit(['stash', 'drop', '--quiet', await this.getBackupStash(ctx)])
|
||||
debugLog('Done dropping backup stash!')
|
||||
} catch (error) {
|
||||
handleError(error, ctx)
|
||||
}
|
||||
}
|
||||
}
|
55
node_modules/lint-staged/lib/groupFilesByConfig.js
generated
vendored
Normal file
55
node_modules/lint-staged/lib/groupFilesByConfig.js
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
const debugLog = debug('lint-staged:groupFilesByConfig')
|
||||
|
||||
export const groupFilesByConfig = async ({ configs, files, singleConfigMode }) => {
|
||||
debugLog('Grouping %d files by %d configurations', files.length, Object.keys(configs).length)
|
||||
|
||||
const filesSet = new Set(files)
|
||||
const filesByConfig = {}
|
||||
|
||||
/** Configs are sorted deepest first by `searchConfigs` */
|
||||
for (const [filepath, config] of Object.entries(configs)) {
|
||||
/** When passed an explicit config object via the Node.js API‚ or an explicit path, skip logic */
|
||||
if (singleConfigMode) {
|
||||
filesByConfig[filepath] = { config, files }
|
||||
break
|
||||
}
|
||||
|
||||
const dir = path.normalize(path.dirname(filepath))
|
||||
|
||||
/** Check if file is inside directory of the configuration file */
|
||||
const isInsideDir = (file) => {
|
||||
const relative = path.relative(dir, file)
|
||||
return relative && !relative.startsWith('..') && !path.isAbsolute(relative)
|
||||
}
|
||||
|
||||
/** This config should match all files since it has a parent glob */
|
||||
const includeAllFiles = Object.keys(config).some((glob) => glob.startsWith('..'))
|
||||
|
||||
const scopedFiles = new Set(includeAllFiles ? filesSet : undefined)
|
||||
|
||||
/**
|
||||
* Without a parent glob, if file is inside the config file's directory,
|
||||
* assign it to that configuration.
|
||||
*/
|
||||
if (!includeAllFiles) {
|
||||
filesSet.forEach((file) => {
|
||||
if (isInsideDir(file)) {
|
||||
scopedFiles.add(file)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** Files should only match a single config */
|
||||
scopedFiles.forEach((file) => {
|
||||
filesSet.delete(file)
|
||||
})
|
||||
|
||||
filesByConfig[filepath] = { config, files: Array.from(scopedFiles) }
|
||||
}
|
||||
|
||||
return filesByConfig
|
||||
}
|
137
node_modules/lint-staged/lib/index.js
generated
vendored
Normal file
137
node_modules/lint-staged/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
import debug from 'debug'
|
||||
|
||||
import {
|
||||
PREVENTED_EMPTY_COMMIT,
|
||||
GIT_ERROR,
|
||||
RESTORE_STASH_EXAMPLE,
|
||||
NO_CONFIGURATION,
|
||||
} from './messages.js'
|
||||
import { printTaskOutput } from './printTaskOutput.js'
|
||||
import { runAll } from './runAll.js'
|
||||
import {
|
||||
ApplyEmptyCommitError,
|
||||
ConfigNotFoundError,
|
||||
GetBackupStashError,
|
||||
GitError,
|
||||
} from './symbols.js'
|
||||
import { validateOptions } from './validateOptions.js'
|
||||
|
||||
const debugLog = debug('lint-staged')
|
||||
|
||||
/**
|
||||
* Get the maximum length of a command-line argument string based on current platform
|
||||
*
|
||||
* https://serverfault.com/questions/69430/what-is-the-maximum-length-of-a-command-line-in-mac-os-x
|
||||
* https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation
|
||||
* https://unix.stackexchange.com/a/120652
|
||||
*/
|
||||
const getMaxArgLength = () => {
|
||||
switch (process.platform) {
|
||||
case 'darwin':
|
||||
return 262144
|
||||
case 'win32':
|
||||
return 8191
|
||||
default:
|
||||
return 131072
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {(...any) => void} LogFunction
|
||||
* @typedef {{ error: LogFunction, log: LogFunction, warn: LogFunction }} Logger
|
||||
*
|
||||
* Root lint-staged function that is called from `bin/lint-staged`.
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {Object} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes
|
||||
* @param {boolean | number} [options.concurrent] - The number of tasks to run concurrently, or false to run tasks serially
|
||||
* @param {object} [options.config] - Object with configuration for programmatic API
|
||||
* @param {string} [options.configPath] - Path to configuration file
|
||||
* @param {Object} [options.cwd] - Current working directory
|
||||
* @param {boolean} [options.debug] - Enable debug mode
|
||||
* @param {string} [options.diff] - Override the default "--staged" flag of "git diff" to get list of files
|
||||
* @param {string} [options.diffFilter] - Override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
|
||||
* @param {number} [options.maxArgLength] - Maximum argument string length
|
||||
* @param {boolean} [options.quiet] - Disable lint-staged’s own console output
|
||||
* @param {boolean} [options.relative] - Pass relative filepaths to tasks
|
||||
* @param {boolean|string} [options.shell] - Skip parsing of tasks for better shell support
|
||||
* @param {boolean} [options.stash] - Enable the backup stash, and revert in case of errors
|
||||
* @param {boolean} [options.verbose] - Show task output even when tasks succeed; by default only failed output is shown
|
||||
* @param {Logger} [logger]
|
||||
*
|
||||
* @returns {Promise<boolean>} Promise of whether the linting passed or failed
|
||||
*/
|
||||
const lintStaged = async (
|
||||
{
|
||||
allowEmpty = false,
|
||||
concurrent = true,
|
||||
config: configObject,
|
||||
configPath,
|
||||
cwd,
|
||||
debug = false,
|
||||
diff,
|
||||
diffFilter,
|
||||
maxArgLength = getMaxArgLength() / 2,
|
||||
quiet = false,
|
||||
relative = false,
|
||||
shell = false,
|
||||
// Stashing should be disabled by default when the `diff` option is used
|
||||
stash = diff === undefined,
|
||||
verbose = false,
|
||||
} = {},
|
||||
logger = console
|
||||
) => {
|
||||
await validateOptions({ cwd, shell }, logger)
|
||||
|
||||
// Unset GIT_LITERAL_PATHSPECS to not mess with path interpretation
|
||||
debugLog('Unset GIT_LITERAL_PATHSPECS (was `%s`)', process.env.GIT_LITERAL_PATHSPECS)
|
||||
delete process.env.GIT_LITERAL_PATHSPECS
|
||||
|
||||
const options = {
|
||||
allowEmpty,
|
||||
concurrent,
|
||||
configObject,
|
||||
configPath,
|
||||
cwd,
|
||||
debug,
|
||||
diff,
|
||||
diffFilter,
|
||||
maxArgLength,
|
||||
quiet,
|
||||
relative,
|
||||
shell,
|
||||
stash,
|
||||
verbose,
|
||||
}
|
||||
|
||||
try {
|
||||
const ctx = await runAll(options, logger)
|
||||
debugLog('Tasks were executed successfully!')
|
||||
printTaskOutput(ctx, logger)
|
||||
return true
|
||||
} catch (runAllError) {
|
||||
if (runAllError?.ctx?.errors) {
|
||||
const { ctx } = runAllError
|
||||
|
||||
if (ctx.errors.has(ConfigNotFoundError)) {
|
||||
logger.error(NO_CONFIGURATION)
|
||||
} else if (ctx.errors.has(ApplyEmptyCommitError)) {
|
||||
logger.warn(PREVENTED_EMPTY_COMMIT)
|
||||
} else if (ctx.errors.has(GitError) && !ctx.errors.has(GetBackupStashError)) {
|
||||
logger.error(GIT_ERROR)
|
||||
if (ctx.shouldBackup) {
|
||||
// No sense to show this if the backup stash itself is missing.
|
||||
logger.error(RESTORE_STASH_EXAMPLE)
|
||||
}
|
||||
}
|
||||
|
||||
printTaskOutput(ctx, logger)
|
||||
return false
|
||||
}
|
||||
|
||||
// Probably a compilation error in the config js file. Pass it up to the outer error handler for logging.
|
||||
throw runAllError
|
||||
}
|
||||
}
|
||||
|
||||
export default lintStaged
|
96
node_modules/lint-staged/lib/loadConfig.js
generated
vendored
Normal file
96
node_modules/lint-staged/lib/loadConfig.js
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/** @typedef {import('./index').Logger} Logger */
|
||||
|
||||
import debug from 'debug'
|
||||
import { lilconfig } from 'lilconfig'
|
||||
import YAML from 'yaml'
|
||||
|
||||
import { dynamicImport } from './dynamicImport.js'
|
||||
import { resolveConfig } from './resolveConfig.js'
|
||||
|
||||
const debugLog = debug('lint-staged:loadConfig')
|
||||
|
||||
const PACKAGE_JSON = 'package.json'
|
||||
|
||||
/**
|
||||
* The list of files `lint-staged` will read configuration
|
||||
* from, in the declared order.
|
||||
*/
|
||||
export const searchPlaces = [
|
||||
PACKAGE_JSON,
|
||||
'.lintstagedrc',
|
||||
'.lintstagedrc.json',
|
||||
'.lintstagedrc.yaml',
|
||||
'.lintstagedrc.yml',
|
||||
'.lintstagedrc.mjs',
|
||||
'.lintstagedrc.js',
|
||||
'.lintstagedrc.cjs',
|
||||
'lint-staged.config.mjs',
|
||||
'lint-staged.config.js',
|
||||
'lint-staged.config.cjs',
|
||||
]
|
||||
|
||||
const jsonParse = (path, content) => {
|
||||
try {
|
||||
return JSON.parse(content)
|
||||
} catch (error) {
|
||||
if (path.endsWith(PACKAGE_JSON)) {
|
||||
debugLog('Ignoring invalid package file `%s` with content:\n%s', path, content)
|
||||
return undefined
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const yamlParse = (path, content) => YAML.parse(content)
|
||||
|
||||
/**
|
||||
* `lilconfig` doesn't support yaml files by default,
|
||||
* so we add custom loaders for those. Files without
|
||||
* an extensions are assumed to be yaml — this
|
||||
* assumption is in `cosmiconfig` as well.
|
||||
*/
|
||||
const loaders = {
|
||||
'.js': dynamicImport,
|
||||
'.json': jsonParse,
|
||||
'.mjs': dynamicImport,
|
||||
'.cjs': dynamicImport,
|
||||
'.yaml': yamlParse,
|
||||
'.yml': yamlParse,
|
||||
noExt: yamlParse,
|
||||
}
|
||||
|
||||
const explorer = lilconfig('lint-staged', { searchPlaces, loaders })
|
||||
|
||||
/**
|
||||
* @param {object} options
|
||||
* @param {string} [options.configPath] - Explicit path to a config file
|
||||
* @param {string} [options.cwd] - Current working directory
|
||||
*/
|
||||
export const loadConfig = async ({ configPath, cwd }, logger) => {
|
||||
try {
|
||||
if (configPath) {
|
||||
debugLog('Loading configuration from `%s`...', configPath)
|
||||
} else {
|
||||
debugLog('Searching for configuration from `%s`...', cwd)
|
||||
}
|
||||
|
||||
const result = await (configPath
|
||||
? explorer.load(resolveConfig(configPath))
|
||||
: explorer.search(cwd))
|
||||
|
||||
if (!result) return {}
|
||||
|
||||
// config is a promise when using the `dynamicImport` loader
|
||||
const config = await result.config
|
||||
const filepath = result.filepath
|
||||
|
||||
debugLog('Successfully loaded config from `%s`:\n%O', filepath, config)
|
||||
|
||||
return { config, filepath }
|
||||
} catch (error) {
|
||||
debugLog('Failed to load configuration!')
|
||||
logger.error(error)
|
||||
return {}
|
||||
}
|
||||
}
|
50
node_modules/lint-staged/lib/makeCmdTasks.js
generated
vendored
Normal file
50
node_modules/lint-staged/lib/makeCmdTasks.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
import debug from 'debug'
|
||||
|
||||
import { configurationError } from './messages.js'
|
||||
import { resolveTaskFn } from './resolveTaskFn.js'
|
||||
|
||||
const debugLog = debug('lint-staged:makeCmdTasks')
|
||||
|
||||
/**
|
||||
* Creates and returns an array of listr tasks which map to the given commands.
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {Array<string|Function>|string|Function} options.commands
|
||||
* @param {string} options.cwd
|
||||
* @param {Array<string>} options.files
|
||||
* @param {string} options.gitDir
|
||||
* @param {Boolean} shell
|
||||
* @param {Boolean} verbose
|
||||
*/
|
||||
export const makeCmdTasks = async ({ commands, cwd, files, gitDir, shell, verbose }) => {
|
||||
debugLog('Creating listr tasks for commands %o', commands)
|
||||
const commandArray = Array.isArray(commands) ? commands : [commands]
|
||||
const cmdTasks = []
|
||||
|
||||
for (const cmd of commandArray) {
|
||||
// command function may return array of commands that already include `stagedFiles`
|
||||
const isFn = typeof cmd === 'function'
|
||||
const resolved = isFn ? await cmd(files) : cmd
|
||||
|
||||
const resolvedArray = Array.isArray(resolved) ? resolved : [resolved] // Wrap non-array command as array
|
||||
|
||||
for (const command of resolvedArray) {
|
||||
// If the function linter didn't return string | string[] it won't work
|
||||
// Do the validation here instead of `validateConfig` to skip evaluating the function multiple times
|
||||
if (isFn && typeof command !== 'string') {
|
||||
throw new Error(
|
||||
configurationError(
|
||||
'[Function]',
|
||||
'Function task should return a string or an array of strings',
|
||||
resolved
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const task = resolveTaskFn({ command, cwd, files, gitDir, isFn, shell, verbose })
|
||||
cmdTasks.push({ title: command, command, task })
|
||||
}
|
||||
}
|
||||
|
||||
return cmdTasks
|
||||
}
|
74
node_modules/lint-staged/lib/messages.js
generated
vendored
Normal file
74
node_modules/lint-staged/lib/messages.js
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
import { inspect } from 'node:util'
|
||||
|
||||
import chalk from 'chalk'
|
||||
|
||||
import { error, info, warning } from './figures.js'
|
||||
|
||||
export const configurationError = (opt, helpMsg, value) =>
|
||||
`${chalk.redBright(`${error} Validation Error:`)}
|
||||
|
||||
Invalid value for '${chalk.bold(opt)}': ${chalk.bold(inspect(value))}
|
||||
|
||||
${helpMsg}`
|
||||
|
||||
export const NOT_GIT_REPO = chalk.redBright(`${error} Current directory is not a git directory!`)
|
||||
|
||||
export const FAILED_GET_STAGED_FILES = chalk.redBright(`${error} Failed to get staged files!`)
|
||||
|
||||
export const incorrectBraces = (before, after) =>
|
||||
chalk.yellow(
|
||||
`${warning} Detected incorrect braces with only single value: \`${before}\`. Reformatted as: \`${after}\`
|
||||
`
|
||||
)
|
||||
|
||||
export const NO_CONFIGURATION = `${error} No valid configuration found.`
|
||||
|
||||
export const NO_STAGED_FILES = `${info} No staged files found.`
|
||||
|
||||
export const NO_TASKS = `${info} No staged files match any configured task.`
|
||||
|
||||
export const skippingBackup = (hasInitialCommit, diff) => {
|
||||
const reason =
|
||||
diff !== undefined
|
||||
? '`--diff` was used'
|
||||
: hasInitialCommit
|
||||
? '`--no-stash` was used'
|
||||
: 'there’s no initial commit yet'
|
||||
|
||||
return chalk.yellow(`${warning} Skipping backup because ${reason}.\n`)
|
||||
}
|
||||
|
||||
export const DEPRECATED_GIT_ADD = chalk.yellow(
|
||||
`${warning} Some of your tasks use \`git add\` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index.
|
||||
`
|
||||
)
|
||||
|
||||
export const TASK_ERROR = 'Skipped because of errors from tasks.'
|
||||
|
||||
export const SKIPPED_GIT_ERROR = 'Skipped because of previous git error.'
|
||||
|
||||
export const GIT_ERROR = `\n ${chalk.redBright(`${error} lint-staged failed due to a git error.`)}`
|
||||
|
||||
export const invalidOption = (name, value, message) => `${chalk.redBright(
|
||||
`${error} Validation Error:`
|
||||
)}
|
||||
|
||||
Invalid value for option '${chalk.bold(name)}': ${chalk.bold(value)}
|
||||
|
||||
${message}
|
||||
|
||||
See https://github.com/okonet/lint-staged#command-line-flags`
|
||||
|
||||
export const PREVENTED_EMPTY_COMMIT = `
|
||||
${chalk.yellow(`${warning} lint-staged prevented an empty git commit.
|
||||
Use the --allow-empty option to continue, or check your task configuration`)}
|
||||
`
|
||||
|
||||
export const RESTORE_STASH_EXAMPLE = ` Any lost modifications can be restored from a git stash:
|
||||
|
||||
> git stash list
|
||||
stash@{0}: automatic lint-staged backup
|
||||
> git stash apply --index stash@{0}
|
||||
`
|
||||
|
||||
export const CONFIG_STDIN_ERROR = 'Error: Could not read config from stdin.'
|
50
node_modules/lint-staged/lib/normalizePath.js
generated
vendored
Normal file
50
node_modules/lint-staged/lib/normalizePath.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Reimplementation of "normalize-path"
|
||||
* @see https://github.com/jonschlinkert/normalize-path/blob/52c3a95ebebc2d98c1ad7606cbafa7e658656899/index.js
|
||||
*/
|
||||
|
||||
/*!
|
||||
* normalize-path <https://github.com/jonschlinkert/normalize-path>
|
||||
*
|
||||
* Copyright (c) 2014-2018, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
import path from 'node:path'
|
||||
|
||||
/**
|
||||
* A file starting with \\?\
|
||||
* @see https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#win32-file-namespaces
|
||||
*/
|
||||
const WIN32_FILE_NS = '\\\\?\\'
|
||||
|
||||
/**
|
||||
* A file starting with \\.\
|
||||
* @see https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#win32-file-namespaces
|
||||
*/
|
||||
const WIN32_DEVICE_NS = '\\\\.\\'
|
||||
|
||||
/**
|
||||
* Normalize input file path to use POSIX separators
|
||||
* @param {String} input
|
||||
* @returns String
|
||||
*/
|
||||
export const normalizePath = (input) => {
|
||||
if (input === path.posix.sep || input === path.win32.sep) {
|
||||
return path.posix.sep
|
||||
}
|
||||
|
||||
let normalized = input.split(/[/\\]+/).join(path.posix.sep)
|
||||
|
||||
/** Handle win32 Namespaced paths by changing e.g. \\.\ to //./ */
|
||||
if (input.startsWith(WIN32_FILE_NS) || input.startsWith(WIN32_DEVICE_NS)) {
|
||||
normalized = normalized.replace(/^\/(\.|\?)/, '//$1')
|
||||
}
|
||||
|
||||
/** Remove trailing slash */
|
||||
if (normalized.endsWith(path.posix.sep)) {
|
||||
normalized = normalized.slice(0, -1)
|
||||
}
|
||||
|
||||
return normalized
|
||||
}
|
11
node_modules/lint-staged/lib/parseGitZOutput.js
generated
vendored
Normal file
11
node_modules/lint-staged/lib/parseGitZOutput.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Return array of strings split from the output of `git <something> -z`.
|
||||
* With `-z`, git prints `fileA\u0000fileB\u0000fileC\u0000` so we need to
|
||||
* remove the last occurrence of `\u0000` before splitting
|
||||
*/
|
||||
export const parseGitZOutput = (input) =>
|
||||
input
|
||||
? input
|
||||
.replace(/\u0000$/, '') // eslint-disable-line no-control-regex
|
||||
.split('\u0000')
|
||||
: []
|
12
node_modules/lint-staged/lib/printTaskOutput.js
generated
vendored
Normal file
12
node_modules/lint-staged/lib/printTaskOutput.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Handle logging of listr `ctx.output` to the specified `logger`
|
||||
* @param {Object} ctx - The listr initial state
|
||||
* @param {Object} logger - The logger
|
||||
*/
|
||||
export const printTaskOutput = (ctx = {}, logger) => {
|
||||
if (!Array.isArray(ctx.output)) return
|
||||
const log = ctx.errors?.size > 0 ? logger.error : logger.log
|
||||
for (const line of ctx.output) {
|
||||
log(line)
|
||||
}
|
||||
}
|
15
node_modules/lint-staged/lib/resolveConfig.js
generated
vendored
Normal file
15
node_modules/lint-staged/lib/resolveConfig.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
/**
|
||||
* require() does not exist for ESM, so we must create it to use require.resolve().
|
||||
* @see https://nodejs.org/api/module.html#modulecreaterequirefilename
|
||||
*/
|
||||
const require = createRequire(import.meta.url)
|
||||
|
||||
export function resolveConfig(configPath) {
|
||||
try {
|
||||
return require.resolve(configPath)
|
||||
} catch {
|
||||
return configPath
|
||||
}
|
||||
}
|
70
node_modules/lint-staged/lib/resolveGitRepo.js
generated
vendored
Normal file
70
node_modules/lint-staged/lib/resolveGitRepo.js
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
import { execGit } from './execGit.js'
|
||||
import { readFile } from './file.js'
|
||||
import { normalizePath } from './normalizePath.js'
|
||||
|
||||
const debugLog = debug('lint-staged:resolveGitRepo')
|
||||
|
||||
/**
|
||||
* Resolve path to the .git directory, with special handling for
|
||||
* submodules and worktrees
|
||||
*/
|
||||
const resolveGitConfigDir = async (gitDir) => {
|
||||
// Get the real path in case it's a symlink
|
||||
const defaultDir = normalizePath(await fs.realpath(path.join(gitDir, '.git')))
|
||||
const stats = await fs.lstat(defaultDir)
|
||||
// If .git is a directory, use it
|
||||
if (stats.isDirectory()) return defaultDir
|
||||
// Otherwise .git is a file containing path to real location
|
||||
const file = (await readFile(defaultDir)).toString()
|
||||
return path.resolve(gitDir, file.replace(/^gitdir: /, '')).trim()
|
||||
}
|
||||
|
||||
// exported for test
|
||||
export const determineGitDir = (cwd, relativeDir) => {
|
||||
// if relative dir and cwd have different endings normalize it
|
||||
// this happens under windows, where normalize is unable to normalize git's output
|
||||
if (relativeDir && relativeDir.endsWith(path.sep)) {
|
||||
relativeDir = relativeDir.slice(0, -1)
|
||||
}
|
||||
if (relativeDir) {
|
||||
// the current working dir is inside the git top-level directory
|
||||
return normalizePath(cwd.substring(0, cwd.lastIndexOf(relativeDir)))
|
||||
} else {
|
||||
// the current working dir is the top-level git directory
|
||||
return normalizePath(cwd)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve git directory and possible submodule paths
|
||||
*/
|
||||
export const resolveGitRepo = async (cwd = process.cwd()) => {
|
||||
try {
|
||||
debugLog('Resolving git repo from `%s`', cwd)
|
||||
|
||||
// Unset GIT_DIR before running any git operations in case it's pointing to an incorrect location
|
||||
debugLog('Unset GIT_DIR (was `%s`)', process.env.GIT_DIR)
|
||||
delete process.env.GIT_DIR
|
||||
debugLog('Unset GIT_WORK_TREE (was `%s`)', process.env.GIT_WORK_TREE)
|
||||
delete process.env.GIT_WORK_TREE
|
||||
|
||||
// read the path of the current directory relative to the top-level directory
|
||||
// don't read the toplevel directly, it will lead to an posix conform path on non posix systems (cygwin)
|
||||
const gitRel = normalizePath(await execGit(['rev-parse', '--show-prefix'], { cwd }))
|
||||
const gitDir = determineGitDir(normalizePath(cwd), gitRel)
|
||||
const gitConfigDir = normalizePath(await resolveGitConfigDir(gitDir))
|
||||
|
||||
debugLog('Resolved git directory to be `%s`', gitDir)
|
||||
debugLog('Resolved git config directory to be `%s`', gitConfigDir)
|
||||
|
||||
return { gitDir, gitConfigDir }
|
||||
} catch (error) {
|
||||
debugLog('Failed to resolve git repo with error:', error)
|
||||
return { error, gitDir: null, gitConfigDir: null }
|
||||
}
|
||||
}
|
176
node_modules/lint-staged/lib/resolveTaskFn.js
generated
vendored
Normal file
176
node_modules/lint-staged/lib/resolveTaskFn.js
generated
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
import chalk from 'chalk'
|
||||
import { execa, execaCommand } from 'execa'
|
||||
import debug from 'debug'
|
||||
import { parseArgsStringToArgv } from 'string-argv'
|
||||
import pidTree from 'pidtree'
|
||||
|
||||
import { error, info } from './figures.js'
|
||||
import { getInitialState } from './state.js'
|
||||
import { TaskError } from './symbols.js'
|
||||
|
||||
const TASK_ERROR = 'lint-staged:taskError'
|
||||
|
||||
const debugLog = debug('lint-staged:resolveTaskFn')
|
||||
|
||||
const getTag = ({ code, killed, signal }) => (killed && 'KILLED') || signal || code || 'FAILED'
|
||||
|
||||
/**
|
||||
* Handle task console output.
|
||||
*
|
||||
* @param {string} command
|
||||
* @param {Object} result
|
||||
* @param {string} result.stdout
|
||||
* @param {string} result.stderr
|
||||
* @param {boolean} result.failed
|
||||
* @param {boolean} result.killed
|
||||
* @param {string} result.signal
|
||||
* @param {Object} ctx
|
||||
* @returns {Error}
|
||||
*/
|
||||
const handleOutput = (command, result, ctx, isError = false) => {
|
||||
const { stderr, stdout } = result
|
||||
const hasOutput = !!stderr || !!stdout
|
||||
|
||||
if (hasOutput) {
|
||||
const outputTitle = isError ? chalk.redBright(`${error} ${command}:`) : `${info} ${command}:`
|
||||
const output = []
|
||||
.concat(ctx.quiet ? [] : ['', outputTitle])
|
||||
.concat(stderr ? stderr : [])
|
||||
.concat(stdout ? stdout : [])
|
||||
ctx.output.push(output.join('\n'))
|
||||
} else if (isError) {
|
||||
// Show generic error when task had no output
|
||||
const tag = getTag(result)
|
||||
const message = chalk.redBright(`\n${error} ${command} failed without output (${tag}).`)
|
||||
if (!ctx.quiet) ctx.output.push(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill an execa process along with all its child processes.
|
||||
* @param {execa.ExecaChildProcess<string>} execaProcess
|
||||
*/
|
||||
const killExecaProcess = async (execaProcess) => {
|
||||
try {
|
||||
const childPids = await pidTree(execaProcess.pid)
|
||||
for (const childPid of childPids) {
|
||||
try {
|
||||
process.kill(childPid)
|
||||
} catch (error) {
|
||||
debugLog(`Failed to kill process with pid "%d": %o`, childPid, error)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Suppress "No matching pid found" error. This probably means
|
||||
// the process already died before executing.
|
||||
debugLog(`Failed to kill process with pid "%d": %o`, execaProcess.pid, error)
|
||||
}
|
||||
|
||||
// The execa process is killed separately in order to get the `KILLED` status.
|
||||
execaProcess.kill()
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts the execution of the execa process that we spawned if
|
||||
* another task adds an error to the context.
|
||||
*
|
||||
* @param {Object} ctx
|
||||
* @param {execa.ExecaChildProcess<string>} execaChildProcess
|
||||
* @returns {() => Promise<void>} Function that clears the interval that
|
||||
* checks the context.
|
||||
*/
|
||||
const interruptExecutionOnError = (ctx, execaChildProcess) => {
|
||||
let killPromise
|
||||
|
||||
const errorListener = async () => {
|
||||
killPromise = killExecaProcess(execaChildProcess)
|
||||
await killPromise
|
||||
}
|
||||
|
||||
ctx.events.on(TASK_ERROR, errorListener, { once: true })
|
||||
|
||||
return async () => {
|
||||
ctx.events.off(TASK_ERROR, errorListener)
|
||||
await killPromise
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a error output dependding on process result.
|
||||
*
|
||||
* @param {string} command
|
||||
* @param {Object} result
|
||||
* @param {string} result.stdout
|
||||
* @param {string} result.stderr
|
||||
* @param {boolean} result.failed
|
||||
* @param {boolean} result.killed
|
||||
* @param {string} result.signal
|
||||
* @param {Object} ctx
|
||||
* @returns {Error}
|
||||
*/
|
||||
const makeErr = (command, result, ctx) => {
|
||||
ctx.errors.add(TaskError)
|
||||
|
||||
// https://nodejs.org/api/events.html#error-events
|
||||
ctx.events.emit(TASK_ERROR, TaskError)
|
||||
|
||||
handleOutput(command, result, ctx, true)
|
||||
const tag = getTag(result)
|
||||
return new Error(`${chalk.redBright(command)} ${chalk.dim(`[${tag}]`)}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the task function for the linter.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {string} options.command — Linter task
|
||||
* @param {string} [options.cwd]
|
||||
* @param {String} options.gitDir - Current git repo path
|
||||
* @param {Boolean} options.isFn - Whether the linter task is a function
|
||||
* @param {Array<string>} options.files — Filepaths to run the linter task against
|
||||
* @param {Boolean} [options.shell] — Whether to skip parsing linter task for better shell support
|
||||
* @param {Boolean} [options.verbose] — Always show task verbose
|
||||
* @returns {() => Promise<Array<string>>}
|
||||
*/
|
||||
export const resolveTaskFn = ({
|
||||
command,
|
||||
cwd = process.cwd(),
|
||||
files,
|
||||
gitDir,
|
||||
isFn,
|
||||
shell = false,
|
||||
verbose = false,
|
||||
}) => {
|
||||
const [cmd, ...args] = parseArgsStringToArgv(command)
|
||||
debugLog('cmd:', cmd)
|
||||
debugLog('args:', args)
|
||||
|
||||
const execaOptions = {
|
||||
// Only use gitDir as CWD if we are using the git binary
|
||||
// e.g `npm` should run tasks in the actual CWD
|
||||
cwd: /^git(\.exe)?/i.test(cmd) ? gitDir : cwd,
|
||||
preferLocal: true,
|
||||
reject: false,
|
||||
shell,
|
||||
}
|
||||
|
||||
debugLog('execaOptions:', execaOptions)
|
||||
|
||||
return async (ctx = getInitialState()) => {
|
||||
const execaChildProcess = shell
|
||||
? execaCommand(isFn ? command : `${command} ${files.join(' ')}`, execaOptions)
|
||||
: execa(cmd, isFn ? args : args.concat(files), execaOptions)
|
||||
|
||||
const quitInterruptCheck = interruptExecutionOnError(ctx, execaChildProcess)
|
||||
const result = await execaChildProcess
|
||||
await quitInterruptCheck()
|
||||
|
||||
if (result.failed || result.killed || result.signal != null) {
|
||||
throw makeErr(command, result, ctx)
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
handleOutput(command, result, ctx)
|
||||
}
|
||||
}
|
||||
}
|
324
node_modules/lint-staged/lib/runAll.js
generated
vendored
Normal file
324
node_modules/lint-staged/lib/runAll.js
generated
vendored
Normal file
@ -0,0 +1,324 @@
|
||||
/** @typedef {import('./index').Logger} Logger */
|
||||
|
||||
import path from 'node:path'
|
||||
|
||||
import chalk from 'chalk'
|
||||
import debug from 'debug'
|
||||
import { Listr } from 'listr2'
|
||||
|
||||
import { chunkFiles } from './chunkFiles.js'
|
||||
import { execGit } from './execGit.js'
|
||||
import { generateTasks } from './generateTasks.js'
|
||||
import { getRenderer } from './getRenderer.js'
|
||||
import { getStagedFiles } from './getStagedFiles.js'
|
||||
import { GitWorkflow } from './gitWorkflow.js'
|
||||
import { groupFilesByConfig } from './groupFilesByConfig.js'
|
||||
import { makeCmdTasks } from './makeCmdTasks.js'
|
||||
import {
|
||||
DEPRECATED_GIT_ADD,
|
||||
FAILED_GET_STAGED_FILES,
|
||||
NOT_GIT_REPO,
|
||||
NO_STAGED_FILES,
|
||||
NO_TASKS,
|
||||
SKIPPED_GIT_ERROR,
|
||||
skippingBackup,
|
||||
} from './messages.js'
|
||||
import { normalizePath } from './normalizePath.js'
|
||||
import { resolveGitRepo } from './resolveGitRepo.js'
|
||||
import {
|
||||
applyModificationsSkipped,
|
||||
cleanupEnabled,
|
||||
cleanupSkipped,
|
||||
getInitialState,
|
||||
hasPartiallyStagedFiles,
|
||||
restoreOriginalStateEnabled,
|
||||
restoreOriginalStateSkipped,
|
||||
restoreUnstagedChangesSkipped,
|
||||
} from './state.js'
|
||||
import { GitRepoError, GetStagedFilesError, GitError, ConfigNotFoundError } from './symbols.js'
|
||||
import { searchConfigs } from './searchConfigs.js'
|
||||
|
||||
const debugLog = debug('lint-staged:runAll')
|
||||
|
||||
const createError = (ctx) => Object.assign(new Error('lint-staged failed'), { ctx })
|
||||
|
||||
/**
|
||||
* Executes all tasks and either resolves or rejects the promise
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {boolean} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes
|
||||
* @param {boolean | number} [options.concurrent] - The number of tasks to run concurrently, or false to run tasks serially
|
||||
* @param {Object} [options.configObject] - Explicit config object from the js API
|
||||
* @param {string} [options.configPath] - Explicit path to a config file
|
||||
* @param {string} [options.cwd] - Current working directory
|
||||
* @param {boolean} [options.debug] - Enable debug mode
|
||||
* @param {string} [options.diff] - Override the default "--staged" flag of "git diff" to get list of files
|
||||
* @param {string} [options.diffFilter] - Override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
|
||||
* @param {number} [options.maxArgLength] - Maximum argument string length
|
||||
* @param {boolean} [options.quiet] - Disable lint-staged’s own console output
|
||||
* @param {boolean} [options.relative] - Pass relative filepaths to tasks
|
||||
* @param {boolean} [options.shell] - Skip parsing of tasks for better shell support
|
||||
* @param {boolean} [options.stash] - Enable the backup stash, and revert in case of errors
|
||||
* @param {boolean} [options.verbose] - Show task output even when tasks succeed; by default only failed output is shown
|
||||
* @param {Logger} logger
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export const runAll = async (
|
||||
{
|
||||
allowEmpty = false,
|
||||
concurrent = true,
|
||||
configObject,
|
||||
configPath,
|
||||
cwd,
|
||||
debug = false,
|
||||
diff,
|
||||
diffFilter,
|
||||
maxArgLength,
|
||||
quiet = false,
|
||||
relative = false,
|
||||
shell = false,
|
||||
// Stashing should be disabled by default when the `diff` option is used
|
||||
stash = diff === undefined,
|
||||
verbose = false,
|
||||
},
|
||||
logger = console
|
||||
) => {
|
||||
debugLog('Running all linter scripts...')
|
||||
|
||||
// Resolve relative CWD option
|
||||
const hasExplicitCwd = !!cwd
|
||||
cwd = hasExplicitCwd ? path.resolve(cwd) : process.cwd()
|
||||
debugLog('Using working directory `%s`', cwd)
|
||||
|
||||
const ctx = getInitialState({ quiet })
|
||||
|
||||
const { gitDir, gitConfigDir } = await resolveGitRepo(cwd)
|
||||
if (!gitDir) {
|
||||
if (!quiet) ctx.output.push(NOT_GIT_REPO)
|
||||
ctx.errors.add(GitRepoError)
|
||||
throw createError(ctx)
|
||||
}
|
||||
|
||||
// Test whether we have any commits or not.
|
||||
// Stashing must be disabled with no initial commit.
|
||||
const hasInitialCommit = await execGit(['log', '-1'], { cwd: gitDir })
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
|
||||
// Lint-staged will create a backup stash only when there's an initial commit,
|
||||
// and when using the default list of staged files by default
|
||||
ctx.shouldBackup = hasInitialCommit && stash
|
||||
if (!ctx.shouldBackup) {
|
||||
logger.warn(skippingBackup(hasInitialCommit, diff))
|
||||
}
|
||||
|
||||
const files = await getStagedFiles({ cwd: gitDir, diff, diffFilter })
|
||||
if (!files) {
|
||||
if (!quiet) ctx.output.push(FAILED_GET_STAGED_FILES)
|
||||
ctx.errors.add(GetStagedFilesError)
|
||||
throw createError(ctx, GetStagedFilesError)
|
||||
}
|
||||
debugLog('Loaded list of staged files in git:\n%O', files)
|
||||
|
||||
// If there are no files avoid executing any lint-staged logic
|
||||
if (files.length === 0) {
|
||||
if (!quiet) ctx.output.push(NO_STAGED_FILES)
|
||||
return ctx
|
||||
}
|
||||
|
||||
const foundConfigs = await searchConfigs({ configObject, configPath, cwd, gitDir }, logger)
|
||||
const numberOfConfigs = Object.keys(foundConfigs).length
|
||||
|
||||
// Throw if no configurations were found
|
||||
if (numberOfConfigs === 0) {
|
||||
ctx.errors.add(ConfigNotFoundError)
|
||||
throw createError(ctx, ConfigNotFoundError)
|
||||
}
|
||||
|
||||
const filesByConfig = await groupFilesByConfig({
|
||||
configs: foundConfigs,
|
||||
files,
|
||||
singleConfigMode: configObject || configPath !== undefined,
|
||||
})
|
||||
|
||||
const hasMultipleConfigs = numberOfConfigs > 1
|
||||
|
||||
// lint-staged 10 will automatically add modifications to index
|
||||
// Warn user when their command includes `git add`
|
||||
let hasDeprecatedGitAdd = false
|
||||
|
||||
const listrOptions = {
|
||||
ctx,
|
||||
exitOnError: false,
|
||||
registerSignalListeners: false,
|
||||
...getRenderer({ debug, quiet }, logger),
|
||||
}
|
||||
|
||||
const listrTasks = []
|
||||
|
||||
// Set of all staged files that matched a task glob. Values in a set are unique.
|
||||
const matchedFiles = new Set()
|
||||
|
||||
for (const [configPath, { config, files }] of Object.entries(filesByConfig)) {
|
||||
const configName = configPath ? normalizePath(path.relative(cwd, configPath)) : 'Config object'
|
||||
|
||||
const stagedFileChunks = chunkFiles({ baseDir: gitDir, files, maxArgLength, relative })
|
||||
|
||||
// Use actual cwd if it's specified, or there's only a single config file.
|
||||
// Otherwise use the directory of the config file for each config group,
|
||||
// to make sure tasks are separated from each other.
|
||||
const groupCwd = hasMultipleConfigs && !hasExplicitCwd ? path.dirname(configPath) : cwd
|
||||
|
||||
const chunkCount = stagedFileChunks.length
|
||||
if (chunkCount > 1) {
|
||||
debugLog('Chunked staged files from `%s` into %d part', configPath, chunkCount)
|
||||
}
|
||||
|
||||
for (const [index, files] of stagedFileChunks.entries()) {
|
||||
const chunkListrTasks = await Promise.all(
|
||||
generateTasks({ config, cwd: groupCwd, files, relative }).map((task) =>
|
||||
makeCmdTasks({
|
||||
commands: task.commands,
|
||||
cwd: groupCwd,
|
||||
files: task.fileList,
|
||||
gitDir,
|
||||
shell,
|
||||
verbose,
|
||||
}).then((subTasks) => {
|
||||
// Add files from task to match set
|
||||
task.fileList.forEach((file) => {
|
||||
// Make sure relative files are normalized to the
|
||||
// group cwd, because other there might be identical
|
||||
// relative filenames in the entire set.
|
||||
const normalizedFile = path.isAbsolute(file)
|
||||
? file
|
||||
: normalizePath(path.join(groupCwd, file))
|
||||
|
||||
matchedFiles.add(normalizedFile)
|
||||
})
|
||||
|
||||
hasDeprecatedGitAdd =
|
||||
hasDeprecatedGitAdd || subTasks.some((subTask) => subTask.command === 'git add')
|
||||
|
||||
const fileCount = task.fileList.length
|
||||
|
||||
return {
|
||||
title: `${task.pattern}${chalk.dim(
|
||||
` — ${fileCount} ${fileCount === 1 ? 'file' : 'files'}`
|
||||
)}`,
|
||||
task: async (ctx, task) =>
|
||||
task.newListr(
|
||||
subTasks,
|
||||
// Subtasks should not run in parallel, and should exit on error
|
||||
{ concurrent: false, exitOnError: true }
|
||||
),
|
||||
skip: () => {
|
||||
// Skip task when no files matched
|
||||
if (fileCount === 0) {
|
||||
return `${task.pattern}${chalk.dim(' — no files')}`
|
||||
}
|
||||
return false
|
||||
},
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
listrTasks.push({
|
||||
title:
|
||||
`${configName}${chalk.dim(` — ${files.length} ${files.length > 1 ? 'files' : 'file'}`)}` +
|
||||
(chunkCount > 1 ? chalk.dim(` (chunk ${index + 1}/${chunkCount})...`) : ''),
|
||||
task: (ctx, task) => task.newListr(chunkListrTasks, { concurrent, exitOnError: true }),
|
||||
skip: () => {
|
||||
// Skip if the first step (backup) failed
|
||||
if (ctx.errors.has(GitError)) return SKIPPED_GIT_ERROR
|
||||
// Skip chunk when no every task is skipped (due to no matches)
|
||||
if (chunkListrTasks.every((task) => task.skip())) {
|
||||
return `${configName}${chalk.dim(' — no tasks to run')}`
|
||||
}
|
||||
return false
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDeprecatedGitAdd) {
|
||||
logger.warn(DEPRECATED_GIT_ADD)
|
||||
}
|
||||
|
||||
// If all of the configured tasks should be skipped
|
||||
// avoid executing any lint-staged logic
|
||||
if (listrTasks.every((task) => task.skip())) {
|
||||
if (!quiet) ctx.output.push(NO_TASKS)
|
||||
return ctx
|
||||
}
|
||||
|
||||
// Chunk matched files for better Windows compatibility
|
||||
const matchedFileChunks = chunkFiles({
|
||||
// matched files are relative to `cwd`, not `gitDir`, when `relative` is used
|
||||
baseDir: cwd,
|
||||
files: Array.from(matchedFiles),
|
||||
maxArgLength,
|
||||
relative: false,
|
||||
})
|
||||
|
||||
const git = new GitWorkflow({
|
||||
allowEmpty,
|
||||
gitConfigDir,
|
||||
gitDir,
|
||||
matchedFileChunks,
|
||||
diff,
|
||||
diffFilter,
|
||||
})
|
||||
|
||||
const runner = new Listr(
|
||||
[
|
||||
{
|
||||
title: 'Preparing lint-staged...',
|
||||
task: (ctx) => git.prepare(ctx),
|
||||
},
|
||||
{
|
||||
title: 'Hiding unstaged changes to partially staged files...',
|
||||
task: (ctx) => git.hideUnstagedChanges(ctx),
|
||||
enabled: hasPartiallyStagedFiles,
|
||||
},
|
||||
{
|
||||
title: `Running tasks for staged files...`,
|
||||
task: (ctx, task) => task.newListr(listrTasks, { concurrent }),
|
||||
skip: () => listrTasks.every((task) => task.skip()),
|
||||
},
|
||||
{
|
||||
title: 'Applying modifications from tasks...',
|
||||
task: (ctx) => git.applyModifications(ctx),
|
||||
skip: applyModificationsSkipped,
|
||||
},
|
||||
{
|
||||
title: 'Restoring unstaged changes to partially staged files...',
|
||||
task: (ctx) => git.restoreUnstagedChanges(ctx),
|
||||
enabled: hasPartiallyStagedFiles,
|
||||
skip: restoreUnstagedChangesSkipped,
|
||||
},
|
||||
{
|
||||
title: 'Reverting to original state because of errors...',
|
||||
task: (ctx) => git.restoreOriginalState(ctx),
|
||||
enabled: restoreOriginalStateEnabled,
|
||||
skip: restoreOriginalStateSkipped,
|
||||
},
|
||||
{
|
||||
title: 'Cleaning up temporary files...',
|
||||
task: (ctx) => git.cleanup(ctx),
|
||||
enabled: cleanupEnabled,
|
||||
skip: cleanupSkipped,
|
||||
},
|
||||
],
|
||||
listrOptions
|
||||
)
|
||||
|
||||
await runner.run()
|
||||
|
||||
if (ctx.errors.size > 0) {
|
||||
throw createError(ctx)
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
123
node_modules/lint-staged/lib/searchConfigs.js
generated
vendored
Normal file
123
node_modules/lint-staged/lib/searchConfigs.js
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
/** @typedef {import('./index').Logger} Logger */
|
||||
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
import { execGit } from './execGit.js'
|
||||
import { loadConfig, searchPlaces } from './loadConfig.js'
|
||||
import { normalizePath } from './normalizePath.js'
|
||||
import { parseGitZOutput } from './parseGitZOutput.js'
|
||||
import { validateConfig } from './validateConfig.js'
|
||||
|
||||
const debugLog = debug('lint-staged:searchConfigs')
|
||||
|
||||
const EXEC_GIT = ['ls-files', '-z', '--full-name']
|
||||
|
||||
const filterPossibleConfigFiles = (files) =>
|
||||
files.filter((file) => searchPlaces.includes(path.basename(file)))
|
||||
|
||||
const numberOfLevels = (file) => file.split('/').length
|
||||
|
||||
const sortDeepestParth = (a, b) => (numberOfLevels(a) > numberOfLevels(b) ? -1 : 1)
|
||||
|
||||
const isInsideDirectory = (dir) => (file) => file.startsWith(normalizePath(dir))
|
||||
|
||||
/**
|
||||
* Search all config files from the git repository, preferring those inside `cwd`.
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {Object} [options.configObject] - Explicit config object from the js API
|
||||
* @param {string} [options.configPath] - Explicit path to a config file
|
||||
* @param {string} [options.cwd] - Current working directory
|
||||
* @param {Logger} logger
|
||||
*
|
||||
* @returns {Promise<{ [key: string]: { config: *, files: string[] } }>} found configs with filepath as key, and config as value
|
||||
*/
|
||||
export const searchConfigs = async (
|
||||
{ configObject, configPath, cwd = process.cwd(), gitDir = cwd },
|
||||
logger
|
||||
) => {
|
||||
debugLog('Searching for configuration files...')
|
||||
|
||||
// Return explicit config object from js API
|
||||
if (configObject) {
|
||||
debugLog('Using single direct configuration object...')
|
||||
|
||||
return { '': validateConfig(configObject, 'config object', logger) }
|
||||
}
|
||||
|
||||
// Use only explicit config path instead of discovering multiple
|
||||
if (configPath) {
|
||||
debugLog('Using single configuration path...')
|
||||
|
||||
const { config, filepath } = await loadConfig({ configPath }, logger)
|
||||
|
||||
if (!config) return {}
|
||||
return { [configPath]: validateConfig(config, filepath, logger) }
|
||||
}
|
||||
|
||||
const [cachedFiles, otherFiles] = await Promise.all([
|
||||
/** Get all possible config files known to git */
|
||||
execGit(EXEC_GIT, { cwd: gitDir }).then(parseGitZOutput).then(filterPossibleConfigFiles),
|
||||
/** Get all possible config files from uncommitted files */
|
||||
execGit([...EXEC_GIT, '--others', '--exclude-standard'], { cwd: gitDir })
|
||||
.then(parseGitZOutput)
|
||||
.then(filterPossibleConfigFiles),
|
||||
])
|
||||
|
||||
/** Sort possible config files so that deepest is first */
|
||||
const possibleConfigFiles = [...cachedFiles, ...otherFiles]
|
||||
.map((file) => normalizePath(path.join(gitDir, file)))
|
||||
.filter(isInsideDirectory(cwd))
|
||||
.sort(sortDeepestParth)
|
||||
|
||||
debugLog('Found possible config files:', possibleConfigFiles)
|
||||
|
||||
/** Create object with key as config file, and value as null */
|
||||
const configs = possibleConfigFiles.reduce(
|
||||
(acc, configPath) => Object.assign(acc, { [configPath]: null }),
|
||||
{}
|
||||
)
|
||||
|
||||
/** Load and validate all configs to the above object */
|
||||
await Promise.all(
|
||||
Object.keys(configs).map((configPath) =>
|
||||
loadConfig({ configPath }, logger).then(({ config, filepath }) => {
|
||||
if (config) {
|
||||
if (configPath !== filepath) {
|
||||
debugLog('Config file "%s" resolved to "%s"', configPath, filepath)
|
||||
}
|
||||
|
||||
configs[configPath] = validateConfig(config, filepath, logger)
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
/** Get validated configs from the above object, without any `null` values (not found) */
|
||||
const foundConfigs = Object.entries(configs)
|
||||
.filter(([, value]) => !!value)
|
||||
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
|
||||
|
||||
/**
|
||||
* Try to find a single config from parent directories
|
||||
* to match old behavior before monorepo support
|
||||
*/
|
||||
if (!Object.keys(foundConfigs).length) {
|
||||
debugLog('Could not find config files inside "%s"', cwd)
|
||||
|
||||
const { config, filepath } = await loadConfig({ cwd }, logger)
|
||||
if (config) {
|
||||
debugLog('Found parent configuration file from "%s"', filepath)
|
||||
|
||||
foundConfigs[filepath] = validateConfig(config, filepath, logger)
|
||||
} else {
|
||||
debugLog('Could not find parent configuration files from "%s"', cwd)
|
||||
}
|
||||
}
|
||||
|
||||
debugLog('Found %d config files', Object.keys(foundConfigs).length)
|
||||
|
||||
return foundConfigs
|
||||
}
|
79
node_modules/lint-staged/lib/state.js
generated
vendored
Normal file
79
node_modules/lint-staged/lib/state.js
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
import EventEmitter from 'events'
|
||||
|
||||
import { GIT_ERROR, TASK_ERROR } from './messages.js'
|
||||
import {
|
||||
ApplyEmptyCommitError,
|
||||
TaskError,
|
||||
RestoreOriginalStateError,
|
||||
GitError,
|
||||
RestoreUnstagedChangesError,
|
||||
} from './symbols.js'
|
||||
|
||||
export const getInitialState = ({ quiet = false } = {}) => ({
|
||||
hasPartiallyStagedFiles: null,
|
||||
shouldBackup: null,
|
||||
errors: new Set([]),
|
||||
events: new EventEmitter(),
|
||||
output: [],
|
||||
quiet,
|
||||
})
|
||||
|
||||
export const hasPartiallyStagedFiles = (ctx) => ctx.hasPartiallyStagedFiles
|
||||
|
||||
export const applyModificationsSkipped = (ctx) => {
|
||||
// Always apply back unstaged modifications when skipping backup
|
||||
if (!ctx.shouldBackup) return false
|
||||
// Should be skipped in case of git errors
|
||||
if (ctx.errors.has(GitError)) {
|
||||
return GIT_ERROR
|
||||
}
|
||||
// Should be skipped when tasks fail
|
||||
if (ctx.errors.has(TaskError)) {
|
||||
return TASK_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
export const restoreUnstagedChangesSkipped = (ctx) => {
|
||||
// Should be skipped in case of git errors
|
||||
if (ctx.errors.has(GitError)) {
|
||||
return GIT_ERROR
|
||||
}
|
||||
// Should be skipped when tasks fail
|
||||
if (ctx.errors.has(TaskError)) {
|
||||
return TASK_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
export const restoreOriginalStateEnabled = (ctx) =>
|
||||
ctx.shouldBackup &&
|
||||
(ctx.errors.has(TaskError) ||
|
||||
ctx.errors.has(ApplyEmptyCommitError) ||
|
||||
ctx.errors.has(RestoreUnstagedChangesError))
|
||||
|
||||
export const restoreOriginalStateSkipped = (ctx) => {
|
||||
// Should be skipped in case of unknown git errors
|
||||
if (
|
||||
ctx.errors.has(GitError) &&
|
||||
!ctx.errors.has(ApplyEmptyCommitError) &&
|
||||
!ctx.errors.has(RestoreUnstagedChangesError)
|
||||
) {
|
||||
return GIT_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
export const cleanupEnabled = (ctx) => ctx.shouldBackup
|
||||
|
||||
export const cleanupSkipped = (ctx) => {
|
||||
// Should be skipped in case of unknown git errors
|
||||
if (
|
||||
ctx.errors.has(GitError) &&
|
||||
!ctx.errors.has(ApplyEmptyCommitError) &&
|
||||
!ctx.errors.has(RestoreUnstagedChangesError)
|
||||
) {
|
||||
return GIT_ERROR
|
||||
}
|
||||
// Should be skipped when reverting to original state fails
|
||||
if (ctx.errors.has(RestoreOriginalStateError)) {
|
||||
return GIT_ERROR
|
||||
}
|
||||
}
|
27
node_modules/lint-staged/lib/symbols.js
generated
vendored
Normal file
27
node_modules/lint-staged/lib/symbols.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
export const ApplyEmptyCommitError = Symbol('ApplyEmptyCommitError')
|
||||
|
||||
export const ConfigNotFoundError = new Error('Configuration could not be found')
|
||||
|
||||
export const ConfigFormatError = new Error('Configuration should be an object or a function')
|
||||
|
||||
export const ConfigEmptyError = new Error('Configuration should not be empty')
|
||||
|
||||
export const GetBackupStashError = Symbol('GetBackupStashError')
|
||||
|
||||
export const GetStagedFilesError = Symbol('GetStagedFilesError')
|
||||
|
||||
export const GitError = Symbol('GitError')
|
||||
|
||||
export const GitRepoError = Symbol('GitRepoError')
|
||||
|
||||
export const HideUnstagedChangesError = Symbol('HideUnstagedChangesError')
|
||||
|
||||
export const InvalidOptionsError = new Error('Invalid Options')
|
||||
|
||||
export const RestoreMergeStatusError = Symbol('RestoreMergeStatusError')
|
||||
|
||||
export const RestoreOriginalStateError = Symbol('RestoreOriginalStateError')
|
||||
|
||||
export const RestoreUnstagedChangesError = Symbol('RestoreUnstagedChangesError')
|
||||
|
||||
export const TaskError = Symbol('TaskError')
|
91
node_modules/lint-staged/lib/validateBraces.js
generated
vendored
Normal file
91
node_modules/lint-staged/lib/validateBraces.js
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
import { incorrectBraces } from './messages.js'
|
||||
|
||||
/**
|
||||
* A correctly-formed brace expansion must contain unquoted opening and closing braces,
|
||||
* and at least one unquoted comma or a valid sequence expression.
|
||||
* Any incorrectly formed brace expansion is left unchanged.
|
||||
*
|
||||
* @see https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
|
||||
*
|
||||
* Lint-staged uses `micromatch` for brace expansion, and its behavior is to treat
|
||||
* invalid brace expansions as literal strings, which means they (typically) do not match
|
||||
* anything.
|
||||
*
|
||||
* This RegExp tries to match most cases of invalid brace expansions, so that they can be
|
||||
* detected, warned about, and re-formatted by removing the braces and thus hopefully
|
||||
* matching the files as intended by the user. The only real fix is to remove the incorrect
|
||||
* braces from user configuration, but this is left to the user (after seeing the warning).
|
||||
*
|
||||
* @example <caption>Globs with brace expansions</caption>
|
||||
* - *.{js,tx} // expanded as *.js, *.ts
|
||||
* - *.{{j,t}s,css} // expanded as *.js, *.ts, *.css
|
||||
* - file_{1..10}.css // expanded as file_1.css, file_2.css, …, file_10.css
|
||||
*
|
||||
* @example <caption>Globs with incorrect brace expansions</caption>
|
||||
* - *.{js} // should just be *.js
|
||||
* - *.{js,{ts}} // should just be *.{js,ts}
|
||||
* - *.\{js\} // escaped braces, so they're treated literally
|
||||
* - *.${js} // dollar-sign inhibits expansion, so treated literally
|
||||
* - *.{js\,ts} // the comma is escaped, so treated literally
|
||||
*/
|
||||
export const INCORRECT_BRACES_REGEXP = /(?<![\\$])({)(?:(?!(?<!\\),|\.\.|\{|\}).)*?(?<!\\)(})/g
|
||||
|
||||
/**
|
||||
* @param {string} pattern
|
||||
* @returns {string}
|
||||
*/
|
||||
const stripIncorrectBraces = (pattern) => {
|
||||
let output = `${pattern}`
|
||||
let match = null
|
||||
|
||||
while ((match = INCORRECT_BRACES_REGEXP.exec(pattern))) {
|
||||
const fullMatch = match[0]
|
||||
const withoutBraces = fullMatch.replace(/{/, '').replace(/}/, '')
|
||||
output = output.replace(fullMatch, withoutBraces)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
* This RegExp matches "duplicate" opening and closing braces, without any other braces
|
||||
* in between, where the duplication is redundant and should be removed.
|
||||
*
|
||||
* @example *.{{js,ts}} // should just be *.{js,ts}
|
||||
*/
|
||||
export const DOUBLE_BRACES_REGEXP = /{{[^}{]*}}/
|
||||
|
||||
/**
|
||||
* @param {string} pattern
|
||||
* @returns {string}
|
||||
*/
|
||||
const stripDoubleBraces = (pattern) => {
|
||||
let output = `${pattern}`
|
||||
const match = DOUBLE_BRACES_REGEXP.exec(pattern)?.[0]
|
||||
|
||||
if (match) {
|
||||
const withoutBraces = match.replace('{{', '{').replace('}}', '}')
|
||||
output = output.replace(match, withoutBraces)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and remove incorrect brace expansions from glob pattern.
|
||||
* For example `*.{js}` is incorrect because it doesn't contain a `,` or `..`,
|
||||
* and will be reformatted as `*.js`.
|
||||
*
|
||||
* @param {string} pattern the glob pattern
|
||||
* @param {*} logger
|
||||
* @returns {string}
|
||||
*/
|
||||
export const validateBraces = (pattern, logger) => {
|
||||
const fixedPattern = stripDoubleBraces(stripIncorrectBraces(pattern))
|
||||
|
||||
if (fixedPattern !== pattern) {
|
||||
logger.warn(incorrectBraces(pattern, fixedPattern))
|
||||
}
|
||||
|
||||
return fixedPattern
|
||||
}
|
116
node_modules/lint-staged/lib/validateConfig.js
generated
vendored
Normal file
116
node_modules/lint-staged/lib/validateConfig.js
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/** @typedef {import('./index').Logger} Logger */
|
||||
|
||||
import { inspect } from 'node:util'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
import { configurationError } from './messages.js'
|
||||
import { ConfigEmptyError, ConfigFormatError } from './symbols.js'
|
||||
import { validateBraces } from './validateBraces.js'
|
||||
|
||||
const debugLog = debug('lint-staged:validateConfig')
|
||||
|
||||
const isObject = (test) => test && typeof test === 'object' && !Array.isArray(test)
|
||||
|
||||
const TEST_DEPRECATED_KEYS = new Map([
|
||||
['concurrent', (key) => typeof key === 'boolean'],
|
||||
['chunkSize', (key) => typeof key === 'number'],
|
||||
['globOptions', isObject],
|
||||
['linters', isObject],
|
||||
['ignore', (key) => Array.isArray(key)],
|
||||
['subTaskConcurrency', (key) => typeof key === 'number'],
|
||||
['renderer', (key) => typeof key === 'string'],
|
||||
['relative', (key) => typeof key === 'boolean'],
|
||||
])
|
||||
|
||||
/**
|
||||
* Runs config validation. Throws error if the config is not valid.
|
||||
* @param {Object} config
|
||||
* @param {string} configPath
|
||||
* @param {Logger} logger
|
||||
* @returns {Object} config
|
||||
*/
|
||||
export const validateConfig = (config, configPath, logger) => {
|
||||
debugLog('Validating config from `%s`...', configPath)
|
||||
|
||||
if (!config || (typeof config !== 'object' && typeof config !== 'function')) {
|
||||
throw ConfigFormatError
|
||||
}
|
||||
|
||||
/**
|
||||
* Function configurations receive all staged files as their argument.
|
||||
* They are not further validated here to make sure the function gets
|
||||
* evaluated only once.
|
||||
*
|
||||
* @see makeCmdTasks
|
||||
*/
|
||||
if (typeof config === 'function') {
|
||||
return { '*': config }
|
||||
}
|
||||
|
||||
if (Object.entries(config).length === 0) {
|
||||
throw ConfigEmptyError
|
||||
}
|
||||
|
||||
const errors = []
|
||||
|
||||
/**
|
||||
* Create a new validated config because the keys (patterns) might change.
|
||||
* Since the Object.reduce method already loops through each entry in the config,
|
||||
* it can be used for validating the values at the same time.
|
||||
*/
|
||||
const validatedConfig = Object.entries(config).reduce((collection, [pattern, task]) => {
|
||||
/** Versions < 9 had more complex configuration options that are no longer supported. */
|
||||
if (TEST_DEPRECATED_KEYS.has(pattern)) {
|
||||
const testFn = TEST_DEPRECATED_KEYS.get(pattern)
|
||||
if (testFn(task)) {
|
||||
errors.push(
|
||||
configurationError(pattern, 'Advanced configuration has been deprecated.', task)
|
||||
)
|
||||
}
|
||||
|
||||
/** Return early for deprecated keys to skip validating their (deprecated) values */
|
||||
return collection
|
||||
}
|
||||
|
||||
if (
|
||||
(!Array.isArray(task) ||
|
||||
task.some((item) => typeof item !== 'string' && typeof item !== 'function')) &&
|
||||
typeof task !== 'string' &&
|
||||
typeof task !== 'function'
|
||||
) {
|
||||
errors.push(
|
||||
configurationError(
|
||||
pattern,
|
||||
'Should be a string, a function, or an array of strings and functions.',
|
||||
task
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A typical configuration error is using invalid brace expansion, like `*.{js}`.
|
||||
* These are automatically fixed and warned about.
|
||||
*/
|
||||
const fixedPattern = validateBraces(pattern, logger)
|
||||
|
||||
return { ...collection, [fixedPattern]: task }
|
||||
}, {})
|
||||
|
||||
if (errors.length) {
|
||||
const message = errors.join('\n\n')
|
||||
|
||||
logger.error(`Could not parse lint-staged config.
|
||||
|
||||
${message}
|
||||
|
||||
See https://github.com/okonet/lint-staged#configuration.`)
|
||||
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
debugLog('Validated config from `%s`:', configPath)
|
||||
debugLog(inspect(config, { compact: false }))
|
||||
|
||||
return validatedConfig
|
||||
}
|
45
node_modules/lint-staged/lib/validateOptions.js
generated
vendored
Normal file
45
node_modules/lint-staged/lib/validateOptions.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
import { constants } from 'node:fs'
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
|
||||
import debug from 'debug'
|
||||
|
||||
import { invalidOption } from './messages.js'
|
||||
import { InvalidOptionsError } from './symbols.js'
|
||||
|
||||
const debugLog = debug('lint-staged:validateOptions')
|
||||
|
||||
/**
|
||||
* Validate lint-staged options, either from the Node.js API or the command line flags.
|
||||
* @param {*} options
|
||||
* @param {boolean|string} [options.cwd] - Current working directory
|
||||
* @param {boolean|string} [options.shell] - Skip parsing of tasks for better shell support
|
||||
*
|
||||
* @throws {InvalidOptionsError}
|
||||
*/
|
||||
export const validateOptions = async (options = {}, logger) => {
|
||||
debugLog('Validating options...')
|
||||
|
||||
/** Ensure the passed cwd option exists; it might also be relative */
|
||||
if (typeof options.cwd === 'string') {
|
||||
try {
|
||||
const resolved = path.resolve(options.cwd)
|
||||
await fs.access(resolved, constants.F_OK)
|
||||
} catch (error) {
|
||||
logger.error(invalidOption('cwd', options.cwd, error.message))
|
||||
throw InvalidOptionsError
|
||||
}
|
||||
}
|
||||
|
||||
/** Ensure the passed shell option is executable */
|
||||
if (typeof options.shell === 'string') {
|
||||
try {
|
||||
await fs.access(options.shell, constants.X_OK)
|
||||
} catch (error) {
|
||||
logger.error(invalidOption('shell', options.shell, error.message))
|
||||
throw InvalidOptionsError
|
||||
}
|
||||
}
|
||||
|
||||
debugLog('Validated options!')
|
||||
}
|
9
node_modules/lint-staged/node_modules/chalk/license
generated
vendored
Normal file
9
node_modules/lint-staged/node_modules/chalk/license
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
83
node_modules/lint-staged/node_modules/chalk/package.json
generated
vendored
Normal file
83
node_modules/lint-staged/node_modules/chalk/package.json
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
{
|
||||
"name": "chalk",
|
||||
"version": "5.3.0",
|
||||
"description": "Terminal string styling done right",
|
||||
"license": "MIT",
|
||||
"repository": "chalk/chalk",
|
||||
"funding": "https://github.com/chalk/chalk?sponsor=1",
|
||||
"type": "module",
|
||||
"main": "./source/index.js",
|
||||
"exports": "./source/index.js",
|
||||
"imports": {
|
||||
"#ansi-styles": "./source/vendor/ansi-styles/index.js",
|
||||
"#supports-color": {
|
||||
"node": "./source/vendor/supports-color/index.js",
|
||||
"default": "./source/vendor/supports-color/browser.js"
|
||||
}
|
||||
},
|
||||
"types": "./source/index.d.ts",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && c8 ava && tsd",
|
||||
"bench": "matcha benchmark.js"
|
||||
},
|
||||
"files": [
|
||||
"source",
|
||||
"!source/index.test-d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"ansi",
|
||||
"style",
|
||||
"styles",
|
||||
"tty",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.10",
|
||||
"ava": "^3.15.0",
|
||||
"c8": "^7.10.0",
|
||||
"color-convert": "^2.0.1",
|
||||
"execa": "^6.0.0",
|
||||
"log-update": "^5.0.0",
|
||||
"matcha": "^0.7.0",
|
||||
"tsd": "^0.19.0",
|
||||
"xo": "^0.53.0",
|
||||
"yoctodelay": "^2.0.0"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"xo": {
|
||||
"rules": {
|
||||
"unicorn/prefer-string-slice": "off",
|
||||
"@typescript-eslint/consistent-type-imports": "off",
|
||||
"@typescript-eslint/consistent-type-exports": "off",
|
||||
"@typescript-eslint/consistent-type-definitions": "off",
|
||||
"unicorn/expiring-todo-comments": "off"
|
||||
}
|
||||
},
|
||||
"c8": {
|
||||
"reporter": [
|
||||
"text",
|
||||
"lcov"
|
||||
],
|
||||
"exclude": [
|
||||
"source/vendor"
|
||||
]
|
||||
}
|
||||
}
|
325
node_modules/lint-staged/node_modules/chalk/readme.md
generated
vendored
Normal file
325
node_modules/lint-staged/node_modules/chalk/readme.md
generated
vendored
Normal file
@ -0,0 +1,325 @@
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<br>
|
||||
<img width="320" src="media/logo.svg" alt="Chalk">
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
> Terminal string styling done right
|
||||
|
||||
[](https://codecov.io/gh/chalk/chalk)
|
||||
[](https://www.npmjs.com/package/chalk?activeTab=dependents)
|
||||
[](https://www.npmjs.com/package/chalk)
|
||||
[](https://repl.it/github/chalk/chalk)
|
||||
|
||||

|
||||
|
||||
<br>
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<p>
|
||||
<p>
|
||||
<sup>
|
||||
Sindre Sorhus' open source work is supported by the community on <a href="https://github.com/sponsors/sindresorhus">GitHub Sponsors</a>
|
||||
</sup>
|
||||
</p>
|
||||
<sup>Special thanks to:</sup>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://standardresume.co/tech">
|
||||
<img src="https://sindresorhus.com/assets/thanks/standard-resume-logo.svg" width="160">
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://retool.com/?utm_campaign=sindresorhus">
|
||||
<img src="https://sindresorhus.com/assets/thanks/retool-logo.svg" width="230">
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://strapi.io/?ref=sindresorhus">
|
||||
<div>
|
||||
<img src="https://sindresorhus.com/assets/thanks/strapi-logo-white-bg.png" width="220" alt="Strapi">
|
||||
</div>
|
||||
<b>Strapi is the leading open-source headless CMS.</b>
|
||||
<div>
|
||||
<sup>It’s 100% JavaScript, fully customizable, and developer-first.</sup>
|
||||
</div>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://www.stackaid.us/?utm_campaign=sindre">
|
||||
<div>
|
||||
<img src="https://sindresorhus.com/assets/thanks/stackaid-logo.png" width="230" alt="StackAid">
|
||||
</div>
|
||||
<b>Fund your open source dependencies</b>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<br>
|
||||
|
||||
## Highlights
|
||||
|
||||
- Expressive API
|
||||
- Highly performant
|
||||
- No dependencies
|
||||
- Ability to nest styles
|
||||
- [256/Truecolor color support](#256-and-truecolor-color-support)
|
||||
- Auto-detects color support
|
||||
- Doesn't extend `String.prototype`
|
||||
- Clean and focused
|
||||
- Actively maintained
|
||||
- [Used by ~86,000 packages](https://www.npmjs.com/browse/depended/chalk) as of October 4, 2022
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm install chalk
|
||||
```
|
||||
|
||||
**IMPORTANT:** Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now. [Read more.](https://github.com/chalk/chalk/releases/tag/v5.0.0)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import chalk from 'chalk';
|
||||
|
||||
console.log(chalk.blue('Hello world!'));
|
||||
```
|
||||
|
||||
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
|
||||
|
||||
```js
|
||||
import chalk from 'chalk';
|
||||
|
||||
const log = console.log;
|
||||
|
||||
// Combine styled and normal strings
|
||||
log(chalk.blue('Hello') + ' World' + chalk.red('!'));
|
||||
|
||||
// Compose multiple styles using the chainable API
|
||||
log(chalk.blue.bgRed.bold('Hello world!'));
|
||||
|
||||
// Pass in multiple arguments
|
||||
log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));
|
||||
|
||||
// Nest styles
|
||||
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
|
||||
|
||||
// Nest styles of the same type even (color, underline, background)
|
||||
log(chalk.green(
|
||||
'I am a green line ' +
|
||||
chalk.blue.underline.bold('with a blue substring') +
|
||||
' that becomes green again!'
|
||||
));
|
||||
|
||||
// ES2015 template literal
|
||||
log(`
|
||||
CPU: ${chalk.red('90%')}
|
||||
RAM: ${chalk.green('40%')}
|
||||
DISK: ${chalk.yellow('70%')}
|
||||
`);
|
||||
|
||||
// Use RGB colors in terminal emulators that support it.
|
||||
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
|
||||
log(chalk.hex('#DEADED').bold('Bold gray!'));
|
||||
```
|
||||
|
||||
Easily define your own themes:
|
||||
|
||||
```js
|
||||
import chalk from 'chalk';
|
||||
|
||||
const error = chalk.bold.red;
|
||||
const warning = chalk.hex('#FFA500'); // Orange color
|
||||
|
||||
console.log(error('Error!'));
|
||||
console.log(warning('Warning!'));
|
||||
```
|
||||
|
||||
Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):
|
||||
|
||||
```js
|
||||
import chalk from 'chalk';
|
||||
|
||||
const name = 'Sindre';
|
||||
console.log(chalk.green('Hello %s'), name);
|
||||
//=> 'Hello Sindre'
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### chalk.`<style>[.<style>...](string, [string...])`
|
||||
|
||||
Example: `chalk.red.bold.underline('Hello', 'world');`
|
||||
|
||||
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
|
||||
|
||||
Multiple arguments will be separated by space.
|
||||
|
||||
### chalk.level
|
||||
|
||||
Specifies the level of color support.
|
||||
|
||||
Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers.
|
||||
|
||||
If you need to change this in a reusable module, create a new instance:
|
||||
|
||||
```js
|
||||
import {Chalk} from 'chalk';
|
||||
|
||||
const customChalk = new Chalk({level: 0});
|
||||
```
|
||||
|
||||
| Level | Description |
|
||||
| :---: | :--- |
|
||||
| `0` | All colors disabled |
|
||||
| `1` | Basic color support (16 colors) |
|
||||
| `2` | 256 color support |
|
||||
| `3` | Truecolor support (16 million colors) |
|
||||
|
||||
### supportsColor
|
||||
|
||||
Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.
|
||||
|
||||
Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.
|
||||
|
||||
Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.
|
||||
|
||||
### chalkStderr and supportsColorStderr
|
||||
|
||||
`chalkStderr` contains a separate instance configured with color support detected for `stderr` stream instead of `stdout`. Override rules from `supportsColor` apply to this too. `supportsColorStderr` is exposed for convenience.
|
||||
|
||||
### modifierNames, foregroundColorNames, backgroundColorNames, and colorNames
|
||||
|
||||
All supported style strings are exposed as an array of strings for convenience. `colorNames` is the combination of `foregroundColorNames` and `backgroundColorNames`.
|
||||
|
||||
This can be useful if you wrap Chalk and need to validate input:
|
||||
|
||||
```js
|
||||
import {modifierNames, foregroundColorNames} from 'chalk';
|
||||
|
||||
console.log(modifierNames.includes('bold'));
|
||||
//=> true
|
||||
|
||||
console.log(foregroundColorNames.includes('pink'));
|
||||
//=> false
|
||||
```
|
||||
|
||||
## Styles
|
||||
|
||||
### Modifiers
|
||||
|
||||
- `reset` - Reset the current style.
|
||||
- `bold` - Make the text bold.
|
||||
- `dim` - Make the text have lower opacity.
|
||||
- `italic` - Make the text italic. *(Not widely supported)*
|
||||
- `underline` - Put a horizontal line below the text. *(Not widely supported)*
|
||||
- `overline` - Put a horizontal line above the text. *(Not widely supported)*
|
||||
- `inverse`- Invert background and foreground colors.
|
||||
- `hidden` - Print the text but make it invisible.
|
||||
- `strikethrough` - Puts a horizontal line through the center of the text. *(Not widely supported)*
|
||||
- `visible`- Print the text only when Chalk has a color level above zero. Can be useful for things that are purely cosmetic.
|
||||
|
||||
### Colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue`
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `blackBright` (alias: `gray`, `grey`)
|
||||
- `redBright`
|
||||
- `greenBright`
|
||||
- `yellowBright`
|
||||
- `blueBright`
|
||||
- `magentaBright`
|
||||
- `cyanBright`
|
||||
- `whiteBright`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
- `bgBlackBright` (alias: `bgGray`, `bgGrey`)
|
||||
- `bgRedBright`
|
||||
- `bgGreenBright`
|
||||
- `bgYellowBright`
|
||||
- `bgBlueBright`
|
||||
- `bgMagentaBright`
|
||||
- `bgCyanBright`
|
||||
- `bgWhiteBright`
|
||||
|
||||
## 256 and Truecolor color support
|
||||
|
||||
Chalk supports 256 colors and [Truecolor](https://github.com/termstandard/colors) (16 million colors) on supported terminal apps.
|
||||
|
||||
Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).
|
||||
|
||||
Examples:
|
||||
|
||||
- `chalk.hex('#DEADED').underline('Hello, world!')`
|
||||
- `chalk.rgb(15, 100, 204).inverse('Hello!')`
|
||||
|
||||
Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `hex` for foreground colors and `bgHex` for background colors).
|
||||
|
||||
- `chalk.bgHex('#DEADED').underline('Hello, world!')`
|
||||
- `chalk.bgRgb(15, 100, 204).inverse('Hello!')`
|
||||
|
||||
The following color models can be used:
|
||||
|
||||
- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')`
|
||||
- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')`
|
||||
- [`ansi256`](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) - Example: `chalk.bgAnsi256(194)('Honeydew, more or less')`
|
||||
|
||||
## Browser support
|
||||
|
||||
Since Chrome 69, ANSI escape codes are natively supported in the developer console.
|
||||
|
||||
## Windows
|
||||
|
||||
If you're on Windows, do yourself a favor and use [Windows Terminal](https://github.com/microsoft/terminal) instead of `cmd.exe`.
|
||||
|
||||
## Origin story
|
||||
|
||||
[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative.
|
||||
|
||||
## Related
|
||||
|
||||
- [chalk-template](https://github.com/chalk/chalk-template) - [Tagged template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) support for this module
|
||||
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
|
||||
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
|
||||
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
|
||||
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
|
||||
- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream
|
||||
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
|
||||
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
|
||||
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
|
||||
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
|
||||
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
|
||||
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
|
||||
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
|
||||
- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings
|
||||
- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal
|
||||
|
||||
## Maintainers
|
||||
|
||||
- [Sindre Sorhus](https://github.com/sindresorhus)
|
||||
- [Josh Junon](https://github.com/qix-)
|
320
node_modules/lint-staged/node_modules/chalk/source/index.d.ts
generated
vendored
Normal file
320
node_modules/lint-staged/node_modules/chalk/source/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,320 @@
|
||||
// TODO: Make it this when TS suports that.
|
||||
// import {ModifierName, ForegroundColor, BackgroundColor, ColorName} from '#ansi-styles';
|
||||
// import {ColorInfo, ColorSupportLevel} from '#supports-color';
|
||||
import {ModifierName, ForegroundColorName, BackgroundColorName, ColorName} from './vendor/ansi-styles/index.js';
|
||||
import {ColorInfo, ColorSupportLevel} from './vendor/supports-color/index.js';
|
||||
|
||||
export interface Options {
|
||||
/**
|
||||
Specify the color support for Chalk.
|
||||
|
||||
By default, color support is automatically detected based on the environment.
|
||||
|
||||
Levels:
|
||||
- `0` - All colors disabled.
|
||||
- `1` - Basic 16 colors support.
|
||||
- `2` - ANSI 256 colors support.
|
||||
- `3` - Truecolor 16 million colors support.
|
||||
*/
|
||||
readonly level?: ColorSupportLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
Return a new Chalk instance.
|
||||
*/
|
||||
export const Chalk: new (options?: Options) => ChalkInstance; // eslint-disable-line @typescript-eslint/naming-convention
|
||||
|
||||
export interface ChalkInstance {
|
||||
(...text: unknown[]): string;
|
||||
|
||||
/**
|
||||
The color support for Chalk.
|
||||
|
||||
By default, color support is automatically detected based on the environment.
|
||||
|
||||
Levels:
|
||||
- `0` - All colors disabled.
|
||||
- `1` - Basic 16 colors support.
|
||||
- `2` - ANSI 256 colors support.
|
||||
- `3` - Truecolor 16 million colors support.
|
||||
*/
|
||||
level: ColorSupportLevel;
|
||||
|
||||
/**
|
||||
Use RGB values to set text color.
|
||||
|
||||
@example
|
||||
```
|
||||
import chalk from 'chalk';
|
||||
|
||||
chalk.rgb(222, 173, 237);
|
||||
```
|
||||
*/
|
||||
rgb: (red: number, green: number, blue: number) => this;
|
||||
|
||||
/**
|
||||
Use HEX value to set text color.
|
||||
|
||||
@param color - Hexadecimal value representing the desired color.
|
||||
|
||||
@example
|
||||
```
|
||||
import chalk from 'chalk';
|
||||
|
||||
chalk.hex('#DEADED');
|
||||
```
|
||||
*/
|
||||
hex: (color: string) => this;
|
||||
|
||||
/**
|
||||
Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color.
|
||||
|
||||
@example
|
||||
```
|
||||
import chalk from 'chalk';
|
||||
|
||||
chalk.ansi256(201);
|
||||
```
|
||||
*/
|
||||
ansi256: (index: number) => this;
|
||||
|
||||
/**
|
||||
Use RGB values to set background color.
|
||||
|
||||
@example
|
||||
```
|
||||
import chalk from 'chalk';
|
||||
|
||||
chalk.bgRgb(222, 173, 237);
|
||||
```
|
||||
*/
|
||||
bgRgb: (red: number, green: number, blue: number) => this;
|
||||
|
||||
/**
|
||||
Use HEX value to set background color.
|
||||
|
||||
@param color - Hexadecimal value representing the desired color.
|
||||
|
||||
@example
|
||||
```
|
||||
import chalk from 'chalk';
|
||||
|
||||
chalk.bgHex('#DEADED');
|
||||
```
|
||||
*/
|
||||
bgHex: (color: string) => this;
|
||||
|
||||
/**
|
||||
Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color.
|
||||
|
||||
@example
|
||||
```
|
||||
import chalk from 'chalk';
|
||||
|
||||
chalk.bgAnsi256(201);
|
||||
```
|
||||
*/
|
||||
bgAnsi256: (index: number) => this;
|
||||
|
||||
/**
|
||||
Modifier: Reset the current style.
|
||||
*/
|
||||
readonly reset: this;
|
||||
|
||||
/**
|
||||
Modifier: Make the text bold.
|
||||
*/
|
||||
readonly bold: this;
|
||||
|
||||
/**
|
||||
Modifier: Make the text have lower opacity.
|
||||
*/
|
||||
readonly dim: this;
|
||||
|
||||
/**
|
||||
Modifier: Make the text italic. *(Not widely supported)*
|
||||
*/
|
||||
readonly italic: this;
|
||||
|
||||
/**
|
||||
Modifier: Put a horizontal line below the text. *(Not widely supported)*
|
||||
*/
|
||||
readonly underline: this;
|
||||
|
||||
/**
|
||||
Modifier: Put a horizontal line above the text. *(Not widely supported)*
|
||||
*/
|
||||
readonly overline: this;
|
||||
|
||||
/**
|
||||
Modifier: Invert background and foreground colors.
|
||||
*/
|
||||
readonly inverse: this;
|
||||
|
||||
/**
|
||||
Modifier: Print the text but make it invisible.
|
||||
*/
|
||||
readonly hidden: this;
|
||||
|
||||
/**
|
||||
Modifier: Puts a horizontal line through the center of the text. *(Not widely supported)*
|
||||
*/
|
||||
readonly strikethrough: this;
|
||||
|
||||
/**
|
||||
Modifier: Print the text only when Chalk has a color level above zero.
|
||||
|
||||
Can be useful for things that are purely cosmetic.
|
||||
*/
|
||||
readonly visible: this;
|
||||
|
||||
readonly black: this;
|
||||
readonly red: this;
|
||||
readonly green: this;
|
||||
readonly yellow: this;
|
||||
readonly blue: this;
|
||||
readonly magenta: this;
|
||||
readonly cyan: this;
|
||||
readonly white: this;
|
||||
|
||||
/*
|
||||
Alias for `blackBright`.
|
||||
*/
|
||||
readonly gray: this;
|
||||
|
||||
/*
|
||||
Alias for `blackBright`.
|
||||
*/
|
||||
readonly grey: this;
|
||||
|
||||
readonly blackBright: this;
|
||||
readonly redBright: this;
|
||||
readonly greenBright: this;
|
||||
readonly yellowBright: this;
|
||||
readonly blueBright: this;
|
||||
readonly magentaBright: this;
|
||||
readonly cyanBright: this;
|
||||
readonly whiteBright: this;
|
||||
|
||||
readonly bgBlack: this;
|
||||
readonly bgRed: this;
|
||||
readonly bgGreen: this;
|
||||
readonly bgYellow: this;
|
||||
readonly bgBlue: this;
|
||||
readonly bgMagenta: this;
|
||||
readonly bgCyan: this;
|
||||
readonly bgWhite: this;
|
||||
|
||||
/*
|
||||
Alias for `bgBlackBright`.
|
||||
*/
|
||||
readonly bgGray: this;
|
||||
|
||||
/*
|
||||
Alias for `bgBlackBright`.
|
||||
*/
|
||||
readonly bgGrey: this;
|
||||
|
||||
readonly bgBlackBright: this;
|
||||
readonly bgRedBright: this;
|
||||
readonly bgGreenBright: this;
|
||||
readonly bgYellowBright: this;
|
||||
readonly bgBlueBright: this;
|
||||
readonly bgMagentaBright: this;
|
||||
readonly bgCyanBright: this;
|
||||
readonly bgWhiteBright: this;
|
||||
}
|
||||
|
||||
/**
|
||||
Main Chalk object that allows to chain styles together.
|
||||
|
||||
Call the last one as a method with a string argument.
|
||||
|
||||
Order doesn't matter, and later styles take precedent in case of a conflict.
|
||||
|
||||
This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
|
||||
*/
|
||||
declare const chalk: ChalkInstance;
|
||||
|
||||
export const supportsColor: ColorInfo;
|
||||
|
||||
export const chalkStderr: typeof chalk;
|
||||
export const supportsColorStderr: typeof supportsColor;
|
||||
|
||||
export {
|
||||
ModifierName, ForegroundColorName, BackgroundColorName, ColorName,
|
||||
modifierNames, foregroundColorNames, backgroundColorNames, colorNames,
|
||||
// } from '#ansi-styles';
|
||||
} from './vendor/ansi-styles/index.js';
|
||||
|
||||
export {
|
||||
ColorInfo,
|
||||
ColorSupport,
|
||||
ColorSupportLevel,
|
||||
// } from '#supports-color';
|
||||
} from './vendor/supports-color/index.js';
|
||||
|
||||
// TODO: Remove these aliases in the next major version
|
||||
/**
|
||||
@deprecated Use `ModifierName` instead.
|
||||
|
||||
Basic modifier names.
|
||||
*/
|
||||
export type Modifiers = ModifierName;
|
||||
|
||||
/**
|
||||
@deprecated Use `ForegroundColorName` instead.
|
||||
|
||||
Basic foreground color names.
|
||||
|
||||
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
|
||||
*/
|
||||
export type ForegroundColor = ForegroundColorName;
|
||||
|
||||
/**
|
||||
@deprecated Use `BackgroundColorName` instead.
|
||||
|
||||
Basic background color names.
|
||||
|
||||
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
|
||||
*/
|
||||
export type BackgroundColor = BackgroundColorName;
|
||||
|
||||
/**
|
||||
@deprecated Use `ColorName` instead.
|
||||
|
||||
Basic color names. The combination of foreground and background color names.
|
||||
|
||||
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
|
||||
*/
|
||||
export type Color = ColorName;
|
||||
|
||||
/**
|
||||
@deprecated Use `modifierNames` instead.
|
||||
|
||||
Basic modifier names.
|
||||
*/
|
||||
export const modifiers: readonly Modifiers[];
|
||||
|
||||
/**
|
||||
@deprecated Use `foregroundColorNames` instead.
|
||||
|
||||
Basic foreground color names.
|
||||
*/
|
||||
export const foregroundColors: readonly ForegroundColor[];
|
||||
|
||||
/**
|
||||
@deprecated Use `backgroundColorNames` instead.
|
||||
|
||||
Basic background color names.
|
||||
*/
|
||||
export const backgroundColors: readonly BackgroundColor[];
|
||||
|
||||
/**
|
||||
@deprecated Use `colorNames` instead.
|
||||
|
||||
Basic color names. The combination of foreground and background color names.
|
||||
*/
|
||||
export const colors: readonly Color[];
|
||||
|
||||
export default chalk;
|
225
node_modules/lint-staged/node_modules/chalk/source/index.js
generated
vendored
Normal file
225
node_modules/lint-staged/node_modules/chalk/source/index.js
generated
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
import ansiStyles from '#ansi-styles';
|
||||
import supportsColor from '#supports-color';
|
||||
import { // eslint-disable-line import/order
|
||||
stringReplaceAll,
|
||||
stringEncaseCRLFWithFirstIndex,
|
||||
} from './utilities.js';
|
||||
|
||||
const {stdout: stdoutColor, stderr: stderrColor} = supportsColor;
|
||||
|
||||
const GENERATOR = Symbol('GENERATOR');
|
||||
const STYLER = Symbol('STYLER');
|
||||
const IS_EMPTY = Symbol('IS_EMPTY');
|
||||
|
||||
// `supportsColor.level` → `ansiStyles.color[name]` mapping
|
||||
const levelMapping = [
|
||||
'ansi',
|
||||
'ansi',
|
||||
'ansi256',
|
||||
'ansi16m',
|
||||
];
|
||||
|
||||
const styles = Object.create(null);
|
||||
|
||||
const applyOptions = (object, options = {}) => {
|
||||
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
||||
throw new Error('The `level` option should be an integer from 0 to 3');
|
||||
}
|
||||
|
||||
// Detect level if not set manually
|
||||
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
||||
object.level = options.level === undefined ? colorLevel : options.level;
|
||||
};
|
||||
|
||||
export class Chalk {
|
||||
constructor(options) {
|
||||
// eslint-disable-next-line no-constructor-return
|
||||
return chalkFactory(options);
|
||||
}
|
||||
}
|
||||
|
||||
const chalkFactory = options => {
|
||||
const chalk = (...strings) => strings.join(' ');
|
||||
applyOptions(chalk, options);
|
||||
|
||||
Object.setPrototypeOf(chalk, createChalk.prototype);
|
||||
|
||||
return chalk;
|
||||
};
|
||||
|
||||
function createChalk(options) {
|
||||
return chalkFactory(options);
|
||||
}
|
||||
|
||||
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
||||
|
||||
for (const [styleName, style] of Object.entries(ansiStyles)) {
|
||||
styles[styleName] = {
|
||||
get() {
|
||||
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
||||
Object.defineProperty(this, styleName, {value: builder});
|
||||
return builder;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
styles.visible = {
|
||||
get() {
|
||||
const builder = createBuilder(this, this[STYLER], true);
|
||||
Object.defineProperty(this, 'visible', {value: builder});
|
||||
return builder;
|
||||
},
|
||||
};
|
||||
|
||||
const getModelAnsi = (model, level, type, ...arguments_) => {
|
||||
if (model === 'rgb') {
|
||||
if (level === 'ansi16m') {
|
||||
return ansiStyles[type].ansi16m(...arguments_);
|
||||
}
|
||||
|
||||
if (level === 'ansi256') {
|
||||
return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));
|
||||
}
|
||||
|
||||
return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));
|
||||
}
|
||||
|
||||
if (model === 'hex') {
|
||||
return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));
|
||||
}
|
||||
|
||||
return ansiStyles[type][model](...arguments_);
|
||||
};
|
||||
|
||||
const usedModels = ['rgb', 'hex', 'ansi256'];
|
||||
|
||||
for (const model of usedModels) {
|
||||
styles[model] = {
|
||||
get() {
|
||||
const {level} = this;
|
||||
return function (...arguments_) {
|
||||
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);
|
||||
return createBuilder(this, styler, this[IS_EMPTY]);
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
|
||||
styles[bgModel] = {
|
||||
get() {
|
||||
const {level} = this;
|
||||
return function (...arguments_) {
|
||||
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);
|
||||
return createBuilder(this, styler, this[IS_EMPTY]);
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const proto = Object.defineProperties(() => {}, {
|
||||
...styles,
|
||||
level: {
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this[GENERATOR].level;
|
||||
},
|
||||
set(level) {
|
||||
this[GENERATOR].level = level;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const createStyler = (open, close, parent) => {
|
||||
let openAll;
|
||||
let closeAll;
|
||||
if (parent === undefined) {
|
||||
openAll = open;
|
||||
closeAll = close;
|
||||
} else {
|
||||
openAll = parent.openAll + open;
|
||||
closeAll = close + parent.closeAll;
|
||||
}
|
||||
|
||||
return {
|
||||
open,
|
||||
close,
|
||||
openAll,
|
||||
closeAll,
|
||||
parent,
|
||||
};
|
||||
};
|
||||
|
||||
const createBuilder = (self, _styler, _isEmpty) => {
|
||||
// Single argument is hot path, implicit coercion is faster than anything
|
||||
// eslint-disable-next-line no-implicit-coercion
|
||||
const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
|
||||
|
||||
// We alter the prototype because we must return a function, but there is
|
||||
// no way to create a function with a different prototype
|
||||
Object.setPrototypeOf(builder, proto);
|
||||
|
||||
builder[GENERATOR] = self;
|
||||
builder[STYLER] = _styler;
|
||||
builder[IS_EMPTY] = _isEmpty;
|
||||
|
||||
return builder;
|
||||
};
|
||||
|
||||
const applyStyle = (self, string) => {
|
||||
if (self.level <= 0 || !string) {
|
||||
return self[IS_EMPTY] ? '' : string;
|
||||
}
|
||||
|
||||
let styler = self[STYLER];
|
||||
|
||||
if (styler === undefined) {
|
||||
return string;
|
||||
}
|
||||
|
||||
const {openAll, closeAll} = styler;
|
||||
if (string.includes('\u001B')) {
|
||||
while (styler !== undefined) {
|
||||
// Replace any instances already present with a re-opening code
|
||||
// otherwise only the part of the string until said closing code
|
||||
// will be colored, and the rest will simply be 'plain'.
|
||||
string = stringReplaceAll(string, styler.close, styler.open);
|
||||
|
||||
styler = styler.parent;
|
||||
}
|
||||
}
|
||||
|
||||
// We can move both next actions out of loop, because remaining actions in loop won't have
|
||||
// any/visible effect on parts we add here. Close the styling before a linebreak and reopen
|
||||
// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92
|
||||
const lfIndex = string.indexOf('\n');
|
||||
if (lfIndex !== -1) {
|
||||
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
||||
}
|
||||
|
||||
return openAll + string + closeAll;
|
||||
};
|
||||
|
||||
Object.defineProperties(createChalk.prototype, styles);
|
||||
|
||||
const chalk = createChalk();
|
||||
export const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});
|
||||
|
||||
export {
|
||||
modifierNames,
|
||||
foregroundColorNames,
|
||||
backgroundColorNames,
|
||||
colorNames,
|
||||
|
||||
// TODO: Remove these aliases in the next major version
|
||||
modifierNames as modifiers,
|
||||
foregroundColorNames as foregroundColors,
|
||||
backgroundColorNames as backgroundColors,
|
||||
colorNames as colors,
|
||||
} from './vendor/ansi-styles/index.js';
|
||||
|
||||
export {
|
||||
stdoutColor as supportsColor,
|
||||
stderrColor as supportsColorStderr,
|
||||
};
|
||||
|
||||
export default chalk;
|
33
node_modules/lint-staged/node_modules/chalk/source/utilities.js
generated
vendored
Normal file
33
node_modules/lint-staged/node_modules/chalk/source/utilities.js
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.
|
||||
export function stringReplaceAll(string, substring, replacer) {
|
||||
let index = string.indexOf(substring);
|
||||
if (index === -1) {
|
||||
return string;
|
||||
}
|
||||
|
||||
const substringLength = substring.length;
|
||||
let endIndex = 0;
|
||||
let returnValue = '';
|
||||
do {
|
||||
returnValue += string.slice(endIndex, index) + substring + replacer;
|
||||
endIndex = index + substringLength;
|
||||
index = string.indexOf(substring, endIndex);
|
||||
} while (index !== -1);
|
||||
|
||||
returnValue += string.slice(endIndex);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
export function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
||||
let endIndex = 0;
|
||||
let returnValue = '';
|
||||
do {
|
||||
const gotCR = string[index - 1] === '\r';
|
||||
returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix;
|
||||
endIndex = index + 1;
|
||||
index = string.indexOf('\n', endIndex);
|
||||
} while (index !== -1);
|
||||
|
||||
returnValue += string.slice(endIndex);
|
||||
return returnValue;
|
||||
}
|
236
node_modules/lint-staged/node_modules/chalk/source/vendor/ansi-styles/index.d.ts
generated
vendored
Normal file
236
node_modules/lint-staged/node_modules/chalk/source/vendor/ansi-styles/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
export interface CSPair { // eslint-disable-line @typescript-eslint/naming-convention
|
||||
/**
|
||||
The ANSI terminal control sequence for starting this style.
|
||||
*/
|
||||
readonly open: string;
|
||||
|
||||
/**
|
||||
The ANSI terminal control sequence for ending this style.
|
||||
*/
|
||||
readonly close: string;
|
||||
}
|
||||
|
||||
export interface ColorBase {
|
||||
/**
|
||||
The ANSI terminal control sequence for ending this color.
|
||||
*/
|
||||
readonly close: string;
|
||||
|
||||
ansi(code: number): string;
|
||||
|
||||
ansi256(code: number): string;
|
||||
|
||||
ansi16m(red: number, green: number, blue: number): string;
|
||||
}
|
||||
|
||||
export interface Modifier {
|
||||
/**
|
||||
Resets the current color chain.
|
||||
*/
|
||||
readonly reset: CSPair;
|
||||
|
||||
/**
|
||||
Make text bold.
|
||||
*/
|
||||
readonly bold: CSPair;
|
||||
|
||||
/**
|
||||
Emitting only a small amount of light.
|
||||
*/
|
||||
readonly dim: CSPair;
|
||||
|
||||
/**
|
||||
Make text italic. (Not widely supported)
|
||||
*/
|
||||
readonly italic: CSPair;
|
||||
|
||||
/**
|
||||
Make text underline. (Not widely supported)
|
||||
*/
|
||||
readonly underline: CSPair;
|
||||
|
||||
/**
|
||||
Make text overline.
|
||||
|
||||
Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.
|
||||
*/
|
||||
readonly overline: CSPair;
|
||||
|
||||
/**
|
||||
Inverse background and foreground colors.
|
||||
*/
|
||||
readonly inverse: CSPair;
|
||||
|
||||
/**
|
||||
Prints the text, but makes it invisible.
|
||||
*/
|
||||
readonly hidden: CSPair;
|
||||
|
||||
/**
|
||||
Puts a horizontal line through the center of the text. (Not widely supported)
|
||||
*/
|
||||
readonly strikethrough: CSPair;
|
||||
}
|
||||
|
||||
export interface ForegroundColor {
|
||||
readonly black: CSPair;
|
||||
readonly red: CSPair;
|
||||
readonly green: CSPair;
|
||||
readonly yellow: CSPair;
|
||||
readonly blue: CSPair;
|
||||
readonly cyan: CSPair;
|
||||
readonly magenta: CSPair;
|
||||
readonly white: CSPair;
|
||||
|
||||
/**
|
||||
Alias for `blackBright`.
|
||||
*/
|
||||
readonly gray: CSPair;
|
||||
|
||||
/**
|
||||
Alias for `blackBright`.
|
||||
*/
|
||||
readonly grey: CSPair;
|
||||
|
||||
readonly blackBright: CSPair;
|
||||
readonly redBright: CSPair;
|
||||
readonly greenBright: CSPair;
|
||||
readonly yellowBright: CSPair;
|
||||
readonly blueBright: CSPair;
|
||||
readonly cyanBright: CSPair;
|
||||
readonly magentaBright: CSPair;
|
||||
readonly whiteBright: CSPair;
|
||||
}
|
||||
|
||||
export interface BackgroundColor {
|
||||
readonly bgBlack: CSPair;
|
||||
readonly bgRed: CSPair;
|
||||
readonly bgGreen: CSPair;
|
||||
readonly bgYellow: CSPair;
|
||||
readonly bgBlue: CSPair;
|
||||
readonly bgCyan: CSPair;
|
||||
readonly bgMagenta: CSPair;
|
||||
readonly bgWhite: CSPair;
|
||||
|
||||
/**
|
||||
Alias for `bgBlackBright`.
|
||||
*/
|
||||
readonly bgGray: CSPair;
|
||||
|
||||
/**
|
||||
Alias for `bgBlackBright`.
|
||||
*/
|
||||
readonly bgGrey: CSPair;
|
||||
|
||||
readonly bgBlackBright: CSPair;
|
||||
readonly bgRedBright: CSPair;
|
||||
readonly bgGreenBright: CSPair;
|
||||
readonly bgYellowBright: CSPair;
|
||||
readonly bgBlueBright: CSPair;
|
||||
readonly bgCyanBright: CSPair;
|
||||
readonly bgMagentaBright: CSPair;
|
||||
readonly bgWhiteBright: CSPair;
|
||||
}
|
||||
|
||||
export interface ConvertColor {
|
||||
/**
|
||||
Convert from the RGB color space to the ANSI 256 color space.
|
||||
|
||||
@param red - (`0...255`)
|
||||
@param green - (`0...255`)
|
||||
@param blue - (`0...255`)
|
||||
*/
|
||||
rgbToAnsi256(red: number, green: number, blue: number): number;
|
||||
|
||||
/**
|
||||
Convert from the RGB HEX color space to the RGB color space.
|
||||
|
||||
@param hex - A hexadecimal string containing RGB data.
|
||||
*/
|
||||
hexToRgb(hex: string): [red: number, green: number, blue: number];
|
||||
|
||||
/**
|
||||
Convert from the RGB HEX color space to the ANSI 256 color space.
|
||||
|
||||
@param hex - A hexadecimal string containing RGB data.
|
||||
*/
|
||||
hexToAnsi256(hex: string): number;
|
||||
|
||||
/**
|
||||
Convert from the ANSI 256 color space to the ANSI 16 color space.
|
||||
|
||||
@param code - A number representing the ANSI 256 color.
|
||||
*/
|
||||
ansi256ToAnsi(code: number): number;
|
||||
|
||||
/**
|
||||
Convert from the RGB color space to the ANSI 16 color space.
|
||||
|
||||
@param red - (`0...255`)
|
||||
@param green - (`0...255`)
|
||||
@param blue - (`0...255`)
|
||||
*/
|
||||
rgbToAnsi(red: number, green: number, blue: number): number;
|
||||
|
||||
/**
|
||||
Convert from the RGB HEX color space to the ANSI 16 color space.
|
||||
|
||||
@param hex - A hexadecimal string containing RGB data.
|
||||
*/
|
||||
hexToAnsi(hex: string): number;
|
||||
}
|
||||
|
||||
/**
|
||||
Basic modifier names.
|
||||
*/
|
||||
export type ModifierName = keyof Modifier;
|
||||
|
||||
/**
|
||||
Basic foreground color names.
|
||||
|
||||
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
|
||||
*/
|
||||
export type ForegroundColorName = keyof ForegroundColor;
|
||||
|
||||
/**
|
||||
Basic background color names.
|
||||
|
||||
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
|
||||
*/
|
||||
export type BackgroundColorName = keyof BackgroundColor;
|
||||
|
||||
/**
|
||||
Basic color names. The combination of foreground and background color names.
|
||||
|
||||
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
|
||||
*/
|
||||
export type ColorName = ForegroundColorName | BackgroundColorName;
|
||||
|
||||
/**
|
||||
Basic modifier names.
|
||||
*/
|
||||
export const modifierNames: readonly ModifierName[];
|
||||
|
||||
/**
|
||||
Basic foreground color names.
|
||||
*/
|
||||
export const foregroundColorNames: readonly ForegroundColorName[];
|
||||
|
||||
/**
|
||||
Basic background color names.
|
||||
*/
|
||||
export const backgroundColorNames: readonly BackgroundColorName[];
|
||||
|
||||
/*
|
||||
Basic color names. The combination of foreground and background color names.
|
||||
*/
|
||||
export const colorNames: readonly ColorName[];
|
||||
|
||||
declare const ansiStyles: {
|
||||
readonly modifier: Modifier;
|
||||
readonly color: ColorBase & ForegroundColor;
|
||||
readonly bgColor: ColorBase & BackgroundColor;
|
||||
readonly codes: ReadonlyMap<number, number>;
|
||||
} & ForegroundColor & BackgroundColor & Modifier & ConvertColor;
|
||||
|
||||
export default ansiStyles;
|
223
node_modules/lint-staged/node_modules/chalk/source/vendor/ansi-styles/index.js
generated
vendored
Normal file
223
node_modules/lint-staged/node_modules/chalk/source/vendor/ansi-styles/index.js
generated
vendored
Normal file
@ -0,0 +1,223 @@
|
||||
const ANSI_BACKGROUND_OFFSET = 10;
|
||||
|
||||
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
|
||||
|
||||
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
|
||||
|
||||
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
|
||||
|
||||
const styles = {
|
||||
modifier: {
|
||||
reset: [0, 0],
|
||||
// 21 isn't widely supported and 22 does the same thing
|
||||
bold: [1, 22],
|
||||
dim: [2, 22],
|
||||
italic: [3, 23],
|
||||
underline: [4, 24],
|
||||
overline: [53, 55],
|
||||
inverse: [7, 27],
|
||||
hidden: [8, 28],
|
||||
strikethrough: [9, 29],
|
||||
},
|
||||
color: {
|
||||
black: [30, 39],
|
||||
red: [31, 39],
|
||||
green: [32, 39],
|
||||
yellow: [33, 39],
|
||||
blue: [34, 39],
|
||||
magenta: [35, 39],
|
||||
cyan: [36, 39],
|
||||
white: [37, 39],
|
||||
|
||||
// Bright color
|
||||
blackBright: [90, 39],
|
||||
gray: [90, 39], // Alias of `blackBright`
|
||||
grey: [90, 39], // Alias of `blackBright`
|
||||
redBright: [91, 39],
|
||||
greenBright: [92, 39],
|
||||
yellowBright: [93, 39],
|
||||
blueBright: [94, 39],
|
||||
magentaBright: [95, 39],
|
||||
cyanBright: [96, 39],
|
||||
whiteBright: [97, 39],
|
||||
},
|
||||
bgColor: {
|
||||
bgBlack: [40, 49],
|
||||
bgRed: [41, 49],
|
||||
bgGreen: [42, 49],
|
||||
bgYellow: [43, 49],
|
||||
bgBlue: [44, 49],
|
||||
bgMagenta: [45, 49],
|
||||
bgCyan: [46, 49],
|
||||
bgWhite: [47, 49],
|
||||
|
||||
// Bright color
|
||||
bgBlackBright: [100, 49],
|
||||
bgGray: [100, 49], // Alias of `bgBlackBright`
|
||||
bgGrey: [100, 49], // Alias of `bgBlackBright`
|
||||
bgRedBright: [101, 49],
|
||||
bgGreenBright: [102, 49],
|
||||
bgYellowBright: [103, 49],
|
||||
bgBlueBright: [104, 49],
|
||||
bgMagentaBright: [105, 49],
|
||||
bgCyanBright: [106, 49],
|
||||
bgWhiteBright: [107, 49],
|
||||
},
|
||||
};
|
||||
|
||||
export const modifierNames = Object.keys(styles.modifier);
|
||||
export const foregroundColorNames = Object.keys(styles.color);
|
||||
export const backgroundColorNames = Object.keys(styles.bgColor);
|
||||
export const colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
||||
|
||||
function assembleStyles() {
|
||||
const codes = new Map();
|
||||
|
||||
for (const [groupName, group] of Object.entries(styles)) {
|
||||
for (const [styleName, style] of Object.entries(group)) {
|
||||
styles[styleName] = {
|
||||
open: `\u001B[${style[0]}m`,
|
||||
close: `\u001B[${style[1]}m`,
|
||||
};
|
||||
|
||||
group[styleName] = styles[styleName];
|
||||
|
||||
codes.set(style[0], style[1]);
|
||||
}
|
||||
|
||||
Object.defineProperty(styles, groupName, {
|
||||
value: group,
|
||||
enumerable: false,
|
||||
});
|
||||
}
|
||||
|
||||
Object.defineProperty(styles, 'codes', {
|
||||
value: codes,
|
||||
enumerable: false,
|
||||
});
|
||||
|
||||
styles.color.close = '\u001B[39m';
|
||||
styles.bgColor.close = '\u001B[49m';
|
||||
|
||||
styles.color.ansi = wrapAnsi16();
|
||||
styles.color.ansi256 = wrapAnsi256();
|
||||
styles.color.ansi16m = wrapAnsi16m();
|
||||
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
||||
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
||||
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
||||
|
||||
// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
|
||||
Object.defineProperties(styles, {
|
||||
rgbToAnsi256: {
|
||||
value(red, green, blue) {
|
||||
// We use the extended greyscale palette here, with the exception of
|
||||
// black and white. normal palette only has 4 greyscale shades.
|
||||
if (red === green && green === blue) {
|
||||
if (red < 8) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
if (red > 248) {
|
||||
return 231;
|
||||
}
|
||||
|
||||
return Math.round(((red - 8) / 247) * 24) + 232;
|
||||
}
|
||||
|
||||
return 16
|
||||
+ (36 * Math.round(red / 255 * 5))
|
||||
+ (6 * Math.round(green / 255 * 5))
|
||||
+ Math.round(blue / 255 * 5);
|
||||
},
|
||||
enumerable: false,
|
||||
},
|
||||
hexToRgb: {
|
||||
value(hex) {
|
||||
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
||||
if (!matches) {
|
||||
return [0, 0, 0];
|
||||
}
|
||||
|
||||
let [colorString] = matches;
|
||||
|
||||
if (colorString.length === 3) {
|
||||
colorString = [...colorString].map(character => character + character).join('');
|
||||
}
|
||||
|
||||
const integer = Number.parseInt(colorString, 16);
|
||||
|
||||
return [
|
||||
/* eslint-disable no-bitwise */
|
||||
(integer >> 16) & 0xFF,
|
||||
(integer >> 8) & 0xFF,
|
||||
integer & 0xFF,
|
||||
/* eslint-enable no-bitwise */
|
||||
];
|
||||
},
|
||||
enumerable: false,
|
||||
},
|
||||
hexToAnsi256: {
|
||||
value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
||||
enumerable: false,
|
||||
},
|
||||
ansi256ToAnsi: {
|
||||
value(code) {
|
||||
if (code < 8) {
|
||||
return 30 + code;
|
||||
}
|
||||
|
||||
if (code < 16) {
|
||||
return 90 + (code - 8);
|
||||
}
|
||||
|
||||
let red;
|
||||
let green;
|
||||
let blue;
|
||||
|
||||
if (code >= 232) {
|
||||
red = (((code - 232) * 10) + 8) / 255;
|
||||
green = red;
|
||||
blue = red;
|
||||
} else {
|
||||
code -= 16;
|
||||
|
||||
const remainder = code % 36;
|
||||
|
||||
red = Math.floor(code / 36) / 5;
|
||||
green = Math.floor(remainder / 6) / 5;
|
||||
blue = (remainder % 6) / 5;
|
||||
}
|
||||
|
||||
const value = Math.max(red, green, blue) * 2;
|
||||
|
||||
if (value === 0) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-bitwise
|
||||
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
|
||||
|
||||
if (value === 2) {
|
||||
result += 60;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
enumerable: false,
|
||||
},
|
||||
rgbToAnsi: {
|
||||
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
||||
enumerable: false,
|
||||
},
|
||||
hexToAnsi: {
|
||||
value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
||||
enumerable: false,
|
||||
},
|
||||
});
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
const ansiStyles = assembleStyles();
|
||||
|
||||
export default ansiStyles;
|
1
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/browser.d.ts
generated
vendored
Normal file
1
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/browser.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export {default} from './index.js';
|
30
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/browser.js
generated
vendored
Normal file
30
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/browser.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/* eslint-env browser */
|
||||
|
||||
const level = (() => {
|
||||
if (navigator.userAgentData) {
|
||||
const brand = navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium');
|
||||
if (brand && brand.version > 93) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (/\b(Chrome|Chromium)\//.test(navigator.userAgent)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
})();
|
||||
|
||||
const colorSupport = level !== 0 && {
|
||||
level,
|
||||
hasBasic: true,
|
||||
has256: level >= 2,
|
||||
has16m: level >= 3,
|
||||
};
|
||||
|
||||
const supportsColor = {
|
||||
stdout: colorSupport,
|
||||
stderr: colorSupport,
|
||||
};
|
||||
|
||||
export default supportsColor;
|
55
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/index.d.ts
generated
vendored
Normal file
55
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
import type {WriteStream} from 'node:tty';
|
||||
|
||||
export type Options = {
|
||||
/**
|
||||
Whether `process.argv` should be sniffed for `--color` and `--no-color` flags.
|
||||
|
||||
@default true
|
||||
*/
|
||||
readonly sniffFlags?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
Levels:
|
||||
- `0` - All colors disabled.
|
||||
- `1` - Basic 16 colors support.
|
||||
- `2` - ANSI 256 colors support.
|
||||
- `3` - Truecolor 16 million colors support.
|
||||
*/
|
||||
export type ColorSupportLevel = 0 | 1 | 2 | 3;
|
||||
|
||||
/**
|
||||
Detect whether the terminal supports color.
|
||||
*/
|
||||
export type ColorSupport = {
|
||||
/**
|
||||
The color level.
|
||||
*/
|
||||
level: ColorSupportLevel;
|
||||
|
||||
/**
|
||||
Whether basic 16 colors are supported.
|
||||
*/
|
||||
hasBasic: boolean;
|
||||
|
||||
/**
|
||||
Whether ANSI 256 colors are supported.
|
||||
*/
|
||||
has256: boolean;
|
||||
|
||||
/**
|
||||
Whether Truecolor 16 million colors are supported.
|
||||
*/
|
||||
has16m: boolean;
|
||||
};
|
||||
|
||||
export type ColorInfo = ColorSupport | false;
|
||||
|
||||
export function createSupportsColor(stream?: WriteStream, options?: Options): ColorInfo;
|
||||
|
||||
declare const supportsColor: {
|
||||
stdout: ColorInfo;
|
||||
stderr: ColorInfo;
|
||||
};
|
||||
|
||||
export default supportsColor;
|
182
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/index.js
generated
vendored
Normal file
182
node_modules/lint-staged/node_modules/chalk/source/vendor/supports-color/index.js
generated
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
import process from 'node:process';
|
||||
import os from 'node:os';
|
||||
import tty from 'node:tty';
|
||||
|
||||
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
|
||||
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
|
||||
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
|
||||
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
||||
const position = argv.indexOf(prefix + flag);
|
||||
const terminatorPosition = argv.indexOf('--');
|
||||
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
||||
}
|
||||
|
||||
const {env} = process;
|
||||
|
||||
let flagForceColor;
|
||||
if (
|
||||
hasFlag('no-color')
|
||||
|| hasFlag('no-colors')
|
||||
|| hasFlag('color=false')
|
||||
|| hasFlag('color=never')
|
||||
) {
|
||||
flagForceColor = 0;
|
||||
} else if (
|
||||
hasFlag('color')
|
||||
|| hasFlag('colors')
|
||||
|| hasFlag('color=true')
|
||||
|| hasFlag('color=always')
|
||||
) {
|
||||
flagForceColor = 1;
|
||||
}
|
||||
|
||||
function envForceColor() {
|
||||
if ('FORCE_COLOR' in env) {
|
||||
if (env.FORCE_COLOR === 'true') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (env.FORCE_COLOR === 'false') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
||||
}
|
||||
}
|
||||
|
||||
function translateLevel(level) {
|
||||
if (level === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
level,
|
||||
hasBasic: true,
|
||||
has256: level >= 2,
|
||||
has16m: level >= 3,
|
||||
};
|
||||
}
|
||||
|
||||
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
|
||||
const noFlagForceColor = envForceColor();
|
||||
if (noFlagForceColor !== undefined) {
|
||||
flagForceColor = noFlagForceColor;
|
||||
}
|
||||
|
||||
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
||||
|
||||
if (forceColor === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sniffFlags) {
|
||||
if (hasFlag('color=16m')
|
||||
|| hasFlag('color=full')
|
||||
|| hasFlag('color=truecolor')) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (hasFlag('color=256')) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for Azure DevOps pipelines.
|
||||
// Has to be above the `!streamIsTTY` check.
|
||||
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const min = forceColor || 0;
|
||||
|
||||
if (env.TERM === 'dumb') {
|
||||
return min;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
|
||||
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
|
||||
const osRelease = os.release().split('.');
|
||||
if (
|
||||
Number(osRelease[0]) >= 10
|
||||
&& Number(osRelease[2]) >= 10_586
|
||||
) {
|
||||
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ('CI' in env) {
|
||||
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
if ('TEAMCITY_VERSION' in env) {
|
||||
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
||||
}
|
||||
|
||||
if (env.COLORTERM === 'truecolor') {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (env.TERM === 'xterm-kitty') {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if ('TERM_PROGRAM' in env) {
|
||||
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
|
||||
|
||||
switch (env.TERM_PROGRAM) {
|
||||
case 'iTerm.app': {
|
||||
return version >= 3 ? 3 : 2;
|
||||
}
|
||||
|
||||
case 'Apple_Terminal': {
|
||||
return 2;
|
||||
}
|
||||
// No default
|
||||
}
|
||||
}
|
||||
|
||||
if (/-256(color)?$/i.test(env.TERM)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ('COLORTERM' in env) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
export function createSupportsColor(stream, options = {}) {
|
||||
const level = _supportsColor(stream, {
|
||||
streamIsTTY: stream && stream.isTTY,
|
||||
...options,
|
||||
});
|
||||
|
||||
return translateLevel(level);
|
||||
}
|
||||
|
||||
const supportsColor = {
|
||||
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
||||
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
||||
};
|
||||
|
||||
export default supportsColor;
|
20
node_modules/lint-staged/node_modules/debug/LICENSE
generated
vendored
Normal file
20
node_modules/lint-staged/node_modules/debug/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2018-2021 Josh Junon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the 'Software'), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
481
node_modules/lint-staged/node_modules/debug/README.md
generated
vendored
Normal file
481
node_modules/lint-staged/node_modules/debug/README.md
generated
vendored
Normal file
@ -0,0 +1,481 @@
|
||||
# debug
|
||||
[](https://travis-ci.org/debug-js/debug) [](https://coveralls.io/github/debug-js/debug?branch=master) [](https://visionmedia-community-slackin.now.sh/) [](#backers)
|
||||
[](#sponsors)
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
|
||||
|
||||
A tiny JavaScript debugging utility modelled after Node.js core's debugging
|
||||
technique. Works in Node.js and web browsers.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ npm install debug
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
|
||||
|
||||
Example [_app.js_](./examples/node/app.js):
|
||||
|
||||
```js
|
||||
var debug = require('debug')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %o', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
```
|
||||
|
||||
Example [_worker.js_](./examples/node/worker.js):
|
||||
|
||||
```js
|
||||
var a = require('debug')('worker:a')
|
||||
, b = require('debug')('worker:b');
|
||||
|
||||
function work() {
|
||||
a('doing lots of uninteresting work');
|
||||
setTimeout(work, Math.random() * 1000);
|
||||
}
|
||||
|
||||
work();
|
||||
|
||||
function workb() {
|
||||
b('doing some work');
|
||||
setTimeout(workb, Math.random() * 2000);
|
||||
}
|
||||
|
||||
workb();
|
||||
```
|
||||
|
||||
The `DEBUG` environment variable is then used to enable these based on space or
|
||||
comma-delimited names.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 04 pm" src="https://user-images.githubusercontent.com/71256/29091703-a6302cdc-7c38-11e7-8304-7c0b3bc600cd.png">
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 38 pm" src="https://user-images.githubusercontent.com/71256/29091700-a62a6888-7c38-11e7-800b-db911291ca2b.png">
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 25 pm" src="https://user-images.githubusercontent.com/71256/29091701-a62ea114-7c38-11e7-826a-2692bedca740.png">
|
||||
|
||||
#### Windows command prompt notes
|
||||
|
||||
##### CMD
|
||||
|
||||
On Windows the environment variable is set using the `set` command.
|
||||
|
||||
```cmd
|
||||
set DEBUG=*,-not_this
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
set DEBUG=* & node app.js
|
||||
```
|
||||
|
||||
##### PowerShell (VS Code default)
|
||||
|
||||
PowerShell uses different syntax to set environment variables.
|
||||
|
||||
```cmd
|
||||
$env:DEBUG = "*,-not_this"
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
$env:DEBUG='app';node app.js
|
||||
```
|
||||
|
||||
Then, run the program to be debugged as usual.
|
||||
|
||||
npm script example:
|
||||
```js
|
||||
"windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js",
|
||||
```
|
||||
|
||||
## Namespace Colors
|
||||
|
||||
Every debug instance has a color generated for it based on its namespace name.
|
||||
This helps when visually parsing the debug output to identify which debug instance
|
||||
a debug line belongs to.
|
||||
|
||||
#### Node.js
|
||||
|
||||
In Node.js, colors are enabled when stderr is a TTY. You also _should_ install
|
||||
the [`supports-color`](https://npmjs.org/supports-color) module alongside debug,
|
||||
otherwise debug will only use a small handful of basic colors.
|
||||
|
||||
<img width="521" src="https://user-images.githubusercontent.com/71256/29092181-47f6a9e6-7c3a-11e7-9a14-1928d8a711cd.png">
|
||||
|
||||
#### Web Browser
|
||||
|
||||
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
|
||||
option. These are WebKit web inspectors, Firefox ([since version
|
||||
31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
|
||||
and the Firebug plugin for Firefox (any version).
|
||||
|
||||
<img width="524" src="https://user-images.githubusercontent.com/71256/29092033-b65f9f2e-7c39-11e7-8e32-f6f0d8e865c1.png">
|
||||
|
||||
|
||||
## Millisecond diff
|
||||
|
||||
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
|
||||
|
||||
When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below:
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091956-6bd78372-7c39-11e7-8c55-c948396d6edd.png">
|
||||
|
||||
|
||||
## Conventions
|
||||
|
||||
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output.
|
||||
|
||||
## Wildcards
|
||||
|
||||
The `*` character may be used as a wildcard. Suppose for example your library has
|
||||
debuggers named "connect:bodyParser", "connect:compress", "connect:session",
|
||||
instead of listing all three with
|
||||
`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do
|
||||
`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
|
||||
|
||||
You can also exclude specific debuggers by prefixing them with a "-" character.
|
||||
For example, `DEBUG=*,-connect:*` would include all debuggers except those
|
||||
starting with "connect:".
|
||||
|
||||
## Environment Variables
|
||||
|
||||
When running through Node.js, you can set a few environment variables that will
|
||||
change the behavior of the debug logging:
|
||||
|
||||
| Name | Purpose |
|
||||
|-----------|-------------------------------------------------|
|
||||
| `DEBUG` | Enables/disables specific debugging namespaces. |
|
||||
| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). |
|
||||
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
|
||||
| `DEBUG_DEPTH` | Object inspection depth. |
|
||||
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
|
||||
|
||||
|
||||
__Note:__ The environment variables beginning with `DEBUG_` end up being
|
||||
converted into an Options object that gets used with `%o`/`%O` formatters.
|
||||
See the Node.js documentation for
|
||||
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
|
||||
for the complete list.
|
||||
|
||||
## Formatters
|
||||
|
||||
Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting.
|
||||
Below are the officially supported formatters:
|
||||
|
||||
| Formatter | Representation |
|
||||
|-----------|----------------|
|
||||
| `%O` | Pretty-print an Object on multiple lines. |
|
||||
| `%o` | Pretty-print an Object all on a single line. |
|
||||
| `%s` | String. |
|
||||
| `%d` | Number (both integer and float). |
|
||||
| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
|
||||
| `%%` | Single percent sign ('%'). This does not consume an argument. |
|
||||
|
||||
|
||||
### Custom formatters
|
||||
|
||||
You can add custom formatters by extending the `debug.formatters` object.
|
||||
For example, if you wanted to add support for rendering a Buffer as hex with
|
||||
`%h`, you could do something like:
|
||||
|
||||
```js
|
||||
const createDebug = require('debug')
|
||||
createDebug.formatters.h = (v) => {
|
||||
return v.toString('hex')
|
||||
}
|
||||
|
||||
// …elsewhere
|
||||
const debug = createDebug('foo')
|
||||
debug('this is hex: %h', new Buffer('hello world'))
|
||||
// foo this is hex: 68656c6c6f20776f726c6421 +0ms
|
||||
```
|
||||
|
||||
|
||||
## Browser Support
|
||||
|
||||
You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
|
||||
or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
|
||||
if you don't want to build it yourself.
|
||||
|
||||
Debug's enable state is currently persisted by `localStorage`.
|
||||
Consider the situation shown below where you have `worker:a` and `worker:b`,
|
||||
and wish to debug both. You can enable this using `localStorage.debug`:
|
||||
|
||||
```js
|
||||
localStorage.debug = 'worker:*'
|
||||
```
|
||||
|
||||
And then refresh the page.
|
||||
|
||||
```js
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
b('doing some work');
|
||||
}, 1200);
|
||||
```
|
||||
|
||||
In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_.
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/7143133/152083257-29034707-c42c-4959-8add-3cee850e6fcf.png">
|
||||
|
||||
## Output streams
|
||||
|
||||
By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
|
||||
|
||||
Example [_stdout.js_](./examples/node/stdout.js):
|
||||
|
||||
```js
|
||||
var debug = require('debug');
|
||||
var error = debug('app:error');
|
||||
|
||||
// by default stderr is used
|
||||
error('goes to stderr!');
|
||||
|
||||
var log = debug('app:log');
|
||||
// set this namespace to log via console.log
|
||||
log.log = console.log.bind(console); // don't forget to bind to console!
|
||||
log('goes to stdout');
|
||||
error('still goes to stderr!');
|
||||
|
||||
// set all output to go via console.info
|
||||
// overrides all per-namespace log settings
|
||||
debug.log = console.info.bind(console);
|
||||
error('now goes to stdout via console.info');
|
||||
log('still goes to stdout, but via console.info now');
|
||||
```
|
||||
|
||||
## Extend
|
||||
You can simply extend debugger
|
||||
```js
|
||||
const log = require('debug')('auth');
|
||||
|
||||
//creates new debug instance with extended namespace
|
||||
const logSign = log.extend('sign');
|
||||
const logLogin = log.extend('login');
|
||||
|
||||
log('hello'); // auth hello
|
||||
logSign('hello'); //auth:sign hello
|
||||
logLogin('hello'); //auth:login hello
|
||||
```
|
||||
|
||||
## Set dynamically
|
||||
|
||||
You can also enable debug dynamically by calling the `enable()` method :
|
||||
|
||||
```js
|
||||
let debug = require('debug');
|
||||
|
||||
console.log(1, debug.enabled('test'));
|
||||
|
||||
debug.enable('test');
|
||||
console.log(2, debug.enabled('test'));
|
||||
|
||||
debug.disable();
|
||||
console.log(3, debug.enabled('test'));
|
||||
|
||||
```
|
||||
|
||||
print :
|
||||
```
|
||||
1 false
|
||||
2 true
|
||||
3 false
|
||||
```
|
||||
|
||||
Usage :
|
||||
`enable(namespaces)`
|
||||
`namespaces` can include modes separated by a colon and wildcards.
|
||||
|
||||
Note that calling `enable()` completely overrides previously set DEBUG variable :
|
||||
|
||||
```
|
||||
$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))'
|
||||
=> false
|
||||
```
|
||||
|
||||
`disable()`
|
||||
|
||||
Will disable all namespaces. The functions returns the namespaces currently
|
||||
enabled (and skipped). This can be useful if you want to disable debugging
|
||||
temporarily without knowing what was enabled to begin with.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
let debug = require('debug');
|
||||
debug.enable('foo:*,-foo:bar');
|
||||
let namespaces = debug.disable();
|
||||
debug.enable(namespaces);
|
||||
```
|
||||
|
||||
Note: There is no guarantee that the string will be identical to the initial
|
||||
enable string, but semantically they will be identical.
|
||||
|
||||
## Checking whether a debug target is enabled
|
||||
|
||||
After you've created a debug instance, you can determine whether or not it is
|
||||
enabled by checking the `enabled` property:
|
||||
|
||||
```javascript
|
||||
const debug = require('debug')('http');
|
||||
|
||||
if (debug.enabled) {
|
||||
// do stuff...
|
||||
}
|
||||
```
|
||||
|
||||
You can also manually toggle this property to force the debug instance to be
|
||||
enabled or disabled.
|
||||
|
||||
## Usage in child processes
|
||||
|
||||
Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process.
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
worker = fork(WORKER_WRAP_PATH, [workerPath], {
|
||||
stdio: [
|
||||
/* stdin: */ 0,
|
||||
/* stdout: */ 'pipe',
|
||||
/* stderr: */ 'pipe',
|
||||
'ipc',
|
||||
],
|
||||
env: Object.assign({}, process.env, {
|
||||
DEBUG_COLORS: 1 // without this settings, colors won't be shown
|
||||
}),
|
||||
});
|
||||
|
||||
worker.stderr.pipe(process.stderr, { end: false });
|
||||
```
|
||||
|
||||
|
||||
## Authors
|
||||
|
||||
- TJ Holowaychuk
|
||||
- Nathan Rajlich
|
||||
- Andrew Rhyne
|
||||
- Josh Junon
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
|
||||
|
||||
<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
|
||||
|
||||
|
||||
## Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2018-2021 Josh Junon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
59
node_modules/lint-staged/node_modules/debug/package.json
generated
vendored
Normal file
59
node_modules/lint-staged/node_modules/debug/package.json
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "4.3.4",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/debug-js/debug.git"
|
||||
},
|
||||
"description": "Lightweight debugging utility for Node.js and the browser",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"log",
|
||||
"debugger"
|
||||
],
|
||||
"files": [
|
||||
"src",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"author": "Josh Junon <josh.junon@protonmail.com>",
|
||||
"contributors": [
|
||||
"TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
|
||||
"Andrew Rhyne <rhyneandrew@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"lint": "xo",
|
||||
"test": "npm run test:node && npm run test:browser && npm run lint",
|
||||
"test:node": "istanbul cover _mocha -- test.js",
|
||||
"test:browser": "karma start --single-run",
|
||||
"test:coverage": "cat ./coverage/lcov.info | coveralls"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"brfs": "^2.0.1",
|
||||
"browserify": "^16.2.3",
|
||||
"coveralls": "^3.0.2",
|
||||
"istanbul": "^0.4.5",
|
||||
"karma": "^3.1.4",
|
||||
"karma-browserify": "^6.0.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-lcov-reporter": "^1.2.0",
|
||||
"xo": "^0.23.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"main": "./src/index.js",
|
||||
"browser": "./src/browser.js",
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
}
|
||||
}
|
269
node_modules/lint-staged/node_modules/debug/src/browser.js
generated
vendored
Normal file
269
node_modules/lint-staged/node_modules/debug/src/browser.js
generated
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
/* eslint-env browser */
|
||||
|
||||
/**
|
||||
* This is the web browser implementation of `debug()`.
|
||||
*/
|
||||
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.storage = localstorage();
|
||||
exports.destroy = (() => {
|
||||
let warned = false;
|
||||
|
||||
return () => {
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
exports.colors = [
|
||||
'#0000CC',
|
||||
'#0000FF',
|
||||
'#0033CC',
|
||||
'#0033FF',
|
||||
'#0066CC',
|
||||
'#0066FF',
|
||||
'#0099CC',
|
||||
'#0099FF',
|
||||
'#00CC00',
|
||||
'#00CC33',
|
||||
'#00CC66',
|
||||
'#00CC99',
|
||||
'#00CCCC',
|
||||
'#00CCFF',
|
||||
'#3300CC',
|
||||
'#3300FF',
|
||||
'#3333CC',
|
||||
'#3333FF',
|
||||
'#3366CC',
|
||||
'#3366FF',
|
||||
'#3399CC',
|
||||
'#3399FF',
|
||||
'#33CC00',
|
||||
'#33CC33',
|
||||
'#33CC66',
|
||||
'#33CC99',
|
||||
'#33CCCC',
|
||||
'#33CCFF',
|
||||
'#6600CC',
|
||||
'#6600FF',
|
||||
'#6633CC',
|
||||
'#6633FF',
|
||||
'#66CC00',
|
||||
'#66CC33',
|
||||
'#9900CC',
|
||||
'#9900FF',
|
||||
'#9933CC',
|
||||
'#9933FF',
|
||||
'#99CC00',
|
||||
'#99CC33',
|
||||
'#CC0000',
|
||||
'#CC0033',
|
||||
'#CC0066',
|
||||
'#CC0099',
|
||||
'#CC00CC',
|
||||
'#CC00FF',
|
||||
'#CC3300',
|
||||
'#CC3333',
|
||||
'#CC3366',
|
||||
'#CC3399',
|
||||
'#CC33CC',
|
||||
'#CC33FF',
|
||||
'#CC6600',
|
||||
'#CC6633',
|
||||
'#CC9900',
|
||||
'#CC9933',
|
||||
'#CCCC00',
|
||||
'#CCCC33',
|
||||
'#FF0000',
|
||||
'#FF0033',
|
||||
'#FF0066',
|
||||
'#FF0099',
|
||||
'#FF00CC',
|
||||
'#FF00FF',
|
||||
'#FF3300',
|
||||
'#FF3333',
|
||||
'#FF3366',
|
||||
'#FF3399',
|
||||
'#FF33CC',
|
||||
'#FF33FF',
|
||||
'#FF6600',
|
||||
'#FF6633',
|
||||
'#FF9900',
|
||||
'#FF9933',
|
||||
'#FFCC00',
|
||||
'#FFCC33'
|
||||
];
|
||||
|
||||
/**
|
||||
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
||||
* and the Firebug extension (any Firefox version) are known
|
||||
* to support "%c" CSS customizations.
|
||||
*
|
||||
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
function useColors() {
|
||||
// NB: In an Electron preload script, document will be defined but not fully
|
||||
// initialized. Since we know we're in Chrome, we'll just detect this case
|
||||
// explicitly
|
||||
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Internet Explorer and Edge do not support colors.
|
||||
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
||||
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
||||
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
||||
// Is firebug? http://stackoverflow.com/a/398120/376773
|
||||
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
||||
// Is firefox >= v31?
|
||||
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
|
||||
// Double check webkit in userAgent just in case we are in a worker
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorize log arguments if enabled.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function formatArgs(args) {
|
||||
args[0] = (this.useColors ? '%c' : '') +
|
||||
this.namespace +
|
||||
(this.useColors ? ' %c' : ' ') +
|
||||
args[0] +
|
||||
(this.useColors ? '%c ' : ' ') +
|
||||
'+' + module.exports.humanize(this.diff);
|
||||
|
||||
if (!this.useColors) {
|
||||
return;
|
||||
}
|
||||
|
||||
const c = 'color: ' + this.color;
|
||||
args.splice(1, 0, c, 'color: inherit');
|
||||
|
||||
// The final "%c" is somewhat tricky, because there could be other
|
||||
// arguments passed either before or after the %c, so we need to
|
||||
// figure out the correct index to insert the CSS into
|
||||
let index = 0;
|
||||
let lastC = 0;
|
||||
args[0].replace(/%[a-zA-Z%]/g, match => {
|
||||
if (match === '%%') {
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
if (match === '%c') {
|
||||
// We only are interested in the *last* %c
|
||||
// (the user may have provided their own)
|
||||
lastC = index;
|
||||
}
|
||||
});
|
||||
|
||||
args.splice(lastC, 0, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `console.debug()` when available.
|
||||
* No-op when `console.debug` is not a "function".
|
||||
* If `console.debug` is not available, falls back
|
||||
* to `console.log`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
exports.log = console.debug || console.log || (() => {});
|
||||
|
||||
/**
|
||||
* Save `namespaces`.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api private
|
||||
*/
|
||||
function save(namespaces) {
|
||||
try {
|
||||
if (namespaces) {
|
||||
exports.storage.setItem('debug', namespaces);
|
||||
} else {
|
||||
exports.storage.removeItem('debug');
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load `namespaces`.
|
||||
*
|
||||
* @return {String} returns the previously persisted debug modes
|
||||
* @api private
|
||||
*/
|
||||
function load() {
|
||||
let r;
|
||||
try {
|
||||
r = exports.storage.getItem('debug');
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
|
||||
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
||||
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
||||
r = process.env.DEBUG;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Localstorage attempts to return the localstorage.
|
||||
*
|
||||
* This is necessary because safari throws
|
||||
* when a user disables cookies/localstorage
|
||||
* and you attempt to access it.
|
||||
*
|
||||
* @return {LocalStorage}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function localstorage() {
|
||||
try {
|
||||
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
|
||||
// The Browser also has localStorage in the global context.
|
||||
return localStorage;
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = require('./common')(exports);
|
||||
|
||||
const {formatters} = module.exports;
|
||||
|
||||
/**
|
||||
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
||||
*/
|
||||
|
||||
formatters.j = function (v) {
|
||||
try {
|
||||
return JSON.stringify(v);
|
||||
} catch (error) {
|
||||
return '[UnexpectedJSONParseError]: ' + error.message;
|
||||
}
|
||||
};
|
274
node_modules/lint-staged/node_modules/debug/src/common.js
generated
vendored
Normal file
274
node_modules/lint-staged/node_modules/debug/src/common.js
generated
vendored
Normal file
@ -0,0 +1,274 @@
|
||||
|
||||
/**
|
||||
* This is the common logic for both the Node.js and web browser
|
||||
* implementations of `debug()`.
|
||||
*/
|
||||
|
||||
function setup(env) {
|
||||
createDebug.debug = createDebug;
|
||||
createDebug.default = createDebug;
|
||||
createDebug.coerce = coerce;
|
||||
createDebug.disable = disable;
|
||||
createDebug.enable = enable;
|
||||
createDebug.enabled = enabled;
|
||||
createDebug.humanize = require('ms');
|
||||
createDebug.destroy = destroy;
|
||||
|
||||
Object.keys(env).forEach(key => {
|
||||
createDebug[key] = env[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* The currently active debug mode names, and names to skip.
|
||||
*/
|
||||
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
/**
|
||||
* Map of special "%n" handling functions, for the debug "format" argument.
|
||||
*
|
||||
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
||||
*/
|
||||
createDebug.formatters = {};
|
||||
|
||||
/**
|
||||
* Selects a color for a debug namespace
|
||||
* @param {String} namespace The namespace string for the debug instance to be colored
|
||||
* @return {Number|String} An ANSI color code for the given namespace
|
||||
* @api private
|
||||
*/
|
||||
function selectColor(namespace) {
|
||||
let hash = 0;
|
||||
|
||||
for (let i = 0; i < namespace.length; i++) {
|
||||
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
|
||||
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
||||
}
|
||||
createDebug.selectColor = selectColor;
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `namespace`.
|
||||
*
|
||||
* @param {String} namespace
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
function createDebug(namespace) {
|
||||
let prevTime;
|
||||
let enableOverride = null;
|
||||
let namespacesCache;
|
||||
let enabledCache;
|
||||
|
||||
function debug(...args) {
|
||||
// Disabled?
|
||||
if (!debug.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const self = debug;
|
||||
|
||||
// Set `diff` timestamp
|
||||
const curr = Number(new Date());
|
||||
const ms = curr - (prevTime || curr);
|
||||
self.diff = ms;
|
||||
self.prev = prevTime;
|
||||
self.curr = curr;
|
||||
prevTime = curr;
|
||||
|
||||
args[0] = createDebug.coerce(args[0]);
|
||||
|
||||
if (typeof args[0] !== 'string') {
|
||||
// Anything else let's inspect with %O
|
||||
args.unshift('%O');
|
||||
}
|
||||
|
||||
// Apply any `formatters` transformations
|
||||
let index = 0;
|
||||
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
||||
// If we encounter an escaped % then don't increase the array index
|
||||
if (match === '%%') {
|
||||
return '%';
|
||||
}
|
||||
index++;
|
||||
const formatter = createDebug.formatters[format];
|
||||
if (typeof formatter === 'function') {
|
||||
const val = args[index];
|
||||
match = formatter.call(self, val);
|
||||
|
||||
// Now we need to remove `args[index]` since it's inlined in the `format`
|
||||
args.splice(index, 1);
|
||||
index--;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
// Apply env-specific formatting (colors, etc.)
|
||||
createDebug.formatArgs.call(self, args);
|
||||
|
||||
const logFn = self.log || createDebug.log;
|
||||
logFn.apply(self, args);
|
||||
}
|
||||
|
||||
debug.namespace = namespace;
|
||||
debug.useColors = createDebug.useColors();
|
||||
debug.color = createDebug.selectColor(namespace);
|
||||
debug.extend = extend;
|
||||
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
|
||||
|
||||
Object.defineProperty(debug, 'enabled', {
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: () => {
|
||||
if (enableOverride !== null) {
|
||||
return enableOverride;
|
||||
}
|
||||
if (namespacesCache !== createDebug.namespaces) {
|
||||
namespacesCache = createDebug.namespaces;
|
||||
enabledCache = createDebug.enabled(namespace);
|
||||
}
|
||||
|
||||
return enabledCache;
|
||||
},
|
||||
set: v => {
|
||||
enableOverride = v;
|
||||
}
|
||||
});
|
||||
|
||||
// Env-specific initialization logic for debug instances
|
||||
if (typeof createDebug.init === 'function') {
|
||||
createDebug.init(debug);
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
function extend(namespace, delimiter) {
|
||||
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
|
||||
newDebug.log = this.log;
|
||||
return newDebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a debug mode by namespaces. This can include modes
|
||||
* separated by a colon and wildcards.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api public
|
||||
*/
|
||||
function enable(namespaces) {
|
||||
createDebug.save(namespaces);
|
||||
createDebug.namespaces = namespaces;
|
||||
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
let i;
|
||||
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
|
||||
const len = split.length;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!split[i]) {
|
||||
// ignore empty strings
|
||||
continue;
|
||||
}
|
||||
|
||||
namespaces = split[i].replace(/\*/g, '.*?');
|
||||
|
||||
if (namespaces[0] === '-') {
|
||||
createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
|
||||
} else {
|
||||
createDebug.names.push(new RegExp('^' + namespaces + '$'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
* @return {String} namespaces
|
||||
* @api public
|
||||
*/
|
||||
function disable() {
|
||||
const namespaces = [
|
||||
...createDebug.names.map(toNamespace),
|
||||
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
|
||||
].join(',');
|
||||
createDebug.enable('');
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given mode name is enabled, false otherwise.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
function enabled(name) {
|
||||
if (name[name.length - 1] === '*') {
|
||||
return true;
|
||||
}
|
||||
|
||||
let i;
|
||||
let len;
|
||||
|
||||
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
||||
if (createDebug.skips[i].test(name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, len = createDebug.names.length; i < len; i++) {
|
||||
if (createDebug.names[i].test(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert regexp to namespace
|
||||
*
|
||||
* @param {RegExp} regxep
|
||||
* @return {String} namespace
|
||||
* @api private
|
||||
*/
|
||||
function toNamespace(regexp) {
|
||||
return regexp.toString()
|
||||
.substring(2, regexp.toString().length - 2)
|
||||
.replace(/\.\*\?$/, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce `val`.
|
||||
*
|
||||
* @param {Mixed} val
|
||||
* @return {Mixed}
|
||||
* @api private
|
||||
*/
|
||||
function coerce(val) {
|
||||
if (val instanceof Error) {
|
||||
return val.stack || val.message;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX DO NOT USE. This is a temporary stub function.
|
||||
* XXX It WILL be removed in the next major release.
|
||||
*/
|
||||
function destroy() {
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
|
||||
createDebug.enable(createDebug.load());
|
||||
|
||||
return createDebug;
|
||||
}
|
||||
|
||||
module.exports = setup;
|
10
node_modules/lint-staged/node_modules/debug/src/index.js
generated
vendored
Normal file
10
node_modules/lint-staged/node_modules/debug/src/index.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Detect Electron renderer / nwjs process, which is node, but we should
|
||||
* treat as a browser.
|
||||
*/
|
||||
|
||||
if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
|
||||
module.exports = require('./browser.js');
|
||||
} else {
|
||||
module.exports = require('./node.js');
|
||||
}
|
263
node_modules/lint-staged/node_modules/debug/src/node.js
generated
vendored
Normal file
263
node_modules/lint-staged/node_modules/debug/src/node.js
generated
vendored
Normal file
@ -0,0 +1,263 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const tty = require('tty');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* This is the Node.js implementation of `debug()`.
|
||||
*/
|
||||
|
||||
exports.init = init;
|
||||
exports.log = log;
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.destroy = util.deprecate(
|
||||
() => {},
|
||||
'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
exports.colors = [6, 2, 3, 4, 5, 1];
|
||||
|
||||
try {
|
||||
// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
const supportsColor = require('supports-color');
|
||||
|
||||
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
|
||||
exports.colors = [
|
||||
20,
|
||||
21,
|
||||
26,
|
||||
27,
|
||||
32,
|
||||
33,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
56,
|
||||
57,
|
||||
62,
|
||||
63,
|
||||
68,
|
||||
69,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
92,
|
||||
93,
|
||||
98,
|
||||
99,
|
||||
112,
|
||||
113,
|
||||
128,
|
||||
129,
|
||||
134,
|
||||
135,
|
||||
148,
|
||||
149,
|
||||
160,
|
||||
161,
|
||||
162,
|
||||
163,
|
||||
164,
|
||||
165,
|
||||
166,
|
||||
167,
|
||||
168,
|
||||
169,
|
||||
170,
|
||||
171,
|
||||
172,
|
||||
173,
|
||||
178,
|
||||
179,
|
||||
184,
|
||||
185,
|
||||
196,
|
||||
197,
|
||||
198,
|
||||
199,
|
||||
200,
|
||||
201,
|
||||
202,
|
||||
203,
|
||||
204,
|
||||
205,
|
||||
206,
|
||||
207,
|
||||
208,
|
||||
209,
|
||||
214,
|
||||
215,
|
||||
220,
|
||||
221
|
||||
];
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallow - we only care if `supports-color` is available; it doesn't have to be.
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the default `inspectOpts` object from the environment variables.
|
||||
*
|
||||
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
|
||||
*/
|
||||
|
||||
exports.inspectOpts = Object.keys(process.env).filter(key => {
|
||||
return /^debug_/i.test(key);
|
||||
}).reduce((obj, key) => {
|
||||
// Camel-case
|
||||
const prop = key
|
||||
.substring(6)
|
||||
.toLowerCase()
|
||||
.replace(/_([a-z])/g, (_, k) => {
|
||||
return k.toUpperCase();
|
||||
});
|
||||
|
||||
// Coerce string value into JS value
|
||||
let val = process.env[key];
|
||||
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
||||
val = true;
|
||||
} else if (/^(no|off|false|disabled)$/i.test(val)) {
|
||||
val = false;
|
||||
} else if (val === 'null') {
|
||||
val = null;
|
||||
} else {
|
||||
val = Number(val);
|
||||
}
|
||||
|
||||
obj[prop] = val;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
/**
|
||||
* Is stdout a TTY? Colored output is enabled when `true`.
|
||||
*/
|
||||
|
||||
function useColors() {
|
||||
return 'colors' in exports.inspectOpts ?
|
||||
Boolean(exports.inspectOpts.colors) :
|
||||
tty.isatty(process.stderr.fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ANSI color escape codes if enabled.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function formatArgs(args) {
|
||||
const {namespace: name, useColors} = this;
|
||||
|
||||
if (useColors) {
|
||||
const c = this.color;
|
||||
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
|
||||
const prefix = ` ${colorCode};1m${name} \u001B[0m`;
|
||||
|
||||
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
|
||||
args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
|
||||
} else {
|
||||
args[0] = getDate() + name + ' ' + args[0];
|
||||
}
|
||||
}
|
||||
|
||||
function getDate() {
|
||||
if (exports.inspectOpts.hideDate) {
|
||||
return '';
|
||||
}
|
||||
return new Date().toISOString() + ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `util.format()` with the specified arguments and writes to stderr.
|
||||
*/
|
||||
|
||||
function log(...args) {
|
||||
return process.stderr.write(util.format(...args) + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save `namespaces`.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api private
|
||||
*/
|
||||
function save(namespaces) {
|
||||
if (namespaces) {
|
||||
process.env.DEBUG = namespaces;
|
||||
} else {
|
||||
// If you set a process.env field to null or undefined, it gets cast to the
|
||||
// string 'null' or 'undefined'. Just delete instead.
|
||||
delete process.env.DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load `namespaces`.
|
||||
*
|
||||
* @return {String} returns the previously persisted debug modes
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function load() {
|
||||
return process.env.DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init logic for `debug` instances.
|
||||
*
|
||||
* Create a new `inspectOpts` object in case `useColors` is set
|
||||
* differently for a particular `debug` instance.
|
||||
*/
|
||||
|
||||
function init(debug) {
|
||||
debug.inspectOpts = {};
|
||||
|
||||
const keys = Object.keys(exports.inspectOpts);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = require('./common')(exports);
|
||||
|
||||
const {formatters} = module.exports;
|
||||
|
||||
/**
|
||||
* Map %o to `util.inspect()`, all on a single line.
|
||||
*/
|
||||
|
||||
formatters.o = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts)
|
||||
.split('\n')
|
||||
.map(str => str.trim())
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Map %O to `util.inspect()`, allowing multiple lines if needed.
|
||||
*/
|
||||
|
||||
formatters.O = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts);
|
||||
};
|
162
node_modules/lint-staged/node_modules/ms/index.js
generated
vendored
Normal file
162
node_modules/lint-staged/node_modules/ms/index.js
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Helpers.
|
||||
*/
|
||||
|
||||
var s = 1000;
|
||||
var m = s * 60;
|
||||
var h = m * 60;
|
||||
var d = h * 24;
|
||||
var w = d * 7;
|
||||
var y = d * 365.25;
|
||||
|
||||
/**
|
||||
* Parse or format the given `val`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `long` verbose formatting [false]
|
||||
*
|
||||
* @param {String|Number} val
|
||||
* @param {Object} [options]
|
||||
* @throws {Error} throw an error if val is not a non-empty string or a number
|
||||
* @return {String|Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function(val, options) {
|
||||
options = options || {};
|
||||
var type = typeof val;
|
||||
if (type === 'string' && val.length > 0) {
|
||||
return parse(val);
|
||||
} else if (type === 'number' && isFinite(val)) {
|
||||
return options.long ? fmtLong(val) : fmtShort(val);
|
||||
}
|
||||
throw new Error(
|
||||
'val is not a non-empty string or a valid number. val=' +
|
||||
JSON.stringify(val)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given `str` and return milliseconds.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function parse(str) {
|
||||
str = String(str);
|
||||
if (str.length > 100) {
|
||||
return;
|
||||
}
|
||||
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
||||
str
|
||||
);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
var n = parseFloat(match[1]);
|
||||
var type = (match[2] || 'ms').toLowerCase();
|
||||
switch (type) {
|
||||
case 'years':
|
||||
case 'year':
|
||||
case 'yrs':
|
||||
case 'yr':
|
||||
case 'y':
|
||||
return n * y;
|
||||
case 'weeks':
|
||||
case 'week':
|
||||
case 'w':
|
||||
return n * w;
|
||||
case 'days':
|
||||
case 'day':
|
||||
case 'd':
|
||||
return n * d;
|
||||
case 'hours':
|
||||
case 'hour':
|
||||
case 'hrs':
|
||||
case 'hr':
|
||||
case 'h':
|
||||
return n * h;
|
||||
case 'minutes':
|
||||
case 'minute':
|
||||
case 'mins':
|
||||
case 'min':
|
||||
case 'm':
|
||||
return n * m;
|
||||
case 'seconds':
|
||||
case 'second':
|
||||
case 'secs':
|
||||
case 'sec':
|
||||
case 's':
|
||||
return n * s;
|
||||
case 'milliseconds':
|
||||
case 'millisecond':
|
||||
case 'msecs':
|
||||
case 'msec':
|
||||
case 'ms':
|
||||
return n;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Short format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtShort(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return Math.round(ms / d) + 'd';
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return Math.round(ms / h) + 'h';
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return Math.round(ms / m) + 'm';
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return Math.round(ms / s) + 's';
|
||||
}
|
||||
return ms + 'ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Long format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtLong(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return plural(ms, msAbs, d, 'day');
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return plural(ms, msAbs, h, 'hour');
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return plural(ms, msAbs, m, 'minute');
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return plural(ms, msAbs, s, 'second');
|
||||
}
|
||||
return ms + ' ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralization helper.
|
||||
*/
|
||||
|
||||
function plural(ms, msAbs, n, name) {
|
||||
var isPlural = msAbs >= n * 1.5;
|
||||
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
|
||||
}
|
21
node_modules/lint-staged/node_modules/ms/license.md
generated
vendored
Normal file
21
node_modules/lint-staged/node_modules/ms/license.md
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Zeit, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
37
node_modules/lint-staged/node_modules/ms/package.json
generated
vendored
Normal file
37
node_modules/lint-staged/node_modules/ms/package.json
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.1.2",
|
||||
"description": "Tiny millisecond conversion utility",
|
||||
"repository": "zeit/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"lint": "eslint lib/* bin/*",
|
||||
"test": "mocha tests.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"npm run lint",
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "4.12.1",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.14.3",
|
||||
"lint-staged": "5.0.0",
|
||||
"mocha": "4.0.1"
|
||||
}
|
||||
}
|
60
node_modules/lint-staged/node_modules/ms/readme.md
generated
vendored
Normal file
60
node_modules/lint-staged/node_modules/ms/readme.md
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
# ms
|
||||
|
||||
[](https://travis-ci.org/zeit/ms)
|
||||
[](https://spectrum.chat/zeit)
|
||||
|
||||
Use this package to easily convert various time formats to milliseconds.
|
||||
|
||||
## Examples
|
||||
|
||||
```js
|
||||
ms('2 days') // 172800000
|
||||
ms('1d') // 86400000
|
||||
ms('10h') // 36000000
|
||||
ms('2.5 hrs') // 9000000
|
||||
ms('2h') // 7200000
|
||||
ms('1m') // 60000
|
||||
ms('5s') // 5000
|
||||
ms('1y') // 31557600000
|
||||
ms('100') // 100
|
||||
ms('-3 days') // -259200000
|
||||
ms('-1h') // -3600000
|
||||
ms('-200') // -200
|
||||
```
|
||||
|
||||
### Convert from Milliseconds
|
||||
|
||||
```js
|
||||
ms(60000) // "1m"
|
||||
ms(2 * 60000) // "2m"
|
||||
ms(-3 * 60000) // "-3m"
|
||||
ms(ms('10 hours')) // "10h"
|
||||
```
|
||||
|
||||
### Time Format Written-Out
|
||||
|
||||
```js
|
||||
ms(60000, { long: true }) // "1 minute"
|
||||
ms(2 * 60000, { long: true }) // "2 minutes"
|
||||
ms(-3 * 60000, { long: true }) // "-3 minutes"
|
||||
ms(ms('10 hours'), { long: true }) // "10 hours"
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Works both in [Node.js](https://nodejs.org) and in the browser
|
||||
- If a number is supplied to `ms`, a string with a unit is returned
|
||||
- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`)
|
||||
- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned
|
||||
|
||||
## Related Packages
|
||||
|
||||
- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time.
|
||||
|
||||
## Caught a Bug?
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
|
||||
2. Link the package to the global module directory: `npm link`
|
||||
3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms!
|
||||
|
||||
As always, you can run the tests using: `npm test`
|
77
node_modules/lint-staged/package.json
generated
vendored
Normal file
77
node_modules/lint-staged/package.json
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "lint-staged",
|
||||
"version": "13.3.0",
|
||||
"description": "Lint files staged by git",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/okonet/lint-staged",
|
||||
"author": "Andrey Okonetchnikov <andrey@okonet.ru>",
|
||||
"maintainers": [
|
||||
"Lufty Wiranda <lufty.wiranda@gmail.com>",
|
||||
"Suhas Karanth <sudo.suhas@gmail.com>",
|
||||
"Iiro Jäppinen <iiro@jappinen.fi> (https://iiro.fi)"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/lint-staged"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
},
|
||||
"type": "module",
|
||||
"bin": "./bin/lint-staged.js",
|
||||
"exports": {
|
||||
".": "./lib/index.js",
|
||||
"./bin": "./bin/lint-staged.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "jest --coverage",
|
||||
"test:watch": "jest --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "5.3.0",
|
||||
"commander": "11.0.0",
|
||||
"debug": "4.3.4",
|
||||
"execa": "7.2.0",
|
||||
"lilconfig": "2.1.0",
|
||||
"listr2": "6.6.1",
|
||||
"micromatch": "4.0.5",
|
||||
"pidtree": "0.6.0",
|
||||
"string-argv": "0.3.2",
|
||||
"yaml": "2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.22.10",
|
||||
"@babel/eslint-parser": "7.22.10",
|
||||
"@babel/preset-env": "7.22.10",
|
||||
"babel-jest": "29.6.2",
|
||||
"babel-plugin-transform-imports": "2.0.0",
|
||||
"consolemock": "1.1.0",
|
||||
"eslint": "8.46.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
"eslint-plugin-import": "2.28.0",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-prettier": "5.0.0",
|
||||
"husky": "8.0.3",
|
||||
"jest": "29.6.2",
|
||||
"jest-snapshot-serializer-ansi": "2.1.0",
|
||||
"prettier": "3.0.1"
|
||||
},
|
||||
"keywords": [
|
||||
"lint",
|
||||
"git",
|
||||
"staged",
|
||||
"eslint",
|
||||
"prettier",
|
||||
"stylelint",
|
||||
"code",
|
||||
"quality",
|
||||
"check",
|
||||
"format",
|
||||
"validate"
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user