Repository: okonet/lint-staged
Pull request #1160 (2022-05-30 12:46:57)

Remove Node.js 12 support
This PR:

- creates a breaking change to remove support for Node.js 12 since it's now EOL
- adds some fancy new stuff: `node:` protocol imports and `?.` optional chaining
- finally updates `execa@6`, and also `yaml@2`
- removes the `supports-color` dependency since `colorette` already exports a similar flag

I'm keeping it as a draft because it's rebased to https://github.com/okonet/lint-staged/pull/1159, but what do you think @okonet ?

codecov[bot]: # [Codecov](https://codecov.io/gh/okonet/lint-staged/pull/1160?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov) Report
> Merging [#1160](https://codecov.io/gh/okonet/lint-staged/pull/1160?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov) (91f4948) into [diff-option](https://codecov.io/gh/okonet/lint-staged/commit/16b2d3974232fd6c26ab93e01fa2bfbdccec09bd?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov) (16b2d39) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@              Coverage Diff              @@
##           diff-option     #1160   +/-   ##
=============================================
  Coverage       100.00%   100.00%           
=============================================
  Files               25        25           
  Lines              722       722           
  Branches           198       198           
=============================================
  Hits               722       722           
```


| [Impacted Files](https://codecov.io/gh/okonet/lint-staged/pull/1160?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov) | Coverage Δ | |
|---|---|---|
| [lib/chunkFiles.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2NodW5rRmlsZXMuanM=) | `100.00% <ø> (ø)` | |
| [lib/dynamicImport.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2R5bmFtaWNJbXBvcnQuanM=) | `100.00% <ø> (ø)` | |
| [lib/execGit.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2V4ZWNHaXQuanM=) | `100.00% <ø> (ø)` | |
| [lib/file.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2ZpbGUuanM=) | `100.00% <ø> (ø)` | |
| [lib/generateTasks.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2dlbmVyYXRlVGFza3MuanM=) | `100.00% <ø> (ø)` | |
| [lib/getStagedFiles.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2dldFN0YWdlZEZpbGVzLmpz) | `100.00% <ø> (ø)` | |
| [lib/gitWorkflow.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2dpdFdvcmtmbG93Lmpz) | `100.00% <ø> (ø)` | |
| [lib/groupFilesByConfig.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL2dyb3VwRmlsZXNCeUNvbmZpZy5qcw==) | `100.00% <ø> (ø)` | |
| [lib/resolveGitRepo.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL3Jlc29sdmVHaXRSZXBvLmpz) | `100.00% <ø> (ø)` | |
| [lib/runAll.js](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov#diff-bGliL3J1bkFsbC5qcw==) | `100.00% <ø> (ø)` | |
| ... and [5 more](https://codecov.io/gh/okonet/lint-staged/pull/1160/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/okonet/lint-staged/pull/1160?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/okonet/lint-staged/pull/1160?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov). Last update [16b2d39...91f4948](https://codecov.io/gh/okonet/lint-staged/pull/1160?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Andrey+Okonetchnikov).

iiroj: @okonet looks like you need to update the required checks.
okonet: Done!

Patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index cc1851b..abc53b8 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -40,9 +40,8 @@ jobs:
   test:
     strategy:
       matrix:
-        # Test with Node.js v12 (LTS), v14 (LTS), v16 (LTS), and 18 (Current)
+        # Test with Node.js v14 (LTS), v16 (LTS), and 18 (Current)
         node:
-          - 12
           - 14
           - 16
           - 18
diff --git a/README.md b/README.md
index 42b6938..9e14350 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,10 @@ See [Releases](https://github.com/okonet/lint-staged/releases).
 
 ### Migration
 
+#### 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).
diff --git a/bin/lint-staged.js b/bin/lint-staged.js
index 115ce1a..ff8c0d9 100755
--- a/bin/lint-staged.js
+++ b/bin/lint-staged.js
@@ -1,19 +1,19 @@
 #!/usr/bin/env node
 
-import fs from 'fs'
-import path from 'path'
-import { fileURLToPath } from 'url'
+import fs from 'node:fs'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
 
+import { isColorSupported } from 'colorette'
 import { Option, program } from 'commander'
 import debug from 'debug'
-import supportsColor from 'supports-color'
 
 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.stdout) {
-  process.env.FORCE_COLOR = supportsColor.stdout.level.toString()
+if (isColorSupported) {
+  process.env.FORCE_COLOR = '1'
 }
 
 // Do not terminate main Listr process on SIGINT
diff --git a/lib/chunkFiles.js b/lib/chunkFiles.js
index f04c25a..64761a0 100644
--- a/lib/chunkFiles.js
+++ b/lib/chunkFiles.js
@@ -1,4 +1,4 @@
-import path from 'path'
+import path from 'node:path'
 
 import debug from 'debug'
 import normalize from 'normalize-path'
diff --git a/lib/dynamicImport.js b/lib/dynamicImport.js
index 75e228f..fba6409 100644
--- a/lib/dynamicImport.js
+++ b/lib/dynamicImport.js
@@ -1,3 +1,3 @@
-import { pathToFileURL } from 'url'
+import { pathToFileURL } from 'node:url'
 
 export const dynamicImport = (path) => import(pathToFileURL(path)).then((module) => module.default)
diff --git a/lib/execGit.js b/lib/execGit.js
index 432a290..e2f79c6 100644
--- a/lib/execGit.js
+++ b/lib/execGit.js
@@ -1,5 +1,5 @@
 import debug from 'debug'
-import execa from 'execa'
+import { execa } from 'execa'
 
 const debugLog = debug('lint-staged:execGit')
 
diff --git a/lib/file.js b/lib/file.js
index 3f88414..2d871fa 100644
--- a/lib/file.js
+++ b/lib/file.js
@@ -1,4 +1,4 @@
-import { promises as fs } from 'fs'
+import fs from 'node:fs/promises'
 
 import debug from 'debug'
 
diff --git a/lib/generateTasks.js b/lib/generateTasks.js
index 99e3e91..b05d625 100644
--- a/lib/generateTasks.js
+++ b/lib/generateTasks.js
@@ -1,4 +1,4 @@
-import path from 'path'
+import path from 'node:path'
 
 import debug from 'debug'
 import micromatch from 'micromatch'
diff --git a/lib/getStagedFiles.js b/lib/getStagedFiles.js
index 08f7723..b301d42 100644
--- a/lib/getStagedFiles.js
+++ b/lib/getStagedFiles.js
@@ -1,4 +1,4 @@
-import path from 'path'
+import path from 'node:path'
 
 import normalize from 'normalize-path'
 
diff --git a/lib/gitWorkflow.js b/lib/gitWorkflow.js
index a2f8423..8ae95e7 100644
--- a/lib/gitWorkflow.js
+++ b/lib/gitWorkflow.js
@@ -1,4 +1,4 @@
-import path from 'path'
+import path from 'node:path'
 
 import debug from 'debug'
 
diff --git a/lib/groupFilesByConfig.js b/lib/groupFilesByConfig.js
index ee5c67a..e6e90e7 100644
--- a/lib/groupFilesByConfig.js
+++ b/lib/groupFilesByConfig.js
@@ -1,4 +1,4 @@
-import path from 'path'
+import path from 'node:path'
 
 import debug from 'debug'
 
diff --git a/lib/index.js b/lib/index.js
index 2e250fe..85420f5 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -109,7 +109,7 @@ const lintStaged = async (
     printTaskOutput(ctx, logger)
     return true
   } catch (runAllError) {
-    if (runAllError && runAllError.ctx && runAllError.ctx.errors) {
+    if (runAllError?.ctx?.errors) {
       const { ctx } = runAllError
 
       if (ctx.errors.has(ConfigNotFoundError)) {
diff --git a/lib/printTaskOutput.js b/lib/printTaskOutput.js
index 831f8fd..e3a4845 100644
--- a/lib/printTaskOutput.js
+++ b/lib/printTaskOutput.js
@@ -5,7 +5,7 @@
  */
 export const printTaskOutput = (ctx = {}, logger) => {
   if (!Array.isArray(ctx.output)) return
-  const log = ctx.errors && ctx.errors.size > 0 ? logger.error : logger.log
+  const log = ctx.errors?.size > 0 ? logger.error : logger.log
   for (const line of ctx.output) {
     log(line)
   }
diff --git a/lib/resolveConfig.js b/lib/resolveConfig.js
index 0b9f357..cb4ab0b 100644
--- a/lib/resolveConfig.js
+++ b/lib/resolveConfig.js
@@ -1,4 +1,4 @@
-import { createRequire } from 'module'
+import { createRequire } from 'node:module'
 
 /**
  * require() does not exist for ESM, so we must create it to use require.resolve().
diff --git a/lib/resolveGitRepo.js b/lib/resolveGitRepo.js
index 3e74603..f015705 100644
--- a/lib/resolveGitRepo.js
+++ b/lib/resolveGitRepo.js
@@ -1,5 +1,5 @@
-import { promises as fs } from 'fs'
-import path from 'path'
+import fs from 'node:fs/promises'
+import path from 'node:path'
 
 import debug from 'debug'
 import normalize from 'normalize-path'
diff --git a/lib/resolveTaskFn.js b/lib/resolveTaskFn.js
index 77a4ab7..45f16b5 100644
--- a/lib/resolveTaskFn.js
+++ b/lib/resolveTaskFn.js
@@ -1,5 +1,5 @@
 import { redBright, dim } from 'colorette'
-import execa from 'execa'
+import { execa, execaCommand } from 'execa'
 import debug from 'debug'
 import { parseArgsStringToArgv } from 'string-argv'
 import pidTree from 'pidtree'
@@ -139,7 +139,7 @@ export const resolveTaskFn = ({
 
   return async (ctx = getInitialState()) => {
     const execaChildProcess = shell
-      ? execa.command(isFn ? command : `${command} ${files.join(' ')}`, execaOptions)
+      ? execaCommand(isFn ? command : `${command} ${files.join(' ')}`, execaOptions)
       : execa(cmd, isFn ? args : args.concat(files), execaOptions)
 
     const quitInterruptCheck = interruptExecutionOnError(ctx, execaChildProcess)
diff --git a/lib/runAll.js b/lib/runAll.js
index 08f06d1..63b68a1 100644
--- a/lib/runAll.js
+++ b/lib/runAll.js
@@ -1,6 +1,6 @@
 /** @typedef {import('./index').Logger} Logger */
 
-import path from 'path'
+import path from 'node:path'
 
 import { dim } from 'colorette'
 import debug from 'debug'
diff --git a/lib/searchConfigs.js b/lib/searchConfigs.js
index 02fc3a5..dce5b0d 100644
--- a/lib/searchConfigs.js
+++ b/lib/searchConfigs.js
@@ -1,6 +1,6 @@
 /** @typedef {import('./index').Logger} Logger */
 
-import { basename, join } from 'path'
+import path from 'node:path'
 
 import debug from 'debug'
 import normalize from 'normalize-path'
@@ -15,7 +15,7 @@ const debugLog = debug('lint-staged:searchConfigs')
 const EXEC_GIT = ['ls-files', '-z', '--full-name']
 
 const filterPossibleConfigFiles = (files) =>
-  files.filter((file) => searchPlaces.includes(basename(file)))
+  files.filter((file) => searchPlaces.includes(path.basename(file)))
 
 const numberOfLevels = (file) => file.split('/').length
 
@@ -68,7 +68,7 @@ export const searchConfigs = async (
 
   /** Sort possible config files so that deepest is first */
   const possibleConfigFiles = [...cachedFiles, ...otherFiles]
-    .map((file) => normalize(join(gitDir, file)))
+    .map((file) => normalize(path.join(gitDir, file)))
     .filter(isInsideDirectory(cwd))
     .sort(sortDeepestParth)
 
diff --git a/lib/validateOptions.js b/lib/validateOptions.js
index 78b4c01..a97e60c 100644
--- a/lib/validateOptions.js
+++ b/lib/validateOptions.js
@@ -1,5 +1,6 @@
-import { constants, promises as fs } from 'fs'
-import path from 'path'
+import { constants } from 'node:fs'
+import fs from 'node:fs/promises'
+import path from 'node:path'
 
 import debug from 'debug'
 
diff --git a/package-lock.json b/package-lock.json
index e50e5a2..6859c49 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,7 +13,7 @@
         "colorette": "^2.0.16",
         "commander": "^9.3.0",
         "debug": "^4.3.4",
-        "execa": "^5.1.1",
+        "execa": "^6.1.0",
         "lilconfig": "2.0.5",
         "listr2": "^4.0.5",
         "micromatch": "^4.0.5",
@@ -21,8 +21,7 @@
         "object-inspect": "^1.12.2",
         "pidtree": "^0.5.0",
         "string-argv": "^0.3.1",
-        "supports-color": "^9.2.2",
-        "yaml": "^1.10.2"
+        "yaml": "^2.1.1"
       },
       "bin": {
         "lint-staged": "bin/lint-staged.js"
@@ -46,7 +45,7 @@
         "prettier": "^2.6.2"
       },
       "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+        "node": "^14.13.1 || >=16.0.0"
       },
       "funding": {
         "url": "https://opencollective.com/lint-staged"
@@ -4094,27 +4093,52 @@
       }
     },
     "node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz",
+      "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==",
       "dependencies": {
         "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
+        "get-stream": "^6.0.1",
+        "human-signals": "^3.0.1",
+        "is-stream": "^3.0.0",
         "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
+        "npm-run-path": "^5.1.0",
+        "onetime": "^6.0.0",
+        "signal-exit": "^3.0.7",
+        "strip-final-newline": "^3.0.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
       "funding": {
         "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
+    "node_modules/execa/node_modules/mimic-fn": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+      "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/execa/node_modules/onetime": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+      "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+      "dependencies": {
+        "mimic-fn": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/exit": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
@@ -4483,11 +4507,11 @@
       "dev": true
     },
     "node_modules/human-signals": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
-      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz",
+      "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==",
       "engines": {
-        "node": ">=10.17.0"
+        "node": ">=12.20.0"
       }
     },
     "node_modules/husky": {
@@ -4834,11 +4858,11 @@
       }
     },
     "node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
       "engines": {
-        "node": ">=8"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
@@ -5019,6 +5043,71 @@
         "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
       }
     },
+    "node_modules/jest-changed-files/node_modules/execa": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^6.0.0",
+        "human-signals": "^2.1.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+      }
+    },
+    "node_modules/jest-changed-files/node_modules/human-signals": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.17.0"
+      }
+    },
+    "node_modules/jest-changed-files/node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/jest-changed-files/node_modules/npm-run-path": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/jest-changed-files/node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/jest-circus": {
       "version": "28.1.0",
       "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz",
@@ -6005,6 +6094,71 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "node_modules/jest-runtime/node_modules/execa": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^6.0.0",
+        "human-signals": "^2.1.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/human-signals": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.17.0"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/npm-run-path": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/jest-runtime/node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/jest-runtime/node_modules/supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -6894,14 +7048,28 @@
       }
     },
     "node_modules/npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
+      "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
       "dependencies": {
-        "path-key": "^3.0.0"
+        "path-key": "^4.0.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/npm-run-path/node_modules/path-key": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+      "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/object-inspect": {
@@ -7713,11 +7881,14 @@
       }
     },
     "node_modules/strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
       "engines": {
-        "node": ">=6"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/strip-json-comments": {
@@ -7732,17 +7903,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/supports-color": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz",
-      "integrity": "sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/supports-color?sponsor=1"
-      }
-    },
     "node_modules/supports-hyperlinks": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
@@ -8171,11 +8331,11 @@
       "dev": true
     },
     "node_modules/yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
+      "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==",
       "engines": {
-        "node": ">= 6"
+        "node": ">= 14"
       }
     },
     "node_modules/yargs": {
@@ -11221,19 +11381,34 @@
       "dev": true
     },
     "execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz",
+      "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==",
       "requires": {
         "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
+        "get-stream": "^6.0.1",
+        "human-signals": "^3.0.1",
+        "is-stream": "^3.0.0",
         "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
+        "npm-run-path": "^5.1.0",
+        "onetime": "^6.0.0",
+        "signal-exit": "^3.0.7",
+        "strip-final-newline": "^3.0.0"
+      },
+      "dependencies": {
+        "mimic-fn": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+          "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="
+        },
+        "onetime": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+          "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+          "requires": {
+            "mimic-fn": "^4.0.0"
+          }
+        }
       }
     },
     "exit": {
@@ -11513,9 +11688,9 @@
       "dev": true
     },
     "human-signals": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
-      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz",
+      "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ=="
     },
     "husky": {
       "version": "8.0.1",
@@ -11748,9 +11923,9 @@
       }
     },
     "is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+      "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="
     },
     "is-string": {
       "version": "1.0.7",
@@ -11874,6 +12049,52 @@
       "requires": {
         "execa": "^5.0.0",
         "throat": "^6.0.1"
+      },
+      "dependencies": {
+        "execa": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+          "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.3",
+            "get-stream": "^6.0.0",
+            "human-signals": "^2.1.0",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.1",
+            "onetime": "^5.1.2",
+            "signal-exit": "^3.0.3",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "human-signals": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+          "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+          "dev": true
+        },
+        "is-stream": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+          "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "strip-final-newline": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+          "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+          "dev": true
+        }
       }
     },
     "jest-circus": {
@@ -12614,6 +12835,50 @@
           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
         },
+        "execa": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+          "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.3",
+            "get-stream": "^6.0.0",
+            "human-signals": "^2.1.0",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.1",
+            "onetime": "^5.1.2",
+            "signal-exit": "^3.0.3",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "human-signals": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+          "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+          "dev": true
+        },
+        "is-stream": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+          "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "strip-final-newline": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+          "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+          "dev": true
+        },
         "supports-color": {
           "version": "7.2.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -13289,11 +13554,18 @@
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
     },
     "npm-run-path": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
-      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
+      "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
       "requires": {
-        "path-key": "^3.0.0"
+        "path-key": "^4.0.0"
+      },
+      "dependencies": {
+        "path-key": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+          "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="
+        }
       }
     },
     "object-inspect": {
@@ -13880,9 +14152,9 @@
       "dev": true
     },
     "strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+      "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="
     },
     "strip-json-comments": {
       "version": "3.1.1",
@@ -13890,11 +14162,6 @@
       "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true
     },
-    "supports-color": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz",
-      "integrity": "sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA=="
-    },
     "supports-hyperlinks": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
@@ -14224,9 +14491,9 @@
       "dev": true
     },
     "yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz",
+      "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw=="
     },
     "yargs": {
       "version": "17.5.1",
diff --git a/package.json b/package.json
index 7483656..7ca78e3 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "url": "https://opencollective.com/lint-staged"
   },
   "engines": {
-    "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+    "node": "^14.13.1 || >=16.0.0"
   },
   "type": "module",
   "bin": "./bin/lint-staged.js",
@@ -36,7 +36,7 @@
     "colorette": "^2.0.16",
     "commander": "^9.3.0",
     "debug": "^4.3.4",
-    "execa": "^5.1.1",
+    "execa": "^6.1.0",
     "lilconfig": "2.0.5",
     "listr2": "^4.0.5",
     "micromatch": "^4.0.5",
@@ -44,8 +44,7 @@
     "object-inspect": "^1.12.2",
     "pidtree": "^0.5.0",
     "string-argv": "^0.3.1",
-    "supports-color": "^9.2.2",
-    "yaml": "^1.10.2"
+    "yaml": "^2.1.1"
   },
   "devDependencies": {
     "@babel/core": "^7.18.2",


Test patch:
diff --git a/test/__mocks__/execa.js b/test/__mocks__/execa.js
index 5d0d450..4534fd3 100644
--- a/test/__mocks__/execa.js
+++ b/test/__mocks__/execa.js
@@ -1,6 +1,6 @@
 import { createExecaReturnValue } from '../utils/createExecaReturnValue'
 
-const execa = jest.fn(() =>
+export const execa = jest.fn(() =>
   createExecaReturnValue({
     stdout: 'a-ok',
     stderr: '',
@@ -12,6 +12,4 @@ const execa = jest.fn(() =>
   })
 )
 
-execa.command = execa
-
-module.exports = execa
+export const execaCommand = execa
diff --git a/test/execGit.spec.js b/test/execGit.spec.js
index fec9351..17f9592 100644
--- a/test/execGit.spec.js
+++ b/test/execGit.spec.js
@@ -1,6 +1,6 @@
 import path from 'path'
 
-import execa from 'execa'
+import { execa } from 'execa'
 
 import { execGit, GIT_GLOBAL_OPTIONS } from '../lib/execGit'
 
diff --git a/test/loadConfig.spec.js b/test/loadConfig.spec.js
index 2a533a1..4488836 100644
--- a/test/loadConfig.spec.js
+++ b/test/loadConfig.spec.js
@@ -21,7 +21,7 @@ jest.unmock('execa')
  * This converts paths into `file://` urls, but this doesn't
  * work with `import()` when using babel + jest.
  */
-jest.mock('url', () => ({
+jest.mock('node:url', () => ({
   pathToFileURL: (path) => path,
 }))
 
diff --git a/test/makeCmdTasks.spec.js b/test/makeCmdTasks.spec.js
index 5d5e316..999052f 100644
--- a/test/makeCmdTasks.spec.js
+++ b/test/makeCmdTasks.spec.js
@@ -1,4 +1,4 @@
-import execa from 'execa'
+import { execa } from 'execa'
 
 import { makeCmdTasks } from '../lib/makeCmdTasks'
 
diff --git a/test/resolveTaskFn.spec.js b/test/resolveTaskFn.spec.js
index f46d579..c5bbb33 100644
--- a/test/resolveTaskFn.spec.js
+++ b/test/resolveTaskFn.spec.js
@@ -1,4 +1,4 @@
-import execa from 'execa'
+import { execa } from 'execa'
 import pidTree from 'pidtree'
 
 import { resolveTaskFn } from '../lib/resolveTaskFn'
diff --git a/test/runAll.spec.js b/test/runAll.spec.js
index 58a6cef..5c1e742 100644
--- a/test/runAll.spec.js
+++ b/test/runAll.spec.js
@@ -1,7 +1,7 @@
 import path from 'path'
 
 import makeConsoleMock from 'consolemock'
-import execa from 'execa'
+import { execa } from 'execa'
 import normalize from 'normalize-path'
 
 import { getStagedFiles } from '../lib/getStagedFiles'