Repository: eslint-community/eslint-plugin-promise
Pull request #441 (2023-04-26 21:05:06)

chore: add `format` workflow


Patch:
diff --git a/.eslint-doc-generatorrc.js b/.eslint-doc-generatorrc.js
new file mode 100644
index 0000000..0f204f5
--- /dev/null
+++ b/.eslint-doc-generatorrc.js
@@ -0,0 +1,10 @@
+/** @type {import('eslint-doc-generator').GenerateOptions} */
+module.exports = {
+  configEmoji: [
+    ['recommended', '✅'],
+    ['flat/recommended', '✅'],
+  ],
+  postprocess: (doc) => {
+    return doc.replace(/✅\s*✅/gu, '✅')
+  },
+}
diff --git a/.github/workflows/CI.yml b/.github/workflows/ci.yml
similarity index 85%
rename from .github/workflows/CI.yml
rename to .github/workflows/ci.yml
index 08b260c..614ba4f 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/ci.yml
@@ -21,10 +21,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: ⬇️ Checkout repo
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: ⎔ Setup Node
-        uses: actions/setup-node@v3
+        uses: actions/setup-node@v4
         with:
           node-version: 18
 
@@ -41,9 +41,13 @@ jobs:
     strategy:
       matrix:
         eslint: [8]
-        node: [12.22.0, 12, 14.17.0, 14, 16.0.0, 16, 18]
+        node: [12.22.0, 12, 14.17.0, 14, 16.0.0, 16, 18, 20]
         os: [ubuntu-latest]
         include:
+          # ESLint v9
+          - eslint: 9
+            node: 20
+            os: ubuntu-latest
           # On other platforms
           - os: windows-latest
             eslint: 8
@@ -62,10 +66,10 @@ jobs:
     runs-on: ${{ matrix.os }}
     steps:
       - name: ⬇️ Checkout repo
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: ⎔ Setup Node v${{ matrix.node }}
-        uses: actions/setup-node@v3
+        uses: actions/setup-node@v4
         with:
           cache: npm
           node-version: ${{ matrix.node }}
@@ -80,7 +84,7 @@ jobs:
         run: npm run test -- --runInBand
 
       - name: ⬆️ Upload coverage report
-        uses: codecov/codecov-action@v3
+        uses: codecov/codecov-action@v4
 
   release:
     name: 🚀 Release
@@ -92,10 +96,10 @@ jobs:
       github.ref) && github.event_name == 'push'
     steps:
       - name: ⬇️ Checkout repo
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: ⎔ Setup node
-        uses: actions/setup-node@v3
+        uses: actions/setup-node@v4
         with:
           node-version: 18
 
@@ -103,7 +107,7 @@ jobs:
         run: npm install
 
       - name: 🚀 Release
-        uses: cycjimmy/semantic-release-action@v3
+        uses: cycjimmy/semantic-release-action@v4
         with:
           semantic_version: 19
           branches: |
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
new file mode 100644
index 0000000..0578b54
--- /dev/null
+++ b/.github/workflows/format.yml
@@ -0,0 +1,44 @@
+name: 👔 Format
+
+on:
+  push:
+    branches:
+      - main
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  format:
+    if: github.repository == 'eslint-community/eslint-plugin/promise'
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: ⬇️ Checkout repo
+        uses: actions/checkout@v3
+
+      - name: ⎔ Setup node
+        uses: actions/setup-node@v3
+        with:
+          node-version: 18
+
+      - name: 📥 Install deps
+        run: npm install
+
+      - name: 👔 Format
+        run: npm run format
+
+      - name: 💪 Commit
+        run: |
+          git config --local user.email "github-actions[bot]@users.noreply.github.com"
+          git config --local user.name "github-actions[bot]"
+
+          git add .
+          if [ -z "$(git status --porcelain)" ]; then
+            echo "💿 no formatting changed"
+            exit 0
+          fi
+          git commit -m "chore: format"
+          git push
+          echo "💿 pushed formatting changes https://github.com/$GITHUB_REPOSITORY/commit/$(git rev-parse HEAD)"
diff --git a/README.md b/README.md
index 30a82e7..44a38b1 100644
--- a/README.md
+++ b/README.md
@@ -61,18 +61,31 @@ Then configure the rules you want to use under the rules section.
     "promise/avoid-new": "warn",
     "promise/no-new-statics": "error",
     "promise/no-return-in-finally": "warn",
-    "promise/valid-params": "warn"
+    "promise/valid-params": "warn",
+    "promise/no-multiple-resolved": "error"
   }
 }
 ```
 
 or start with the recommended rule set:
 
-```json
-{
-  "extends": ["plugin:promise/recommended"]
-}
-```
+- `eslint.config.js`:
+
+  ```js
+  import pluginPromise from 'eslint-plugin-promise'
+  export default [
+    // ...
+    pluginPromise.configs['flat/recommended'],
+  ]
+  ```
+
+- `.eslintrc.*`:
+
+  ```json
+  {
+    "extends": ["plugin:promise/recommended"]
+  }
+  ```
 
 ## Rules
 
@@ -81,9 +94,9 @@ or start with the recommended rule set:
 💼 Configurations enabled in.\
 ⚠️ Configurations set to warn in.\
 🚫 Configurations disabled in.\
+✅ Set in the `flat/recommended` configuration.\
 ✅ Set in the `recommended` configuration.\
-🔧 Automatically fixable by the
-[`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
+🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
 
 | Name                                                                 | Description                                                                            | 💼  | ⚠️  | 🚫  | 🔧  |
 | :------------------------------------------------------------------- | :------------------------------------------------------------------------------------- | :-- | :-- | :-- | :-- |
diff --git a/docs/rules/always-return.md b/docs/rules/always-return.md
index 52bfda7..d778771 100644
--- a/docs/rules/always-return.md
+++ b/docs/rules/always-return.md
@@ -1,6 +1,7 @@
 # Require returning inside each `then()` to create readable and reusable Promise chains (`promise/always-return`)
 
-💼 This rule is enabled in the ✅ `recommended` config.
+💼 This rule is enabled in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/avoid-new.md b/docs/rules/avoid-new.md
index a62f6ba..a03c6a1 100644
--- a/docs/rules/avoid-new.md
+++ b/docs/rules/avoid-new.md
@@ -1,6 +1,7 @@
 # Disallow creating `new` promises outside of utility libs (use [pify][] instead) (`promise/avoid-new`)
 
-🚫 This rule is _disabled_ in the ✅ `recommended` config.
+🚫 This rule is _disabled_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/catch-or-return.md b/docs/rules/catch-or-return.md
index 0019adb..1833ca5 100644
--- a/docs/rules/catch-or-return.md
+++ b/docs/rules/catch-or-return.md
@@ -1,6 +1,7 @@
 # Enforce the use of `catch()` on un-returned promises (`promise/catch-or-return`)
 
-💼 This rule is enabled in the ✅ `recommended` config.
+💼 This rule is enabled in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/no-callback-in-promise.md b/docs/rules/no-callback-in-promise.md
index 8ae3ac5..0188b1a 100644
--- a/docs/rules/no-callback-in-promise.md
+++ b/docs/rules/no-callback-in-promise.md
@@ -1,6 +1,7 @@
 # Disallow calling `cb()` inside of a `then()` (use [nodeify][] instead) (`promise/no-callback-in-promise`)
 
-⚠️ This rule _warns_ in the ✅ `recommended` config.
+⚠️ This rule _warns_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/no-native.md b/docs/rules/no-native.md
index d2d1c30..fff32d9 100644
--- a/docs/rules/no-native.md
+++ b/docs/rules/no-native.md
@@ -1,6 +1,7 @@
 # Require creating a `Promise` constructor before using it in an ES5 environment (`promise/no-native`)
 
-🚫 This rule is _disabled_ in the ✅ `recommended` config.
+🚫 This rule is _disabled_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/no-nesting.md b/docs/rules/no-nesting.md
index 311d81a..bc7d816 100644
--- a/docs/rules/no-nesting.md
+++ b/docs/rules/no-nesting.md
@@ -1,6 +1,7 @@
 # Disallow nested `then()` or `catch()` statements (`promise/no-nesting`)
 
-⚠️ This rule _warns_ in the ✅ `recommended` config.
+⚠️ This rule _warns_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/no-new-statics.md b/docs/rules/no-new-statics.md
index ea1aa47..2e5a383 100644
--- a/docs/rules/no-new-statics.md
+++ b/docs/rules/no-new-statics.md
@@ -1,6 +1,7 @@
 # Disallow calling `new` on a Promise static method (`promise/no-new-statics`)
 
-💼 This rule is enabled in the ✅ `recommended` config.
+💼 This rule is enabled in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 🔧 This rule is automatically fixable by the
 [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
diff --git a/docs/rules/no-promise-in-callback.md b/docs/rules/no-promise-in-callback.md
index 72cc89f..54f0e02 100644
--- a/docs/rules/no-promise-in-callback.md
+++ b/docs/rules/no-promise-in-callback.md
@@ -1,5 +1,6 @@
 # Disallow using promises inside of callbacks (`promise/no-promise-in-callback`)
 
-⚠️ This rule _warns_ in the ✅ `recommended` config.
+⚠️ This rule _warns_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
diff --git a/docs/rules/no-return-in-finally.md b/docs/rules/no-return-in-finally.md
index de0364e..864bdb1 100644
--- a/docs/rules/no-return-in-finally.md
+++ b/docs/rules/no-return-in-finally.md
@@ -1,6 +1,7 @@
 # Disallow return statements in `finally()` (`promise/no-return-in-finally`)
 
-⚠️ This rule _warns_ in the ✅ `recommended` config.
+⚠️ This rule _warns_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/no-return-wrap.md b/docs/rules/no-return-wrap.md
index 7be071d..0e98089 100644
--- a/docs/rules/no-return-wrap.md
+++ b/docs/rules/no-return-wrap.md
@@ -1,6 +1,7 @@
 # Disallow wrapping values in `Promise.resolve` or `Promise.reject` when not needed (`promise/no-return-wrap`)
 
-💼 This rule is enabled in the ✅ `recommended` config.
+💼 This rule is enabled in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/param-names.md b/docs/rules/param-names.md
index cc76a97..9a71e54 100644
--- a/docs/rules/param-names.md
+++ b/docs/rules/param-names.md
@@ -1,6 +1,7 @@
 # Enforce consistent param names and ordering when creating new promises (`promise/param-names`)
 
-💼 This rule is enabled in the ✅ `recommended` config.
+💼 This rule is enabled in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/docs/rules/valid-params.md b/docs/rules/valid-params.md
index bdaae97..f238771 100644
--- a/docs/rules/valid-params.md
+++ b/docs/rules/valid-params.md
@@ -1,6 +1,7 @@
 # Enforces the proper number of arguments are passed to Promise functions (`promise/valid-params`)
 
-⚠️ This rule _warns_ in the ✅ `recommended` config.
+⚠️ This rule _warns_ in the following configs: ✅ `flat/recommended`, ✅
+`recommended`.
 
 <!-- end auto-generated rule header -->
 
diff --git a/index.js b/index.js
index 40b8105..e554a3c 100644
--- a/index.js
+++ b/index.js
@@ -1,6 +1,21 @@
 'use strict'
 
-module.exports = {
+const recommendedRules = {
+  'promise/always-return': 'error',
+  'promise/no-return-wrap': 'error',
+  'promise/param-names': 'error',
+  'promise/catch-or-return': 'error',
+  'promise/no-native': 'off',
+  'promise/no-nesting': 'warn',
+  'promise/no-promise-in-callback': 'warn',
+  'promise/no-callback-in-promise': 'warn',
+  'promise/avoid-new': 'off',
+  'promise/no-new-statics': 'error',
+  'promise/no-return-in-finally': 'warn',
+  'promise/valid-params': 'warn',
+}
+
+const pluginPromise = {
   rules: {
     'param-names': require('./rules/param-names'),
     'no-return-wrap': require('./rules/no-return-wrap'),
@@ -25,23 +40,15 @@ module.exports = {
     'no-native': 0,
     'catch-or-return': 1,
   },
-  configs: {
-    recommended: {
-      plugins: ['promise'],
-      rules: {
-        'promise/always-return': 'error',
-        'promise/no-return-wrap': 'error',
-        'promise/param-names': 'error',
-        'promise/catch-or-return': 'error',
-        'promise/no-native': 'off',
-        'promise/no-nesting': 'warn',
-        'promise/no-promise-in-callback': 'warn',
-        'promise/no-callback-in-promise': 'warn',
-        'promise/avoid-new': 'off',
-        'promise/no-new-statics': 'error',
-        'promise/no-return-in-finally': 'warn',
-        'promise/valid-params': 'warn',
-      },
-    },
+}
+pluginPromise.configs = {
+  recommended: {
+    plugins: ['promise'],
+    rules: recommendedRules,
+  },
+  'flat/recommended': {
+    plugins: { promise: pluginPromise },
+    rules: recommendedRules,
   },
 }
+module.exports = pluginPromise
diff --git a/package-lock.json b/package-lock.json
index d5158e1..25569e2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,11 +13,12 @@
         "doctoc": "^2.2.1",
         "eslint": "^8.28.0",
         "eslint-config-prettier": "^8.5.0",
-        "eslint-doc-generator": "^0.25.0",
+        "eslint-doc-generator": "^1.7.1",
         "eslint-plugin-eslint-plugin": "^4.4.1",
         "eslint-plugin-jest": "^26.9.0",
         "eslint-plugin-node": "^11.1.0",
         "eslint-plugin-prettier": "^4.2.1",
+        "globals": "^14.0.0",
         "husky": "^7.0.4",
         "jest": "^28.1.3",
         "lint-staged": "^12.5.0",
@@ -28,8 +29,11 @@
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      },
       "peerDependencies": {
-        "eslint": "^7.0.0 || ^8.0.0"
+        "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
       }
     },
     "node_modules/@ampproject/remapping": {
@@ -46,12 +50,13 @@
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
-      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+      "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.18.6"
+        "@babel/highlight": "^7.24.2",
+        "picocolors": "^1.0.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -106,13 +111,14 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.19.0",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
-      "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==",
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz",
+      "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.19.0",
-        "@jridgewell/gen-mapping": "^0.3.2",
+        "@babel/types": "^7.24.0",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
         "jsesc": "^2.5.1"
       },
       "engines": {
@@ -120,14 +126,14 @@
       }
     },
     "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
-      "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/set-array": "^1.2.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/trace-mapping": "^0.3.24"
       },
       "engines": {
         "node": ">=6.0.0"
@@ -161,34 +167,34 @@
       }
     },
     "node_modules/@babel/helper-environment-visitor": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
-      "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-function-name": {
-      "version": "7.19.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
-      "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+      "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
       "dev": true,
       "dependencies": {
-        "@babel/template": "^7.18.10",
-        "@babel/types": "^7.19.0"
+        "@babel/template": "^7.22.15",
+        "@babel/types": "^7.23.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-hoist-variables": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
-      "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+      "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.18.6"
+        "@babel/types": "^7.22.5"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -247,30 +253,30 @@
       }
     },
     "node_modules/@babel/helper-split-export-declaration": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
-      "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+      "version": "7.22.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+      "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.18.6"
+        "@babel/types": "^7.22.5"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.18.10",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
-      "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+      "version": "7.24.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+      "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
-      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -300,14 +306,15 @@
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
-      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+      "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.18.6",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
+        "@babel/helper-validator-identifier": "^7.22.20",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -385,9 +392,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz",
-      "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==",
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
+      "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -559,34 +566,34 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.18.10",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
-      "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+      "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.18.6",
-        "@babel/parser": "^7.18.10",
-        "@babel/types": "^7.18.10"
+        "@babel/code-frame": "^7.23.5",
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz",
-      "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==",
-      "dev": true,
-      "dependencies": {
-        "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.19.0",
-        "@babel/helper-environment-visitor": "^7.18.9",
-        "@babel/helper-function-name": "^7.19.0",
-        "@babel/helper-hoist-variables": "^7.18.6",
-        "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.19.1",
-        "@babel/types": "^7.19.0",
-        "debug": "^4.1.0",
+      "version": "7.24.1",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz",
+      "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.24.1",
+        "@babel/generator": "^7.24.1",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
+        "@babel/helper-hoist-variables": "^7.22.5",
+        "@babel/helper-split-export-declaration": "^7.22.6",
+        "@babel/parser": "^7.24.1",
+        "@babel/types": "^7.24.0",
+        "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
       "engines": {
@@ -603,13 +610,13 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.19.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz",
-      "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+      "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-string-parser": "^7.18.10",
-        "@babel/helper-validator-identifier": "^7.18.6",
+        "@babel/helper-string-parser": "^7.23.4",
+        "@babel/helper-validator-identifier": "^7.22.20",
         "to-fast-properties": "^2.0.0"
       },
       "engines": {
@@ -645,6 +652,21 @@
         "url": "https://opencollective.com/eslint"
       }
     },
+    "node_modules/@eslint/eslintrc/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/@humanwhocodes/config-array": {
       "version": "0.11.6",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz",
@@ -1088,9 +1110,9 @@
       }
     },
     "node_modules/@jridgewell/set-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
-      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
       "dev": true,
       "engines": {
         "node": ">=6.0.0"
@@ -1103,13 +1125,13 @@
       "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.15",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
-      "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
     "node_modules/@nodelib/fs.scandir": {
@@ -1289,12 +1311,6 @@
       "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==",
       "dev": true
     },
-    "node_modules/@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
-      "dev": true
-    },
     "node_modules/@types/prettier": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
@@ -1811,6 +1827,12 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "node_modules/boolean": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
+      "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
+      "dev": true
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1822,12 +1844,12 @@
       }
     },
     "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
       "dev": true,
       "dependencies": {
-        "fill-range": "^7.0.1"
+        "fill-range": "^7.1.1"
       },
       "engines": {
         "node": ">=8"
@@ -2141,22 +2163,6 @@
         "safe-buffer": "~5.1.1"
       }
     },
-    "node_modules/cosmiconfig": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
-      "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
-      "dev": true,
-      "dependencies": {
-        "@types/parse-json": "^4.0.0",
-        "import-fresh": "^3.2.1",
-        "parse-json": "^5.0.0",
-        "path-type": "^4.0.0",
-        "yaml": "^1.10.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -2348,6 +2354,33 @@
         "url": "https://github.com/fb55/domutils?sponsor=1"
       }
     },
+    "node_modules/dot-prop": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-7.2.0.tgz",
+      "integrity": "sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^2.11.2"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/dot-prop/node_modules/type-fest": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+      "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/eastasianwidth": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -2544,19 +2577,22 @@
       }
     },
     "node_modules/eslint-doc-generator": {
-      "version": "0.25.0",
-      "resolved": "https://registry.npmjs.org/eslint-doc-generator/-/eslint-doc-generator-0.25.0.tgz",
-      "integrity": "sha512-zNzxaQ63uEZc5snwhBD+TrskVfvOi5UYGlWAFKbYdGG9G+8MZKXkaGdPVcT8cdvTWBLyxT2ovJxY+PEhwIRBEA==",
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-doc-generator/-/eslint-doc-generator-1.7.1.tgz",
+      "integrity": "sha512-i1Zjl+Xcy712SZhbceCeMVaIdhbFqY27i8d7f9gyb9P/6AQNnPA0VCWynAFVGYa0hpeR5kwUI09+GBELgC2nnA==",
       "dev": true,
       "dependencies": {
         "@typescript-eslint/utils": "^5.38.1",
         "ajv": "^8.11.2",
-        "camelcase": "^7.0.0",
-        "commander": "^9.4.0",
-        "cosmiconfig": "^7.1.0",
+        "boolean": "^3.2.0",
+        "commander": "^10.0.0",
+        "cosmiconfig": "^8.0.0",
         "deepmerge": "^4.2.2",
+        "dot-prop": "^7.2.0",
         "jest-diff": "^29.2.1",
-        "markdown-table": "^3.0.2",
+        "json-schema-traverse": "^1.0.0",
+        "markdown-table": "^3.0.3",
+        "no-case": "^3.0.4",
         "type-fest": "^3.0.0"
       },
       "bin": {
@@ -2609,16 +2645,39 @@
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/eslint-doc-generator/node_modules/camelcase": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.0.tgz",
-      "integrity": "sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ==",
+    "node_modules/eslint-doc-generator/node_modules/commander": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+      "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
       "dev": true,
       "engines": {
-        "node": ">=14.16"
+        "node": ">=14"
+      }
+    },
+    "node_modules/eslint-doc-generator/node_modules/cosmiconfig": {
+      "version": "8.3.6",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+      "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+      "dev": true,
+      "dependencies": {
+        "import-fresh": "^3.3.0",
+        "js-yaml": "^4.1.0",
+        "parse-json": "^5.2.0",
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=14"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/sponsors/d-fischer"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.9.5"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
       }
     },
     "node_modules/eslint-doc-generator/node_modules/diff-sequences": {
@@ -2661,9 +2720,9 @@
       "dev": true
     },
     "node_modules/eslint-doc-generator/node_modules/markdown-table": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz",
-      "integrity": "sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
+      "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==",
       "dev": true,
       "funding": {
         "type": "github",
@@ -2696,6 +2755,21 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/eslint-doc-generator/node_modules/typescript": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
+      "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
     "node_modules/eslint-plugin-es": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
@@ -2902,6 +2976,21 @@
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
+    "node_modules/eslint/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/espree": {
       "version": "9.4.0",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
@@ -3124,9 +3213,9 @@
       }
     },
     "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
       "dev": true,
       "dependencies": {
         "to-regex-range": "^5.0.1"
@@ -3334,15 +3423,12 @@
       }
     },
     "node_modules/globals": {
-      "version": "13.17.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+      "version": "14.0.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
       "dev": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
       "engines": {
-        "node": ">=8"
+        "node": ">=18"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
@@ -4943,6 +5029,15 @@
         "url": "https://github.com/sponsors/wooorm"
       }
     },
+    "node_modules/lower-case": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+      "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^2.0.3"
+      }
+    },
     "node_modules/lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -5368,6 +5463,16 @@
       "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
       "dev": true
     },
+    "node_modules/no-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+      "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+      "dev": true,
+      "dependencies": {
+        "lower-case": "^2.0.2",
+        "tslib": "^2.0.3"
+      }
+    },
     "node_modules/node-int64": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -7270,12 +7375,13 @@
       }
     },
     "@babel/code-frame": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
-      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+      "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
       "dev": true,
       "requires": {
-        "@babel/highlight": "^7.18.6"
+        "@babel/highlight": "^7.24.2",
+        "picocolors": "^1.0.0"
       }
     },
     "@babel/compat-data": {
@@ -7316,25 +7422,26 @@
       }
     },
     "@babel/generator": {
-      "version": "7.19.0",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
-      "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==",
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz",
+      "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.19.0",
-        "@jridgewell/gen-mapping": "^0.3.2",
+        "@babel/types": "^7.24.0",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
         "jsesc": "^2.5.1"
       },
       "dependencies": {
         "@jridgewell/gen-mapping": {
-          "version": "0.3.2",
-          "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
-          "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+          "version": "0.3.5",
+          "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+          "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
           "dev": true,
           "requires": {
-            "@jridgewell/set-array": "^1.0.1",
+            "@jridgewell/set-array": "^1.2.1",
             "@jridgewell/sourcemap-codec": "^1.4.10",
-            "@jridgewell/trace-mapping": "^0.3.9"
+            "@jridgewell/trace-mapping": "^0.3.24"
           }
         }
       }
@@ -7360,28 +7467,28 @@
       }
     },
     "@babel/helper-environment-visitor": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
-      "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
       "dev": true
     },
     "@babel/helper-function-name": {
-      "version": "7.19.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
-      "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+      "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
       "dev": true,
       "requires": {
-        "@babel/template": "^7.18.10",
-        "@babel/types": "^7.19.0"
+        "@babel/template": "^7.22.15",
+        "@babel/types": "^7.23.0"
       }
     },
     "@babel/helper-hoist-variables": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
-      "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+      "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.18.6"
+        "@babel/types": "^7.22.5"
       }
     },
     "@babel/helper-module-imports": {
@@ -7425,24 +7532,24 @@
       }
     },
     "@babel/helper-split-export-declaration": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
-      "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+      "version": "7.22.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+      "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.18.6"
+        "@babel/types": "^7.22.5"
       }
     },
     "@babel/helper-string-parser": {
-      "version": "7.18.10",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
-      "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+      "version": "7.24.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+      "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
       "dev": true
     },
     "@babel/helper-validator-identifier": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
-      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
       "dev": true
     },
     "@babel/helper-validator-option": {
@@ -7463,14 +7570,15 @@
       }
     },
     "@babel/highlight": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
-      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+      "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.18.6",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
+        "@babel/helper-validator-identifier": "^7.22.20",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
       },
       "dependencies": {
         "ansi-styles": {
@@ -7532,9 +7640,9 @@
       }
     },
     "@babel/parser": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz",
-      "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==",
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
+      "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
       "dev": true
     },
     "@babel/plugin-syntax-async-generators": {
@@ -7655,31 +7763,31 @@
       }
     },
     "@babel/template": {
-      "version": "7.18.10",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
-      "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+      "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.18.6",
-        "@babel/parser": "^7.18.10",
-        "@babel/types": "^7.18.10"
+        "@babel/code-frame": "^7.23.5",
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0"
       }
     },
     "@babel/traverse": {
-      "version": "7.19.1",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz",
-      "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.19.0",
-        "@babel/helper-environment-visitor": "^7.18.9",
-        "@babel/helper-function-name": "^7.19.0",
-        "@babel/helper-hoist-variables": "^7.18.6",
-        "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.19.1",
-        "@babel/types": "^7.19.0",
-        "debug": "^4.1.0",
+      "version": "7.24.1",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz",
+      "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.24.1",
+        "@babel/generator": "^7.24.1",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
+        "@babel/helper-hoist-variables": "^7.22.5",
+        "@babel/helper-split-export-declaration": "^7.22.6",
+        "@babel/parser": "^7.24.1",
+        "@babel/types": "^7.24.0",
+        "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
       "dependencies": {
@@ -7692,13 +7800,13 @@
       }
     },
     "@babel/types": {
-      "version": "7.19.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz",
-      "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+      "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
       "dev": true,
       "requires": {
-        "@babel/helper-string-parser": "^7.18.10",
-        "@babel/helper-validator-identifier": "^7.18.6",
+        "@babel/helper-string-parser": "^7.23.4",
+        "@babel/helper-validator-identifier": "^7.22.20",
         "to-fast-properties": "^2.0.0"
       }
     },
@@ -7723,6 +7831,17 @@
         "js-yaml": "^4.1.0",
         "minimatch": "^3.1.2",
         "strip-json-comments": "^3.1.1"
+      },
+      "dependencies": {
+        "globals": {
+          "version": "13.24.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+          "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.20.2"
+          }
+        }
       }
     },
     "@humanwhocodes/config-array": {
@@ -8069,9 +8188,9 @@
       "dev": true
     },
     "@jridgewell/set-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
-      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
       "dev": true
     },
     "@jridgewell/sourcemap-codec": {
@@ -8081,13 +8200,13 @@
       "dev": true
     },
     "@jridgewell/trace-mapping": {
-      "version": "0.3.15",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
-      "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "requires": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
     "@nodelib/fs.scandir": {
@@ -8258,12 +8377,6 @@
       "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==",
       "dev": true
     },
-    "@types/parse-json": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
-      "dev": true
-    },
     "@types/prettier": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
@@ -8619,6 +8732,12 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "boolean": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
+      "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
+      "dev": true
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -8630,12 +8749,12 @@
       }
     },
     "braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
       "dev": true,
       "requires": {
-        "fill-range": "^7.0.1"
+        "fill-range": "^7.1.1"
       }
     },
     "browserslist": {
@@ -8860,19 +8979,6 @@
         "safe-buffer": "~5.1.1"
       }
     },
-    "cosmiconfig": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
-      "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
-      "dev": true,
-      "requires": {
-        "@types/parse-json": "^4.0.0",
-        "import-fresh": "^3.2.1",
-        "parse-json": "^5.0.0",
-        "path-type": "^4.0.0",
-        "yaml": "^1.10.0"
-      }
-    },
     "cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -9010,6 +9116,23 @@
         "domhandler": "^4.2.0"
       }
     },
+    "dot-prop": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-7.2.0.tgz",
+      "integrity": "sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==",
+      "dev": true,
+      "requires": {
+        "type-fest": "^2.11.2"
+      },
+      "dependencies": {
+        "type-fest": {
+          "version": "2.19.0",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+          "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+          "dev": true
+        }
+      }
+    },
     "eastasianwidth": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -9149,6 +9272,17 @@
         "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
         "text-table": "^0.2.0"
+      },
+      "dependencies": {
+        "globals": {
+          "version": "13.24.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+          "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.20.2"
+          }
+        }
       }
     },
     "eslint-config-prettier": {
@@ -9159,19 +9293,22 @@
       "requires": {}
     },
     "eslint-doc-generator": {
-      "version": "0.25.0",
-      "resolved": "https://registry.npmjs.org/eslint-doc-generator/-/eslint-doc-generator-0.25.0.tgz",
-      "integrity": "sha512-zNzxaQ63uEZc5snwhBD+TrskVfvOi5UYGlWAFKbYdGG9G+8MZKXkaGdPVcT8cdvTWBLyxT2ovJxY+PEhwIRBEA==",
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-doc-generator/-/eslint-doc-generator-1.7.1.tgz",
+      "integrity": "sha512-i1Zjl+Xcy712SZhbceCeMVaIdhbFqY27i8d7f9gyb9P/6AQNnPA0VCWynAFVGYa0hpeR5kwUI09+GBELgC2nnA==",
       "dev": true,
       "requires": {
         "@typescript-eslint/utils": "^5.38.1",
         "ajv": "^8.11.2",
-        "camelcase": "^7.0.0",
-        "commander": "^9.4.0",
-        "cosmiconfig": "^7.1.0",
+        "boolean": "^3.2.0",
+        "commander": "^10.0.0",
+        "cosmiconfig": "^8.0.0",
         "deepmerge": "^4.2.2",
+        "dot-prop": "^7.2.0",
         "jest-diff": "^29.2.1",
-        "markdown-table": "^3.0.2",
+        "json-schema-traverse": "^1.0.0",
+        "markdown-table": "^3.0.3",
+        "no-case": "^3.0.4",
         "type-fest": "^3.0.0"
       },
       "dependencies": {
@@ -9202,12 +9339,24 @@
           "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
           "dev": true
         },
-        "camelcase": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.0.tgz",
-          "integrity": "sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ==",
+        "commander": {
+          "version": "10.0.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+          "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
           "dev": true
         },
+        "cosmiconfig": {
+          "version": "8.3.6",
+          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+          "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+          "dev": true,
+          "requires": {
+            "import-fresh": "^3.3.0",
+            "js-yaml": "^4.1.0",
+            "parse-json": "^5.2.0",
+            "path-type": "^4.0.0"
+          }
+        },
         "diff-sequences": {
           "version": "29.2.0",
           "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.2.0.tgz",
@@ -9239,9 +9388,9 @@
           "dev": true
         },
         "markdown-table": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz",
-          "integrity": "sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==",
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
+          "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==",
           "dev": true
         },
         "pretty-format": {
@@ -9260,6 +9409,14 @@
           "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.1.0.tgz",
           "integrity": "sha512-StmrZmK3eD9mDF9Vt7UhqthrDSk66O9iYl5t5a0TSoVkHjl0XZx/xuc/BRz4urAXXGHOY5OLsE0RdJFIApSFmw==",
           "dev": true
+        },
+        "typescript": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
+          "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
@@ -9562,9 +9719,9 @@
       }
     },
     "fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
       "dev": true,
       "requires": {
         "to-regex-range": "^5.0.1"
@@ -9708,13 +9865,10 @@
       }
     },
     "globals": {
-      "version": "13.17.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
-      "dev": true,
-      "requires": {
-        "type-fest": "^0.20.2"
-      }
+      "version": "14.0.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+      "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+      "dev": true
     },
     "globby": {
       "version": "11.1.0",
@@ -10867,6 +11021,15 @@
       "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==",
       "dev": true
     },
+    "lower-case": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+      "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+      "dev": true,
+      "requires": {
+        "tslib": "^2.0.3"
+      }
+    },
     "lru-cache": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -11177,6 +11340,16 @@
       "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
       "dev": true
     },
+    "no-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+      "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+      "dev": true,
+      "requires": {
+        "lower-case": "^2.0.2",
+        "tslib": "^2.0.3"
+      }
+    },
     "node-int64": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
diff --git a/package.json b/package.json
index e9c2078..c332849 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,7 @@
     "Aadit M Shah <aaditmshah@aadit.codes> (https://aadit.codes/)"
   ],
   "scripts": {
-    "format": "prettier --write .",
+    "format": "prettier --write . && npm run lint -- --fix",
     "lint": "npm-run-all \"lint:*\"",
     "lint:eslint-docs": "npm run update:eslint-docs && git diff --exit-code",
     "lint:js": "eslint --report-unused-disable-directives .",
@@ -55,18 +55,27 @@
         "lines": 100,
         "statements": 100
       }
-    }
+    },
+    "collectCoverageFrom": [
+      "rules/*.js",
+      "rules/*/*.js",
+      "!rules/lib/eslint-compat.js"
+    ],
+    "testPathIgnorePatterns": [
+      "__tests__/rule-tester.js"
+    ]
   },
   "devDependencies": {
     "@typescript-eslint/parser": "^5.45.0",
     "doctoc": "^2.2.1",
     "eslint": "^8.28.0",
     "eslint-config-prettier": "^8.5.0",
-    "eslint-doc-generator": "^0.25.0",
+    "eslint-doc-generator": "^1.7.1",
     "eslint-plugin-eslint-plugin": "^4.4.1",
     "eslint-plugin-jest": "^26.9.0",
     "eslint-plugin-node": "^11.1.0",
     "eslint-plugin-prettier": "^4.2.1",
+    "globals": "^14.0.0",
     "husky": "^7.0.4",
     "jest": "^28.1.3",
     "lint-staged": "^12.5.0",
@@ -75,9 +84,10 @@
     "typescript": "^4.9.3"
   },
   "peerDependencies": {
-    "eslint": "^7.0.0 || ^8.0.0"
+    "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
   },
   "engines": {
     "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-  }
+  },
+  "funding": "https://opencollective.com/eslint"
 }
diff --git a/rules/always-return.js b/rules/always-return.js
index 5b48b25..57d497d 100644
--- a/rules/always-return.js
+++ b/rules/always-return.js
@@ -143,6 +143,9 @@ module.exports = {
         additionalProperties: false,
       },
     ],
+    messages: {
+      thenShouldReturnOrThrow: 'Each then() should return a value or throw',
+    },
   },
   create(context) {
     const options = context.options[0] || {}
@@ -242,7 +245,7 @@ module.exports = {
           const branch = funcInfo.branchInfoMap[id]
           if (!branch.good) {
             context.report({
-              message: 'Each then() should return a value or throw',
+              messageId: 'thenShouldReturnOrThrow',
               node: branch.node,
             })
           }
diff --git a/rules/avoid-new.js b/rules/avoid-new.js
index 7d4b93a..c5742ae 100644
--- a/rules/avoid-new.js
+++ b/rules/avoid-new.js
@@ -16,12 +16,15 @@ module.exports = {
       url: getDocsUrl('avoid-new'),
     },
     schema: [],
+    messages: {
+      avoidNew: 'Avoid creating new promises.',
+    },
   },
   create(context) {
     return {
       NewExpression(node) {
         if (node.callee.name === 'Promise') {
-          context.report({ node, message: 'Avoid creating new promises.' })
+          context.report({ node, messageId: 'avoidNew' })
         }
       },
     }
diff --git a/rules/lib/eslint-compat.js b/rules/lib/eslint-compat.js
new file mode 100644
index 0000000..bf969d2
--- /dev/null
+++ b/rules/lib/eslint-compat.js
@@ -0,0 +1,33 @@
+'use strict'
+
+function getSourceCode(context) {
+  if (context.sourceCode != null) {
+    return context.sourceCode
+  }
+
+  return context.getSourceCode()
+}
+
+function getAncestors(context, node) {
+  const sourceCode = getSourceCode(context)
+  if (typeof sourceCode.getAncestors === 'function') {
+    return sourceCode.getAncestors(node)
+  }
+
+  return context.getAncestors(node)
+}
+
+function getScope(context, node) {
+  const sourceCode = getSourceCode(context)
+  if (typeof sourceCode.getScope === 'function') {
+    return sourceCode.getScope(node)
+  }
+
+  return context.getScope(node)
+}
+
+module.exports = {
+  getSourceCode,
+  getAncestors,
+  getScope,
+}
diff --git a/rules/no-callback-in-promise.js b/rules/no-callback-in-promise.js
index 45d0bf0..cd86c47 100644
--- a/rules/no-callback-in-promise.js
+++ b/rules/no-callback-in-promise.js
@@ -5,11 +5,14 @@
 
 'use strict'
 
+const { getAncestors } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 const hasPromiseCallback = require('./lib/has-promise-callback')
 const isInsidePromise = require('./lib/is-inside-promise')
 const isCallback = require('./lib/is-callback')
 
+const CB_BLACKLIST = ['callback', 'cb', 'next', 'done']
+
 module.exports = {
   meta: {
     type: 'suggestion',
@@ -47,12 +50,7 @@ module.exports = {
           if (hasPromiseCallback(node)) {
             const name =
               node.arguments && node.arguments[0] && node.arguments[0].name
-            if (
-              name === 'callback' ||
-              name === 'cb' ||
-              name === 'next' ||
-              name === 'done'
-            ) {
+            if (!exceptions.includes(name) && CB_BLACKLIST.includes(name)) {
               context.report({
                 node: node.arguments[0],
                 messageId: 'callback',
@@ -61,7 +59,7 @@ module.exports = {
           }
           return
         }
-        if (context.getAncestors().some(isInsidePromise)) {
+        if (getAncestors(context, node).some(isInsidePromise)) {
           context.report({
             node,
             messageId: 'callback',
diff --git a/rules/no-multiple-resolved.js b/rules/no-multiple-resolved.js
index 4d45405..513290d 100644
--- a/rules/no-multiple-resolved.js
+++ b/rules/no-multiple-resolved.js
@@ -5,6 +5,7 @@
 
 'use strict'
 
+const { getScope } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 const {
   isPromiseConstructorWithInlineExecutor,
@@ -138,12 +139,22 @@ class CodePathInfo {
     /** @type {Map<CodePathSegment, CodePathSegmentInfo>} */
     this.segmentInfos = new Map()
     this.resolvedCount = 0
-    /** @type {CodePathSegment[]} */
-    this.allSegments = []
+    /** @type {Set<CodePathSegment>} */
+    this.currentSegments = new Set()
+  }
+
+  /** @param {CodePathSegment} segment */
+  onSegmentEnter(segment) {
+    this.currentSegments.add(segment)
+  }
+
+  /** @param {CodePathSegment} segment */
+  onSegmentExit(segment) {
+    this.currentSegments.delete(segment)
   }
 
   getCurrentSegmentInfos() {
-    return this.path.currentSegments.map((segment) => {
+    return [...this.currentSegments].map((segment) => {
       const info = this.segmentInfos.get(segment)
       if (info) {
         return info
@@ -400,7 +411,7 @@ module.exports = {
           (node) => node && node.type === 'Identifier'
         )
         for (const resolver of resolvers) {
-          const variable = context.getScope().set.get(resolver.name)
+          const variable = getScope(context, node).set.get(resolver.name)
           // istanbul ignore next -- Usually always present.
           if (!variable) continue
           for (const reference of variable.references) {
@@ -433,6 +444,15 @@ module.exports = {
       ) {
         lastThrowableExpression = node
       },
+      /** @param {CodePathSegment} segment */
+      onCodePathSegmentStart(segment) {
+        codePathInfoStack[0].onSegmentEnter(segment)
+      },
+      /** @param {CodePathSegment} segment */
+      /* istanbul ignore next */ // It is not called in ESLint v7.
+      onUnreachableCodePathSegmentStart(segment) {
+        codePathInfoStack[0].onSegmentEnter(segment)
+      },
       /**
        * @param {CodePathSegment} segment
        * @param {Node} node
@@ -452,6 +472,12 @@ module.exports = {
             promiseCodePathContext.addResolvedTryBlockCodePathSegment(segment)
           }
         }
+        codePathInfoStack[0].onSegmentExit(segment)
+      },
+      /** @param {CodePathSegment} segment */
+      /* istanbul ignore next */ // It is not called in ESLint v7.
+      onUnreachableCodePathSegmentEnd(segment) {
+        codePathInfoStack[0].onSegmentExit(segment)
       },
       /** @type {Identifier} */
       'CallExpression > Identifier.callee'(node) {
diff --git a/rules/no-native.js b/rules/no-native.js
index c92d60a..373c7f9 100644
--- a/rules/no-native.js
+++ b/rules/no-native.js
@@ -3,6 +3,7 @@
 
 'use strict'
 
+const { getScope } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 
 function isDeclared(scope, ref) {
@@ -45,8 +46,8 @@ module.exports = {
      * @private
      */
     return {
-      'Program:exit'() {
-        const scope = context.getScope()
+      'Program:exit'(node) {
+        const scope = getScope(context, node)
         const leftToBeResolved =
           scope.implicit.left ||
           /**
diff --git a/rules/no-nesting.js b/rules/no-nesting.js
index 128b391..ed9d08a 100644
--- a/rules/no-nesting.js
+++ b/rules/no-nesting.js
@@ -5,6 +5,7 @@
 
 'use strict'
 
+const { getScope } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 const hasPromiseCallback = require('./lib/has-promise-callback')
 const isInsidePromise = require('./lib/is-inside-promise')
@@ -17,6 +18,9 @@ module.exports = {
       url: getDocsUrl('no-nesting'),
     },
     schema: [],
+    messages: {
+      avoidNesting: 'Avoid nesting promises.',
+    },
   },
   create(context) {
     /**
@@ -41,7 +45,7 @@ module.exports = {
     return {
       ':function'(node) {
         if (isInsidePromise(node)) {
-          callbackScopes.unshift(context.getScope())
+          callbackScopes.unshift(getScope(context, node))
         }
       },
       ':function:exit'(node) {
@@ -111,7 +115,7 @@ module.exports = {
 
         context.report({
           node: node.callee.property,
-          message: 'Avoid nesting promises.',
+          messageId: 'avoidNesting',
         })
       },
     }
diff --git a/rules/no-new-statics.js b/rules/no-new-statics.js
index 0b79990..890fab8 100644
--- a/rules/no-new-statics.js
+++ b/rules/no-new-statics.js
@@ -12,6 +12,9 @@ module.exports = {
     },
     fixable: 'code',
     schema: [],
+    messages: {
+      avoidNewStatic: "Avoid calling 'new' on 'Promise.{{ name }}()'",
+    },
   },
   create(context) {
     return {
@@ -23,7 +26,7 @@ module.exports = {
         ) {
           context.report({
             node,
-            message: "Avoid calling 'new' on 'Promise.{{ name }}()'",
+            messageId: 'avoidNewStatic',
             data: { name: node.callee.property.name },
             fix(fixer) {
               return fixer.replaceTextRange(
diff --git a/rules/no-promise-in-callback.js b/rules/no-promise-in-callback.js
index 05b23d7..fefd22e 100644
--- a/rules/no-promise-in-callback.js
+++ b/rules/no-promise-in-callback.js
@@ -5,6 +5,7 @@
 
 'use strict'
 
+const { getAncestors } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 const isPromise = require('./lib/is-promise')
 const isInsideCallback = require('./lib/is-inside-callback')
@@ -17,6 +18,9 @@ module.exports = {
       url: getDocsUrl('no-promise-in-callback'),
     },
     schema: [],
+    messages: {
+      avoidPromiseInCallback: 'Avoid using promises inside of callbacks.',
+    },
   },
   create(context) {
     return {
@@ -30,10 +34,10 @@ module.exports = {
         // what about if the parent is an ArrowFunctionExpression
         // would that imply an implicit return?
 
-        if (context.getAncestors().some(isInsideCallback)) {
+        if (getAncestors(context, node).some(isInsideCallback)) {
           context.report({
             node: node.callee,
-            message: 'Avoid using promises inside of callbacks.',
+            messageId: 'avoidPromiseInCallback',
           })
         }
       },
diff --git a/rules/no-return-in-finally.js b/rules/no-return-in-finally.js
index bd57987..d9e3db8 100644
--- a/rules/no-return-in-finally.js
+++ b/rules/no-return-in-finally.js
@@ -11,6 +11,9 @@ module.exports = {
       url: getDocsUrl('no-return-in-finally'),
     },
     schema: [],
+    messages: {
+      avoidReturnInFinally: 'No return in finally',
+    },
   },
   create(context) {
     return {
@@ -35,7 +38,7 @@ module.exports = {
               ) {
                 context.report({
                   node: node.callee.property,
-                  message: 'No return in finally',
+                  messageId: 'avoidReturnInFinally',
                 })
               }
             }
diff --git a/rules/no-return-wrap.js b/rules/no-return-wrap.js
index 334f55d..5ab2ccb 100644
--- a/rules/no-return-wrap.js
+++ b/rules/no-return-wrap.js
@@ -6,12 +6,12 @@
 
 'use strict'
 
+const { getAncestors } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 const isPromise = require('./lib/is-promise')
 
-function isInPromise(context) {
-  let functionNode = context
-    .getAncestors()
+function isInPromise(context, node) {
+  let functionNode = getAncestors(context, node)
     .filter((node) => {
       return (
         node.type === 'ArrowFunctionExpression' ||
@@ -70,7 +70,7 @@ module.exports = {
      */
     function checkCallExpression({ callee }, node) {
       if (
-        isInPromise(context) &&
+        isInPromise(context, node) &&
         callee.type === 'MemberExpression' &&
         callee.object.name === 'Promise'
       ) {
diff --git a/rules/param-names.js b/rules/param-names.js
index bde6f04..c210d51 100644
--- a/rules/param-names.js
+++ b/rules/param-names.js
@@ -23,6 +23,12 @@ module.exports = {
         additionalProperties: false,
       },
     ],
+    messages: {
+      resolveParamNames:
+        'Promise constructor parameters must be named to match "{{ resolvePattern }}"',
+      rejectParamNames:
+        'Promise constructor parameters must be named to match "{{ rejectPattern }}"',
+    },
   },
   create(context) {
     const options = context.options[0] || {}
@@ -45,8 +51,7 @@ module.exports = {
           if (resolveParamName && !resolvePattern.test(resolveParamName)) {
             context.report({
               node: params[0],
-              message:
-                'Promise constructor parameters must be named to match "{{ resolvePattern }}"',
+              messageId: 'resolveParamNames',
               data: {
                 resolvePattern: resolvePattern.source,
               },
@@ -56,8 +61,7 @@ module.exports = {
           if (rejectParamName && !rejectPattern.test(rejectParamName)) {
             context.report({
               node: params[1],
-              message:
-                'Promise constructor parameters must be named to match "{{ rejectPattern }}"',
+              messageId: 'rejectParamNames',
               data: {
                 rejectPattern: rejectPattern.source,
               },
diff --git a/rules/prefer-await-to-callbacks.js b/rules/prefer-await-to-callbacks.js
index a0070fa..ca5f9ff 100644
--- a/rules/prefer-await-to-callbacks.js
+++ b/rules/prefer-await-to-callbacks.js
@@ -1,5 +1,6 @@
 'use strict'
 
+const { getAncestors } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 
 module.exports = {
@@ -21,8 +22,8 @@ module.exports = {
         context.report({ node: lastParam, messageId: 'error' })
       }
     }
-    function isInsideYieldOrAwait() {
-      return context.getAncestors().some((parent) => {
+    function isInsideYieldOrAwait(node) {
+      return getAncestors(context, node).some((parent) => {
         return (
           parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
         )
@@ -82,7 +83,7 @@ module.exports = {
             arg.params[0] &&
             (arg.params[0].name === 'err' || arg.params[0].name === 'error')
           ) {
-            if (!isInsideYieldOrAwait()) {
+            if (!isInsideYieldOrAwait(node)) {
               context.report({ node: arg, messageId: 'error' })
             }
           }
diff --git a/rules/prefer-await-to-then.js b/rules/prefer-await-to-then.js
index 2faba9f..0f3de93 100644
--- a/rules/prefer-await-to-then.js
+++ b/rules/prefer-await-to-then.js
@@ -5,6 +5,7 @@
 
 'use strict'
 
+const { getAncestors, getScope } = require('./lib/eslint-compat')
 const getDocsUrl = require('./lib/get-docs-url')
 
 module.exports = {
@@ -16,11 +17,14 @@ module.exports = {
       url: getDocsUrl('prefer-await-to-then'),
     },
     schema: [],
+    messages: {
+      preferAwaitToCallback: 'Prefer await to then()/catch()/finally().',
+    },
   },
   create(context) {
     /** Returns true if node is inside yield or await expression. */
-    function isInsideYieldOrAwait() {
-      return context.getAncestors().some((parent) => {
+    function isInsideYieldOrAwait(node) {
+      return getAncestors(context, node).some((parent) => {
         return (
           parent.type === 'AwaitExpression' || parent.type === 'YieldExpression'
         )
@@ -32,13 +36,13 @@ module.exports = {
      * Await statements are not allowed at the top level,
      * only within function declarations.
      */
-    function isTopLevelScoped() {
-      return context.getScope().block.type === 'Program'
+    function isTopLevelScoped(node) {
+      return getScope(context, node).block.type === 'Program'
     }
 
     return {
       'CallExpression > MemberExpression.callee'(node) {
-        if (isTopLevelScoped() || isInsideYieldOrAwait()) {
+        if (isTopLevelScoped(node) || isInsideYieldOrAwait(node)) {
           return
         }
 
@@ -51,7 +55,7 @@ module.exports = {
         ) {
           context.report({
             node: node.property,
-            message: 'Prefer await to then()/catch()/finally().',
+            messageId: 'preferAwaitToCallback',
           })
         }
       },
diff --git a/rules/valid-params.js b/rules/valid-params.js
index 714e9f6..f06c40e 100644
--- a/rules/valid-params.js
+++ b/rules/valid-params.js
@@ -12,6 +12,14 @@ module.exports = {
       url: getDocsUrl('valid-params'),
     },
     schema: [],
+    messages: {
+      requireOneOptionalArgument:
+        'Promise.{{ name }}() requires 0 or 1 arguments, but received {{ numArgs }}',
+      requireOneArgument:
+        'Promise.{{ name }}() requires 1 argument, but received {{ numArgs }}',
+      requireTwoOptionalArguments:
+        'Promise.{{ name }}() requires 1 or 2 arguments, but received {{ numArgs }}',
+    },
   },
   create(context) {
     return {
@@ -30,8 +38,7 @@ module.exports = {
             if (numArgs > 1) {
               context.report({
                 node,
-                message:
-                  'Promise.{{ name }}() requires 0 or 1 arguments, but received {{ numArgs }}',
+                messageId: 'requireOneOptionalArgument',
                 data: { name, numArgs },
               })
             }
@@ -40,8 +47,7 @@ module.exports = {
             if (numArgs < 1 || numArgs > 2) {
               context.report({
                 node,
-                message:
-                  'Promise.{{ name }}() requires 1 or 2 arguments, but received {{ numArgs }}',
+                messageId: 'requireTwoOptionalArguments',
                 data: { name, numArgs },
               })
             }
@@ -55,8 +61,7 @@ module.exports = {
             if (numArgs !== 1) {
               context.report({
                 node,
-                message:
-                  'Promise.{{ name }}() requires 1 argument, but received {{ numArgs }}',
+                messageId: 'requireOneArgument',
                 data: { name, numArgs },
               })
             }


Test patch:
diff --git a/__tests__/always-return.js b/__tests__/always-return.js
index df319dc..f9411f1 100644
--- a/__tests__/always-return.js
+++ b/__tests__/always-return.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/always-return')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 11,
diff --git a/__tests__/avoid-new.js b/__tests__/avoid-new.js
index 55b63af..dded79a 100644
--- a/__tests__/avoid-new.js
+++ b/__tests__/avoid-new.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/avoid-new')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,
diff --git a/__tests__/catch-or-return.js b/__tests__/catch-or-return.js
index 68d4135..c4426d5 100644
--- a/__tests__/catch-or-return.js
+++ b/__tests__/catch-or-return.js
@@ -1,8 +1,12 @@
 'use strict'
 
 const rule = require('../rules/catch-or-return')
-const RuleTester = require('eslint').RuleTester
-const ruleTester = new RuleTester()
+const { RuleTester } = require('./rule-tester')
+const ruleTester = new RuleTester({
+  parserOptions: {
+    ecmaVersion: 6,
+  },
+})
 
 const catchMessage = 'Expected catch() or return'
 const doneMessage = 'Expected done() or return'
@@ -19,10 +23,7 @@ ruleTester.run('catch-or-return', rule, {
     'frank.then(to).finally(fn).catch(jail)',
 
     // arrow function use case
-    {
-      code: 'postJSON("/smajobber/api/reportJob.json")\n\t.then(()=>this.setState())\n\t.catch(()=>this.setState())',
-      parserOptions: { ecmaVersion: 6 },
-    },
+    'postJSON("/smajobber/api/reportJob.json")\n\t.then(()=>this.setState())\n\t.catch(()=>this.setState())',
 
     // return
     'function a() { return frank().then(go) }',
diff --git a/__tests__/index.js b/__tests__/index.js
index fee0c7f..66198d9 100644
--- a/__tests__/index.js
+++ b/__tests__/index.js
@@ -3,3 +3,11 @@
 test('can require index file', () => {
   expect(require('../index')).toBeInstanceOf(Object)
 })
+
+test('rule set', () => {
+  const plugin = require('../index')
+  expect(plugin.configs.recommended.rules).toEqual(
+    plugin.configs['flat/recommended'].rules
+  )
+  expect(plugin.configs['flat/recommended'].plugins.promise).toBe(plugin)
+})
diff --git a/__tests__/no-callback-in-promise.js b/__tests__/no-callback-in-promise.js
index 606a6d2..eb59c9f 100644
--- a/__tests__/no-callback-in-promise.js
+++ b/__tests__/no-callback-in-promise.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-callback-in-promise')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,
@@ -34,6 +34,18 @@ ruleTester.run('no-callback-in-promise', rule, {
       code: 'a.then(() => next())',
       options: [{ exceptions: ['next'] }],
     },
+    {
+      code: 'a.then(() => next()).catch((err) => next(err))',
+      options: [{ exceptions: ['next'] }],
+    },
+    {
+      code: 'a.then(next)',
+      options: [{ exceptions: ['next'] }],
+    },
+    {
+      code: 'a.then(next).catch(next)',
+      options: [{ exceptions: ['next'] }],
+    },
   ],
 
   invalid: [
diff --git a/__tests__/no-multiple-resolved.js b/__tests__/no-multiple-resolved.js
index 1792025..4adf614 100644
--- a/__tests__/no-multiple-resolved.js
+++ b/__tests__/no-multiple-resolved.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-multiple-resolved')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 2020,
diff --git a/__tests__/no-native.js b/__tests__/no-native.js
index 77edce3..cd8d15c 100644
--- a/__tests__/no-native.js
+++ b/__tests__/no-native.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-native')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const parserOptions = {
   ecmaVersion: 6,
   sourceType: 'module',
diff --git a/__tests__/no-nesting.js b/__tests__/no-nesting.js
index 1943efa..722d104 100644
--- a/__tests__/no-nesting.js
+++ b/__tests__/no-nesting.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-nesting')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,
diff --git a/__tests__/no-new-statics.js b/__tests__/no-new-statics.js
index e0fbe21..96abe1e 100644
--- a/__tests__/no-new-statics.js
+++ b/__tests__/no-new-statics.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-new-statics')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester()
 
 ruleTester.run('no-new-statics', rule, {
diff --git a/__tests__/no-promise-in-callback.js b/__tests__/no-promise-in-callback.js
index 5f76664..a11142b 100644
--- a/__tests__/no-promise-in-callback.js
+++ b/__tests__/no-promise-in-callback.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-promise-in-callback')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,
diff --git a/__tests__/no-return-in-finally.js b/__tests__/no-return-in-finally.js
index 1e3ca83..7763686 100644
--- a/__tests__/no-return-in-finally.js
+++ b/__tests__/no-return-in-finally.js
@@ -1,6 +1,6 @@
 'use strict'
 
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const rule = require('../rules/no-return-in-finally')
 const ruleTester = new RuleTester({
   parserOptions: {
diff --git a/__tests__/no-return-wrap.js b/__tests__/no-return-wrap.js
index 601dcd5..eb7f082 100644
--- a/__tests__/no-return-wrap.js
+++ b/__tests__/no-return-wrap.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/no-return-wrap')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,
diff --git a/__tests__/param-names.js b/__tests__/param-names.js
index f4a8059..54416fc 100644
--- a/__tests__/param-names.js
+++ b/__tests__/param-names.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/param-names')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,
diff --git a/__tests__/prefer-await-to-callbacks.js b/__tests__/prefer-await-to-callbacks.js
index 4c391d7..3ea4d74 100644
--- a/__tests__/prefer-await-to-callbacks.js
+++ b/__tests__/prefer-await-to-callbacks.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/prefer-await-to-callbacks')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 8,
diff --git a/__tests__/prefer-await-to-then.js b/__tests__/prefer-await-to-then.js
index a01d33a..3bdf5bd 100644
--- a/__tests__/prefer-await-to-then.js
+++ b/__tests__/prefer-await-to-then.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/prefer-await-to-then')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 8,
diff --git a/__tests__/rule-tester.js b/__tests__/rule-tester.js
new file mode 100644
index 0000000..057a31e
--- /dev/null
+++ b/__tests__/rule-tester.js
@@ -0,0 +1,68 @@
+/**
+ * @fileoverview Helpers for tests.
+ * @author 唯然<weiran.zsd@outlook.com>
+ */
+'use strict'
+const { version } = require('eslint/package.json')
+const { RuleTester } = require('eslint')
+const globals = require('globals')
+
+const majorVersion = Number.parseInt(version.split('.')[0], 10)
+
+function convertConfig(config) {
+  if (config instanceof Object === false) {
+    return config
+  }
+
+  if (config.languageOptions == null) {
+    config.languageOptions = {}
+  }
+
+  if (config.parserOptions) {
+    Object.assign(config.languageOptions, config.parserOptions)
+    delete config.parserOptions
+  }
+
+  if (typeof config.parser === 'string') {
+    config.languageOptions.parser = require(config.parser)
+    delete config.parser
+  }
+
+  if (config.globals instanceof Object) {
+    config.languageOptions.globals = config.globals
+    delete config.globals
+  }
+
+  if (config.env instanceof Object) {
+    if (config.languageOptions.globals == null) {
+      config.languageOptions.globals = {}
+    }
+
+    for (const key in config.env) {
+      Object.assign(config.languageOptions.globals, globals[key])
+    }
+
+    delete config.env
+  }
+
+  delete config.parserOptions
+  delete config.parser
+
+  return config
+}
+
+exports.RuleTester = function (config = {}) {
+  if (majorVersion <= 8) {
+    return new RuleTester(config)
+  }
+
+  const ruleTester = new RuleTester(convertConfig(config))
+  const $run = ruleTester.run.bind(ruleTester)
+  ruleTester.run = function (name, rule, tests) {
+    tests.valid = tests.valid.map(convertConfig)
+    tests.invalid = tests.invalid.map(convertConfig)
+
+    $run(name, rule, tests)
+  }
+  return ruleTester
+}
diff --git a/__tests__/valid-params.js b/__tests__/valid-params.js
index ca671b9..968135c 100644
--- a/__tests__/valid-params.js
+++ b/__tests__/valid-params.js
@@ -1,7 +1,7 @@
 'use strict'
 
 const rule = require('../rules/valid-params')
-const RuleTester = require('eslint').RuleTester
+const { RuleTester } = require('./rule-tester')
 const ruleTester = new RuleTester({
   parserOptions: {
     ecmaVersion: 6,